mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 18:21:04 +00:00
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:
parent
2643ae980a
commit
50b2423a2b
5 changed files with 108 additions and 57 deletions
|
@ -469,6 +469,28 @@ has_dmabuf_capable_peer (GstVaapiPluginBase * plugin, GstPad * pad)
|
||||||
return is_dmabuf_capable;
|
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
|
static gboolean
|
||||||
gst_vaapi_buffer_pool_caps_is_equal (GstBufferPool * pool, GstCaps * newcaps)
|
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;
|
GstBufferPool *pool;
|
||||||
GstStructure *config;
|
GstStructure *config;
|
||||||
GstVideoInfo vi;
|
GstVideoInfo vi;
|
||||||
|
GstAllocator *allocator;
|
||||||
|
gboolean configured;
|
||||||
|
|
||||||
/* video decoders don't use a buffer pool in the sink pad */
|
/* video decoders don't use a buffer pool in the sink pad */
|
||||||
if (GST_IS_VIDEO_DECODER (plugin))
|
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);
|
gst_video_info_force_nv12_if_encoded (&vi);
|
||||||
plugin->sinkpad_buffer_size = GST_VIDEO_INFO_SIZE (&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);
|
config = gst_buffer_pool_get_config (pool);
|
||||||
gst_buffer_pool_config_set_params (config, caps,
|
gst_buffer_pool_config_set_params (config, caps,
|
||||||
plugin->sinkpad_buffer_size, 0, 0);
|
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_config_add_option (config,
|
||||||
GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META);
|
GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META);
|
||||||
gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_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;
|
goto error_pool_config;
|
||||||
plugin->sinkpad_buffer_pool = pool;
|
plugin->sinkpad_buffer_pool = pool;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -545,6 +576,12 @@ error_invalid_caps:
|
||||||
gst_object_unref (pool);
|
gst_object_unref (pool);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
error_create_allocator:
|
||||||
|
{
|
||||||
|
GST_ERROR_OBJECT (plugin, "failed to create allocator");
|
||||||
|
gst_object_unref (pool);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
error_create_pool:
|
error_create_pool:
|
||||||
{
|
{
|
||||||
GST_ERROR_OBJECT (plugin, "failed to create buffer 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);
|
plugin->sinkpad_buffer_size, 0, 0);
|
||||||
|
|
||||||
if (has_dmabuf_capable_peer (plugin, plugin->sinkpad)) {
|
if (has_dmabuf_capable_peer (plugin, plugin->sinkpad)) {
|
||||||
GstStructure *const config =
|
if (!set_dmabuf_allocator (plugin, plugin->sinkpad_buffer_pool, caps))
|
||||||
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))
|
|
||||||
goto error_pool_config;
|
goto error_pool_config;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -668,6 +700,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin,
|
||||||
gboolean update_pool = FALSE;
|
gboolean update_pool = FALSE;
|
||||||
gboolean has_video_meta = FALSE;
|
gboolean has_video_meta = FALSE;
|
||||||
gboolean has_video_alignment = FALSE;
|
gboolean has_video_alignment = FALSE;
|
||||||
|
GstAllocator *allocator;
|
||||||
#if (USE_GLX || USE_EGL)
|
#if (USE_GLX || USE_EGL)
|
||||||
gboolean has_texture_upload_meta = FALSE;
|
gboolean has_texture_upload_meta = FALSE;
|
||||||
guint idx;
|
guint idx;
|
||||||
|
@ -749,10 +782,17 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin,
|
||||||
if (!pool)
|
if (!pool)
|
||||||
goto error_create_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);
|
config = gst_buffer_pool_get_config (pool);
|
||||||
gst_buffer_pool_config_set_params (config, caps, size, min, max);
|
gst_buffer_pool_config_set_params (config, caps, size, min, max);
|
||||||
gst_buffer_pool_config_add_option (config,
|
gst_buffer_pool_config_add_option (config,
|
||||||
GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META);
|
GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META);
|
||||||
|
gst_buffer_pool_config_set_allocator (config, allocator, NULL);
|
||||||
|
|
||||||
|
gst_object_unref (allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!config)
|
if (!config)
|
||||||
|
@ -809,6 +849,12 @@ error_create_pool:
|
||||||
GST_ERROR_OBJECT (plugin, "failed to create buffer pool");
|
GST_ERROR_OBJECT (plugin, "failed to create buffer pool");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
error_create_allocator:
|
||||||
|
{
|
||||||
|
GST_ERROR_OBJECT (plugin, "failed to create allocator");
|
||||||
|
gst_object_unref (pool);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
error_config_failed:
|
error_config_failed:
|
||||||
{
|
{
|
||||||
if (pool)
|
if (pool)
|
||||||
|
|
|
@ -136,13 +136,15 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool,
|
||||||
{
|
{
|
||||||
GstVaapiVideoBufferPoolPrivate *const priv =
|
GstVaapiVideoBufferPoolPrivate *const priv =
|
||||||
GST_VAAPI_VIDEO_BUFFER_POOL (pool)->priv;
|
GST_VAAPI_VIDEO_BUFFER_POOL (pool)->priv;
|
||||||
GstCaps *caps = NULL;
|
GstCaps *caps;
|
||||||
GstVideoInfo *const cur_vip = &priv->video_info;
|
|
||||||
GstVideoInfo new_vip;
|
GstVideoInfo new_vip;
|
||||||
|
const GstVideoInfo *alloc_vip;
|
||||||
GstVideoAlignment align;
|
GstVideoAlignment align;
|
||||||
GstAllocator *allocator;
|
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))
|
if (!gst_buffer_pool_config_get_params (config, &caps, NULL, NULL, NULL))
|
||||||
goto error_invalid_config;
|
goto error_invalid_config;
|
||||||
if (!caps)
|
if (!caps)
|
||||||
|
@ -150,43 +152,36 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool,
|
||||||
if (!gst_video_info_from_caps (&new_vip, caps))
|
if (!gst_video_info_from_caps (&new_vip, caps))
|
||||||
goto error_invalid_caps;
|
goto error_invalid_caps;
|
||||||
|
|
||||||
use_dmabuf_memory = gst_buffer_pool_config_has_option (config,
|
allocator = NULL;
|
||||||
GST_BUFFER_POOL_OPTION_DMABUF_MEMORY);
|
if (!gst_buffer_pool_config_get_allocator (config, &allocator, NULL))
|
||||||
if (priv->use_dmabuf_memory != use_dmabuf_memory) {
|
goto error_invalid_allocator;
|
||||||
priv->use_dmabuf_memory = use_dmabuf_memory;
|
|
||||||
g_clear_object (&priv->allocator);
|
|
||||||
}
|
|
||||||
|
|
||||||
changed_caps = !priv->allocator || gst_video_info_changed (cur_vip, &new_vip);
|
if (gst_video_info_changed (&priv->video_info, &new_vip))
|
||||||
if (changed_caps) {
|
gst_object_replace ((GstObject **) & priv->allocator, NULL);
|
||||||
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;
|
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_buffer_pool_config_has_option (config,
|
if (!gst_buffer_pool_config_has_option (config,
|
||||||
GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META))
|
GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META))
|
||||||
goto error_no_vaapi_video_meta_option;
|
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,
|
priv->has_video_meta = gst_buffer_pool_config_has_option (config,
|
||||||
GST_BUFFER_POOL_OPTION_VIDEO_META);
|
GST_BUFFER_POOL_OPTION_VIDEO_META);
|
||||||
|
|
||||||
|
@ -213,7 +208,7 @@ error_invalid_config:
|
||||||
}
|
}
|
||||||
error_no_caps:
|
error_no_caps:
|
||||||
{
|
{
|
||||||
GST_ERROR_OBJECT (pool, "no valid caps in config");
|
GST_ERROR_OBJECT (pool, "no caps in config");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
error_invalid_caps:
|
error_invalid_caps:
|
||||||
|
@ -221,9 +216,14 @@ error_invalid_caps:
|
||||||
GST_ERROR_OBJECT (pool, "invalid caps %" GST_PTR_FORMAT, caps);
|
GST_ERROR_OBJECT (pool, "invalid caps %" GST_PTR_FORMAT, caps);
|
||||||
return FALSE;
|
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;
|
return FALSE;
|
||||||
}
|
}
|
||||||
error_create_allocator_info:
|
error_create_allocator_info:
|
||||||
|
@ -232,9 +232,9 @@ error_create_allocator_info:
|
||||||
"failed to create GstVaapiVideoAllocator `video-info'");
|
"failed to create GstVaapiVideoAllocator `video-info'");
|
||||||
return FALSE;
|
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;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,17 +54,6 @@ typedef struct _GstVaapiVideoBufferPoolPrivate GstVaapiVideoBufferPoolPrivate;
|
||||||
#define GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META \
|
#define GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META \
|
||||||
"GstBufferPoolOptionVaapiVideoMeta"
|
"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:
|
* GstVaapiVideoBufferPoolAcquireFlags:
|
||||||
* @GST_VAAPI_VIDEO_BUFFER_POOL_ACQUIRE_FLAG_NO_ALLOC: option to
|
* @GST_VAAPI_VIDEO_BUFFER_POOL_ACQUIRE_FLAG_NO_ALLOC: option to
|
||||||
|
|
|
@ -1035,3 +1035,16 @@ gst_allocator_set_vaapi_video_info (GstAllocator * allocator,
|
||||||
|
|
||||||
return TRUE;
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -214,6 +214,9 @@ gboolean
|
||||||
gst_allocator_set_vaapi_video_info (GstAllocator * allocator,
|
gst_allocator_set_vaapi_video_info (GstAllocator * allocator,
|
||||||
const GstVideoInfo * vip, guint flags);
|
const GstVideoInfo * vip, guint flags);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_vaapi_is_dmabuf_allocator (GstAllocator * allocator);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* GST_VAAPI_VIDEO_MEMORY_H */
|
#endif /* GST_VAAPI_VIDEO_MEMORY_H */
|
||||||
|
|
Loading…
Reference in a new issue