plugins: add gst_vaapi_plugin_base_create_pool()

This patch refactors the code in pluginbase in order to centralize the buffer
pool instantiation. As the buffer pool config may have different options, these
are gathered using a bitwise flag.

https://bugzilla.gnome.org/show_bug.cgi?id=765435
This commit is contained in:
Víctor Manuel Jáquez Leal 2016-05-10 15:57:06 +02:00
parent 50b2423a2b
commit d0c72182a4

View file

@ -37,6 +37,13 @@
/* Environment variable for disable driver white-list */ /* Environment variable for disable driver white-list */
#define GST_VAAPI_ALL_DRIVERS_ENV "GST_VAAPI_ALL_DRIVERS" #define GST_VAAPI_ALL_DRIVERS_ENV "GST_VAAPI_ALL_DRIVERS"
enum
{
GST_VAAPI_OPTION_VIDEO_META = (1u << 0),
GST_VAAPI_OPTION_VIDEO_ALIGNMENT = (1u << 1),
GST_VAAPI_OPTION_GL_TEXTURE_UPLOAD = (1u << 2),
};
/* GstVideoContext interface */ /* GstVideoContext interface */
static void static void
plugin_set_display (GstVaapiPluginBase * plugin, GstVaapiDisplay * display) plugin_set_display (GstVaapiPluginBase * plugin, GstVaapiDisplay * display)
@ -508,6 +515,70 @@ gst_vaapi_buffer_pool_caps_is_equal (GstBufferPool * pool, GstCaps * newcaps)
return ret; return ret;
} }
/**
* gst_vaapi_plugin_base_create_pool:
* @plugin: a #GstVaapiPluginBase
* @caps: the initial #GstCaps for the resulting buffer pool
* @size: the size of each buffer, not including prefix and padding
* @options: #GstBufferPool options encoded as bit-wise flags
* @allocator: (allow-none): the #GstAllocator to use or %NULL
*
* Create an instance of #GstVaapiVideoBufferPool
*
* Returns: (transfer full): a new allocated #GstBufferPool
**/
static GstBufferPool *
gst_vaapi_plugin_base_create_pool (GstVaapiPluginBase * plugin, GstCaps * caps,
gsize size, guint min_buffers, guint max_buffers, guint options,
GstAllocator * allocator)
{
GstBufferPool *pool;
GstStructure *config;
if (!(pool = gst_vaapi_video_buffer_pool_new (plugin->display)))
goto error_create_pool;
config = gst_buffer_pool_get_config (pool);
gst_buffer_pool_config_set_params (config, caps, size, min_buffers,
max_buffers);
gst_buffer_pool_config_add_option (config,
GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META);
if (options & GST_VAAPI_OPTION_VIDEO_META) {
gst_buffer_pool_config_add_option (config,
GST_BUFFER_POOL_OPTION_VIDEO_META);
}
if (options & GST_VAAPI_OPTION_VIDEO_ALIGNMENT) {
gst_buffer_pool_config_add_option (config,
GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT);
}
#if (USE_GLX || USE_EGL)
if (options & GST_VAAPI_OPTION_GL_TEXTURE_UPLOAD) {
gst_buffer_pool_config_add_option (config,
GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META);
}
#endif
if (allocator)
gst_buffer_pool_config_set_allocator (config, allocator, NULL);
if (!gst_buffer_pool_set_config (pool, config))
goto error_pool_config;
return pool;
/* ERRORS */
error_create_pool:
{
GST_ERROR_OBJECT (plugin, "failed to create buffer pool");
return NULL;
}
error_pool_config:
{
gst_object_unref (pool);
GST_ELEMENT_ERROR (plugin, RESOURCE, SETTINGS,
("Failed to configure the buffer pool"),
("Configuration is most likely invalid, please report this issue."));
return NULL;
}
}
/** /**
* ensure_sinkpad_buffer_pool: * ensure_sinkpad_buffer_pool:
* @plugin: a #GstVaapiPluginBase * @plugin: a #GstVaapiPluginBase
@ -522,10 +593,8 @@ static gboolean
ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps)
{ {
GstBufferPool *pool; GstBufferPool *pool;
GstStructure *config;
GstVideoInfo vi; GstVideoInfo vi;
GstAllocator *allocator; 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))
@ -542,55 +611,37 @@ ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps)
plugin->sinkpad_buffer_size = 0; plugin->sinkpad_buffer_size = 0;
} }
pool = gst_vaapi_video_buffer_pool_new (plugin->display);
if (!pool)
goto error_create_pool;
if (!gst_video_info_from_caps (&vi, caps)) if (!gst_video_info_from_caps (&vi, caps))
goto error_invalid_caps; goto error_invalid_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);
allocator = gst_vaapi_video_allocator_new (plugin->display, &vi, 0); allocator = gst_vaapi_video_allocator_new (plugin->display, &vi, 0);
if (!allocator) if (!allocator)
goto error_create_allocator; goto error_create_allocator;
config = gst_buffer_pool_get_config (pool); pool = gst_vaapi_plugin_base_create_pool (plugin, caps,
gst_buffer_pool_config_set_params (config, caps, GST_VIDEO_INFO_SIZE (&vi), 0, 0, GST_VAAPI_OPTION_VIDEO_META, allocator);
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);
configured = gst_buffer_pool_set_config (pool, config);
gst_object_unref (allocator); gst_object_unref (allocator);
if (!configured) if (!pool)
goto error_pool_config; goto error_create_pool;
plugin->sinkpad_buffer_pool = pool; plugin->sinkpad_buffer_pool = pool;
plugin->sinkpad_buffer_size = GST_VIDEO_INFO_SIZE (&vi);
return TRUE; return TRUE;
/* ERRORS */ /* ERRORS */
error_invalid_caps: error_invalid_caps:
{ {
GST_ERROR_OBJECT (plugin, "invalid caps %" GST_PTR_FORMAT, caps); GST_ERROR_OBJECT (plugin, "invalid caps %" GST_PTR_FORMAT, caps);
gst_object_unref (pool);
return FALSE; return FALSE;
} }
error_create_allocator: error_create_allocator:
{ {
GST_ERROR_OBJECT (plugin, "failed to create allocator"); GST_ERROR_OBJECT (plugin, "failed to create allocator");
gst_object_unref (pool);
return FALSE; return FALSE;
} }
error_create_pool: error_create_pool:
{ {
GST_ERROR_OBJECT (plugin, "failed to create buffer pool"); /* error message already sent */
return FALSE;
}
error_pool_config:
{
GST_ERROR_OBJECT (plugin, "failed to reset buffer pool config");
gst_object_unref (pool);
return FALSE; return FALSE;
} }
} }
@ -694,15 +745,12 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin,
{ {
GstCaps *caps = NULL; GstCaps *caps = NULL;
GstBufferPool *pool; GstBufferPool *pool;
GstStructure *config;
GstVideoInfo vi; GstVideoInfo vi;
guint size, min, max; guint size, min, max;
gboolean update_pool = FALSE; gboolean update_pool = FALSE;
gboolean has_video_meta = FALSE; guint pool_options;
gboolean has_video_alignment = FALSE;
GstAllocator *allocator; GstAllocator *allocator;
#if (USE_GLX || USE_EGL) #if (USE_GLX || USE_EGL)
gboolean has_texture_upload_meta = FALSE;
guint idx; guint idx;
#endif #endif
@ -716,17 +764,19 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin,
so explicitly through GstVideoGLTextureUploadMeta */ so explicitly through GstVideoGLTextureUploadMeta */
gst_object_replace (&plugin->gl_context, NULL); gst_object_replace (&plugin->gl_context, NULL);
has_video_meta = gst_query_find_allocation_meta (query, pool_options = 0;
GST_VIDEO_META_API_TYPE, NULL); if (gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL))
pool_options |= GST_VAAPI_OPTION_VIDEO_META;
#if (USE_GLX || USE_EGL) #if (USE_GLX || USE_EGL)
has_texture_upload_meta = gst_query_find_allocation_meta (query, if (gst_query_find_allocation_meta (query,
GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, &idx) && GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, &idx) &&
gst_vaapi_caps_feature_contains (caps, gst_vaapi_caps_feature_contains (caps,
GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META); GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META))
pool_options |= GST_VAAPI_OPTION_GL_TEXTURE_UPLOAD;
#if USE_GST_GL_HELPERS #if USE_GST_GL_HELPERS
if (has_texture_upload_meta) { if (pool_options & GST_VAAPI_OPTION_GL_TEXTURE_UPLOAD) {
const GstStructure *params; const GstStructure *params;
GstObject *gl_context; GstObject *gl_context;
@ -759,8 +809,9 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin,
if (pool) { if (pool) {
/* Check whether downstream element proposed a bufferpool but did /* Check whether downstream element proposed a bufferpool but did
not provide a correct propose_allocation() implementation */ not provide a correct propose_allocation() implementation */
has_video_alignment = gst_buffer_pool_has_option (pool, if (gst_buffer_pool_has_option (pool,
GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT); GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT))
pool_options |= GST_VAAPI_OPTION_VIDEO_ALIGNMENT;
/* GstVaapiVideoMeta is mandatory, and this implies VA surface memory */ /* GstVaapiVideoMeta is mandatory, and this implies VA surface memory */
if (!gst_buffer_pool_has_option (pool, if (!gst_buffer_pool_has_option (pool,
@ -776,48 +827,17 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin,
min = max = 0; min = max = 0;
} }
config = NULL;
if (!pool) { if (!pool) {
pool = gst_vaapi_video_buffer_pool_new (plugin->display);
if (!pool)
goto error_create_pool;
allocator = gst_vaapi_video_allocator_new (plugin->display, &vi, 0); allocator = gst_vaapi_video_allocator_new (plugin->display, &vi, 0);
if (!allocator) if (!allocator)
goto error_create_allocator; goto error_create_allocator;
pool = gst_vaapi_plugin_base_create_pool (plugin, caps, size, min, max,
config = gst_buffer_pool_get_config (pool); pool_options, allocator);
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); gst_object_unref (allocator);
if (!pool)
goto error_create_pool;
} }
if (!config)
config = gst_buffer_pool_get_config (pool);
/* Check whether GstVideoMeta, or GstVideoAlignment, is needed (raw video) */
if (has_video_meta) {
gst_buffer_pool_config_add_option (config,
GST_BUFFER_POOL_OPTION_VIDEO_META);
} else if (has_video_alignment) {
gst_buffer_pool_config_add_option (config,
GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT);
}
/* GstVideoGLTextureUploadMeta (OpenGL) */
#if (USE_GLX || USE_EGL)
if (has_texture_upload_meta) {
gst_buffer_pool_config_add_option (config,
GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META);
}
#endif
if (!gst_buffer_pool_set_config (pool, config))
goto error_config_failed;
if (update_pool) if (update_pool)
gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max); gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max);
else else
@ -844,24 +864,14 @@ error_ensure_display:
plugin->display_type_req); plugin->display_type_req);
return FALSE; return FALSE;
} }
error_create_pool:
{
GST_ERROR_OBJECT (plugin, "failed to create buffer pool");
return FALSE;
}
error_create_allocator: error_create_allocator:
{ {
GST_ERROR_OBJECT (plugin, "failed to create allocator"); GST_ERROR_OBJECT (plugin, "failed to create allocator");
gst_object_unref (pool);
return FALSE; return FALSE;
} }
error_config_failed: error_create_pool:
{ {
if (pool) /* error message already sent */
gst_object_unref (pool);
GST_ELEMENT_ERROR (plugin, RESOURCE, SETTINGS,
("Failed to configure the buffer pool"),
("Configuration is most likely invalid, please report this issue."));
return FALSE; return FALSE;
} }
} }