From 959d14ce8a9e0de184dfc7e73090e5287fa1f11e Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 24 Mar 2016 15:09:43 +0200 Subject: [PATCH] vaapidecode: Fix decide_allocation handling Set the already configured pool in decide_allocation query in cases where pool renegotiation is not required. https://bugzilla.gnome.org/show_bug.cgi?id=753914 --- gst/vaapi/gstvaapidecode.c | 38 +++++++++++++++++++++++++++++----- gst/vaapi/gstvaapipluginbase.c | 27 ++++++++++++------------ 2 files changed, 46 insertions(+), 19 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 9739b3f521..1dbabe1926 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -399,7 +399,10 @@ gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, * But there are issues with it especially for some vp9 streams where * upstream element set un-cropped values in set_format() which make * everything a mess. So better doing the explicit check here irrespective - * of what notification we get from upstream or libgstvaapi */ + * of what notification we get from upstream or libgstvaapi.Also, even if + * we received notification from libgstvaapi, the frame we are going to + * be pushed at this point might not have the notified resolution if there + * are queued frames in decoded picture buffer. */ decode->do_pool_renego = is_surface_resolution_changed (decode, GST_VAAPI_SURFACE_PROXY_SURFACE (proxy)); @@ -680,6 +683,7 @@ gst_vaapidecode_decide_allocation (GstVideoDecoder * vdec, GstQuery * query) { GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); GstCaps *caps = NULL; + gboolean ret = FALSE; gst_query_parse_allocation (query, &caps, NULL); decode->has_texture_upload_meta = FALSE; @@ -692,21 +696,45 @@ gst_vaapidecode_decide_allocation (GstVideoDecoder * vdec, GstQuery * query) #endif if (decode->do_pool_renego) { - gboolean ret; - caps = gst_caps_copy (caps); + /* Always use un-cropped dimension of decoded surface for pool negotiation */ gst_caps_set_simple (caps, "width", G_TYPE_INT, GST_VIDEO_INFO_WIDTH (&decode->decoded_info), "height", G_TYPE_INT, GST_VIDEO_INFO_HEIGHT (&decode->decoded_info), NULL); + ret = gst_vaapi_plugin_base_decide_allocation (GST_VAAPI_PLUGIN_BASE (vdec), query, 0, caps); + gst_caps_unref (caps); decode->do_pool_renego = FALSE; - return ret; } else { - return TRUE; + /* No need to renegotiate the pool, set the previously configured pool in query */ + guint size, min, max; + GstStructure *config; + GstVaapiPluginBase *plugin = GST_VAAPI_PLUGIN_BASE (vdec); + GstBufferPool *pool = plugin->srcpad_buffer_pool; + + if (G_UNLIKELY (!pool)) { + GST_ERROR ("Failed to find configured VaapiVideoBufferPool! "); + return ret; + } + + config = gst_buffer_pool_get_config (pool); + if (!config + || !gst_buffer_pool_config_get_params (config, NULL, &size, &min, &max)) + return ret; + gst_structure_free (config); + + if (gst_query_get_n_allocation_pools (query) > 0) + gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max); + else + gst_query_add_allocation_pool (query, pool, size, min, max); + + ret = TRUE; } + + return ret; } static inline gboolean diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 5fa2c71f47..e764cea629 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -601,8 +601,8 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, GstCaps *caps = NULL; GstBufferPool *pool; GstStructure *config; - GstQuery *new_query; GstVideoInfo vi; + GstQuery *old_query = NULL, *new_query = NULL; guint size, min, max; gboolean update_pool = FALSE; gboolean has_video_meta = FALSE; @@ -614,17 +614,18 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, g_return_val_if_fail (plugin->display != NULL, FALSE); - gst_query_parse_allocation (query, &caps, NULL); - /* Make sure new caps get advertised to all downstream elements */ if (preferred_caps) { - new_query = gst_query_new_allocation (preferred_caps, FALSE); + new_query = gst_query_new_allocation (preferred_caps, TRUE); if (!gst_pad_peer_query (GST_VAAPI_PLUGIN_BASE_SRC_PAD (plugin), new_query)) { GST_DEBUG ("didn't get downstream ALLOCATION hints"); } - gst_query_unref (new_query); + old_query = query; + query = new_query; } + gst_query_parse_allocation (query, &caps, NULL); + /* We don't need any GL context beyond this point if not requested so explicitly through GstVideoGLTextureUploadMeta */ gst_object_replace (&plugin->gl_context, NULL); @@ -669,10 +670,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, goto error_ensure_display; gst_video_info_init (&vi); - if (!preferred_caps) - gst_video_info_from_caps (&vi, caps); - else - gst_video_info_from_caps (&vi, preferred_caps); + 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, @@ -706,11 +704,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, goto error_create_pool; config = gst_buffer_pool_get_config (pool); - if (!preferred_caps) - gst_buffer_pool_config_set_params (config, caps, size, min, max); - else - gst_buffer_pool_config_set_params (config, preferred_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_OPTION_VAAPI_VIDEO_META); if (!gst_buffer_pool_set_config (pool, config)) @@ -737,6 +731,11 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin, } #endif + if (old_query) + query = old_query; + if (new_query) + gst_query_unref (new_query); + if (update_pool) gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max); else