diff --git a/subprojects/gst-plugins-bad/ext/vulkan/vkdownload.c b/subprojects/gst-plugins-bad/ext/vulkan/vkdownload.c index 219eefd7fa..7c5ef6a243 100644 --- a/subprojects/gst-plugins-bad/ext/vulkan/vkdownload.c +++ b/subprojects/gst-plugins-bad/ext/vulkan/vkdownload.c @@ -83,7 +83,6 @@ struct ImageToRawDownload GstVideoInfo out_info; GstBufferPool *pool; - gboolean pool_active; GstVulkanOperation *exec; }; @@ -138,6 +137,61 @@ _image_to_raw_propose_allocation (gpointer impl, GstQuery * decide_query, /* FIXME: implement */ } +static gboolean +_image_to_raw_decide_allocation (gpointer impl, GstQuery * query) +{ + struct ImageToRawDownload *raw = impl; + GstStructure *config; + guint min = 1, max = 0, size = 1; + GstCaps *caps; + gboolean update_pool = FALSE; + GstBufferPool *pool = NULL; + + gst_query_parse_allocation (query, &caps, NULL); + if (!caps) + return FALSE; + + if (gst_query_get_n_allocation_pools (query) > 0) { + gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max); + if (GST_IS_VULKAN_BUFFER_POOL (pool)) { + update_pool = TRUE; + } else { + gst_clear_object (&pool); + } + } + + /* let's null current pool */ + gst_clear_object (&raw->pool); + + if (!pool) { + pool = gst_vulkan_buffer_pool_new (raw->download->device); + } + + config = gst_buffer_pool_get_config (pool); + + gst_buffer_pool_config_set_params (config, raw->download->out_caps, size, + min, max); + if (gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL)) { + gst_buffer_pool_config_add_option (config, + GST_BUFFER_POOL_OPTION_VIDEO_META); + } + + if (!gst_buffer_pool_set_config (pool, config)) { + gst_clear_object (&pool); + GST_ERROR_OBJECT (raw->download, "Failed to set buffer pool config"); + return FALSE; + } + + 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); + + raw->pool = pool; + + return TRUE; +} + static GstFlowReturn _image_to_raw_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf) { @@ -161,22 +215,13 @@ _image_to_raw_perform (gpointer impl, GstBuffer * inbuf, GstBuffer ** outbuf) } if (!raw->pool) { - GstStructure *config; - guint min = 0, max = 0; - gsize size = 1; - - raw->pool = gst_vulkan_buffer_pool_new (raw->download->device); - config = gst_buffer_pool_get_config (raw->pool); - gst_buffer_pool_config_set_params (config, raw->download->out_caps, size, - min, max); - if (!gst_buffer_pool_set_config (raw->pool, config)) { - gst_clear_object (&raw->pool); - return GST_FLOW_ERROR; - } + GST_ERROR_OBJECT (raw->download, "No pool found."); + goto error; } - if (!raw->pool_active) { - gst_buffer_pool_set_active (raw->pool, TRUE); - raw->pool_active = TRUE; + + if (!gst_buffer_pool_set_active (raw->pool, TRUE)) { + GST_ERROR_OBJECT (raw->download, "Couldn't activate pool."); + goto error; } if ((ret = @@ -321,10 +366,7 @@ _image_to_raw_free (gpointer impl) struct ImageToRawDownload *raw = impl; if (raw->pool) { - if (raw->pool_active) { - gst_buffer_pool_set_active (raw->pool, FALSE); - } - raw->pool_active = FALSE; + gst_buffer_pool_set_active (raw->pool, FALSE); gst_object_unref (raw->pool); raw->pool = NULL; } @@ -346,6 +388,7 @@ static const struct DownloadMethod image_to_raw_download = { _image_to_raw_transform_caps, _image_to_raw_set_caps, _image_to_raw_propose_allocation, + _image_to_raw_decide_allocation, _image_to_raw_perform, _image_to_raw_free, }; @@ -756,7 +799,40 @@ gst_vulkan_download_propose_allocation (GstBaseTransform * bt, static gboolean gst_vulkan_download_decide_allocation (GstBaseTransform * bt, GstQuery * query) { - return TRUE; + GstVulkanDownload *vk_download = GST_VULKAN_DOWNLOAD (bt); + guint i; + gboolean ret = TRUE; + + for (i = 0; i < G_N_ELEMENTS (download_methods); i++) { + GstCaps *templ; + gboolean res; + + templ = gst_static_caps_get (download_methods[i]->in_template); + if (!gst_caps_can_intersect (vk_download->in_caps, templ)) { + gst_caps_unref (templ); + continue; + } + gst_caps_unref (templ); + + templ = gst_static_caps_get (download_methods[i]->out_template); + if (!gst_caps_can_intersect (vk_download->out_caps, templ)) { + gst_caps_unref (templ); + continue; + } + gst_caps_unref (templ); + + res = + download_methods[i]->decide_allocation (vk_download->download_impls[i], + query); + + /* if all methods fail, function fails */ + if (i == 0) + ret = res; + else + ret |= res; + } + + return ret; } static gboolean diff --git a/subprojects/gst-plugins-bad/ext/vulkan/vkdownload.h b/subprojects/gst-plugins-bad/ext/vulkan/vkdownload.h index 126460329a..b92367a499 100644 --- a/subprojects/gst-plugins-bad/ext/vulkan/vkdownload.h +++ b/subprojects/gst-plugins-bad/ext/vulkan/vkdownload.h @@ -53,6 +53,8 @@ struct DownloadMethod void (*propose_allocation) (gpointer impl, GstQuery * decide_query, GstQuery * query); + gboolean (*decide_allocation) (gpointer impl, + GstQuery * decide_query); GstFlowReturn (*perform) (gpointer impl, GstBuffer * buffer, GstBuffer ** outbuf);