| /* |
| * gstxcambufferpool.cpp - bufferpool |
| * |
| * Copyright (c) 2015 Intel Corporation |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| * Author: John Ye <[email protected]> |
| * Author: Wind Yuan <[email protected]> |
| */ |
| |
| /** |
| * SECTION:element-xcambufferpool |
| * |
| * FIXME:Describe xcambufferpool here. |
| * |
| * <refsect2> |
| * <title>Example launch line</title> |
| * |[ |
| * gst-launch -v -m fakesrc ! xcambufferpool ! fakesink silent=TRUE |
| * ]| |
| * </refsect2> |
| */ |
| |
| #include "gstxcambufferpool.h" |
| #include "gstxcambuffermeta.h" |
| |
| #include <gst/video/gstvideopool.h> |
| #include <gst/allocators/gstdmabuf.h> |
| #include <gst/gstmeta.h> |
| |
| using namespace XCam; |
| using namespace GstXCam; |
| |
| XCAM_BEGIN_DECLARE |
| |
| GST_DEBUG_CATEGORY_EXTERN (gst_xcam_src_debug); |
| #define GST_CAT_DEFAULT gst_xcam_src_debug |
| |
| G_DEFINE_TYPE (GstXCamBufferPool, gst_xcam_buffer_pool, GST_TYPE_BUFFER_POOL); |
| #define parent_class gst_xcam_buffer_pool_parent_class |
| |
| static void |
| gst_xcam_buffer_pool_finalize (GObject * object); |
| |
| static gboolean |
| gst_xcam_buffer_pool_start (GstBufferPool *pool); |
| |
| static gboolean |
| gst_xcam_buffer_pool_stop (GstBufferPool *pool); |
| |
| static gboolean |
| gst_xcam_buffer_pool_set_config (GstBufferPool *pool, GstStructure *config); |
| |
| static GstFlowReturn |
| gst_xcam_buffer_pool_acquire_buffer ( |
| GstBufferPool *bpool, |
| GstBuffer **buffer, |
| GstBufferPoolAcquireParams *params); |
| |
| static void |
| gst_xcam_buffer_pool_release_buffer (GstBufferPool *bpool, GstBuffer *buffer); |
| |
| |
| XCAM_END_DECLARE |
| |
| static void |
| gst_xcam_buffer_pool_class_init (GstXCamBufferPoolClass * class_self) |
| { |
| GObjectClass *object_class; |
| GstBufferPoolClass *bufferpool_class; |
| |
| object_class = G_OBJECT_CLASS (class_self); |
| bufferpool_class = GST_BUFFER_POOL_CLASS (class_self); |
| |
| object_class->finalize = gst_xcam_buffer_pool_finalize; |
| |
| bufferpool_class->start = gst_xcam_buffer_pool_start; |
| bufferpool_class->stop = gst_xcam_buffer_pool_stop; |
| bufferpool_class->set_config = gst_xcam_buffer_pool_set_config; |
| bufferpool_class->acquire_buffer = gst_xcam_buffer_pool_acquire_buffer; |
| bufferpool_class->release_buffer = gst_xcam_buffer_pool_release_buffer; |
| |
| } |
| |
| static void |
| gst_xcam_buffer_pool_init (GstXCamBufferPool *pool) |
| { |
| pool->need_video_meta = FALSE; |
| XCAM_CONSTRUCTOR (pool->device_manager, SmartPtr<MainDeviceManager>); |
| } |
| |
| static void |
| gst_xcam_buffer_pool_finalize (GObject * object) |
| { |
| GstXCamBufferPool *pool = GST_XCAM_BUFFER_POOL (object); |
| XCAM_ASSERT (pool); |
| |
| if (pool->src) |
| gst_object_unref (pool->src); |
| if (pool->allocator) |
| gst_object_unref (pool->allocator); |
| XCAM_DESTRUCTOR (pool->device_manager, SmartPtr<MainDeviceManager>); |
| } |
| |
| static gboolean |
| gst_xcam_buffer_pool_start (GstBufferPool *base_pool) |
| { |
| GstXCamBufferPool *pool = GST_XCAM_BUFFER_POOL (base_pool); |
| XCAM_ASSERT (pool); |
| SmartPtr<MainDeviceManager> device_manager = pool->device_manager; |
| XCAM_ASSERT (device_manager.ptr ()); |
| device_manager->resume_dequeue (); |
| return TRUE; |
| } |
| |
| static gboolean |
| gst_xcam_buffer_pool_stop (GstBufferPool *base_pool) |
| { |
| GstXCamBufferPool *pool = GST_XCAM_BUFFER_POOL (base_pool); |
| XCAM_ASSERT (pool); |
| SmartPtr<MainDeviceManager> device_manager = pool->device_manager; |
| XCAM_ASSERT (device_manager.ptr ()); |
| |
| device_manager->pause_dequeue (); |
| return TRUE; |
| } |
| |
| gboolean |
| gst_xcam_buffer_pool_set_config (GstBufferPool *base_pool, GstStructure *config) |
| { |
| GstXCamBufferPool *pool = GST_XCAM_BUFFER_POOL (base_pool); |
| |
| XCAM_ASSERT (pool); |
| pool->need_video_meta = gst_buffer_pool_config_has_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); |
| |
| pool->allocator = gst_dmabuf_allocator_new (); |
| if (pool->allocator == NULL) { |
| GST_WARNING ("xcam buffer pool get allocator failed"); |
| return FALSE; |
| } |
| |
| return TRUE; |
| } |
| |
| static GstFlowReturn |
| gst_xcam_buffer_pool_acquire_buffer ( |
| GstBufferPool *base_pool, |
| GstBuffer **buffer, |
| GstBufferPoolAcquireParams *params) |
| { |
| GstXCamBufferPool *pool = GST_XCAM_BUFFER_POOL (base_pool); |
| XCAM_ASSERT (pool); |
| GstBuffer *out_buf = NULL; |
| GstMemory *mem = NULL; |
| GstXCamBufferMeta *meta = NULL; |
| SmartPtr<MainDeviceManager> device_manager = pool->device_manager; |
| SmartPtr<VideoBuffer> video_buf = device_manager->dequeue_buffer (); |
| VideoBufferInfo video_info; |
| gsize offsets[XCAM_VIDEO_MAX_COMPONENTS]; |
| |
| XCAM_UNUSED (params); |
| |
| if (!video_buf.ptr ()) |
| return GST_FLOW_ERROR; |
| |
| video_info = video_buf->get_video_info (); |
| for (int i = 0; i < XCAM_VIDEO_MAX_COMPONENTS; i++) { |
| offsets[i] = video_info.offsets[i]; |
| } |
| |
| out_buf = gst_buffer_new (); |
| meta = gst_buffer_add_xcam_buffer_meta (out_buf, video_buf); |
| XCAM_ASSERT (meta); |
| ((GstMeta *)(meta))->flags = (GstMetaFlags)(GST_META_FLAG_POOLED | GST_META_FLAG_LOCKED | GST_META_FLAG_READONLY); |
| //GST_META_FLAG_SET (meta, (GST_META_FLAG_POOLED | GST_META_FLAG_LOCKED | GST_META_FLAG_READONLY)); |
| |
| if (GST_XCAM_SRC_MEM_MODE (pool->src) == V4L2_MEMORY_DMABUF) { |
| mem = gst_dmabuf_allocator_alloc ( |
| pool->allocator, dup (video_buf->get_fd ()), video_buf->get_size ()); |
| } else if (GST_XCAM_SRC_MEM_MODE (pool->src) == V4L2_MEMORY_MMAP) { |
| mem = gst_memory_new_wrapped ( |
| (GstMemoryFlags)(GST_MEMORY_FLAG_READONLY | GST_MEMORY_FLAG_NO_SHARE), |
| video_buf->map (), video_buf->get_size (), |
| video_info.offsets[0], video_info.size, |
| NULL, NULL); |
| } else { |
| GST_WARNING ("xcam buffer pool acquire buffer failed since mem_type not supported"); |
| return GST_FLOW_ERROR; |
| } |
| |
| XCAM_ASSERT (mem); |
| gst_buffer_append_memory (out_buf, mem); |
| if (pool->need_video_meta) { |
| GstVideoMeta *video_meta = |
| gst_buffer_add_video_meta_full ( |
| out_buf, GST_VIDEO_FRAME_FLAG_NONE, |
| GST_VIDEO_INFO_FORMAT (GST_XCAM_SRC_OUT_VIDEO_INFO (pool->src)), |
| video_info.width, |
| video_info.height, |
| video_info.components, |
| offsets, |
| (gint*)(video_info.strides)); |
| XCAM_ASSERT (video_meta); |
| // TODO, consider map and unmap later |
| video_meta->map = NULL; |
| video_meta->unmap = NULL; |
| } |
| |
| GST_BUFFER_TIMESTAMP (out_buf) = video_buf->get_timestamp () * 1000; //us to ns |
| |
| *buffer = out_buf; |
| return GST_FLOW_OK; |
| } |
| |
| static void |
| gst_xcam_buffer_pool_release_buffer (GstBufferPool *base_pool, GstBuffer *buffer) |
| { |
| XCAM_UNUSED (base_pool); |
| gst_buffer_unref (buffer); |
| } |
| |
| GstBufferPool * |
| gst_xcam_buffer_pool_new (GstXCamSrc *src, GstCaps *caps, SmartPtr<MainDeviceManager> &device_manager) |
| { |
| GstXCamBufferPool *pool; |
| GstStructure *structure; |
| |
| pool = (GstXCamBufferPool *)g_object_new (GST_TYPE_XCAM_BUFFER_POOL, NULL); |
| XCAM_ASSERT (pool); |
| |
| structure = gst_buffer_pool_get_config (GST_BUFFER_POOL_CAST (pool)); |
| XCAM_ASSERT (structure); |
| gst_buffer_pool_config_set_params ( |
| structure, caps, |
| GST_VIDEO_INFO_SIZE (GST_XCAM_SRC_OUT_VIDEO_INFO (src)), |
| GST_XCAM_SRC_BUF_COUNT (src), |
| GST_XCAM_SRC_BUF_COUNT (src)); |
| gst_buffer_pool_config_add_option (structure, GST_BUFFER_POOL_OPTION_VIDEO_META); |
| gst_buffer_pool_set_config (GST_BUFFER_POOL_CAST (pool), structure); |
| |
| pool->src = src; |
| gst_object_ref (src); |
| pool->device_manager = device_manager; |
| return GST_BUFFER_POOL (pool); |
| } |