pluginbase negotiates allocator with bufferpool

Originally vaapivideobufferpool instantiates its own allocator regardless the
received configuration, and it relies in custom configuration options to
choose which kind of allocator instantiate.

This patch transfers the responsibility of the allocator instantiate to
vaapipluginbase and pass it to the vaapivideobufferpool through its
configuration.

* gst/vaapi/gstvaapipluginbase.c
  + set_dmabuf_allocator(): inserts a dmabuf allocator in the bufferpool
  + ensure_sinkpad_buffer_pool(): set a normal vaapi video allocator in
    bufferpool configuration
  + gst_vaapi_plugin_base_propose_allocation(): call set_dmabuf_allocator() if
    needed.
  + gst_vaapi_plugin_base_decide_allocation(): set a normal vaapi video
    allocator in bufferpool configuration
* gst/vaapi/gstvaapivideobufferpool.c
  + gst_vaapi_video_buffer_pool_set_config(): instead of instantiate the
    allocator, process the received one through its configuration.
* gst/vaapi/gstvaapivideobufferpool.h: removed
  GST_BUFFER_POOL_OPTION_DMABUF_MEMORY since it is not used anymore.
* gst/vaapi/gstvaapivideomemory.c
  + gst_vaapi_is_dmabuf_allocator(): new helper function to identify a dmabuf
    allocator with the vaapi qdata.

https://bugzilla.gnome.org/show_bug.cgi?id=765435
This commit is contained in:
Víctor Manuel Jáquez Leal 2016-05-20 18:46:14 +02:00
parent 2643ae980a
commit 50b2423a2b
5 changed files with 108 additions and 57 deletions

View file

@ -469,6 +469,28 @@ has_dmabuf_capable_peer (GstVaapiPluginBase * plugin, GstPad * pad)
return is_dmabuf_capable;
}
static gboolean
set_dmabuf_allocator (GstVaapiPluginBase * plugin, GstBufferPool * pool,
GstCaps * caps)
{
GstStructure *config;
GstAllocator *allocator;
GstVideoInfo vi;
gboolean ret;
if (!gst_video_info_from_caps (&vi, caps))
return FALSE;
config = gst_buffer_pool_get_config (pool);
allocator = gst_vaapi_dmabuf_allocator_new (plugin->display, &vi,
GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE);
if (!allocator)
return FALSE;
gst_buffer_pool_config_set_allocator (config, allocator, NULL);
ret = gst_buffer_pool_set_config (pool, config);
gst_object_unref (allocator);
return ret;
}
static gboolean
gst_vaapi_buffer_pool_caps_is_equal (GstBufferPool * pool, GstCaps * newcaps)
{
@ -502,6 +524,8 @@ ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps)
GstBufferPool *pool;
GstStructure *config;
GstVideoInfo vi;
GstAllocator *allocator;
gboolean configured;
/* video decoders don't use a buffer pool in the sink pad */
if (GST_IS_VIDEO_DECODER (plugin))
@ -527,13 +551,20 @@ ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps)
gst_video_info_force_nv12_if_encoded (&vi);
plugin->sinkpad_buffer_size = GST_VIDEO_INFO_SIZE (&vi);
allocator = gst_vaapi_video_allocator_new (plugin->display, &vi, 0);
if (!allocator)
goto error_create_allocator;
config = gst_buffer_pool_get_config (pool);
gst_buffer_pool_config_set_params (config, caps,
plugin->sinkpad_buffer_size, 0, 0);
gst_buffer_pool_config_set_allocator (config, allocator, NULL);
gst_buffer_pool_config_add_option (config,
GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META);
gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META);
if (!gst_buffer_pool_set_config (pool, config))
configured = gst_buffer_pool_set_config (pool, config);
gst_object_unref (allocator);
if (!configured)
goto error_pool_config;
plugin->sinkpad_buffer_pool = pool;
return TRUE;
@ -545,6 +576,12 @@ error_invalid_caps:
gst_object_unref (pool);
return FALSE;
}
error_create_allocator:
{
GST_ERROR_OBJECT (plugin, "failed to create allocator");
gst_object_unref (pool);
return FALSE;
}
error_create_pool:
{
GST_ERROR_OBJECT (plugin, "failed to create buffer pool");
@ -618,12 +655,7 @@ gst_vaapi_plugin_base_propose_allocation (GstVaapiPluginBase * plugin,
plugin->sinkpad_buffer_size, 0, 0);
if (has_dmabuf_capable_peer (plugin, plugin->sinkpad)) {
GstStructure *const config =
gst_buffer_pool_get_config (plugin->sinkpad_buffer_pool);
gst_buffer_pool_config_add_option (config,
GST_BUFFER_POOL_OPTION_DMABUF_MEMORY);
if (!gst_buffer_pool_set_config (plugin->sinkpad_buffer_pool, config))
if (!set_dmabuf_allocator (plugin, plugin->sinkpad_buffer_pool, caps))
goto error_pool_config;
}
}
@ -668,6 +700,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin,
gboolean update_pool = FALSE;
gboolean has_video_meta = FALSE;
gboolean has_video_alignment = FALSE;
GstAllocator *allocator;
#if (USE_GLX || USE_EGL)
gboolean has_texture_upload_meta = FALSE;
guint idx;
@ -749,10 +782,17 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin,
if (!pool)
goto error_create_pool;
allocator = gst_vaapi_video_allocator_new (plugin->display, &vi, 0);
if (!allocator)
goto error_create_allocator;
config = gst_buffer_pool_get_config (pool);
gst_buffer_pool_config_set_params (config, caps, size, min, max);
gst_buffer_pool_config_add_option (config,
GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META);
gst_buffer_pool_config_set_allocator (config, allocator, NULL);
gst_object_unref (allocator);
}
if (!config)
@ -809,6 +849,12 @@ error_create_pool:
GST_ERROR_OBJECT (plugin, "failed to create buffer pool");
return FALSE;
}
error_create_allocator:
{
GST_ERROR_OBJECT (plugin, "failed to create allocator");
gst_object_unref (pool);
return FALSE;
}
error_config_failed:
{
if (pool)

View file

@ -136,13 +136,15 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool,
{
GstVaapiVideoBufferPoolPrivate *const priv =
GST_VAAPI_VIDEO_BUFFER_POOL (pool)->priv;
GstCaps *caps = NULL;
GstVideoInfo *const cur_vip = &priv->video_info;
GstCaps *caps;
GstVideoInfo new_vip;
const GstVideoInfo *alloc_vip;
GstVideoAlignment align;
GstAllocator *allocator;
gboolean changed_caps, use_dmabuf_memory;
GST_DEBUG_OBJECT (pool, "config %" GST_PTR_FORMAT, config);
caps = NULL;
if (!gst_buffer_pool_config_get_params (config, &caps, NULL, NULL, NULL))
goto error_invalid_config;
if (!caps)
@ -150,43 +152,36 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool,
if (!gst_video_info_from_caps (&new_vip, caps))
goto error_invalid_caps;
use_dmabuf_memory = gst_buffer_pool_config_has_option (config,
GST_BUFFER_POOL_OPTION_DMABUF_MEMORY);
if (priv->use_dmabuf_memory != use_dmabuf_memory) {
priv->use_dmabuf_memory = use_dmabuf_memory;
g_clear_object (&priv->allocator);
}
allocator = NULL;
if (!gst_buffer_pool_config_get_allocator (config, &allocator, NULL))
goto error_invalid_allocator;
changed_caps = !priv->allocator || gst_video_info_changed (cur_vip, &new_vip);
if (changed_caps) {
const GstVideoInfo *alloc_vip;
guint flags = 0;
if (use_dmabuf_memory) {
/* XXX: also needs fixed strides/offsets */
flags |= GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE;
allocator =
gst_vaapi_dmabuf_allocator_new (priv->display, &new_vip, flags);
} else {
allocator = gst_vaapi_video_allocator_new (priv->display, &new_vip, 0);
}
if (!allocator)
goto error_create_allocator;
gst_object_replace ((GstObject **) & priv->allocator,
GST_OBJECT_CAST (allocator));
gst_object_unref (allocator);
priv->video_info = new_vip;
alloc_vip = gst_allocator_get_vaapi_video_info (allocator, NULL);
if (!alloc_vip)
goto error_create_allocator_info;
priv->alloc_info = *alloc_vip;
}
if (gst_video_info_changed (&priv->video_info, &new_vip))
gst_object_replace ((GstObject **) & priv->allocator, NULL);
priv->video_info = new_vip;
if (!gst_buffer_pool_config_has_option (config,
GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META))
goto error_no_vaapi_video_meta_option;
/* not our allocator, not our buffers */
if (allocator) {
priv->use_dmabuf_memory = gst_vaapi_is_dmabuf_allocator (allocator);
if (priv->use_dmabuf_memory ||
g_strcmp0 (allocator->mem_type, GST_VAAPI_VIDEO_MEMORY_NAME) == 0) {
if (priv->allocator)
gst_object_unref (priv->allocator);
if ((priv->allocator = allocator))
gst_object_ref (allocator);
alloc_vip = gst_allocator_get_vaapi_video_info (priv->allocator, NULL);
if (!alloc_vip)
goto error_create_allocator_info;
priv->alloc_info = *alloc_vip;
}
}
if (!priv->allocator)
goto error_no_allocator;
priv->has_video_meta = gst_buffer_pool_config_has_option (config,
GST_BUFFER_POOL_OPTION_VIDEO_META);
@ -213,7 +208,7 @@ error_invalid_config:
}
error_no_caps:
{
GST_ERROR_OBJECT (pool, "no valid caps in config");
GST_ERROR_OBJECT (pool, "no caps in config");
return FALSE;
}
error_invalid_caps:
@ -221,9 +216,14 @@ error_invalid_caps:
GST_ERROR_OBJECT (pool, "invalid caps %" GST_PTR_FORMAT, caps);
return FALSE;
}
error_create_allocator:
error_invalid_allocator:
{
GST_ERROR_OBJECT (pool, "failed to create GstVaapiVideoAllocator object");
GST_ERROR_OBJECT (pool, "no allocator in config");
return FALSE;
}
error_no_vaapi_video_meta_option:
{
GST_ERROR_OBJECT (pool, "no GstVaapiVideoMeta option in config");
return FALSE;
}
error_create_allocator_info:
@ -232,9 +232,9 @@ error_create_allocator_info:
"failed to create GstVaapiVideoAllocator `video-info'");
return FALSE;
}
error_no_vaapi_video_meta_option:
error_no_allocator:
{
GST_ERROR_OBJECT (pool, "no GstVaapiVideoMeta option");
GST_ERROR_OBJECT (pool, "no allocator defined");
return FALSE;
}
}

View file

@ -54,17 +54,6 @@ typedef struct _GstVaapiVideoBufferPoolPrivate GstVaapiVideoBufferPoolPrivate;
#define GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META \
"GstBufferPoolOptionVaapiVideoMeta"
/**
* GST_BUFFER_POOL_OPTION_DMABUF_MEMORY:
*
* An option that can be activated on bufferpool to request dmabuf
* handles on buffers from the pool.
*/
#ifndef GST_BUFFER_POOL_OPTION_DMABUF_MEMORY
#define GST_BUFFER_POOL_OPTION_DMABUF_MEMORY \
"GstBufferPoolOptionDMABUFMemory"
#endif
/**
* GstVaapiVideoBufferPoolAcquireFlags:
* @GST_VAAPI_VIDEO_BUFFER_POOL_ACQUIRE_FLAG_NO_ALLOC: option to

View file

@ -1035,3 +1035,16 @@ gst_allocator_set_vaapi_video_info (GstAllocator * allocator,
return TRUE;
}
gboolean
gst_vaapi_is_dmabuf_allocator (GstAllocator * allocator)
{
GstStructure *st;
g_return_val_if_fail (GST_IS_ALLOCATOR (allocator), FALSE);
if (g_strcmp0 (allocator->mem_type, GST_ALLOCATOR_DMABUF) != 0)
return FALSE;
st = g_object_get_qdata (G_OBJECT (allocator), GST_VAAPI_VIDEO_INFO_QUARK);
return (st != NULL);
}

View file

@ -214,6 +214,9 @@ gboolean
gst_allocator_set_vaapi_video_info (GstAllocator * allocator,
const GstVideoInfo * vip, guint flags);
gboolean
gst_vaapi_is_dmabuf_allocator (GstAllocator * allocator);
G_END_DECLS
#endif /* GST_VAAPI_VIDEO_MEMORY_H */