mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-09-25 05:20:31 +00:00
video: support allocate multi plane in one gstbuffer
in this modification, a `GST_BUFFER_POOL_OPTION_VIDEO_MULTI_PLANE` option has been added. When this option is enabled, if the requested format `GST_VIDEO_INFO_N_PLANES` is greater than 1, each plane will be individually created as a `GstMemory` and then encapsulated into a `GstBuffer`. This change is very useful when the driver requires data from multiple planes. such as v4l2 elements, driver expected multi gstmemory in one gstbuffer, and each gstmemory contain a dma fd.
This commit is contained in:
parent
802b27ca04
commit
54c5d689ec
2 changed files with 58 additions and 5 deletions
|
@ -101,6 +101,7 @@ struct _GstVideoBufferPoolPrivate
|
|||
GstVideoAlignment video_align;
|
||||
gboolean add_videometa;
|
||||
gboolean need_alignment;
|
||||
gboolean multi_plane;
|
||||
GstAllocator *allocator;
|
||||
GstAllocationParams params;
|
||||
};
|
||||
|
@ -115,7 +116,8 @@ static const gchar **
|
|||
video_buffer_pool_get_options (GstBufferPool * pool)
|
||||
{
|
||||
static const gchar *options[] = { GST_BUFFER_POOL_OPTION_VIDEO_META,
|
||||
GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT, NULL
|
||||
GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT,
|
||||
GST_BUFFER_POOL_OPTION_VIDEO_MULTI_PLANE, NULL
|
||||
};
|
||||
return options;
|
||||
}
|
||||
|
@ -169,6 +171,10 @@ video_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config)
|
|||
priv->need_alignment = gst_buffer_pool_config_has_option (config,
|
||||
GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT);
|
||||
|
||||
/* parse multi plane info */
|
||||
priv->multi_plane = gst_buffer_pool_config_has_option (config,
|
||||
GST_BUFFER_POOL_OPTION_VIDEO_MULTI_PLANE);
|
||||
|
||||
if (priv->need_alignment && priv->add_videometa) {
|
||||
guint max_align, n;
|
||||
|
||||
|
@ -235,6 +241,25 @@ failed_to_align:
|
|||
}
|
||||
}
|
||||
|
||||
static int
|
||||
video_buffer_pool_get_plane_size (GstVideoInfo * info, int plane)
|
||||
{
|
||||
int plane_num = GST_VIDEO_INFO_N_PLANES (info);
|
||||
gsize cur_offset = GST_VIDEO_INFO_PLANE_OFFSET (info, plane);
|
||||
gsize next_offset = (plane == (plane_num - 1)) ?
|
||||
GST_VIDEO_INFO_SIZE (info) :
|
||||
GST_VIDEO_INFO_PLANE_OFFSET (info, plane + 1);
|
||||
|
||||
gsize plane_size = next_offset - cur_offset;
|
||||
|
||||
GST_DEBUG ("plane: %d size: %" G_GSIZE_FORMAT
|
||||
" cur_offset: %" G_GSIZE_FORMAT
|
||||
" next_offset: %" G_GSIZE_FORMAT,
|
||||
plane, plane_size, cur_offset, next_offset);
|
||||
|
||||
return plane_size;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
video_buffer_pool_alloc (GstBufferPool * pool, GstBuffer ** buffer,
|
||||
GstBufferPoolAcquireParams * params)
|
||||
|
@ -247,10 +272,30 @@ video_buffer_pool_alloc (GstBufferPool * pool, GstBuffer ** buffer,
|
|||
|
||||
GST_DEBUG_OBJECT (pool, "alloc %" G_GSIZE_FORMAT, info->size);
|
||||
|
||||
*buffer =
|
||||
gst_buffer_new_allocate (priv->allocator, info->size, &priv->params);
|
||||
if (*buffer == NULL)
|
||||
goto no_memory;
|
||||
if (!priv->multi_plane) {
|
||||
*buffer =
|
||||
gst_buffer_new_allocate (priv->allocator, info->size, &priv->params);
|
||||
if (*buffer == NULL)
|
||||
goto no_memory;
|
||||
} else {
|
||||
gint plane_num = GST_VIDEO_INFO_N_PLANES (info);
|
||||
|
||||
*buffer = gst_buffer_new ();
|
||||
if (*buffer == NULL)
|
||||
goto no_memory;
|
||||
|
||||
for (int plane = 0; plane < plane_num; plane++) {
|
||||
GstMemory *mem = gst_allocator_alloc (priv->allocator,
|
||||
video_buffer_pool_get_plane_size (info, plane), &priv->params);
|
||||
if (mem == NULL) {
|
||||
gst_buffer_unref (*buffer);
|
||||
*buffer = NULL;
|
||||
goto no_memory;
|
||||
}
|
||||
|
||||
gst_buffer_append_memory (*buffer, mem);
|
||||
}
|
||||
}
|
||||
|
||||
if (priv->add_videometa) {
|
||||
GST_DEBUG_OBJECT (pool, "adding GstVideoMeta");
|
||||
|
|
|
@ -45,6 +45,14 @@ G_BEGIN_DECLS
|
|||
*/
|
||||
#define GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT "GstBufferPoolOptionVideoAlignment"
|
||||
|
||||
/**
|
||||
* GST_BUFFER_POOL_OPTION_VIDEO_MULTI_PLANE:
|
||||
*
|
||||
* An option that can be activated on bufferpool to request
|
||||
* multi gstmemory in a gstbuffer when possible
|
||||
*/
|
||||
#define GST_BUFFER_POOL_OPTION_VIDEO_MULTI_PLANE "GstBufferPoolOptionVideoMultiPlane"
|
||||
|
||||
/* setting a bufferpool config */
|
||||
|
||||
GST_VIDEO_API
|
||||
|
|
Loading…
Reference in a new issue