diff options
author | Matthew Waters <matthew@centricular.com> | 2019-11-26 18:11:25 +1100 |
---|---|---|
committer | GStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org> | 2019-11-28 23:27:21 +0000 |
commit | 615022ad93e454d53811889df57cbf0342aec1c6 (patch) | |
tree | 2236361937f4ca5c1724e7028d3a2652b7664723 /gst-libs/gst/vulkan | |
parent | 756d52ef1582d03c9bba5571ddd4aa911749862a (diff) | |
download | gstreamer-plugins-bad-615022ad93e454d53811889df57cbf0342aec1c6.tar.gz |
vulkan: split vkfullscreenrender into two
Part 1 is a base class (vkvideofilter) that handles instance, device,
queue retrieval and holding that has been moved to the library
Part 2 is a fullscreenrenderquad that is still in the plugin that
performs all of the previous vulkan-specific functionality.
Diffstat (limited to 'gst-libs/gst/vulkan')
-rw-r--r-- | gst-libs/gst/vulkan/gstvkvideofilter.c | 338 | ||||
-rw-r--r-- | gst-libs/gst/vulkan/gstvkvideofilter.h | 63 | ||||
-rw-r--r-- | gst-libs/gst/vulkan/meson.build | 2 | ||||
-rw-r--r-- | gst-libs/gst/vulkan/vulkan.h | 4 |
4 files changed, 407 insertions, 0 deletions
diff --git a/gst-libs/gst/vulkan/gstvkvideofilter.c b/gst-libs/gst/vulkan/gstvkvideofilter.c new file mode 100644 index 000000000..2fa838199 --- /dev/null +++ b/gst-libs/gst/vulkan/gstvkvideofilter.c @@ -0,0 +1,338 @@ +/* + * GStreamer + * Copyright (C) 2019 Matthew Waters <matthew@centricular.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +/** + * SECTION:vulkanvideofilter + * @title: vulkanvideofilter + * + * vulkanvideofilter is a helper base class for retrieving and holding the + * #GstVulkanInstance, #GstVulkanDevice and #GstVulkanQueue used by an element. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <string.h> + +#include <gst/vulkan/gstvkvideofilter.h> + +GST_DEBUG_CATEGORY (gst_debug_vulkan_video_filter); +#define GST_CAT_DEFAULT gst_debug_vulkan_video_filter + +static void gst_vulkan_video_filter_finalize (GObject * object); + +static gboolean gst_vulkan_video_filter_query (GstBaseTransform * bt, + GstPadDirection direction, GstQuery * query); +static void gst_vulkan_video_filter_set_context (GstElement * element, + GstContext * context); + +static gboolean gst_vulkan_video_filter_start (GstBaseTransform * bt); +static gboolean gst_vulkan_video_filter_stop (GstBaseTransform * bt); + +static gboolean gst_vulkan_video_filter_set_caps (GstBaseTransform * bt, + GstCaps * in_caps, GstCaps * out_caps); +static GstCaps *gst_vulkan_video_filter_transform_caps (GstBaseTransform * + bt, GstPadDirection direction, GstCaps * caps, GstCaps * filter); +static gboolean +gst_vulkan_video_filter_propose_allocation (GstBaseTransform * bt, + GstQuery * decide_query, GstQuery * query); +static gboolean +gst_vulkan_video_filter_decide_allocation (GstBaseTransform * bt, + GstQuery * query); + +enum +{ + PROP_0, +}; + +enum +{ + SIGNAL_0, + LAST_SIGNAL +}; + +/* static guint gst_vulkan_video_filter_signals[LAST_SIGNAL] = { 0 }; */ + +#define gst_vulkan_video_filter_parent_class parent_class +G_DEFINE_TYPE_WITH_CODE (GstVulkanVideoFilter, + gst_vulkan_video_filter, GST_TYPE_BASE_TRANSFORM, + GST_DEBUG_CATEGORY_INIT (gst_debug_vulkan_video_filter, + "vulkanvideofilter", 0, "Vulkan Video Filter")); + +static void +gst_vulkan_video_filter_class_init (GstVulkanVideoFilterClass * klass) +{ + GObjectClass *gobject_class; + GstElementClass *gstelement_class; + GstBaseTransformClass *gstbasetransform_class; + + gobject_class = (GObjectClass *) klass; + gstelement_class = (GstElementClass *) klass; + gstbasetransform_class = (GstBaseTransformClass *) klass; + + gobject_class->finalize = gst_vulkan_video_filter_finalize; + + gstelement_class->set_context = gst_vulkan_video_filter_set_context; + gstbasetransform_class->start = + GST_DEBUG_FUNCPTR (gst_vulkan_video_filter_start); + gstbasetransform_class->stop = + GST_DEBUG_FUNCPTR (gst_vulkan_video_filter_stop); + gstbasetransform_class->query = + GST_DEBUG_FUNCPTR (gst_vulkan_video_filter_query); + gstbasetransform_class->set_caps = gst_vulkan_video_filter_set_caps; + gstbasetransform_class->transform_caps = + gst_vulkan_video_filter_transform_caps; + gstbasetransform_class->propose_allocation = + gst_vulkan_video_filter_propose_allocation; + gstbasetransform_class->decide_allocation = + gst_vulkan_video_filter_decide_allocation; +} + +static void +gst_vulkan_video_filter_init (GstVulkanVideoFilter * render) +{ +} + +static void +gst_vulkan_video_filter_finalize (GObject * object) +{ + GstVulkanVideoFilter *render = GST_VULKAN_VIDEO_FILTER (object); + + gst_caps_replace (&render->in_caps, NULL); + gst_caps_replace (&render->out_caps, NULL); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static gboolean +gst_vulkan_video_filter_query (GstBaseTransform * bt, + GstPadDirection direction, GstQuery * query) +{ + GstVulkanVideoFilter *render = GST_VULKAN_VIDEO_FILTER (bt); + + switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_CONTEXT:{ + if (gst_vulkan_handle_context_query (GST_ELEMENT (render), query, + NULL, render->instance, render->device)) + return TRUE; + + if (gst_vulkan_queue_handle_context_query (GST_ELEMENT (render), + query, render->queue)) + return TRUE; + + break; + } + default: + break; + } + + return GST_BASE_TRANSFORM_CLASS (parent_class)->query (bt, direction, query); +} + +static void +gst_vulkan_video_filter_set_context (GstElement * element, GstContext * context) +{ + GstVulkanVideoFilter *render = GST_VULKAN_VIDEO_FILTER (element); + + gst_vulkan_handle_set_context (element, context, NULL, &render->instance); + + GST_ELEMENT_CLASS (parent_class)->set_context (element, context); +} + +struct choose_data +{ + GstVulkanVideoFilter *upload; + GstVulkanQueue *queue; +}; + +static gboolean +_choose_queue (GstVulkanDevice * device, GstVulkanQueue * queue, + struct choose_data *data) +{ + guint flags = + device->physical_device->queue_family_props[queue->family].queueFlags; + + if ((flags & VK_QUEUE_GRAPHICS_BIT) != 0) { + if (data->queue) + gst_object_unref (data->queue); + data->queue = gst_object_ref (queue); + return FALSE; + } + + return TRUE; +} + +static GstVulkanQueue * +_find_graphics_queue (GstVulkanVideoFilter * upload) +{ + struct choose_data data; + + data.upload = upload; + data.queue = NULL; + + gst_vulkan_device_foreach_queue (upload->device, + (GstVulkanDeviceForEachQueueFunc) _choose_queue, &data); + + return data.queue; +} + +static GstCaps * +gst_vulkan_video_filter_transform_caps (GstBaseTransform * bt, + GstPadDirection direction, GstCaps * caps, GstCaps * filter) +{ + GstCaps *result, *tmp; + + tmp = gst_caps_copy (caps); + + if (filter) { + result = gst_caps_intersect_full (filter, tmp, GST_CAPS_INTERSECT_FIRST); + gst_caps_unref (tmp); + } else { + result = tmp; + } + + return result; +} + +static gboolean +gst_vulkan_video_filter_set_caps (GstBaseTransform * bt, + GstCaps * in_caps, GstCaps * out_caps) +{ + GstVulkanVideoFilter *render = GST_VULKAN_VIDEO_FILTER (bt); + + if (!gst_video_info_from_caps (&render->in_info, in_caps)) + return FALSE; + if (!gst_video_info_from_caps (&render->out_info, out_caps)) + return FALSE; + + gst_caps_replace (&render->in_caps, in_caps); + gst_caps_replace (&render->out_caps, out_caps); + GST_DEBUG_OBJECT (bt, "set caps: %" GST_PTR_FORMAT, in_caps); + + return TRUE; +} + +static gboolean +gst_vulkan_video_filter_propose_allocation (GstBaseTransform * bt, + GstQuery * decide_query, GstQuery * query) +{ + /* FIXME: */ + return FALSE; +} + +static gboolean +gst_vulkan_video_filter_decide_allocation (GstBaseTransform * bt, + GstQuery * query) +{ + GstVulkanVideoFilter *render = GST_VULKAN_VIDEO_FILTER (bt); + GstBufferPool *pool = NULL; + GstStructure *config; + GstCaps *caps; + guint min, max, size; + gboolean update_pool; + + 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); + + update_pool = TRUE; + } else { + GstVideoInfo vinfo; + + gst_video_info_init (&vinfo); + gst_video_info_from_caps (&vinfo, caps); + size = vinfo.size; + min = max = 0; + update_pool = FALSE; + } + + if (!pool || !GST_IS_VULKAN_IMAGE_BUFFER_POOL (pool)) { + if (pool) + gst_object_unref (pool); + pool = gst_vulkan_image_buffer_pool_new (render->device); + } + + 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_VIDEO_META); + + gst_buffer_pool_set_config (pool, config); + + 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); + + gst_object_unref (pool); + + return TRUE; +} + +static gboolean +gst_vulkan_video_filter_start (GstBaseTransform * bt) +{ + GstVulkanVideoFilter *render = GST_VULKAN_VIDEO_FILTER (bt); + + if (!gst_vulkan_ensure_element_data (GST_ELEMENT (bt), NULL, + &render->instance)) { + GST_ELEMENT_ERROR (render, RESOURCE, NOT_FOUND, + ("Failed to retrieve vulkan instance"), (NULL)); + return FALSE; + } + if (!gst_vulkan_device_run_context_query (GST_ELEMENT (render), + &render->device)) { + GError *error = NULL; + GST_DEBUG_OBJECT (render, "No device retrieved from peer elements"); + if (!(render->device = + gst_vulkan_instance_create_device (render->instance, &error))) { + GST_ELEMENT_ERROR (render, RESOURCE, NOT_FOUND, + ("Failed to create vulkan device"), ("%s", error->message)); + g_clear_error (&error); + return FALSE; + } + } + + if (!gst_vulkan_queue_run_context_query (GST_ELEMENT (render), + &render->queue)) { + GST_DEBUG_OBJECT (render, "No queue retrieved from peer elements"); + render->queue = _find_graphics_queue (render); + } + if (!render->queue) + return FALSE; + + return TRUE; +} + +static gboolean +gst_vulkan_video_filter_stop (GstBaseTransform * bt) +{ + GstVulkanVideoFilter *render = GST_VULKAN_VIDEO_FILTER (bt); + + gst_clear_object (&render->device); + gst_clear_object (&render->queue); + gst_clear_object (&render->instance); + + return TRUE; +} diff --git a/gst-libs/gst/vulkan/gstvkvideofilter.h b/gst-libs/gst/vulkan/gstvkvideofilter.h new file mode 100644 index 000000000..986615b0e --- /dev/null +++ b/gst-libs/gst/vulkan/gstvkvideofilter.h @@ -0,0 +1,63 @@ +/* + * GStreamer + * Copyright (C) 2019 Matthew Waters <matthew@centricular.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef _VK_FULL_SCREEN_RENDER_H_ +#define _VK_FULL_SCREEN_RENDER_H_ + +#include <gst/gst.h> +#include <gst/video/video.h> +#include <gst/vulkan/gstvkqueue.h> + +G_BEGIN_DECLS + +GST_VULKAN_API +GType gst_vulkan_video_filter_get_type(void); +#define GST_TYPE_VULKAN_VIDEO_FILTER (gst_vulkan_video_filter_get_type()) +#define GST_VULKAN_VIDEO_FILTER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VULKAN_VIDEO_FILTER,GstVulkanVideoFilter)) +#define GST_VULKAN_VIDEO_FILTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VULKAN_VIDEO_FILTER,GstVulkanVideoFilterClass)) +#define GST_VULKAN_VIDEO_FILTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_VULKAN_VIDEO_FILTER,GstVulkanVideoFilterClass)) +#define GST_IS_VULKAN_VIDEO_FILTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VULKAN_VIDEO_FILTER)) +#define GST_IS_VULKAN_VIDEO_FILTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VULKAN_VIDEO_FILTER)) + +typedef struct _GstVulkanVideoFilter GstVulkanVideoFilter; +typedef struct _GstVulkanVideoFilterClass GstVulkanVideoFilterClass; + +struct _GstVulkanVideoFilter +{ + GstBaseTransform parent; + + GstVulkanInstance *instance; + GstVulkanDevice *device; + GstVulkanQueue *queue; + + GstCaps *in_caps; + GstVideoInfo in_info; + GstCaps *out_caps; + GstVideoInfo out_info; +}; + +struct _GstVulkanVideoFilterClass +{ + GstBaseTransformClass video_sink_class; +}; + +G_END_DECLS + +#endif diff --git a/gst-libs/gst/vulkan/meson.build b/gst-libs/gst/vulkan/meson.build index ccd2052b4..2878566b1 100644 --- a/gst-libs/gst/vulkan/meson.build +++ b/gst-libs/gst/vulkan/meson.build @@ -27,6 +27,7 @@ vulkan_sources = [ 'gstvkqueue.c', 'gstvkswapper.c', 'gstvktrash.c', + 'gstvkvideofilter.c', 'gstvkutils.c', 'gstvkwindow.c', ] @@ -58,6 +59,7 @@ vulkan_headers = [ 'gstvkswapper.h', 'gstvktrash.h', 'gstvkutils.h', + 'gstvkvideofilter.h', 'gstvkwindow.h', 'vulkan-prelude.h', 'vulkan_fwd.h', diff --git a/gst-libs/gst/vulkan/vulkan.h b/gst-libs/gst/vulkan/vulkan.h index d12371453..013379304 100644 --- a/gst-libs/gst/vulkan/vulkan.h +++ b/gst-libs/gst/vulkan/vulkan.h @@ -25,6 +25,7 @@ #include <gst/vulkan/gstvkapi.h> +/* helper vulkan objects */ #include <gst/vulkan/gstvkdebug.h> #include <gst/vulkan/gstvkerror.h> #include <gst/vulkan/gstvkinstance.h> @@ -52,4 +53,7 @@ #include <gst/vulkan/gstvktrash.h> #include <gst/vulkan/gstvkswapper.h> +/* helper elements */ +#include <gst/vulkan/gstvkvideofilter.h> + #endif /* __GST_VULKAN_H__ */ |