#include <gst/gst.h>
+#ifdef __APPLE__
+#include <TargetConditionals.h>
+#endif
+
int
-main (int argc, char *argv[])
+tutorial_main (int argc, char *argv[])
{
GstElement *pipeline;
GstBus *bus;
gst_object_unref (pipeline);
return 0;
}
+
+int
+main (int argc, char *argv[])
+{
+#if defined(__APPLE__) && TARGET_OS_MAC && !TARGET_OS_IPHONE
+ return gst_macos_main (tutorial_main, argc, argv, NULL);
+#else
+ return tutorial_main (argc, argv);
+#endif
+}
#include <gst/gst.h>
#include <string.h>
+#ifdef __APPLE__
+#include <TargetConditionals.h>
+#endif
+
typedef struct _CustomData
{
gboolean is_live;
}
int
-main (int argc, char *argv[])
+tutorial_main (int argc, char *argv[])
{
GstElement *pipeline;
GstBus *bus;
gst_object_unref (pipeline);
return 0;
}
+
+int
+main (int argc, char *argv[])
+{
+#if defined(__APPLE__) && TARGET_OS_MAC && !TARGET_OS_IPHONE
+ return gst_macos_main (tutorial_main, argc, argv, NULL);
+#else
+ return tutorial_main (argc, argv);
+#endif
+}
#include <stdio.h>
#include <gst/gst.h>
+#ifdef __APPLE__
+#include <TargetConditionals.h>
+#endif
+
typedef struct _CustomData
{
GstElement *pipeline;
}
int
-main (int argc, char *argv[])
+tutorial_main (int argc, char *argv[])
{
CustomData data;
GstStateChangeReturn ret;
gst_object_unref (data.pipeline);
return 0;
}
+
+int
+main (int argc, char *argv[])
+{
+#if defined(__APPLE__) && TARGET_OS_MAC && !TARGET_OS_IPHONE
+ return gst_macos_main (tutorial_main, argc, argv, NULL);
+#else
+ return tutorial_main (argc, argv);
+#endif
+}
#include <clutter-gst/clutter-gst.h>
+#ifdef __APPLE__
+#include <TargetConditionals.h>
+#endif
+
/* Setup the video texture once its size is known */
void
size_change (ClutterActor * texture, gint width, gint height,
}
int
-main (int argc, char *argv[])
+tutorial_main (int argc, char *argv[])
{
GstElement *pipeline, *sink;
ClutterTimeline *timeline;
gst_object_unref (pipeline);
return 0;
}
+
+int
+main (int argc, char *argv[])
+{
+#if defined(__APPLE__) && TARGET_OS_MAC && !TARGET_OS_IPHONE
+ return gst_macos_main (tutorial_main, argc, argv, NULL);
+#else
+ return tutorial_main (argc, argv);
+#endif
+}
#include <gst/gst.h>
+#ifdef __APPLE__
+#include <TargetConditionals.h>
+#endif
+
int
-main (int argc, char *argv[])
+tutorial_main (int argc, char *argv[])
{
GstElement *pipeline, *source, *sink;
GstBus *bus;
gst_object_unref (pipeline);
return 0;
}
+
+int
+main (int argc, char *argv[])
+{
+#if defined(__APPLE__) && TARGET_OS_MAC && !TARGET_OS_IPHONE
+ return gst_macos_main (tutorial_main, argc, argv, NULL);
+#else
+ return tutorial_main (argc, argv);
+#endif
+}
#include <gst/gst.h>
+#ifdef __APPLE__
+#include <TargetConditionals.h>
+#endif
+
/* Structure to contain all our information, so we can pass it to callbacks */
typedef struct _CustomData
{
CustomData * data);
int
-main (int argc, char *argv[])
+tutorial_main (int argc, char *argv[])
{
CustomData data;
GstBus *bus;
/* Unreference the sink pad */
gst_object_unref (sink_pad);
}
+
+int
+main (int argc, char *argv[])
+{
+#if defined(__APPLE__) && TARGET_OS_MAC && !TARGET_OS_IPHONE
+ return gst_macos_main (tutorial_main, argc, argv, NULL);
+#else
+ return tutorial_main (argc, argv);
+#endif
+}
#include <gst/gst.h>
+#ifdef __APPLE__
+#include <TargetConditionals.h>
+#endif
+
/* Structure to contain all our information, so we can pass it around */
typedef struct _CustomData
{
static void handle_message (CustomData * data, GstMessage * msg);
int
-main (int argc, char *argv[])
+tutorial_main (int argc, char *argv[])
{
CustomData data;
GstBus *bus;
}
gst_message_unref (msg);
}
+
+int
+main (int argc, char *argv[])
+{
+#if defined(__APPLE__) && TARGET_OS_MAC && !TARGET_OS_IPHONE
+ return gst_macos_main (tutorial_main, argc, argv, NULL);
+#else
+ return tutorial_main (argc, argv);
+#endif
+}
#include <gst/gst.h>
#include <gst/video/videooverlay.h>
+#ifdef __APPLE__
+#include <TargetConditionals.h>
+#endif
+
#include <gdk/gdk.h>
#if defined (GDK_WINDOWING_X11)
#include <gdk/gdkx.h>
}
int
-main (int argc, char *argv[])
+tutorial_main (int argc, char *argv[])
{
CustomData data;
GstStateChangeReturn ret;
gst_object_unref (data.playbin);
return 0;
}
+
+int
+main (int argc, char *argv[])
+{
+#if defined(__APPLE__) && TARGET_OS_MAC && !TARGET_OS_IPHONE
+ return gst_macos_main (tutorial_main, argc, argv, NULL);
+#else
+ return tutorial_main (argc, argv);
+#endif
+}
#include <gst/gst.h>
+#ifdef __APPLE__
+#include <TargetConditionals.h>
+#endif
+
/* Functions below print the Capabilities in a human-friendly format */
static gboolean
print_field (GQuark field, const GValue * value, gpointer pfx)
}
int
-main (int argc, char *argv[])
+tutorial_main (int argc, char *argv[])
{
GstElement *pipeline, *source, *sink;
GstElementFactory *source_factory, *sink_factory;
gst_object_unref (sink_factory);
return 0;
}
+
+int
+main (int argc, char *argv[])
+{
+#if defined(__APPLE__) && TARGET_OS_MAC && !TARGET_OS_IPHONE
+ return gst_macos_main (tutorial_main, argc, argv, NULL);
+#else
+ return tutorial_main (argc, argv);
+#endif
+}
#include <gst/gst.h>
+#ifdef __APPLE__
+#include <TargetConditionals.h>
+#endif
+
int
-main (int argc, char *argv[])
+tutorial_main (int argc, char *argv[])
{
GstElement *pipeline, *audio_source, *tee, *audio_queue, *audio_convert,
*audio_resample, *audio_sink;
gst_object_unref (pipeline);
return 0;
}
+
+int
+main (int argc, char *argv[])
+{
+#if defined(__APPLE__) && TARGET_OS_MAC && !TARGET_OS_IPHONE
+ return gst_macos_main (tutorial_main, argc, argv, NULL);
+#else
+ return tutorial_main (argc, argv);
+#endif
+}
#include <gst/audio/audio.h>
#include <string.h>
+#ifdef __APPLE__
+#include <TargetConditionals.h>
+#endif
+
#define CHUNK_SIZE 1024 /* Amount of bytes we are sending in each buffer */
#define SAMPLE_RATE 44100 /* Samples per second we are sending */
}
int
-main (int argc, char *argv[])
+tutorial_main (int argc, char *argv[])
{
CustomData data;
GstPad *tee_audio_pad, *tee_video_pad, *tee_app_pad;
gst_object_unref (data.pipeline);
return 0;
}
+
+int
+main (int argc, char *argv[])
+{
+#if defined(__APPLE__) && TARGET_OS_MAC && !TARGET_OS_IPHONE
+ return gst_macos_main (tutorial_main, argc, argv, NULL);
+#else
+ return tutorial_main (argc, argv);
+#endif
+}
#include <gst/gst.h>
#include <gst/pbutils/pbutils.h>
+#ifdef __APPLE__
+#include <TargetConditionals.h>
+#endif
+
/* Structure to contain all our information, so we can pass it around */
typedef struct _CustomData
{
}
int
-main (int argc, char **argv)
+tutorial_main (int argc, char **argv)
{
CustomData data;
GError *err = NULL;
return 0;
}
+
+int
+main (int argc, char *argv[])
+{
+#if defined(__APPLE__) && TARGET_OS_MAC && !TARGET_OS_IPHONE
+ return gst_macos_main (tutorial_main, argc, argv, NULL);
+#else
+ return tutorial_main (argc, argv);
+#endif
+}
#include <stdio.h>
#include <gst/gst.h>
+#ifdef __APPLE__
+#include <TargetConditionals.h>
+#endif
+
/* Structure to contain all our information, so we can pass it around */
typedef struct _CustomData
{
CustomData * data);
int
-main (int argc, char *argv[])
+tutorial_main (int argc, char *argv[])
{
CustomData data;
GstBus *bus;
g_free (str);
return TRUE;
}
+
+int
+main (int argc, char *argv[])
+{
+#if defined(__APPLE__) && TARGET_OS_MAC && !TARGET_OS_IPHONE
+ return gst_macos_main (tutorial_main, argc, argv, NULL);
+#else
+ return tutorial_main (argc, argv);
+#endif
+}
#include <stdio.h>
#include <gst/gst.h>
+#ifdef __APPLE__
+#include <TargetConditionals.h>
+#endif
+
/* Structure to contain all our information, so we can pass it around */
typedef struct _CustomData
{
CustomData * data);
int
-main (int argc, char *argv[])
+tutorial_main (int argc, char *argv[])
{
CustomData data;
GstBus *bus;
g_free (str);
return TRUE;
}
+
+int
+main (int argc, char *argv[])
+{
+#if defined(__APPLE__) && TARGET_OS_MAC && !TARGET_OS_IPHONE
+ return gst_macos_main (tutorial_main, argc, argv, NULL);
+#else
+ return tutorial_main (argc, argv);
+#endif
+}
#include <gst/audio/audio.h>
#include <string.h>
+#ifdef __APPLE__
+#include <TargetConditionals.h>
+#endif
+
#define CHUNK_SIZE 1024 /* Amount of bytes we are sending in each buffer */
#define SAMPLE_RATE 44100 /* Samples per second we are sending */
}
int
-main (int argc, char *argv[])
+tutorial_main (int argc, char *argv[])
{
CustomData data;
GstBus *bus;
gst_object_unref (data.pipeline);
return 0;
}
+
+int
+main (int argc, char *argv[])
+{
+#if defined(__APPLE__) && TARGET_OS_MAC && !TARGET_OS_IPHONE
+ return gst_macos_main (tutorial_main, argc, argv, NULL);
+#else
+ return tutorial_main (argc, argv);
+#endif
+}
#include <gst/gst.h>
#include <string.h>
+#ifdef __APPLE__
+#include <TargetConditionals.h>
+#endif
+
#define GRAPH_LENGTH 78
/* playbin flags */
}
int
-main (int argc, char *argv[])
+tutorial_main (int argc, char *argv[])
{
GstElement *pipeline;
GstBus *bus;
g_print ("\n");
return 0;
}
+
+int
+main (int argc, char *argv[])
+{
+#if defined(__APPLE__) && TARGET_OS_MAC && !TARGET_OS_IPHONE
+ return gst_macos_main (tutorial_main, argc, argv, NULL);
+#else
+ return tutorial_main (argc, argv);
+#endif
+}
#include <gst/gst.h>
#include <gst/video/colorbalance.h>
+#ifdef __APPLE__
+#include <TargetConditionals.h>
+#endif
+
typedef struct _CustomData
{
GstElement *pipeline;
}
int
-main (int argc, char *argv[])
+tutorial_main (int argc, char *argv[])
{
CustomData data;
GstStateChangeReturn ret;
gst_object_unref (data.pipeline);
return 0;
}
+
+int
+main (int argc, char *argv[])
+{
+#if defined(__APPLE__) && TARGET_OS_MAC && !TARGET_OS_IPHONE
+ return gst_macos_main (tutorial_main, argc, argv, NULL);
+#else
+ return tutorial_main (argc, argv);
+#endif
+}
#include <gst/gst.h>
+#ifdef __APPLE__
+#include <TargetConditionals.h>
+#endif
+
/* playbin2 flags */
typedef enum
{
}
int
-main (int argc, char *argv[])
+tutorial_main (int argc, char *argv[])
{
GstElement *pipeline, *vis_plugin;
GstBus *bus;
gst_object_unref (pipeline);
return 0;
}
+
+int
+main (int argc, char *argv[])
+{
+#if defined(__APPLE__) && TARGET_OS_MAC && !TARGET_OS_IPHONE
+ return gst_macos_main (tutorial_main, argc, argv, NULL);
+#else
+ return tutorial_main (argc, argv);
+#endif
+}
#include <gst/gst.h>
+#ifdef __APPLE__
+#include <TargetConditionals.h>
+#endif
+
int
-main (int argc, char *argv[])
+tutorial_main (int argc, char *argv[])
{
GstElement *pipeline, *bin, *equalizer, *convert, *sink;
GstPad *pad, *ghost_pad;
gst_object_unref (pipeline);
return 0;
}
+
+int
+main (int argc, char *argv[])
+{
+#if defined(__APPLE__) && TARGET_OS_MAC && !TARGET_OS_IPHONE
+ return gst_macos_main (tutorial_main, argc, argv, NULL);
+#else
+ return tutorial_main (argc, argv);
+#endif
+}
/* API compatibility stuff */
#include <gst/gstcompat.h>
+#ifdef __APPLE__
+# include <TargetConditionals.h>
+# if TARGET_OS_MAC && !TARGET_OS_IPHONE
+# include <gst/gstmacos.h>
+# endif
+#endif
+
G_BEGIN_DECLS
GST_API
--- /dev/null
+#ifndef __GST_MACOS_H__
+#define __GST_MACOS_H__
+
+#include <gst/gstconfig.h>
+#include <gst/glib-compat.h>
+
+G_BEGIN_DECLS
+
+/**
+ * GstMainFunc:
+ * @argc: the amount of arguments passed in @argv
+ * @argv: (array length=argc): an array of arguments passed to the main function
+ * @user_data: (nullable): user data passed to the main function
+ *
+ * Represents a simple pointer to the main() function of a program.
+ * It is used to pass that function along with its arguments to
+ * gst_macos_main(), which ensures correct behaviour of various
+ * GStreamer elements (e.g glimagesink) on macOS.
+ */
+typedef int (*GstMainFunc) (int argc, char** argv, gpointer user_data);
+
+/**
+ * GstMainFuncSimple:
+ * @user_data: (nullable): user data passed to the main function
+ *
+ * Simplified version of #GstMainFunc, meant to be used with
+ * gst_macos_main_simple(), which does not require argc/argv to be passed.
+ */
+typedef int (*GstMainFuncSimple) (gpointer user_data);
+
+GST_API
+int gst_macos_main (GstMainFunc main_func,
+ int argc,
+ char *argv[],
+ gpointer user_data);
+
+GST_API
+int gst_macos_main_simple (GstMainFuncSimple main_func,
+ gpointer user_data);
+
+G_END_DECLS
+
+#endif /* __GST_MACOS_H__ */
--- /dev/null
+#include "gstmacos.h"
+#include <Cocoa/Cocoa.h>
+
+typedef struct _ThreadArgs ThreadArgs;
+
+struct _ThreadArgs {
+ void* main_func;
+ int argc;
+ char **argv;
+ gpointer user_data;
+ gboolean is_simple;
+};
+
+int
+gst_thread_func (ThreadArgs *args)
+{
+ int ret;
+ if (args->is_simple) {
+ ret = ((GstMainFuncSimple) args->main_func) (args->user_data);
+ } else {
+ ret = ((GstMainFunc) args->main_func) (args->argc, args->argv, args->user_data);
+ }
+
+ [NSApp terminate: nil];
+ return ret;
+}
+
+int
+run_main_with_nsapp (ThreadArgs args)
+{
+ GThread *gst_thread;
+
+ [NSApplication sharedApplication];
+ gst_thread = g_thread_new ("macos-gst-thread", (GThreadFunc) gst_thread_func, &args);
+ [NSApp run];
+
+ return GPOINTER_TO_INT (g_thread_join (gst_thread));
+}
+
+/**
+ * gst_macos_main:
+ * @main_func: (scope async): pointer to the main function to be called
+ * @argc: the amount of arguments passed in @argv
+ * @argv: (array length=argc): an array of arguments to be passed to the main function
+ * @user_data: (nullable): user data to be passed to the main function
+ *
+ * Starts an NSApplication on the main thread before calling
+ * the provided main() function on a secondary thread.
+ *
+ * This ensures that GStreamer can correctly perform actions
+ * such as creating a GL window, which require a Cocoa main loop
+ * to be running on the main thread.
+ *
+ * Do not call this function more than once - especially while
+ * another one is still running - as that will cause unpredictable
+ * behaviour and most likely completely fail.
+ *
+ * Returns: the return value of the provided main_func
+ *
+ * Since: 1.22
+ */
+int
+gst_macos_main (GstMainFunc main_func, int argc, char **argv, gpointer user_data)
+{
+ ThreadArgs args;
+
+ args.argc = argc;
+ args.argv = argv;
+ args.main_func = main_func;
+ args.user_data = user_data;
+ args.is_simple = FALSE;
+
+ return run_main_with_nsapp (args);
+}
+
+/**
+ * gst_macos_main_simple:
+ * @main_func: (scope async): pointer to the main function to be called
+ * @user_data: (nullable): user data to be passed to the main function
+ *
+ * Simplified variant of gst_macos_main(), meant to be used with bindings
+ * for languages which do not have to pass argc and argv like C does.
+ * See gst_macos_main() for a more detailed description.
+ *
+ * Returns: the return value of the provided main_func
+ *
+ * Since: 1.22
+ */
+int
+gst_macos_main_simple (GstMainFuncSimple main_func, gpointer user_data)
+{
+ ThreadArgs args;
+
+ args.argc = 0;
+ args.argv = NULL;
+ args.main_func = main_func;
+ args.user_data = user_data;
+ args.is_simple = TRUE;
+
+ return run_main_with_nsapp (args);
+}
'gstparse.h',
'math-compat.h',
)
+if host_system == 'darwin'
+ gst_headers += 'gstmacos.h'
+ gst_sources += 'gstmacos.m'
+endif
+
install_headers(gst_headers, subdir : 'gstreamer-1.0/gst')
extra_deps = []
extra_deps += cc.find_library('log')
endif
+if host_system == 'darwin'
+ extra_deps += dependency('appleframeworks', modules : ['Cocoa'])
+endif
+
gst_registry = get_option('registry')
if gst_registry
gst_registry_sources = files('gstregistrybinary.c')
endif
gst_version_is_dev = gst_version_minor % 2 == 1 and gst_version_micro < 90
-host_system = host_machine.system()
-
apiversion = '1.0'
soversion = 0
# maintaining compatibility with the previous libtool versioning
helpers_install_dir = join_paths(libexecdir, 'gstreamer-1.0')
cc = meson.get_compiler('c')
+host_system = host_machine.system()
+
+if host_system == 'darwin'
+ ios_test_code = '''#include <TargetConditionals.h>
+ #if ! TARGET_OS_IPHONE
+ #error "Not iOS/tvOS/watchOS/iPhoneSimulator"
+ #endif'''
+ if cc.compiles(ios_test_code, name : 'building for iOS')
+ host_system = 'ios'
+ endif
+
+ add_languages('objc', native: false, required: true)
+endif
cdata = configuration_data()