summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Waters <matthew@centricular.com>2019-03-27 17:56:28 +1100
committerMatthew Waters <matthew@centricular.com>2019-04-08 09:26:20 +0000
commit2e442b801b9a3d06a44c74b0eb9e8b2cac68ff1f (patch)
tree33c17a5eaf76a4bc0dc8189aeea5bd9600e7ee77
parent012d6b1d98b759826a77eec6cd62648b78bca9ca (diff)
downloadgstreamer-plugins-bad-2e442b801b9a3d06a44c74b0eb9e8b2cac68ff1f.tar.gz
vulkan: Add iOS window implementation
-rw-r--r--ext/vulkan/ios/vkdisplay_ios.h67
-rw-r--r--ext/vulkan/ios/vkdisplay_ios.m85
-rw-r--r--ext/vulkan/ios/vkios_utils.h40
-rw-r--r--ext/vulkan/ios/vkwindow_ios.h82
-rw-r--r--ext/vulkan/ios/vkwindow_ios.m265
-rw-r--r--ext/vulkan/meson.build34
-rw-r--r--ext/vulkan/vkapi.h6
-rw-r--r--ext/vulkan/vkconfig.h.meson1
-rw-r--r--ext/vulkan/vkdisplay.c10
-rw-r--r--ext/vulkan/vkdisplay.h1
-rw-r--r--ext/vulkan/vksink.c30
-rw-r--r--ext/vulkan/vksink.h3
-rw-r--r--ext/vulkan/vkwindow.c25
-rw-r--r--ext/vulkan/vkwindow.h4
14 files changed, 646 insertions, 7 deletions
diff --git a/ext/vulkan/ios/vkdisplay_ios.h b/ext/vulkan/ios/vkdisplay_ios.h
new file mode 100644
index 000000000..0cbdbc81b
--- /dev/null
+++ b/ext/vulkan/ios/vkdisplay_ios.h
@@ -0,0 +1,67 @@
+/*
+ * GStreamer
+ * Copyright (C) 2019 Matthew Waters <ystreet00@gmail.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 __GST_VULKAN_DISPLAY_IOS_H__
+#define __GST_VULKAN_DISPLAY_IOS_H__
+
+#include <gst/gst.h>
+
+#include <vk.h>
+#ifndef VK_USE_PLATFORM_IOS_MVK
+#error "VK_USE_PLATFORM_IOS_MVK not defined before including this header"
+#error "Either include vkapi.h or define VK_USE_PLATFORM_IOS_MVK before including this header"
+#endif
+#include <vulkan/vulkan.h>
+
+G_BEGIN_DECLS
+
+GType gst_vulkan_display_ios_get_type (void);
+
+#define GST_TYPE_VULKAN_DISPLAY_IOS (gst_vulkan_display_ios_get_type())
+#define GST_VULKAN_DISPLAY_IOS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VULKAN_DISPLAY_IOS,GstVulkanDisplayIos))
+#define GST_VULKAN_DISPLAY_IOS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_VULKAN_DISPLAY_IOS,GstVulkanDisplayIosClass))
+#define GST_IS_VULKAN_DISPLAY_IOS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VULKAN_DISPLAY_IOS))
+#define GST_IS_VULKAN_DISPLAY_IOS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_VULKAN_DISPLAY_IOS))
+#define GST_VULKAN_DISPLAY_IOS_CAST(obj) ((GstVulkanDisplayIos*)(obj))
+
+typedef struct _GstVulkanDisplayIos GstVulkanDisplayIos;
+typedef struct _GstVulkanDisplayIosClass GstVulkanDisplayIosClass;
+
+/**
+ * GstVulkanDisplayIos:
+ *
+ * the contents of a #GstVulkanDisplayIos are private and should only be accessed
+ * through the provided API
+ */
+struct _GstVulkanDisplayIos
+{
+ GstVulkanDisplay parent;
+};
+
+struct _GstVulkanDisplayIosClass
+{
+ GstVulkanDisplayClass object_class;
+};
+
+GstVulkanDisplayIos * gst_vulkan_display_ios_new (void);
+
+G_END_DECLS
+
+#endif /* __GST_VULKAN_DISPLAY_IOS_H__ */
diff --git a/ext/vulkan/ios/vkdisplay_ios.m b/ext/vulkan/ios/vkdisplay_ios.m
new file mode 100644
index 000000000..64c4400b2
--- /dev/null
+++ b/ext/vulkan/ios/vkdisplay_ios.m
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <UIKit/UIKit.h>
+
+#include "vkdisplay_ios.h"
+
+#define GST_CAT_DEFAULT gst_vulkan_display_debug
+GST_DEBUG_CATEGORY_STATIC (gst_vulkan_display_debug);
+
+G_DEFINE_TYPE (GstVulkanDisplayIos, gst_vulkan_display_ios,
+ GST_TYPE_VULKAN_DISPLAY);
+
+static void gst_vulkan_display_ios_finalize (GObject * object);
+static gpointer gst_vulkan_display_ios_get_handle (GstVulkanDisplay * display);
+
+static void
+gst_vulkan_display_ios_class_init (GstVulkanDisplayIosClass * klass)
+{
+ GST_VULKAN_DISPLAY_CLASS (klass)->get_handle =
+ GST_DEBUG_FUNCPTR (gst_vulkan_display_ios_get_handle);
+
+ G_OBJECT_CLASS (klass)->finalize = gst_vulkan_display_ios_finalize;
+}
+
+static void
+gst_vulkan_display_ios_init (GstVulkanDisplayIos * display_ios)
+{
+ GstVulkanDisplay *display = (GstVulkanDisplay *) display_ios;
+
+ display->type = GST_VULKAN_DISPLAY_TYPE_IOS;
+}
+
+static void
+gst_vulkan_display_ios_finalize (GObject * object)
+{
+ G_OBJECT_CLASS (gst_vulkan_display_ios_parent_class)->finalize (object);
+}
+
+/**
+ * gst_vulkan_display_ios_new:
+ *
+ * Create a new #GstVulkanDisplayIos.
+ *
+ * Returns: (transfer full): a new #GstVulkanDisplayIos or %NULL
+ */
+GstVulkanDisplayIos *
+gst_vulkan_display_ios_new (void)
+{
+ GstVulkanDisplayIos *ret;
+
+ GST_DEBUG_CATEGORY_GET (gst_vulkan_display_debug, "vulkandisplay");
+
+ ret = g_object_new (GST_TYPE_VULKAN_DISPLAY_IOS, NULL);
+ gst_object_ref_sink (ret);
+
+ return ret;
+}
+
+static gpointer
+gst_vulkan_display_ios_get_handle (GstVulkanDisplay * display)
+{
+ return (gpointer) (__bridge gpointer) [UIApplication sharedApplication];
+}
diff --git a/ext/vulkan/ios/vkios_utils.h b/ext/vulkan/ios/vkios_utils.h
new file mode 100644
index 000000000..e7bac24e2
--- /dev/null
+++ b/ext/vulkan/ios/vkios_utils.h
@@ -0,0 +1,40 @@
+/*
+ * 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 __VULKAN_IOS_UTILS_H__
+#define __VULKAN_IOS_UTILS_H__
+
+#include <gst/gst.h>
+#include <UIKit/UIKit.h>
+
+#include "vkwindow_ios.h"
+
+G_BEGIN_DECLS
+
+@interface GstVulkanUIView : UIView
+@end
+
+typedef void (*GstVulkanWindowFunc) (gpointer data);
+
+void _invoke_on_main (GstVulkanWindowFunc func, gpointer data, GDestroyNotify notify);
+
+G_END_DECLS
+
+#endif
diff --git a/ext/vulkan/ios/vkwindow_ios.h b/ext/vulkan/ios/vkwindow_ios.h
new file mode 100644
index 000000000..d652b26fb
--- /dev/null
+++ b/ext/vulkan/ios/vkwindow_ios.h
@@ -0,0 +1,82 @@
+/*
+ * GStreamer
+ * Copyright (C) 2019 Matthew Waters <ystreet00@gmail.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 __GST_VULKAN_WINDOW_IOS_H__
+#define __GST_VULKAN_WINDOW_IOS_H__
+
+#include <vk.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_VULKAN_WINDOW_IOS (gst_vulkan_window_ios_get_type())
+#define GST_VULKAN_WINDOW_IOS(o) (G_TYPE_CHECK_INSTANCE_CAST((o), GST_TYPE_VULKAN_WINDOW_IOS, GstVulkanWindowIos))
+#define GST_VULKAN_WINDOW_IOS_CLASS(k) (G_TYPE_CHECK_CLASS((k), GST_TYPE_VULKAN_WINDOW_IOS, GstVulkanWindowIosClass))
+#define GST_IS_VULKAN_WINDOW_IOS(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), GST_TYPE_VULKAN_WINDOW_IOS))
+#define GST_IS_VULKAN_WINDOW_IOS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), GST_TYPE_VULKAN_WINDOW_IOS))
+#define GST_VULKAN_WINDOW_IOS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GST_TYPE_VULKAN_WINDOW_IOS, GstVulkanWindowIosClass))
+
+typedef struct _GstVulkanWindowIos GstVulkanWindowIos;
+typedef struct _GstVulkanWindowIosPrivate GstVulkanWindowIosPrivate;
+typedef struct _GstVulkanWindowIosClass GstVulkanWindowIosClass;
+
+/**
+ * GstVulkanWindowIos:
+ *
+ * Opaque #GstVulkanWindowIos object
+ */
+struct _GstVulkanWindowIos
+{
+ /*< private >*/
+ GstVulkanWindow parent;
+
+ gpointer view;
+
+ gint visible :1;
+
+ PFN_vkCreateIOSSurfaceMVK CreateIOSSurface;
+
+ /*< private >*/
+ GstVulkanWindowIosPrivate *priv;
+
+ gpointer _reserved[GST_PADDING];
+};
+
+/**
+ * GstVulkanWindowIosClass:
+ *
+ * Opaque #GstVulkanWindowIosClass object
+ */
+struct _GstVulkanWindowIosClass {
+ /*< private >*/
+ GstVulkanWindowClass parent_class;
+
+ /*< private >*/
+ gpointer _reserved[GST_PADDING_LARGE];
+};
+
+GType gst_vulkan_window_ios_get_type (void);
+
+GstVulkanWindowIos * gst_vulkan_window_ios_new (GstVulkanDisplay * display);
+
+gboolean gst_vulkan_window_ios_create_window (GstVulkanWindowIos * window_ios);
+
+G_END_DECLS
+
+#endif /* __GST_VULKAN_WINDOW_IOS_H__ */
diff --git a/ext/vulkan/ios/vkwindow_ios.m b/ext/vulkan/ios/vkwindow_ios.m
new file mode 100644
index 000000000..a6de9a2e2
--- /dev/null
+++ b/ext/vulkan/ios/vkwindow_ios.m
@@ -0,0 +1,265 @@
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <QuartzCore/QuartzCore.h>
+
+#include <gst/gst.h>
+
+#include "vkwindow_ios.h"
+#include "vkdisplay_ios.h"
+
+#include "vkios_utils.h"
+
+#define GST_VULKAN_WINDOW_IOS_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((o), GST_TYPE_VULKAN_WINDOW_IOS, GstVulkanWindowIosPrivate))
+
+#define GST_CAT_DEFAULT gst_vulkan_window_ios_debug
+GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
+
+static void
+_init_debug (void)
+{
+ static volatile gsize _init = 0;
+
+ if (g_once_init_enter (&_init)) {
+ GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "vulkanwindowios", 0,
+ "Vulkan iOS Window");
+ g_once_init_leave (&_init, 1);
+ }
+}
+
+enum
+{
+ PROP_0,
+};
+
+struct _GstVulkanWindowIosPrivate
+{
+ gpointer internal_view;
+ gpointer external_view;
+
+ gint preferred_width;
+ gint preferred_height;
+};
+
+#define gst_vulkan_window_ios_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstVulkanWindowIos, gst_vulkan_window_ios,
+ GST_TYPE_VULKAN_WINDOW, G_ADD_PRIVATE (GstVulkanWindowIos) _init_debug ());
+
+static VkSurfaceKHR gst_vulkan_window_ios_get_surface (GstVulkanWindow * window,
+ GError ** error);
+static gboolean gst_vulkan_window_ios_get_presentation_support (GstVulkanWindow
+ * window, GstVulkanDevice * device, guint32 queue_family_idx);
+static gboolean gst_vulkan_window_ios_open (GstVulkanWindow * window,
+ GError ** error);
+static void gst_vulkan_window_ios_close (GstVulkanWindow * window);
+static void gst_vulkan_window_ios_set_window_handle (GstVulkanWindow * window,
+ guintptr window_handle);
+
+static void
+gst_vulkan_window_ios_finalize (GObject * object)
+{
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gst_vulkan_window_ios_class_init (GstVulkanWindowIosClass * klass)
+{
+ GObjectClass *obj_class = G_OBJECT_CLASS (klass);
+ GstVulkanWindowClass *window_class = (GstVulkanWindowClass *) klass;
+
+ obj_class->finalize = gst_vulkan_window_ios_finalize;
+
+ window_class->open = GST_DEBUG_FUNCPTR (gst_vulkan_window_ios_open);
+ window_class->close = GST_DEBUG_FUNCPTR (gst_vulkan_window_ios_close);
+ window_class->get_surface = gst_vulkan_window_ios_get_surface;
+ window_class->get_presentation_support =
+ gst_vulkan_window_ios_get_presentation_support;
+ window_class->set_window_handle =
+ gst_vulkan_window_ios_set_window_handle;
+}
+
+static void
+gst_vulkan_window_ios_init (GstVulkanWindowIos * window)
+{
+ window->priv = gst_vulkan_window_ios_get_instance_private (window);
+
+ window->priv->preferred_width = 320;
+ window->priv->preferred_height = 240;
+}
+
+/* Must be called in the gl thread */
+GstVulkanWindowIos *
+gst_vulkan_window_ios_new (GstVulkanDisplay * display)
+{
+ GstVulkanWindowIos *window;
+
+ _init_debug ();
+
+ if ((gst_vulkan_display_get_handle_type (display) &
+ GST_VULKAN_DISPLAY_TYPE_IOS)
+ == GST_VULKAN_DISPLAY_TYPE_NONE) {
+ GST_INFO ("Wrong display type %u for this window type %u", display->type,
+ GST_VULKAN_DISPLAY_TYPE_IOS);
+ return NULL;
+ }
+
+ window = g_object_new (GST_TYPE_VULKAN_WINDOW_IOS, NULL);
+ gst_object_ref_sink (window);
+
+ return window;
+}
+
+static void
+_create_window (GstVulkanWindowIos * window_ios)
+{
+ GstVulkanWindowIosPrivate *priv = window_ios->priv;
+ CGRect rect = CGRectMake (0, 0, priv->preferred_width, priv->preferred_height);
+ UIView *external_view = (__bridge UIView *) priv->external_view;
+ GstVulkanUIView *view;
+
+ view = [[GstVulkanUIView alloc] initWithFrame:rect];
+ view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+
+ priv->internal_view = (__bridge_retained gpointer)view;
+ [external_view addSubview:view];
+}
+
+gboolean
+gst_vulkan_window_ios_create_window (GstVulkanWindowIos * window_ios)
+{
+ if (!window_ios->priv->external_view) {
+ GST_WARNING_OBJECT(window_ios, "No external UIView provided");
+ return FALSE;
+ }
+
+ _invoke_on_main ((GstVulkanWindowFunc) _create_window,
+ gst_object_ref (window_ios), gst_object_unref);
+
+ return TRUE;
+}
+
+static VkSurfaceKHR
+gst_vulkan_window_ios_get_surface (GstVulkanWindow * window, GError ** error)
+{
+ GstVulkanWindowIos *window_ios = GST_VULKAN_WINDOW_IOS (window);
+ VkIOSSurfaceCreateInfoMVK info = { 0, };
+ VkSurfaceKHR ret;
+ VkResult err;
+
+ info.sType = VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK;
+ info.pNext = NULL;
+ info.flags = 0;
+ info.pView = window_ios->priv->internal_view;
+
+ if (!window_ios->CreateIOSSurface)
+ window_ios->CreateIOSSurface =
+ gst_vulkan_instance_get_proc_address (window->display->instance,
+ "vkCreateIOSSurfaceMVK");
+ if (!window_ios->CreateIOSSurface) {
+ g_set_error_literal (error, GST_VULKAN_ERROR, VK_ERROR_FEATURE_NOT_PRESENT,
+ "Could not retrieve \"vkCreateIOSSurfaceMVK\" function pointer");
+ return 0;
+ }
+
+ err =
+ window_ios->CreateIOSSurface (window->display->instance->instance, &info,
+ NULL, &ret);
+ if (gst_vulkan_error_to_g_error (err, error, "vkCreateIOSSurfaceMVK") < 0)
+ return 0;
+
+ return ret;
+}
+
+static gboolean
+gst_vulkan_window_ios_get_presentation_support (GstVulkanWindow * window,
+ GstVulkanDevice * device, guint32 queue_family_idx)
+{
+ return TRUE;
+}
+
+static gboolean
+gst_vulkan_window_ios_open (GstVulkanWindow * window, GError ** error)
+{
+ GstVulkanWindowIos *window_ios = GST_VULKAN_WINDOW_IOS (window);
+
+ if (!GST_VULKAN_WINDOW_CLASS (parent_class)->open (window, error))
+ return FALSE;
+
+ return gst_vulkan_window_ios_create_window (window_ios);
+}
+
+static void
+gst_vulkan_window_ios_close (GstVulkanWindow * window)
+{
+ GstVulkanWindowIos *window_ios = GST_VULKAN_WINDOW_IOS (window);
+
+ CFBridgingRelease (window_ios->priv->internal_view);
+ window_ios->priv->internal_view = NULL;
+
+ GST_VULKAN_WINDOW_CLASS (parent_class)->close (window);
+}
+
+static void
+gst_vulkan_window_ios_set_window_handle (GstVulkanWindow * window,
+ guintptr window_handle)
+{
+ GstVulkanWindowIos *window_ios = GST_VULKAN_WINDOW_IOS (window);
+ gpointer view = (gpointer) window_handle;
+
+ g_return_if_fail (view != NULL);
+
+ if (window_ios->priv->external_view && window_ios->priv->external_view != view) {
+ GST_FIXME_OBJECT (window_ios, "View changes are not implemented");
+ return;
+ }
+
+ window_ios->priv->external_view = view;
+}
+
+@implementation GstVulkanUIView
+
++(Class) layerClass
+{
+ return [CAMetalLayer class];
+}
+
+@end
+
+void
+_invoke_on_main (GstVulkanWindowFunc func, gpointer data, GDestroyNotify notify)
+{
+ if ([NSThread isMainThread]) {
+ func (data);
+ if (notify)
+ notify (data);
+ } else {
+ dispatch_async (dispatch_get_main_queue (), ^{
+ func (data);
+ if (notify)
+ notify (data);
+ });
+ }
+}
+
diff --git a/ext/vulkan/meson.build b/ext/vulkan/meson.build
index 4b64f78e9..218bd6e2b 100644
--- a/ext/vulkan/meson.build
+++ b/ext/vulkan/meson.build
@@ -25,7 +25,11 @@ if get_option('vulkan').disabled()
subdir_done()
endif
-vulkan_dep = cc.find_library('vulkan', required : get_option('vulkan'))
+if host_system == 'ios'
+ vulkan_dep = cc.find_library('MoltenVK', required : get_option('vulkan'))
+else
+ vulkan_dep = cc.find_library('vulkan', required : get_option('vulkan'))
+endif
has_vulkan_header = cc.has_header('vulkan/vulkan.h')
if not has_vulkan_header and get_option('vulkan').enabled()
error('vulkan plugin enabled, but vulkan.h not found')
@@ -69,25 +73,43 @@ if vulkan_dep.found() and has_vulkan_header
endif
vulkan_objc_args += ['-fobjc-arc']
- endif
- if host_system == 'darwin'
foundation_dep = dependency('appleframeworks', modules : ['Foundation'], required : get_option('vulkan'))
quartzcore_dep = dependency('appleframeworks', modules : ['QuartzCore'], required : get_option('vulkan'))
corefoundation_dep = dependency('appleframeworks', modules : ['CoreFoundation'], required : get_option('vulkan'))
+ if foundation_dep.found() and quartzcore_dep.found() and corefoundation_dep.found()
+ optional_deps += [foundation_dep, corefoundation_dep, quartzcore_dep]
+ endif
+ endif
+
+ if host_system == 'darwin'
cocoa_dep = dependency('appleframeworks', modules : ['Cocoa'], required : get_option('vulkan'))
- if foundation_dep.found() and quartzcore_dep.found() and corefoundation_dep.found() and cocoa_dep.found()
+ if cocoa_dep.found()
vulkan_sources += [
'cocoa/vkdisplay_cocoa.m',
'cocoa/vkwindow_cocoa.m',
]
- optional_deps += [foundation_dep, corefoundation_dep, quartzcore_dep, cocoa_dep]
+ optional_deps += [cocoa_dep]
have_vulkan_windowing = true
vkconf.set10('GST_VULKAN_HAVE_WINDOW_COCOA', 1)
endif
endif
+ if host_system == 'ios'
+ uikit_dep = dependency('appleframeworks', modules : ['UIKit'], required : get_option('vulkan'))
+
+ if uikit_dep.found()
+ vulkan_sources += [
+ 'ios/vkdisplay_ios.m',
+ 'ios/vkwindow_ios.m',
+ ]
+ optional_deps += [uikit_dep]
+ have_vulkan_windowing = true
+ vkconf.set10('GST_VULKAN_HAVE_WINDOW_IOS', 1)
+ endif
+ endif
+
if have_vulkan_windowing
configure_file(input : 'vkconfig.h.meson',
output : 'vkconfig.h',
@@ -99,7 +121,7 @@ if vulkan_dep.found() and has_vulkan_header
objc_args : gst_plugins_bad_args + vulkan_defines + vulkan_objc_args,
link_args : noseh_link_args,
include_directories : [configinc],
- dependencies : [vulkan_dep, gstvideo_dep, gstbase_dep] + optional_deps,
+ dependencies : [gstvideo_dep, gstbase_dep, vulkan_dep] + optional_deps,
install : true,
install_dir : plugins_install_dir,
)
diff --git a/ext/vulkan/vkapi.h b/ext/vulkan/vkapi.h
index 2df3e2028..0e67e0815 100644
--- a/ext/vulkan/vkapi.h
+++ b/ext/vulkan/vkapi.h
@@ -46,6 +46,12 @@
#endif
#endif
+#if GST_VULKAN_HAVE_WINDOW_IOS
+#ifndef VK_USE_PLATFORM_IOS_MVK
+#define VK_USE_PLATFORM_IOS_MVK
+#endif
+#endif
+
#include <vulkan/vulkan.h>
#endif /* _VK_H_ */
diff --git a/ext/vulkan/vkconfig.h.meson b/ext/vulkan/vkconfig.h.meson
index 1ed97cab0..702b662e6 100644
--- a/ext/vulkan/vkconfig.h.meson
+++ b/ext/vulkan/vkconfig.h.meson
@@ -13,6 +13,7 @@ G_BEGIN_DECLS
#mesondefine GST_VULKAN_HAVE_WINDOW_XCB
#mesondefine GST_VULKAN_HAVE_WINDOW_WAYLAND
#mesondefine GST_VULKAN_HAVE_WINDOW_COCOA
+#mesondefine GST_VULKAN_HAVE_WINDOW_IOS
G_END_DECLS
diff --git a/ext/vulkan/vkdisplay.c b/ext/vulkan/vkdisplay.c
index a8f5096cd..a495e89ad 100644
--- a/ext/vulkan/vkdisplay.c
+++ b/ext/vulkan/vkdisplay.c
@@ -39,6 +39,9 @@
#if GST_VULKAN_HAVE_WINDOW_COCOA
#include "cocoa/vkdisplay_cocoa.h"
#endif
+#if GST_VULKAN_HAVE_WINDOW_IOS
+#include "ios/vkdisplay_ios.h"
+#endif
GST_DEBUG_CATEGORY_STATIC (GST_CAT_CONTEXT);
#define GST_CAT_DEFAULT gst_vulkan_display_debug
@@ -432,6 +435,9 @@ gst_vulkan_display_choose_type (GstVulkanInstance * instance)
#if GST_VULKAN_HAVE_WINDOW_COCOA
CHOOSE_WINSYS (cocoa, COCOA);
#endif
+#if GST_VULKAN_HAVE_WINDOW_IOS
+ CHOOSE_WINSYS (ios, IOS);
+#endif
#undef CHOOSE_WINSYS
@@ -463,6 +469,10 @@ gst_vulkan_display_type_to_extension_string (GstVulkanDisplayType type)
if (type & GST_VULKAN_DISPLAY_TYPE_COCOA)
return VK_MVK_MACOS_SURFACE_EXTENSION_NAME;
#endif
+#if GST_VULKAN_HAVE_WINDOW_IOS
+ if (type & GST_VULKAN_DISPLAY_TYPE_IOS)
+ return VK_MVK_IOS_SURFACE_EXTENSION_NAME;
+#endif
return NULL;
}
diff --git a/ext/vulkan/vkdisplay.h b/ext/vulkan/vkdisplay.h
index 89aa16947..34b5ae15a 100644
--- a/ext/vulkan/vkdisplay.h
+++ b/ext/vulkan/vkdisplay.h
@@ -50,6 +50,7 @@ enum _GstVulkanDisplayType
GST_VULKAN_DISPLAY_TYPE_MIR = (1 << 3),
GST_VULKAN_DISPLAY_TYPE_WIN32 = (1 << 4),
GST_VULKAN_DISPLAY_TYPE_COCOA = (1 << 5),
+ GST_VULKAN_DISPLAY_TYPE_IOS = (1 << 6),
GST_VULKAN_DISPLAY_TYPE_ANY = G_MAXUINT32
};
diff --git a/ext/vulkan/vksink.c b/ext/vulkan/vksink.c
index c9893deeb..ea141df3b 100644
--- a/ext/vulkan/vksink.c
+++ b/ext/vulkan/vksink.c
@@ -65,6 +65,10 @@ static GstFlowReturn gst_vulkan_sink_prepare (GstBaseSink * bsink,
static GstFlowReturn gst_vulkan_sink_show_frame (GstVideoSink * bsink,
GstBuffer * buf);
+static void gst_vulkan_sink_video_overlay_init (GstVideoOverlayInterface *
+ iface);
+
+
static GstStaticPadTemplate gst_vulkan_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
@@ -91,7 +95,9 @@ enum
#define gst_vulkan_sink_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstVulkanSink, gst_vulkan_sink,
GST_TYPE_VIDEO_SINK, GST_DEBUG_CATEGORY_INIT (gst_debug_vulkan_sink,
- "vulkansink", 0, "Vulkan Video Sink"));
+ "vulkansink", 0, "Vulkan Video Sink");
+ G_IMPLEMENT_INTERFACE (GST_TYPE_VIDEO_OVERLAY,
+ gst_vulkan_sink_video_overlay_init));
static void
gst_vulkan_sink_class_init (GstVulkanSinkClass * klass)
@@ -261,6 +267,7 @@ gst_vulkan_sink_change_state (GstElement * element, GstStateChange transition)
return GST_STATE_CHANGE_FAILURE;
}
+ /* FIXME: this probably doesn't need to be so early in the setup process */
if (!(vk_sink->window =
gst_vulkan_display_create_window (vk_sink->display))) {
GST_ELEMENT_ERROR (vk_sink, RESOURCE, NOT_FOUND,
@@ -268,6 +275,13 @@ gst_vulkan_sink_change_state (GstElement * element, GstStateChange transition)
return GST_STATE_CHANGE_FAILURE;
}
+ if (!vk_sink->set_window_handle)
+ gst_video_overlay_prepare_window_handle (GST_VIDEO_OVERLAY (vk_sink));
+
+ if (vk_sink->set_window_handle)
+ gst_vulkan_window_set_window_handle (vk_sink->window,
+ vk_sink->set_window_handle);
+
if (!gst_vulkan_window_open (vk_sink->window, &error)) {
GST_ELEMENT_ERROR (vk_sink, RESOURCE, NOT_FOUND,
("Failed to open window"), ("%s", error->message));
@@ -501,3 +515,17 @@ gst_vulkan_sink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
return GST_FLOW_OK;
}
+
+static void
+gst_vulkan_sink_set_window_handle (GstVideoOverlay * voverlay, guintptr handle)
+{
+ GstVulkanSink *vk_sink = GST_VULKAN_SINK (voverlay);
+
+ vk_sink->set_window_handle = handle;
+}
+
+static void
+gst_vulkan_sink_video_overlay_init (GstVideoOverlayInterface * iface)
+{
+ iface->set_window_handle = gst_vulkan_sink_set_window_handle;
+}
diff --git a/ext/vulkan/vksink.h b/ext/vulkan/vksink.h
index 9f95cf31e..294832f5d 100644
--- a/ext/vulkan/vksink.h
+++ b/ext/vulkan/vksink.h
@@ -56,6 +56,9 @@ struct _GstVulkanSink
/* stream configuration */
GstVideoInfo v_info;
+
+ /* the currently set window handle */
+ guintptr set_window_handle;
};
struct _GstVulkanSinkClass
diff --git a/ext/vulkan/vkwindow.c b/ext/vulkan/vkwindow.c
index 102e96d25..e7e17c198 100644
--- a/ext/vulkan/vkwindow.c
+++ b/ext/vulkan/vkwindow.c
@@ -49,6 +49,9 @@
#if GST_VULKAN_HAVE_WINDOW_COCOA
#include "cocoa/vkwindow_cocoa.h"
#endif
+#if GST_VULKAN_HAVE_WINDOW_IOS
+#include "ios/vkwindow_ios.h"
+#endif
#define GST_CAT_DEFAULT gst_vulkan_window_debug
GST_DEBUG_CATEGORY (GST_CAT_DEFAULT);
@@ -191,6 +194,10 @@ gst_vulkan_window_new (GstVulkanDisplay * display)
if (!window && (!user_choice || g_strstr_len (user_choice, 5, "cocoa")))
window = GST_VULKAN_WINDOW (gst_vulkan_window_cocoa_new (display));
#endif
+#if GST_VULKAN_HAVE_WINDOW_IOS
+ if (!window && (!user_choice || g_strstr_len (user_choice, 3, "ios")))
+ window = GST_VULKAN_WINDOW (gst_vulkan_window_ios_new (display));
+#endif
if (!window) {
/* subclass returned a NULL window */
GST_WARNING ("Could not create window. user specified %s, creating dummy"
@@ -294,6 +301,24 @@ gst_vulkan_window_redraw (GstVulkanWindow * window)
g_signal_emit (window, gst_vulkan_window_signals[SIGNAL_DRAW], 0);
}
+void
+gst_vulkan_window_set_window_handle (GstVulkanWindow * window, guintptr handle)
+{
+ GstVulkanWindowClass *klass;
+
+ g_return_if_fail (GST_IS_VULKAN_WINDOW (window));
+ klass = GST_VULKAN_WINDOW_GET_CLASS (window);
+
+ if (!klass->set_window_handle) {
+ if (handle)
+ g_warning ("%s does not implement the set_window_handle vfunc. "
+ "Output will not be embedded into the specified surface.",
+ GST_OBJECT_NAME (window));
+ } else {
+ klass->set_window_handle (window, handle);
+ }
+}
+
GType gst_vulkan_dummy_window_get_type (void);
G_DEFINE_TYPE (GstVulkanDummyWindow, gst_vulkan_dummy_window,
GST_TYPE_VULKAN_WINDOW);
diff --git a/ext/vulkan/vkwindow.h b/ext/vulkan/vkwindow.h
index 58be80ae7..ff25f9f7d 100644
--- a/ext/vulkan/vkwindow.h
+++ b/ext/vulkan/vkwindow.h
@@ -87,6 +87,8 @@ struct _GstVulkanWindowClass {
gboolean (*get_presentation_support) (GstVulkanWindow *window,
GstVulkanDevice *device,
guint32 queue_family_idx);
+ void (*set_window_handle) (GstVulkanWindow *window,
+ guintptr handle);
/*< private >*/
gpointer _reserved[GST_PADDING];
@@ -100,6 +102,8 @@ VkSurfaceKHR gst_vulkan_window_get_surface (GstVulkanWi
gboolean gst_vulkan_window_get_presentation_support (GstVulkanWindow *window,
GstVulkanDevice *device,
guint32 queue_family_idx);
+void gst_vulkan_window_set_window_handle (GstVulkanWindow *window,
+ guintptr handle);
gboolean gst_vulkan_window_open (GstVulkanWindow *window,
GError ** error);