You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
280 lines
8.7 KiB
280 lines
8.7 KiB
/*
|
|
* 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 <john.ye@intel.com>
|
|
* Author: Wind Yuan <feng.yuan@intel.com>
|
|
*/
|
|
|
|
/**
|
|
* 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<RkispDeviceManager>);
|
|
}
|
|
|
|
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<RkispDeviceManager>);
|
|
}
|
|
|
|
static gboolean
|
|
gst_xcam_buffer_pool_start (GstBufferPool *base_pool)
|
|
{
|
|
GstXCamBufferPool *pool = GST_XCAM_BUFFER_POOL (base_pool);
|
|
XCAM_ASSERT (pool);
|
|
SmartPtr<RkispDeviceManager> 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<RkispDeviceManager> 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 int frame = 0;
|
|
static int frameindex = 0;
|
|
|
|
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<RkispDeviceManager> 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);
|
|
|
|
SmartPtr<V4l2BufferProxy> video_buf_proxy = video_buf.dynamic_cast_ptr<V4l2BufferProxy> ();
|
|
//XCAM_LOG_DEBUG ("xcam buffer pool acquire buffer index: %d", video_buf_proxy->get_v4l2_buf_index());
|
|
|
|
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];
|
|
}
|
|
|
|
//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) {
|
|
out_buf = gst_buffer_new ();
|
|
mem = gst_dmabuf_allocator_alloc (
|
|
pool->allocator, dup (video_buf->get_fd ()), video_buf->get_size ());
|
|
|
|
XCAM_ASSERT (mem);
|
|
gst_buffer_append_memory (out_buf, mem);
|
|
} else if (GST_XCAM_SRC_MEM_MODE (pool->src) == V4L2_MEMORY_MMAP) {
|
|
#if 0
|
|
if (frame%2 == 0)
|
|
memset(video_buf->map (), 100, video_buf->get_size () / 2);
|
|
else
|
|
memset(video_buf->map () + video_buf->get_size () / 2, 100, video_buf->get_size () / 2);
|
|
|
|
frame++;
|
|
#endif
|
|
XCAM_LOG_DEBUG ("xcam buffer pool acquire buffer(%.8x) size: %d", video_buf->map (), video_buf->get_size ());
|
|
|
|
out_buf = gst_buffer_new_allocate (NULL, video_buf->get_size (), NULL);
|
|
gst_buffer_fill (out_buf, 0, video_buf->map (), video_buf->get_size ());
|
|
/*
|
|
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;
|
|
}
|
|
|
|
//gst_buffer_replace_all_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 = gst_buffer_copy(out_buf);
|
|
*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<RkispDeviceManager> &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);
|
|
}
|