mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-06-23 16:30:40 +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
|
@ -101,6 +101,7 @@ struct _GstVideoBufferPoolPrivate
|
||||||
GstVideoAlignment video_align;
|
GstVideoAlignment video_align;
|
||||||
gboolean add_videometa;
|
gboolean add_videometa;
|
||||||
gboolean need_alignment;
|
gboolean need_alignment;
|
||||||
|
gboolean multi_plane;
|
||||||
GstAllocator *allocator;
|
GstAllocator *allocator;
|
||||||
GstAllocationParams params;
|
GstAllocationParams params;
|
||||||
};
|
};
|
||||||
|
@ -115,7 +116,8 @@ static const gchar **
|
||||||
video_buffer_pool_get_options (GstBufferPool * pool)
|
video_buffer_pool_get_options (GstBufferPool * pool)
|
||||||
{
|
{
|
||||||
static const gchar *options[] = { GST_BUFFER_POOL_OPTION_VIDEO_META,
|
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;
|
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,
|
priv->need_alignment = gst_buffer_pool_config_has_option (config,
|
||||||
GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT);
|
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) {
|
if (priv->need_alignment && priv->add_videometa) {
|
||||||
guint max_align, n;
|
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
|
static GstFlowReturn
|
||||||
video_buffer_pool_alloc (GstBufferPool * pool, GstBuffer ** buffer,
|
video_buffer_pool_alloc (GstBufferPool * pool, GstBuffer ** buffer,
|
||||||
GstBufferPoolAcquireParams * params)
|
GstBufferPoolAcquireParams * params)
|
||||||
|
@ -247,10 +272,30 @@ video_buffer_pool_alloc (GstBufferPool * pool, GstBuffer ** buffer,
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (pool, "alloc %" G_GSIZE_FORMAT, info->size);
|
GST_DEBUG_OBJECT (pool, "alloc %" G_GSIZE_FORMAT, info->size);
|
||||||
|
|
||||||
*buffer =
|
if (!priv->multi_plane) {
|
||||||
gst_buffer_new_allocate (priv->allocator, info->size, &priv->params);
|
*buffer =
|
||||||
if (*buffer == NULL)
|
gst_buffer_new_allocate (priv->allocator, info->size, &priv->params);
|
||||||
goto no_memory;
|
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) {
|
if (priv->add_videometa) {
|
||||||
GST_DEBUG_OBJECT (pool, "adding GstVideoMeta");
|
GST_DEBUG_OBJECT (pool, "adding GstVideoMeta");
|
||||||
|
|
|
@ -45,6 +45,14 @@ G_BEGIN_DECLS
|
||||||
*/
|
*/
|
||||||
#define GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT "GstBufferPoolOptionVideoAlignment"
|
#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 */
|
/* setting a bufferpool config */
|
||||||
|
|
||||||
GST_VIDEO_API
|
GST_VIDEO_API
|
||||||
|
|
Loading…
Reference in a new issue