plugins: base: manage pad-specific data in a single struct

Define a struct (GstVaapiPadPrivate) to encapsulate the
pad-specific data (i.e. buffer pool, allocator, info,
caps, etc.).

Add an interface to retrieve the data struct for a given
pad.

Finally, update the base plugin to use the data struct
throughout the implementation.

This will enable us to easily extend the base plugin in the
future to allow for N-to-1 pad subclasses (e.g. overlay/
composite).
This commit is contained in:
U. Artie Eoff 2019-11-12 12:21:52 -08:00 committed by GStreamer Merge Bot
parent b384593d3d
commit ca2942176b
2 changed files with 195 additions and 120 deletions

View file

@ -40,6 +40,44 @@ GST_DEBUG_CATEGORY_STATIC (CAT_PERFORMANCE);
#define BUFFER_POOL_SINK_MIN_BUFFERS 2 #define BUFFER_POOL_SINK_MIN_BUFFERS 2
#define GST_VAAPI_PAD_PRIVATE(pad) \
(GST_VAAPI_PLUGIN_BASE_GET_CLASS(plugin)->get_vaapi_pad_private(plugin, pad))
GstVaapiPadPrivate *
gst_vaapi_pad_private_new (void)
{
GstVaapiPadPrivate *priv = g_new0 (GstVaapiPadPrivate, 1);
gst_video_info_init (&priv->info);
return priv;
}
void
gst_vaapi_pad_private_reset (GstVaapiPadPrivate * priv)
{
g_assert (priv);
gst_caps_replace (&priv->caps, NULL);
gst_video_info_init (&priv->info);
g_clear_object (&priv->buffer_pool);
g_clear_object (&priv->allocator);
priv->buffer_size = 0;
priv->caps_is_raw = FALSE;
g_clear_object (&priv->other_allocator);
priv->can_dmabuf = FALSE;
}
void
gst_vaapi_pad_private_finalize (GstVaapiPadPrivate * priv)
{
gst_vaapi_pad_private_reset (priv);
g_free (priv);
}
/* GstVideoContext interface */ /* GstVideoContext interface */
static void static void
plugin_set_display (GstVaapiPluginBase * plugin, GstVaapiDisplay * display) plugin_set_display (GstVaapiPluginBase * plugin, GstVaapiDisplay * display)
@ -125,7 +163,8 @@ static gboolean
plugin_update_sinkpad_info_from_buffer (GstVaapiPluginBase * plugin, plugin_update_sinkpad_info_from_buffer (GstVaapiPluginBase * plugin,
GstBuffer * buf) GstBuffer * buf)
{ {
GstVideoInfo *const vip = &plugin->sinkpad_info; GstVaapiPadPrivate *sinkpriv = GST_VAAPI_PAD_PRIVATE (plugin->sinkpad);
GstVideoInfo *const vip = &sinkpriv->info;
GstVideoMeta *vmeta; GstVideoMeta *vmeta;
guint i; guint i;
@ -165,7 +204,8 @@ static gboolean
plugin_bind_dma_to_vaapi_buffer (GstVaapiPluginBase * plugin, plugin_bind_dma_to_vaapi_buffer (GstVaapiPluginBase * plugin,
GstBuffer * inbuf, GstBuffer * outbuf) GstBuffer * inbuf, GstBuffer * outbuf)
{ {
GstVideoInfo *const vip = &plugin->sinkpad_info; GstVaapiPadPrivate *sinkpriv = GST_VAAPI_PAD_PRIVATE (plugin->sinkpad);
GstVideoInfo *const vip = &sinkpriv->info;
GstVaapiVideoMeta *meta; GstVaapiVideoMeta *meta;
GstVaapiSurface *surface; GstVaapiSurface *surface;
GstVaapiSurfaceProxy *proxy; GstVaapiSurfaceProxy *proxy;
@ -228,11 +268,22 @@ plugin_reset_texture_map (GstVaapiPluginBase * plugin)
gst_vaapi_display_reset_texture_map (plugin->display); gst_vaapi_display_reset_texture_map (plugin->display);
} }
static GstVaapiPadPrivate *
default_get_vaapi_pad_private (GstVaapiPluginBase * plugin, GstPad * pad)
{
if (plugin->sinkpad == pad)
return plugin->sinkpriv;
g_assert (plugin->srcpad == pad);
return plugin->srcpriv;
}
void void
gst_vaapi_plugin_base_class_init (GstVaapiPluginBaseClass * klass) gst_vaapi_plugin_base_class_init (GstVaapiPluginBaseClass * klass)
{ {
klass->has_interface = default_has_interface; klass->has_interface = default_has_interface;
klass->display_changed = default_display_changed; klass->display_changed = default_display_changed;
klass->get_vaapi_pad_private = default_get_vaapi_pad_private;
} }
void void
@ -245,12 +296,16 @@ gst_vaapi_plugin_base_init (GstVaapiPluginBase * plugin,
/* sink pad */ /* sink pad */
plugin->sinkpad = gst_element_get_static_pad (GST_ELEMENT (plugin), "sink"); plugin->sinkpad = gst_element_get_static_pad (GST_ELEMENT (plugin), "sink");
gst_video_info_init (&plugin->sinkpad_info);
if (plugin->sinkpad)
plugin->sinkpriv = gst_vaapi_pad_private_new ();
/* src pad */ /* src pad */
if (!(GST_OBJECT_FLAGS (plugin) & GST_ELEMENT_FLAG_SINK)) if (!(GST_OBJECT_FLAGS (plugin) & GST_ELEMENT_FLAG_SINK))
plugin->srcpad = gst_element_get_static_pad (GST_ELEMENT (plugin), "src"); plugin->srcpad = gst_element_get_static_pad (GST_ELEMENT (plugin), "src");
gst_video_info_init (&plugin->srcpad_info);
if (plugin->srcpad)
plugin->srcpriv = gst_vaapi_pad_private_new ();
plugin->enable_direct_rendering = plugin->enable_direct_rendering =
(g_getenv ("GST_VAAPI_ENABLE_DIRECT_RENDERING") != NULL); (g_getenv ("GST_VAAPI_ENABLE_DIRECT_RENDERING") != NULL);
@ -261,6 +316,12 @@ gst_vaapi_plugin_base_finalize (GstVaapiPluginBase * plugin)
{ {
gst_vaapi_plugin_base_close (plugin); gst_vaapi_plugin_base_close (plugin);
g_free (plugin->display_name); g_free (plugin->display_name);
if (plugin->sinkpriv)
gst_vaapi_pad_private_finalize (plugin->sinkpriv);
if (plugin->srcpriv)
gst_vaapi_pad_private_finalize (plugin->srcpriv);
if (plugin->sinkpad) if (plugin->sinkpad)
gst_object_unref (plugin->sinkpad); gst_object_unref (plugin->sinkpad);
if (plugin->srcpad) if (plugin->srcpad)
@ -300,19 +361,12 @@ gst_vaapi_plugin_base_close (GstVaapiPluginBase * plugin)
gst_object_replace (&plugin->gl_display, NULL); gst_object_replace (&plugin->gl_display, NULL);
gst_object_replace (&plugin->gl_other_context, NULL); gst_object_replace (&plugin->gl_other_context, NULL);
gst_caps_replace (&plugin->sinkpad_caps, NULL);
gst_video_info_init (&plugin->sinkpad_info);
g_clear_object (&plugin->sinkpad_buffer_pool);
g_clear_object (&plugin->srcpad_buffer_pool);
g_clear_object (&plugin->sinkpad_allocator);
g_clear_object (&plugin->srcpad_allocator);
g_clear_object (&plugin->other_srcpad_allocator);
gst_caps_replace (&plugin->srcpad_caps, NULL);
gst_video_info_init (&plugin->srcpad_info);
gst_caps_replace (&plugin->allowed_raw_caps, NULL); gst_caps_replace (&plugin->allowed_raw_caps, NULL);
if (plugin->sinkpriv)
gst_vaapi_pad_private_reset (plugin->sinkpriv);
if (plugin->srcpriv)
gst_vaapi_pad_private_reset (plugin->srcpriv);
} }
/** /**
@ -438,6 +492,7 @@ static gboolean
ensure_sinkpad_allocator (GstVaapiPluginBase * plugin, GstCaps * caps, ensure_sinkpad_allocator (GstVaapiPluginBase * plugin, GstCaps * caps,
guint * size) guint * size)
{ {
GstVaapiPadPrivate *sinkpriv = GST_VAAPI_PAD_PRIVATE (plugin->sinkpad);
GstVideoInfo vinfo; GstVideoInfo vinfo;
const GstVideoInfo *image_info; const GstVideoInfo *image_info;
GstVaapiImageUsageFlags usage_flag = GstVaapiImageUsageFlags usage_flag =
@ -446,7 +501,7 @@ ensure_sinkpad_allocator (GstVaapiPluginBase * plugin, GstCaps * caps,
if (!gst_video_info_from_caps (&vinfo, caps)) if (!gst_video_info_from_caps (&vinfo, caps))
goto error_invalid_caps; goto error_invalid_caps;
if (!reset_allocator (plugin->sinkpad_allocator, &vinfo)) if (!reset_allocator (sinkpriv->allocator, &vinfo))
goto bail; goto bail;
/* enable direct upload if upstream requests raw video */ /* enable direct upload if upstream requests raw video */
@ -454,15 +509,14 @@ ensure_sinkpad_allocator (GstVaapiPluginBase * plugin, GstCaps * caps,
usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_UPLOAD; usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_UPLOAD;
GST_INFO_OBJECT (plugin, "enabling direct upload in sink allocator"); GST_INFO_OBJECT (plugin, "enabling direct upload in sink allocator");
} }
plugin->sinkpad_allocator = sinkpriv->allocator =
gst_vaapi_video_allocator_new (plugin->display, &vinfo, 0, usage_flag); gst_vaapi_video_allocator_new (plugin->display, &vinfo, 0, usage_flag);
bail: bail:
if (!plugin->sinkpad_allocator) if (!sinkpriv->allocator)
goto error_create_allocator; goto error_create_allocator;
image_info = image_info = gst_allocator_get_vaapi_video_info (sinkpriv->allocator, NULL);
gst_allocator_get_vaapi_video_info (plugin->sinkpad_allocator, NULL);
g_assert (image_info); /* allocator ought set its image info */ g_assert (image_info); /* allocator ought set its image info */
/* update the size with the one generated by the allocator */ /* update the size with the one generated by the allocator */
@ -532,25 +586,25 @@ static gboolean
ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo, ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo,
GstCaps * caps) GstCaps * caps)
{ {
GstVaapiPadPrivate *srcpriv = GST_VAAPI_PAD_PRIVATE (plugin->srcpad);
const GstVideoInfo *image_info; const GstVideoInfo *image_info;
if (!reset_allocator (plugin->srcpad_allocator, vinfo)) if (!reset_allocator (srcpriv->allocator, vinfo))
goto valid_allocator; goto valid_allocator;
plugin->srcpad_allocator = NULL; srcpriv->allocator = NULL;
if (caps && gst_caps_is_video_raw (caps)) { if (caps && gst_caps_is_video_raw (caps)) {
GstAllocator *allocator = create_dmabuf_srcpad_allocator (plugin, vinfo, GstAllocator *allocator = create_dmabuf_srcpad_allocator (plugin, vinfo,
!plugin->srcpad_can_dmabuf); !srcpriv->can_dmabuf);
plugin->srcpad_allocator = allocator; srcpriv->allocator = allocator;
} else if (caps && gst_vaapi_caps_feature_contains (caps, } else if (caps && gst_vaapi_caps_feature_contains (caps,
GST_VAAPI_CAPS_FEATURE_DMABUF)) { GST_VAAPI_CAPS_FEATURE_DMABUF)) {
plugin->srcpad_allocator = srcpriv->allocator = create_dmabuf_srcpad_allocator (plugin, vinfo, FALSE);
create_dmabuf_srcpad_allocator (plugin, vinfo, FALSE); if (!srcpriv->allocator)
if (!plugin->srcpad_allocator)
goto error_create_allocator; goto error_create_allocator;
} }
if (!plugin->srcpad_allocator) { if (!srcpriv->allocator) {
GstVaapiImageUsageFlags usage_flag = GstVaapiImageUsageFlags usage_flag =
GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS; GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS;
@ -559,16 +613,15 @@ ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo,
GST_INFO_OBJECT (plugin, "enabling direct rendering in source allocator"); GST_INFO_OBJECT (plugin, "enabling direct rendering in source allocator");
} }
plugin->srcpad_allocator = srcpriv->allocator =
gst_vaapi_video_allocator_new (plugin->display, vinfo, 0, usage_flag); gst_vaapi_video_allocator_new (plugin->display, vinfo, 0, usage_flag);
} }
if (!plugin->srcpad_allocator) if (!srcpriv->allocator)
goto error_create_allocator; goto error_create_allocator;
valid_allocator: valid_allocator:
image_info = image_info = gst_allocator_get_vaapi_video_info (srcpriv->allocator, NULL);
gst_allocator_get_vaapi_video_info (plugin->srcpad_allocator, NULL);
g_assert (image_info); /* both allocators ought set its image g_assert (image_info); /* both allocators ought set its image
* info */ * info */
@ -580,15 +633,14 @@ valid_allocator:
* different from the "negotiation caps". In this case, we should * different from the "negotiation caps". In this case, we should
* indicate the allocator to store the negotiation caps since they * indicate the allocator to store the negotiation caps since they
* are the one should be used for frame mapping with GstVideoMeta */ * are the one should be used for frame mapping with GstVideoMeta */
gboolean different_caps = plugin->srcpad_caps && gboolean different_caps = srcpriv->caps &&
!gst_caps_is_strictly_equal (plugin->srcpad_caps, caps); !gst_caps_is_strictly_equal (srcpriv->caps, caps);
const GstVideoInfo *previous_negotiated = const GstVideoInfo *previous_negotiated =
gst_allocator_get_vaapi_negotiated_video_info gst_allocator_get_vaapi_negotiated_video_info (srcpriv->allocator);
(plugin->srcpad_allocator);
if (different_caps) { if (different_caps) {
guint i; guint i;
GstVideoInfo vi = plugin->srcpad_info; GstVideoInfo vi = srcpriv->info;
/* update the planes and the size with the allocator image/surface /* update the planes and the size with the allocator image/surface
* info, but not the resolution */ * info, but not the resolution */
@ -599,11 +651,9 @@ valid_allocator:
GST_VIDEO_INFO_PLANE_STRIDE (image_info, i); GST_VIDEO_INFO_PLANE_STRIDE (image_info, i);
} }
GST_VIDEO_INFO_SIZE (&vi) = GST_VIDEO_INFO_SIZE (image_info); GST_VIDEO_INFO_SIZE (&vi) = GST_VIDEO_INFO_SIZE (image_info);
gst_allocator_set_vaapi_negotiated_video_info (plugin->srcpad_allocator, gst_allocator_set_vaapi_negotiated_video_info (srcpriv->allocator, &vi);
&vi);
} else if (previous_negotiated) { } else if (previous_negotiated) {
gst_allocator_set_vaapi_negotiated_video_info (plugin->srcpad_allocator, gst_allocator_set_vaapi_negotiated_video_info (srcpriv->allocator, NULL);
NULL);
} }
} }
return TRUE; return TRUE;
@ -703,6 +753,7 @@ error_pool_config:
static gboolean static gboolean
ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps)
{ {
GstVaapiPadPrivate *sinkpriv = GST_VAAPI_PAD_PRIVATE (plugin->sinkpad);
GstBufferPool *pool; GstBufferPool *pool;
guint size; guint size;
@ -713,13 +764,13 @@ ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps)
if (!gst_vaapi_plugin_base_ensure_display (plugin)) if (!gst_vaapi_plugin_base_ensure_display (plugin))
return FALSE; return FALSE;
if (plugin->sinkpad_buffer_pool) { if (sinkpriv->buffer_pool) {
if (gst_vaapi_buffer_pool_caps_is_equal (plugin->sinkpad_buffer_pool, caps)) if (gst_vaapi_buffer_pool_caps_is_equal (sinkpriv->buffer_pool, caps))
return TRUE; return TRUE;
gst_buffer_pool_set_active (plugin->sinkpad_buffer_pool, FALSE); gst_buffer_pool_set_active (sinkpriv->buffer_pool, FALSE);
g_clear_object (&plugin->sinkpad_buffer_pool); g_clear_object (&sinkpriv->buffer_pool);
g_clear_object (&plugin->sinkpad_allocator); g_clear_object (&sinkpriv->allocator);
plugin->sinkpad_buffer_size = 0; sinkpriv->buffer_size = 0;
} }
if (!ensure_sinkpad_allocator (plugin, caps, &size)) if (!ensure_sinkpad_allocator (plugin, caps, &size))
@ -728,12 +779,12 @@ ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps)
pool = pool =
gst_vaapi_plugin_base_create_pool (plugin, caps, size, gst_vaapi_plugin_base_create_pool (plugin, caps, size,
BUFFER_POOL_SINK_MIN_BUFFERS, 0, BUFFER_POOL_SINK_MIN_BUFFERS, 0,
GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META, plugin->sinkpad_allocator); GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META, sinkpriv->allocator);
if (!pool) if (!pool)
return FALSE; return FALSE;
plugin->sinkpad_buffer_pool = pool; sinkpriv->buffer_pool = pool;
plugin->sinkpad_buffer_size = size; sinkpriv->buffer_size = size;
return TRUE; return TRUE;
} }
@ -752,28 +803,41 @@ gboolean
gst_vaapi_plugin_base_set_caps (GstVaapiPluginBase * plugin, GstCaps * incaps, gst_vaapi_plugin_base_set_caps (GstVaapiPluginBase * plugin, GstCaps * incaps,
GstCaps * outcaps) GstCaps * outcaps)
{ {
if (incaps && incaps != plugin->sinkpad_caps) { GstVaapiPadPrivate *sinkpriv = NULL;
if (!gst_video_info_from_caps (&plugin->sinkpad_info, incaps)) GstVaapiPadPrivate *srcpriv = NULL;
return FALSE;
gst_caps_replace (&plugin->sinkpad_caps, incaps); if (incaps) {
plugin->sinkpad_caps_is_raw = !gst_caps_has_vaapi_surface (incaps); g_assert (plugin->sinkpad);
sinkpriv = GST_VAAPI_PAD_PRIVATE (plugin->sinkpad);
} }
if (outcaps && outcaps != plugin->srcpad_caps) { if (incaps && incaps != sinkpriv->caps) {
if (!gst_video_info_from_caps (&plugin->srcpad_info, outcaps)) if (!gst_video_info_from_caps (&sinkpriv->info, incaps))
return FALSE; return FALSE;
if (plugin->srcpad_buffer_pool gst_caps_replace (&sinkpriv->caps, incaps);
&& !gst_vaapi_buffer_pool_caps_is_equal (plugin->srcpad_buffer_pool, sinkpriv->caps_is_raw = !gst_caps_has_vaapi_surface (incaps);
}
if (outcaps) {
g_assert (plugin->srcpad);
srcpriv = GST_VAAPI_PAD_PRIVATE (plugin->srcpad);
}
if (outcaps && outcaps != srcpriv->caps) {
if (!gst_video_info_from_caps (&srcpriv->info, outcaps))
return FALSE;
if (srcpriv->buffer_pool
&& !gst_vaapi_buffer_pool_caps_is_equal (srcpriv->buffer_pool,
outcaps)) { outcaps)) {
gst_buffer_pool_set_active (plugin->srcpad_buffer_pool, FALSE); gst_buffer_pool_set_active (srcpriv->buffer_pool, FALSE);
g_clear_object (&plugin->srcpad_buffer_pool); g_clear_object (&srcpriv->buffer_pool);
g_clear_object (&plugin->srcpad_allocator); g_clear_object (&srcpriv->allocator);
plugin_reset_texture_map (plugin); plugin_reset_texture_map (plugin);
} }
gst_caps_replace (&plugin->srcpad_caps, outcaps); gst_caps_replace (&srcpriv->caps, outcaps);
} }
if (!ensure_sinkpad_buffer_pool (plugin, plugin->sinkpad_caps)) if (incaps && !ensure_sinkpad_buffer_pool (plugin, sinkpriv->caps))
return FALSE; return FALSE;
return TRUE; return TRUE;
} }
@ -791,6 +855,7 @@ gboolean
gst_vaapi_plugin_base_propose_allocation (GstVaapiPluginBase * plugin, gst_vaapi_plugin_base_propose_allocation (GstVaapiPluginBase * plugin,
GstQuery * query) GstQuery * query)
{ {
GstVaapiPadPrivate *sinkpriv = GST_VAAPI_PAD_PRIVATE (plugin->sinkpad);
GstCaps *caps = NULL; GstCaps *caps = NULL;
GstBufferPool *pool = NULL; GstBufferPool *pool = NULL;
gboolean need_pool; gboolean need_pool;
@ -806,8 +871,7 @@ gst_vaapi_plugin_base_propose_allocation (GstVaapiPluginBase * plugin,
if (need_pool) { if (need_pool) {
pool = gst_vaapi_plugin_base_create_pool (plugin, caps, size, pool = gst_vaapi_plugin_base_create_pool (plugin, caps, size,
BUFFER_POOL_SINK_MIN_BUFFERS, 0, BUFFER_POOL_SINK_MIN_BUFFERS, 0,
GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META, GST_VAAPI_VIDEO_BUFFER_POOL_OPTION_VIDEO_META, sinkpriv->allocator);
plugin->sinkpad_allocator);
if (!pool) if (!pool)
return FALSE; return FALSE;
} }
@ -825,7 +889,7 @@ gst_vaapi_plugin_base_propose_allocation (GstVaapiPluginBase * plugin,
gst_query_add_allocation_param (query, allocator, NULL); gst_query_add_allocation_param (query, allocator, NULL);
gst_object_unref (allocator); gst_object_unref (allocator);
} }
gst_query_add_allocation_param (query, plugin->sinkpad_allocator, NULL); gst_query_add_allocation_param (query, sinkpriv->allocator, NULL);
gst_query_add_allocation_pool (query, pool, size, gst_query_add_allocation_pool (query, pool, size,
BUFFER_POOL_SINK_MIN_BUFFERS, 0); BUFFER_POOL_SINK_MIN_BUFFERS, 0);
@ -859,6 +923,7 @@ gboolean
gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin,
GstQuery * query) GstQuery * query)
{ {
GstVaapiPadPrivate *srcpriv = GST_VAAPI_PAD_PRIVATE (plugin->srcpad);
GstCaps *caps = NULL; GstCaps *caps = NULL;
GstBufferPool *pool; GstBufferPool *pool;
GstVideoInfo vi; GstVideoInfo vi;
@ -928,10 +993,10 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin,
* new buffer */ * new buffer */
if (i == 0 if (i == 0
&& g_strcmp0 (allocator->mem_type, GST_VAAPI_VIDEO_MEMORY_NAME) != 0) { && g_strcmp0 (allocator->mem_type, GST_VAAPI_VIDEO_MEMORY_NAME) != 0) {
if (plugin->other_srcpad_allocator) if (srcpriv->other_allocator)
gst_object_unref (plugin->other_srcpad_allocator); gst_object_unref (srcpriv->other_allocator);
plugin->other_srcpad_allocator = allocator; srcpriv->other_allocator = allocator;
plugin->other_allocator_params = params; srcpriv->other_allocator_params = params;
continue; continue;
} }
@ -939,9 +1004,9 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin,
GST_DEBUG_OBJECT (plugin, "found vaapi allocator in query %" GST_DEBUG_OBJECT (plugin, "found vaapi allocator in query %"
GST_PTR_FORMAT, allocator); GST_PTR_FORMAT, allocator);
index_allocator = i; index_allocator = i;
if (plugin->srcpad_allocator) if (srcpriv->allocator)
gst_object_unref (plugin->srcpad_allocator); gst_object_unref (srcpriv->allocator);
plugin->srcpad_allocator = allocator; srcpriv->allocator = allocator;
break; break;
} }
gst_object_unref (allocator); gst_object_unref (allocator);
@ -978,7 +1043,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin,
size = GST_VIDEO_INFO_SIZE (&vi); /* size might be updated by size = GST_VIDEO_INFO_SIZE (&vi); /* size might be updated by
* allocator */ * allocator */
pool = gst_vaapi_plugin_base_create_pool (plugin, caps, size, min, max, pool = gst_vaapi_plugin_base_create_pool (plugin, caps, size, min, max,
pool_options, plugin->srcpad_allocator); pool_options, srcpriv->allocator);
if (!pool) if (!pool)
goto error; goto error;
} }
@ -989,19 +1054,19 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin,
gst_query_add_allocation_pool (query, pool, size, min, max); gst_query_add_allocation_pool (query, pool, size, min, max);
/* allocator might be updated by ensure_srcpad_allocator() */ /* allocator might be updated by ensure_srcpad_allocator() */
if (plugin->srcpad_allocator) { if (srcpriv->allocator) {
if (index_allocator > 0) { if (index_allocator > 0) {
gst_query_set_nth_allocation_param (query, index_allocator, gst_query_set_nth_allocation_param (query, index_allocator,
plugin->srcpad_allocator, NULL); srcpriv->allocator, NULL);
} else { } else {
GST_DEBUG_OBJECT (plugin, "adding allocator in query %" GST_PTR_FORMAT, GST_DEBUG_OBJECT (plugin, "adding allocator in query %" GST_PTR_FORMAT,
plugin->srcpad_allocator); srcpriv->allocator);
gst_query_add_allocation_param (query, plugin->srcpad_allocator, NULL); gst_query_add_allocation_param (query, srcpriv->allocator, NULL);
} }
} }
g_clear_object (&plugin->srcpad_buffer_pool); g_clear_object (&srcpriv->buffer_pool);
plugin->srcpad_buffer_pool = pool; srcpriv->buffer_pool = pool;
/* if downstream doesn't support GstVideoMeta, and the negotiated /* if downstream doesn't support GstVideoMeta, and the negotiated
* caps are raw video, and the used allocator is the VA-API one, we * caps are raw video, and the used allocator is the VA-API one, we
@ -1051,6 +1116,7 @@ GstFlowReturn
gst_vaapi_plugin_base_get_input_buffer (GstVaapiPluginBase * plugin, gst_vaapi_plugin_base_get_input_buffer (GstVaapiPluginBase * plugin,
GstBuffer * inbuf, GstBuffer ** outbuf_ptr) GstBuffer * inbuf, GstBuffer ** outbuf_ptr)
{ {
GstVaapiPadPrivate *sinkpriv = GST_VAAPI_PAD_PRIVATE (plugin->sinkpad);
GstVaapiVideoMeta *meta; GstVaapiVideoMeta *meta;
GstBuffer *outbuf; GstBuffer *outbuf;
GstVideoFrame src_frame, out_frame; GstVideoFrame src_frame, out_frame;
@ -1065,18 +1131,18 @@ gst_vaapi_plugin_base_get_input_buffer (GstVaapiPluginBase * plugin,
return GST_FLOW_OK; return GST_FLOW_OK;
} }
if (!plugin->sinkpad_caps_is_raw) if (!sinkpriv->caps_is_raw)
goto error_invalid_buffer; goto error_invalid_buffer;
if (!plugin->sinkpad_buffer_pool) if (!sinkpriv->buffer_pool)
goto error_no_pool; goto error_no_pool;
if (!gst_buffer_pool_is_active (plugin->sinkpad_buffer_pool) && if (!gst_buffer_pool_is_active (sinkpriv->buffer_pool) &&
!gst_buffer_pool_set_active (plugin->sinkpad_buffer_pool, TRUE)) !gst_buffer_pool_set_active (sinkpriv->buffer_pool, TRUE))
goto error_active_pool; goto error_active_pool;
outbuf = NULL; outbuf = NULL;
if (gst_buffer_pool_acquire_buffer (plugin->sinkpad_buffer_pool, if (gst_buffer_pool_acquire_buffer (sinkpriv->buffer_pool,
&outbuf, NULL) != GST_FLOW_OK) &outbuf, NULL) != GST_FLOW_OK)
goto error_create_buffer; goto error_create_buffer;
@ -1086,12 +1152,10 @@ gst_vaapi_plugin_base_get_input_buffer (GstVaapiPluginBase * plugin,
goto done; goto done;
} }
if (!gst_video_frame_map (&src_frame, &plugin->sinkpad_info, inbuf, if (!gst_video_frame_map (&src_frame, &sinkpriv->info, inbuf, GST_MAP_READ))
GST_MAP_READ))
goto error_map_src_buffer; goto error_map_src_buffer;
if (!gst_video_frame_map (&out_frame, &plugin->sinkpad_info, outbuf, if (!gst_video_frame_map (&out_frame, &sinkpriv->info, outbuf, GST_MAP_WRITE))
GST_MAP_WRITE))
goto error_map_dst_buffer; goto error_map_dst_buffer;
success = gst_video_frame_copy (&out_frame, &src_frame); success = gst_video_frame_copy (&out_frame, &src_frame);
@ -1419,9 +1483,10 @@ gst_vaapi_plugin_base_set_srcpad_can_dmabuf (GstVaapiPluginBase * plugin,
GstObject * object) GstObject * object)
{ {
#if USE_EGL && USE_GST_GL_HELPERS #if USE_EGL && USE_GST_GL_HELPERS
GstVaapiPadPrivate *srcpriv = GST_VAAPI_PAD_PRIVATE (plugin->srcpad);
GstGLContext *const gl_context = GST_GL_CONTEXT (object); GstGLContext *const gl_context = GST_GL_CONTEXT (object);
plugin->srcpad_can_dmabuf = srcpriv->can_dmabuf =
(!(gst_gl_context_get_gl_api (gl_context) & GST_GL_API_GLES1) (!(gst_gl_context_get_gl_api (gl_context) & GST_GL_API_GLES1)
&& gst_gl_context_check_feature (gl_context, && gst_gl_context_check_feature (gl_context,
"EGL_EXT_image_dma_buf_import")); "EGL_EXT_image_dma_buf_import"));
@ -1458,6 +1523,7 @@ gboolean
gst_vaapi_plugin_copy_va_buffer (GstVaapiPluginBase * plugin, gst_vaapi_plugin_copy_va_buffer (GstVaapiPluginBase * plugin,
GstBuffer * inbuf, GstBuffer * outbuf) GstBuffer * inbuf, GstBuffer * outbuf)
{ {
GstVaapiPadPrivate *srcpriv = GST_VAAPI_PAD_PRIVATE (plugin->srcpad);
GstVideoMeta *vmeta; GstVideoMeta *vmeta;
GstVideoFrame src_frame, dst_frame; GstVideoFrame src_frame, dst_frame;
gboolean success; gboolean success;
@ -1473,11 +1539,9 @@ gst_vaapi_plugin_copy_va_buffer (GstVaapiPluginBase * plugin,
_init_performance_debug (); _init_performance_debug ();
GST_CAT_INFO (CAT_PERFORMANCE, "copying VA buffer to system memory buffer"); GST_CAT_INFO (CAT_PERFORMANCE, "copying VA buffer to system memory buffer");
if (!gst_video_frame_map (&src_frame, &plugin->srcpad_info, inbuf, if (!gst_video_frame_map (&src_frame, &srcpriv->info, inbuf, GST_MAP_READ))
GST_MAP_READ))
return FALSE; return FALSE;
if (!gst_video_frame_map (&dst_frame, &plugin->srcpad_info, outbuf, if (!gst_video_frame_map (&dst_frame, &srcpriv->info, outbuf, GST_MAP_WRITE)) {
GST_MAP_WRITE)) {
gst_video_frame_unmap (&src_frame); gst_video_frame_unmap (&src_frame);
return FALSE; return FALSE;
} }

View file

@ -35,6 +35,7 @@ G_BEGIN_DECLS
typedef struct _GstVaapiPluginBase GstVaapiPluginBase; typedef struct _GstVaapiPluginBase GstVaapiPluginBase;
typedef struct _GstVaapiPluginBaseClass GstVaapiPluginBaseClass; typedef struct _GstVaapiPluginBaseClass GstVaapiPluginBaseClass;
typedef struct _GstVaapiPadPrivate GstVaapiPadPrivate;
#define GST_VAAPI_PLUGIN_BASE(plugin) \ #define GST_VAAPI_PLUGIN_BASE(plugin) \
((GstVaapiPluginBase *)(plugin)) ((GstVaapiPluginBase *)(plugin))
@ -73,26 +74,32 @@ typedef struct _GstVaapiPluginBaseClass GstVaapiPluginBaseClass;
#define GST_VAAPI_PLUGIN_BASE_SINK_PAD(plugin) \ #define GST_VAAPI_PLUGIN_BASE_SINK_PAD(plugin) \
(GST_VAAPI_PLUGIN_BASE(plugin)->sinkpad) (GST_VAAPI_PLUGIN_BASE(plugin)->sinkpad)
#define GST_VAAPI_PLUGIN_BASE_SINK_PAD_PRIVATE(plugin) \
(GST_VAAPI_PLUGIN_BASE(plugin)->sinkpriv)
#define GST_VAAPI_PLUGIN_BASE_SINK_PAD_CAPS(plugin) \ #define GST_VAAPI_PLUGIN_BASE_SINK_PAD_CAPS(plugin) \
(GST_VAAPI_PLUGIN_BASE(plugin)->sinkpad_caps) (GST_VAAPI_PLUGIN_BASE_SINK_PAD_PRIVATE(plugin)->caps)
#define GST_VAAPI_PLUGIN_BASE_SINK_PAD_INFO(plugin) \ #define GST_VAAPI_PLUGIN_BASE_SINK_PAD_INFO(plugin) \
(&GST_VAAPI_PLUGIN_BASE(plugin)->sinkpad_info) (&GST_VAAPI_PLUGIN_BASE_SINK_PAD_PRIVATE(plugin)->info)
#define GST_VAAPI_PLUGIN_BASE_SRC_PAD(plugin) \ #define GST_VAAPI_PLUGIN_BASE_SRC_PAD(plugin) \
(GST_VAAPI_PLUGIN_BASE(plugin)->srcpad) (GST_VAAPI_PLUGIN_BASE(plugin)->srcpad)
#define GST_VAAPI_PLUGIN_BASE_SRC_PAD_PRIVATE(plugin) \
(GST_VAAPI_PLUGIN_BASE(plugin)->srcpriv)
#define GST_VAAPI_PLUGIN_BASE_SRC_PAD_CAPS(plugin) \ #define GST_VAAPI_PLUGIN_BASE_SRC_PAD_CAPS(plugin) \
(GST_VAAPI_PLUGIN_BASE(plugin)->srcpad_caps) (GST_VAAPI_PLUGIN_BASE_SRC_PAD_PRIVATE(plugin)->caps)
#define GST_VAAPI_PLUGIN_BASE_SRC_PAD_INFO(plugin) \ #define GST_VAAPI_PLUGIN_BASE_SRC_PAD_INFO(plugin) \
(&GST_VAAPI_PLUGIN_BASE(plugin)->srcpad_info) (&GST_VAAPI_PLUGIN_BASE_SRC_PAD_PRIVATE(plugin)->info)
#define GST_VAAPI_PLUGIN_BASE_SRC_PAD_CAN_DMABUF(plugin) \ #define GST_VAAPI_PLUGIN_BASE_SRC_PAD_CAN_DMABUF(plugin) \
(GST_VAAPI_PLUGIN_BASE(plugin)->srcpad_can_dmabuf) (GST_VAAPI_PLUGIN_BASE_SRC_PAD_PRIVATE(plugin)->can_dmabuf)
#define GST_VAAPI_PLUGIN_BASE_SRC_PAD_BUFFER_POOL(plugin) \ #define GST_VAAPI_PLUGIN_BASE_SRC_PAD_BUFFER_POOL(plugin) \
(GST_VAAPI_PLUGIN_BASE(plugin)->srcpad_buffer_pool) (GST_VAAPI_PLUGIN_BASE_SRC_PAD_PRIVATE(plugin)->buffer_pool)
#define GST_VAAPI_PLUGIN_BASE_SRC_PAD_ALLOCATOR(plugin) \ #define GST_VAAPI_PLUGIN_BASE_SRC_PAD_ALLOCATOR(plugin) \
(GST_VAAPI_PLUGIN_BASE(plugin)->srcpad_allocator) (GST_VAAPI_PLUGIN_BASE_SRC_PAD_PRIVATE(plugin)->allocator)
#define GST_VAAPI_PLUGIN_BASE_OTHER_ALLOCATOR(plugin) \ #define GST_VAAPI_PLUGIN_BASE_OTHER_ALLOCATOR(plugin) \
(GST_VAAPI_PLUGIN_BASE(plugin)->other_srcpad_allocator) (GST_VAAPI_PLUGIN_BASE_SRC_PAD_PRIVATE(plugin)->other_allocator)
#define GST_VAAPI_PLUGIN_BASE_OTHER_ALLOCATOR_PARAMS(plugin) \ #define GST_VAAPI_PLUGIN_BASE_OTHER_ALLOCATOR_PARAMS(plugin) \
(GST_VAAPI_PLUGIN_BASE(plugin)->other_allocator_params) (GST_VAAPI_PLUGIN_BASE_SRC_PAD_PRIVATE(plugin)->other_allocator_params)
#define GST_VAAPI_PLUGIN_BASE_COPY_OUTPUT_FRAME(plugin) \ #define GST_VAAPI_PLUGIN_BASE_COPY_OUTPUT_FRAME(plugin) \
(GST_VAAPI_PLUGIN_BASE(plugin)->copy_output_frame) (GST_VAAPI_PLUGIN_BASE(plugin)->copy_output_frame)
@ -116,6 +123,21 @@ typedef struct _GstVaapiPluginBaseClass GstVaapiPluginBaseClass;
GST_ELEMENT_CLASS (parent_class)->set_context (element, context); \ GST_ELEMENT_CLASS (parent_class)->set_context (element, context); \
} }
struct _GstVaapiPadPrivate
{
GstCaps *caps;
GstVideoInfo info;
GstBufferPool *buffer_pool;
GstAllocator *allocator;
guint buffer_size;
gboolean caps_is_raw;
gboolean can_dmabuf;
GstAllocator *other_allocator;
GstAllocationParams other_allocator_params;
};
struct _GstVaapiPluginBase struct _GstVaapiPluginBase
{ {
/*< private >*/ /*< private >*/
@ -131,16 +153,10 @@ struct _GstVaapiPluginBase
GstDebugCategory *debug_category; GstDebugCategory *debug_category;
GstPad *sinkpad; GstPad *sinkpad;
GstCaps *sinkpad_caps;
gboolean sinkpad_caps_is_raw;
GstVideoInfo sinkpad_info;
GstBufferPool *sinkpad_buffer_pool;
guint sinkpad_buffer_size;
GstPad *srcpad; GstPad *srcpad;
GstCaps *srcpad_caps;
GstVideoInfo srcpad_info; GstVaapiPadPrivate *sinkpriv;
GstBufferPool *srcpad_buffer_pool; GstVaapiPadPrivate *srcpriv;
GstVaapiDisplay *display; GstVaapiDisplay *display;
GstVaapiDisplayType display_type; GstVaapiDisplayType display_type;
@ -152,14 +168,8 @@ struct _GstVaapiPluginBase
GstObject *gl_other_context; GstObject *gl_other_context;
GstCaps *allowed_raw_caps; GstCaps *allowed_raw_caps;
GstAllocator *sinkpad_allocator;
GstAllocator *srcpad_allocator;
gboolean srcpad_can_dmabuf;
gboolean enable_direct_rendering; gboolean enable_direct_rendering;
GstAllocator *other_srcpad_allocator;
GstAllocationParams other_allocator_params;
gboolean copy_output_frame; gboolean copy_output_frame;
}; };
@ -177,6 +187,7 @@ struct _GstVaapiPluginBaseClass
gboolean (*has_interface) (GstVaapiPluginBase * plugin, GType type); gboolean (*has_interface) (GstVaapiPluginBase * plugin, GType type);
void (*display_changed) (GstVaapiPluginBase * plugin); void (*display_changed) (GstVaapiPluginBase * plugin);
GstVaapiPadPrivate * (*get_vaapi_pad_private) (GstVaapiPluginBase * plugin, GstPad * pad);
}; };
G_GNUC_INTERNAL G_GNUC_INTERNAL