From d0a9575fc22701a68abb790d13524edb86e47f6d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 21 Aug 2014 14:10:36 +0200 Subject: [PATCH] plugins: factor out decide_allocation() hook. Add a default decide_allocation() hook to GstVaapiPluginBase. The caps feature argument can be used to force a bufferpool with a specific kind of memory. --- gst/vaapi/gstvaapidecode.c | 119 +++------------------------------- gst/vaapi/gstvaapipluginbase.c | 141 +++++++++++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapipluginbase.h | 8 +++ 3 files changed, 158 insertions(+), 110 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 4f716c6..989f7a1 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -522,40 +522,26 @@ gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query) { GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec); GstCaps *caps = NULL; - GstBufferPool *pool; - GstStructure *config; - GstVideoInfo vi; - guint size, min, max; - gboolean need_pool, update_pool; - gboolean has_video_meta = FALSE; - gboolean has_video_alignment = FALSE; -#if GST_CHECK_VERSION(1,1,0) && USE_GLX - gboolean has_texture_upload_meta = FALSE; -#endif + gboolean need_pool; GstVideoCodecState *state; + GstVaapiCapsFeature feature; gst_query_parse_allocation(query, &caps, &need_pool); - if (!caps) - goto error_no_caps; - - state = gst_video_decoder_get_output_state(vdec); - decode->has_texture_upload_meta = FALSE; - has_video_meta = gst_query_find_allocation_meta(query, - GST_VIDEO_META_API_TYPE, NULL); - #if GST_CHECK_VERSION(1,1,0) && USE_GLX - has_texture_upload_meta = gst_query_find_allocation_meta(query, - GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, NULL); - decode->has_texture_upload_meta = gst_vaapi_find_preferred_caps_feature(GST_VIDEO_DECODER_SRC_PAD(vdec), GST_VIDEO_FORMAT_ENCODED) == GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META; #endif + feature = decode->has_texture_upload_meta ? + GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META : + GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE; + /* Update src caps if feature is not handled downstream */ + state = gst_video_decoder_get_output_state(vdec); if (!gst_caps_is_always_compatible(caps, state->caps)) { if (decode->has_texture_upload_meta) gst_video_info_set_format(&state->info, GST_VIDEO_FORMAT_RGBA, @@ -565,95 +551,8 @@ gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query) } gst_video_codec_state_unref(state); - gst_video_info_init(&vi); - gst_video_info_from_caps(&vi, caps); - if (GST_VIDEO_INFO_FORMAT(&vi) == GST_VIDEO_FORMAT_ENCODED) - gst_video_info_set_format(&vi, GST_VIDEO_FORMAT_I420, - GST_VIDEO_INFO_WIDTH(&vi), GST_VIDEO_INFO_HEIGHT(&vi)); - - g_return_val_if_fail(GST_VAAPI_PLUGIN_BASE_DISPLAY(decode) != NULL, FALSE); - - if (gst_query_get_n_allocation_pools(query) > 0) { - gst_query_parse_nth_allocation_pool(query, 0, &pool, &size, &min, &max); - size = MAX(size, vi.size); - update_pool = TRUE; - - /* Check whether downstream element proposed a bufferpool but did - not provide a correct propose_allocation() implementation */ - has_video_alignment = gst_buffer_pool_has_option(pool, - GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT); - } - else { - pool = NULL; - size = vi.size; - min = max = 0; - update_pool = FALSE; - } - - if (!pool || !gst_buffer_pool_has_option(pool, - GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META)) { - GST_INFO("no pool or doesn't support GstVaapiVideoMeta, " - "making new pool"); - if (pool) - gst_object_unref(pool); - pool = gst_vaapi_video_buffer_pool_new( - GST_VAAPI_PLUGIN_BASE_DISPLAY(decode)); - if (!pool) - goto error_create_pool; - - 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_set_config(pool, config); - } - - if (has_video_meta) { - config = gst_buffer_pool_get_config(pool); - gst_buffer_pool_config_add_option(config, - GST_BUFFER_POOL_OPTION_VIDEO_META); -#if GST_CHECK_VERSION(1,1,0) && USE_GLX - if (has_texture_upload_meta) - gst_buffer_pool_config_add_option(config, - GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META); -#endif - gst_buffer_pool_set_config(pool, config); - } - else if (has_video_alignment) { - config = gst_buffer_pool_get_config(pool); - gst_buffer_pool_config_add_option(config, - GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT); - gst_buffer_pool_set_config(pool, config); - } - -#if GST_CHECK_VERSION(1,1,0) && USE_GLX - if (decode->has_texture_upload_meta && !has_texture_upload_meta) { - config = gst_buffer_pool_get_config(pool); - gst_buffer_pool_config_add_option(config, - GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META); - gst_buffer_pool_set_config(pool, config); - } -#endif - - if (update_pool) - gst_query_set_nth_allocation_pool(query, 0, pool, size, min, max); - else - gst_query_add_allocation_pool(query, pool, size, min, max); - if (pool) - gst_object_unref(pool); - return TRUE; - - /* ERRORS */ -error_no_caps: - { - GST_ERROR("no caps specified"); - return FALSE; - } -error_create_pool: - { - GST_ERROR("failed to create buffer pool"); - return FALSE; - } + return gst_vaapi_plugin_base_decide_allocation(GST_VAAPI_PLUGIN_BASE(vdec), + query, feature); } #endif diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index ad254f2..f69f84b 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -206,6 +206,7 @@ gst_vaapi_plugin_base_close (GstVaapiPluginBase * plugin) gst_object_unref (plugin->sinkpad_buffer_pool); plugin->sinkpad_buffer_pool = NULL; } + g_clear_object (&plugin->srcpad_buffer_pool); #endif gst_caps_replace (&plugin->srcpad_caps, NULL); @@ -454,6 +455,146 @@ error_no_caps: #endif /** + * gst_vaapi_plugin_base_decide_allocation: + * @plugin: a #GstVaapiPluginBase + * @query: the allocation query to parse + * @feature: the desired #GstVaapiCapsFeature, or zero to find the + * preferred one + * + * Decides allocation parameters for the downstream elements. + * + * Returns: %TRUE if successful, %FALSE otherwise. + */ +#if GST_CHECK_VERSION(1,0,0) +gboolean +gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, + GstQuery * query, guint feature) +{ + GstCaps *caps = NULL; + GstBufferPool *pool; + GstStructure *config; + GstVideoInfo vi; + guint size, min, max; + gboolean need_pool, update_pool; + gboolean has_video_meta = FALSE; + gboolean has_video_alignment = FALSE; +#if GST_CHECK_VERSION(1,1,0) && USE_GLX + gboolean has_texture_upload_meta = FALSE; +#endif + + g_return_val_if_fail (plugin->display != NULL, FALSE); + + gst_query_parse_allocation (query, &caps, &need_pool); + + if (!caps) + goto error_no_caps; + + if (!feature) + feature = + gst_vaapi_find_preferred_caps_feature (plugin->srcpad, + GST_VIDEO_FORMAT_ENCODED); + + has_video_meta = gst_query_find_allocation_meta (query, + GST_VIDEO_META_API_TYPE, NULL); + +#if GST_CHECK_VERSION(1,1,0) && USE_GLX + has_texture_upload_meta = gst_query_find_allocation_meta (query, + GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, NULL); +#endif + + gst_video_info_init (&vi); + gst_video_info_from_caps (&vi, caps); + if (GST_VIDEO_INFO_FORMAT (&vi) == GST_VIDEO_FORMAT_ENCODED) + gst_video_info_set_format (&vi, GST_VIDEO_FORMAT_I420, + GST_VIDEO_INFO_WIDTH (&vi), GST_VIDEO_INFO_HEIGHT (&vi)); + + if (gst_query_get_n_allocation_pools (query) > 0) { + gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max); + size = MAX (size, vi.size); + update_pool = TRUE; + + /* Check whether downstream element proposed a bufferpool but did + not provide a correct propose_allocation() implementation */ + has_video_alignment = gst_buffer_pool_has_option (pool, + GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT); + } else { + pool = NULL; + size = vi.size; + min = max = 0; + update_pool = FALSE; + } + + /* GstVaapiVideoMeta is mandatory, and this implies VA surface memory */ + if (!pool || !gst_buffer_pool_has_option (pool, + GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META)) { + GST_INFO_OBJECT (plugin, "no pool or doesn't support GstVaapiVideoMeta, " + "making new pool"); + if (pool) + gst_object_unref (pool); + pool = gst_vaapi_video_buffer_pool_new (plugin->display); + if (!pool) + goto error_create_pool; + + 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_set_config (pool, config); + } + + /* Check whether GstVideoMeta, or GstVideoAlignment, is needed (raw video) */ + if (has_video_meta) { + config = gst_buffer_pool_get_config (pool); + gst_buffer_pool_config_add_option (config, + GST_BUFFER_POOL_OPTION_VIDEO_META); +#if GST_CHECK_VERSION(1,1,0) && USE_GLX + if (has_texture_upload_meta) + gst_buffer_pool_config_add_option (config, + GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META); +#endif + gst_buffer_pool_set_config (pool, config); + } else if (has_video_alignment) { + config = gst_buffer_pool_get_config (pool); + gst_buffer_pool_config_add_option (config, + GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT); + gst_buffer_pool_set_config (pool, config); + } + + /* GstVideoGLTextureUploadMeta (OpenGL) */ +#if GST_CHECK_VERSION(1,1,0) && USE_GLX + if (feature == GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META + && !has_texture_upload_meta) { + config = gst_buffer_pool_get_config (pool); + gst_buffer_pool_config_add_option (config, + GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META); + gst_buffer_pool_set_config (pool, config); + } +#endif + + if (update_pool) + gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max); + else + gst_query_add_allocation_pool (query, pool, size, min, max); + + g_clear_object (&plugin->srcpad_buffer_pool); + plugin->srcpad_buffer_pool = pool; + return TRUE; + + /* ERRORS */ +error_no_caps: + { + GST_ERROR_OBJECT (plugin, "no caps specified"); + return FALSE; + } +error_create_pool: + { + GST_ERROR_OBJECT (plugin, "failed to create buffer pool"); + return FALSE; + } +} +#endif + +/** * gst_vaapi_plugin_base_allocate_input_buffer: * @plugin: a #GstVaapiPluginBase * @caps: the buffer caps constraints to honour diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index 76413b3..e7426cb 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -136,6 +136,9 @@ struct _GstVaapiPluginBase gboolean srcpad_caps_changed; GstVideoInfo srcpad_info; GstPadQueryFunction srcpad_query; +#if GST_CHECK_VERSION(1,0,0) + GstBufferPool *srcpad_buffer_pool; +#endif GstVaapiDisplay *display; GstVaapiDisplayType display_type; @@ -216,6 +219,11 @@ gst_vaapi_plugin_base_propose_allocation (GstVaapiPluginBase * plugin, GstQuery * query); G_GNUC_INTERNAL +gboolean +gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, + GstQuery * query, guint feature); + +G_GNUC_INTERNAL GstFlowReturn gst_vaapi_plugin_base_allocate_input_buffer (GstVaapiPluginBase * plugin, GstCaps * caps, GstBuffer ** outbuf_ptr); -- 2.7.4