vkdownload: implement decide_allocation virtual method

In the case of caps change such as frame size, a new buffer pool should be
created according to this new caps via the decide_allocation() vmethod.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8931>
This commit is contained in:
Stéphane Cerveau 2025-05-05 14:44:54 +02:00 committed by Víctor Manuel Jáquez Leal
parent 9fb3df1422
commit 7320acdaca
2 changed files with 99 additions and 21 deletions

View File

@ -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

View File

@ -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);