summaryrefslogtreecommitdiff
path: root/gst-libs/gst/vulkan
diff options
context:
space:
mode:
authorMatthew Waters <matthew@centricular.com>2019-11-26 18:11:25 +1100
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>2019-11-28 23:27:21 +0000
commit615022ad93e454d53811889df57cbf0342aec1c6 (patch)
tree2236361937f4ca5c1724e7028d3a2652b7664723 /gst-libs/gst/vulkan
parent756d52ef1582d03c9bba5571ddd4aa911749862a (diff)
downloadgstreamer-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.c338
-rw-r--r--gst-libs/gst/vulkan/gstvkvideofilter.h63
-rw-r--r--gst-libs/gst/vulkan/meson.build2
-rw-r--r--gst-libs/gst/vulkan/vulkan.h4
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__ */