diff --git a/subprojects/gst-docs/examples/tutorials/basic-tutorial-1.c b/subprojects/gst-docs/examples/tutorials/basic-tutorial-1.c index 573d4b2e90..35ae853e0b 100644 --- a/subprojects/gst-docs/examples/tutorials/basic-tutorial-1.c +++ b/subprojects/gst-docs/examples/tutorials/basic-tutorial-1.c @@ -1,7 +1,11 @@ #include +#ifdef __APPLE__ +#include +#endif + int -main (int argc, char *argv[]) +tutorial_main (int argc, char *argv[]) { GstElement *pipeline; GstBus *bus; @@ -38,3 +42,13 @@ main (int argc, char *argv[]) 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 +} diff --git a/subprojects/gst-docs/examples/tutorials/basic-tutorial-12.c b/subprojects/gst-docs/examples/tutorials/basic-tutorial-12.c index d3f0eb9f18..f01f60fac4 100644 --- a/subprojects/gst-docs/examples/tutorials/basic-tutorial-12.c +++ b/subprojects/gst-docs/examples/tutorials/basic-tutorial-12.c @@ -1,6 +1,10 @@ #include #include +#ifdef __APPLE__ +#include +#endif + typedef struct _CustomData { gboolean is_live; @@ -59,7 +63,7 @@ cb_message (GstBus * bus, GstMessage * msg, CustomData * data) } int -main (int argc, char *argv[]) +tutorial_main (int argc, char *argv[]) { GstElement *pipeline; GstBus *bus; @@ -106,3 +110,13 @@ main (int argc, char *argv[]) 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 +} diff --git a/subprojects/gst-docs/examples/tutorials/basic-tutorial-13.c b/subprojects/gst-docs/examples/tutorials/basic-tutorial-13.c index 880702c32d..b7640f643e 100644 --- a/subprojects/gst-docs/examples/tutorials/basic-tutorial-13.c +++ b/subprojects/gst-docs/examples/tutorials/basic-tutorial-13.c @@ -2,6 +2,10 @@ #include #include +#ifdef __APPLE__ +#include +#endif + typedef struct _CustomData { GstElement *pipeline; @@ -103,7 +107,7 @@ handle_keyboard (GIOChannel * source, GIOCondition cond, CustomData * data) } int -main (int argc, char *argv[]) +tutorial_main (int argc, char *argv[]) { CustomData data; GstStateChangeReturn ret; @@ -160,3 +164,13 @@ main (int argc, char *argv[]) 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 +} diff --git a/subprojects/gst-docs/examples/tutorials/basic-tutorial-15.c b/subprojects/gst-docs/examples/tutorials/basic-tutorial-15.c index dcf2db1a13..882a9d6e42 100644 --- a/subprojects/gst-docs/examples/tutorials/basic-tutorial-15.c +++ b/subprojects/gst-docs/examples/tutorials/basic-tutorial-15.c @@ -1,5 +1,9 @@ #include +#ifdef __APPLE__ +#include +#endif + /* Setup the video texture once its size is known */ void size_change (ClutterActor * texture, gint width, gint height, @@ -42,7 +46,7 @@ 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; @@ -106,3 +110,13 @@ main (int argc, char *argv[]) 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 +} diff --git a/subprojects/gst-docs/examples/tutorials/basic-tutorial-2.c b/subprojects/gst-docs/examples/tutorials/basic-tutorial-2.c index 4ccea592e2..6f795ca59c 100644 --- a/subprojects/gst-docs/examples/tutorials/basic-tutorial-2.c +++ b/subprojects/gst-docs/examples/tutorials/basic-tutorial-2.c @@ -1,7 +1,11 @@ #include +#ifdef __APPLE__ +#include +#endif + int -main (int argc, char *argv[]) +tutorial_main (int argc, char *argv[]) { GstElement *pipeline, *source, *sink; GstBus *bus; @@ -80,3 +84,13 @@ main (int argc, char *argv[]) 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 +} diff --git a/subprojects/gst-docs/examples/tutorials/basic-tutorial-3.c b/subprojects/gst-docs/examples/tutorials/basic-tutorial-3.c index 320382d578..722c44a189 100644 --- a/subprojects/gst-docs/examples/tutorials/basic-tutorial-3.c +++ b/subprojects/gst-docs/examples/tutorials/basic-tutorial-3.c @@ -1,5 +1,9 @@ #include +#ifdef __APPLE__ +#include +#endif + /* Structure to contain all our information, so we can pass it to callbacks */ typedef struct _CustomData { @@ -15,7 +19,7 @@ static void pad_added_handler (GstElement * src, GstPad * pad, CustomData * data); int -main (int argc, char *argv[]) +tutorial_main (int argc, char *argv[]) { CustomData data; GstBus *bus; @@ -166,3 +170,13 @@ exit: /* 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 +} diff --git a/subprojects/gst-docs/examples/tutorials/basic-tutorial-4.c b/subprojects/gst-docs/examples/tutorials/basic-tutorial-4.c index b3a522982f..6b5b92dbf7 100644 --- a/subprojects/gst-docs/examples/tutorials/basic-tutorial-4.c +++ b/subprojects/gst-docs/examples/tutorials/basic-tutorial-4.c @@ -1,5 +1,9 @@ #include +#ifdef __APPLE__ +#include +#endif + /* Structure to contain all our information, so we can pass it around */ typedef struct _CustomData { @@ -15,7 +19,7 @@ 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; @@ -170,3 +174,13 @@ handle_message (CustomData * data, GstMessage * msg) } 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 +} diff --git a/subprojects/gst-docs/examples/tutorials/basic-tutorial-5.c b/subprojects/gst-docs/examples/tutorials/basic-tutorial-5.c index 34c75c978f..7aab34c1b7 100644 --- a/subprojects/gst-docs/examples/tutorials/basic-tutorial-5.c +++ b/subprojects/gst-docs/examples/tutorials/basic-tutorial-5.c @@ -4,6 +4,10 @@ #include #include +#ifdef __APPLE__ +#include +#endif + #include #if defined (GDK_WINDOWING_X11) #include @@ -372,7 +376,7 @@ application_cb (GstBus * bus, GstMessage * msg, CustomData * data) } int -main (int argc, char *argv[]) +tutorial_main (int argc, char *argv[]) { CustomData data; GstStateChangeReturn ret; @@ -443,3 +447,13 @@ main (int argc, char *argv[]) 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 +} diff --git a/subprojects/gst-docs/examples/tutorials/basic-tutorial-6.c b/subprojects/gst-docs/examples/tutorials/basic-tutorial-6.c index 2c06b3a9cc..3b6cb69803 100644 --- a/subprojects/gst-docs/examples/tutorials/basic-tutorial-6.c +++ b/subprojects/gst-docs/examples/tutorials/basic-tutorial-6.c @@ -1,5 +1,9 @@ #include +#ifdef __APPLE__ +#include +#endif + /* Functions below print the Capabilities in a human-friendly format */ static gboolean print_field (GQuark field, const GValue * value, gpointer pfx) @@ -110,7 +114,7 @@ print_pad_capabilities (GstElement * element, gchar * pad_name) } int -main (int argc, char *argv[]) +tutorial_main (int argc, char *argv[]) { GstElement *pipeline, *source, *sink; GstElementFactory *source_factory, *sink_factory; @@ -222,3 +226,13 @@ main (int argc, char *argv[]) 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 +} diff --git a/subprojects/gst-docs/examples/tutorials/basic-tutorial-7.c b/subprojects/gst-docs/examples/tutorials/basic-tutorial-7.c index 7cb9c1372f..d2b24134bf 100644 --- a/subprojects/gst-docs/examples/tutorials/basic-tutorial-7.c +++ b/subprojects/gst-docs/examples/tutorials/basic-tutorial-7.c @@ -1,7 +1,11 @@ #include +#ifdef __APPLE__ +#include +#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; @@ -96,3 +100,13 @@ main (int argc, char *argv[]) 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 +} diff --git a/subprojects/gst-docs/examples/tutorials/basic-tutorial-8.c b/subprojects/gst-docs/examples/tutorials/basic-tutorial-8.c index 27749f95b7..50b620547f 100644 --- a/subprojects/gst-docs/examples/tutorials/basic-tutorial-8.c +++ b/subprojects/gst-docs/examples/tutorials/basic-tutorial-8.c @@ -2,6 +2,10 @@ #include #include +#ifdef __APPLE__ +#include +#endif + #define CHUNK_SIZE 1024 /* Amount of bytes we are sending in each buffer */ #define SAMPLE_RATE 44100 /* Samples per second we are sending */ @@ -134,7 +138,7 @@ error_cb (GstBus * bus, GstMessage * msg, CustomData * data) } int -main (int argc, char *argv[]) +tutorial_main (int argc, char *argv[]) { CustomData data; GstPad *tee_audio_pad, *tee_video_pad, *tee_app_pad; @@ -268,3 +272,13 @@ main (int argc, char *argv[]) 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 +} diff --git a/subprojects/gst-docs/examples/tutorials/basic-tutorial-9.c b/subprojects/gst-docs/examples/tutorials/basic-tutorial-9.c index a1ed3b9505..f252f4f044 100644 --- a/subprojects/gst-docs/examples/tutorials/basic-tutorial-9.c +++ b/subprojects/gst-docs/examples/tutorials/basic-tutorial-9.c @@ -2,6 +2,10 @@ #include #include +#ifdef __APPLE__ +#include +#endif + /* Structure to contain all our information, so we can pass it around */ typedef struct _CustomData { @@ -181,7 +185,7 @@ on_finished_cb (GstDiscoverer * discoverer, CustomData * data) } int -main (int argc, char **argv) +tutorial_main (int argc, char **argv) { CustomData data; GError *err = NULL; @@ -238,3 +242,13 @@ main (int argc, char **argv) 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 +} diff --git a/subprojects/gst-docs/examples/tutorials/playback-tutorial-1.c b/subprojects/gst-docs/examples/tutorials/playback-tutorial-1.c index b9daae3e02..b2f783eef8 100644 --- a/subprojects/gst-docs/examples/tutorials/playback-tutorial-1.c +++ b/subprojects/gst-docs/examples/tutorials/playback-tutorial-1.c @@ -1,6 +1,10 @@ #include #include +#ifdef __APPLE__ +#include +#endif + /* Structure to contain all our information, so we can pass it around */ typedef struct _CustomData { @@ -32,7 +36,7 @@ static gboolean handle_keyboard (GIOChannel * source, GIOCondition cond, CustomData * data); int -main (int argc, char *argv[]) +tutorial_main (int argc, char *argv[]) { CustomData data; GstBus *bus; @@ -240,3 +244,13 @@ handle_keyboard (GIOChannel * source, GIOCondition cond, CustomData * data) 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 +} diff --git a/subprojects/gst-docs/examples/tutorials/playback-tutorial-2.c b/subprojects/gst-docs/examples/tutorials/playback-tutorial-2.c index 5e3688ffd6..69837db5e7 100644 --- a/subprojects/gst-docs/examples/tutorials/playback-tutorial-2.c +++ b/subprojects/gst-docs/examples/tutorials/playback-tutorial-2.c @@ -1,6 +1,10 @@ #include #include +#ifdef __APPLE__ +#include +#endif + /* Structure to contain all our information, so we can pass it around */ typedef struct _CustomData { @@ -32,7 +36,7 @@ static gboolean handle_keyboard (GIOChannel * source, GIOCondition cond, CustomData * data); int -main (int argc, char *argv[]) +tutorial_main (int argc, char *argv[]) { CustomData data; GstBus *bus; @@ -244,3 +248,13 @@ handle_keyboard (GIOChannel * source, GIOCondition cond, CustomData * data) 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 +} diff --git a/subprojects/gst-docs/examples/tutorials/playback-tutorial-3.c b/subprojects/gst-docs/examples/tutorials/playback-tutorial-3.c index b29c8e00a7..60a049b5a2 100644 --- a/subprojects/gst-docs/examples/tutorials/playback-tutorial-3.c +++ b/subprojects/gst-docs/examples/tutorials/playback-tutorial-3.c @@ -2,6 +2,10 @@ #include #include +#ifdef __APPLE__ +#include +#endif + #define CHUNK_SIZE 1024 /* Amount of bytes we are sending in each buffer */ #define SAMPLE_RATE 44100 /* Samples per second we are sending */ @@ -133,7 +137,7 @@ source_setup (GstElement * pipeline, GstElement * source, CustomData * data) } int -main (int argc, char *argv[]) +tutorial_main (int argc, char *argv[]) { CustomData data; GstBus *bus; @@ -170,3 +174,13 @@ main (int argc, char *argv[]) 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 +} diff --git a/subprojects/gst-docs/examples/tutorials/playback-tutorial-4.c b/subprojects/gst-docs/examples/tutorials/playback-tutorial-4.c index bba675120f..abbfd92b9b 100644 --- a/subprojects/gst-docs/examples/tutorials/playback-tutorial-4.c +++ b/subprojects/gst-docs/examples/tutorials/playback-tutorial-4.c @@ -1,6 +1,10 @@ #include #include +#ifdef __APPLE__ +#include +#endif + #define GRAPH_LENGTH 78 /* playbin flags */ @@ -122,7 +126,7 @@ refresh_ui (CustomData * data) } int -main (int argc, char *argv[]) +tutorial_main (int argc, char *argv[]) { GstElement *pipeline; GstBus *bus; @@ -186,3 +190,13 @@ main (int argc, char *argv[]) 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 +} diff --git a/subprojects/gst-docs/examples/tutorials/playback-tutorial-5.c b/subprojects/gst-docs/examples/tutorials/playback-tutorial-5.c index dc65ae4d1e..e397b4d146 100644 --- a/subprojects/gst-docs/examples/tutorials/playback-tutorial-5.c +++ b/subprojects/gst-docs/examples/tutorials/playback-tutorial-5.c @@ -3,6 +3,10 @@ #include #include +#ifdef __APPLE__ +#include +#endif + typedef struct _CustomData { GstElement *pipeline; @@ -109,7 +113,7 @@ handle_keyboard (GIOChannel * source, GIOCondition cond, CustomData * data) } int -main (int argc, char *argv[]) +tutorial_main (int argc, char *argv[]) { CustomData data; GstStateChangeReturn ret; @@ -163,3 +167,13 @@ main (int argc, char *argv[]) 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 +} diff --git a/subprojects/gst-docs/examples/tutorials/playback-tutorial-6.c b/subprojects/gst-docs/examples/tutorials/playback-tutorial-6.c index fac6c7f1af..052004068a 100644 --- a/subprojects/gst-docs/examples/tutorials/playback-tutorial-6.c +++ b/subprojects/gst-docs/examples/tutorials/playback-tutorial-6.c @@ -1,5 +1,9 @@ #include +#ifdef __APPLE__ +#include +#endif + /* playbin2 flags */ typedef enum { @@ -22,7 +26,7 @@ filter_vis_features (GstPluginFeature * feature, gpointer data) } int -main (int argc, char *argv[]) +tutorial_main (int argc, char *argv[]) { GstElement *pipeline, *vis_plugin; GstBus *bus; @@ -99,3 +103,13 @@ main (int argc, char *argv[]) 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 +} diff --git a/subprojects/gst-docs/examples/tutorials/playback-tutorial-7.c b/subprojects/gst-docs/examples/tutorials/playback-tutorial-7.c index cd5e061fa4..58a7b821f2 100644 --- a/subprojects/gst-docs/examples/tutorials/playback-tutorial-7.c +++ b/subprojects/gst-docs/examples/tutorials/playback-tutorial-7.c @@ -1,7 +1,11 @@ #include +#ifdef __APPLE__ +#include +#endif + int -main (int argc, char *argv[]) +tutorial_main (int argc, char *argv[]) { GstElement *pipeline, *bin, *equalizer, *convert, *sink; GstPad *pad, *ghost_pad; @@ -60,3 +64,13 @@ main (int argc, char *argv[]) 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 +} diff --git a/subprojects/gstreamer/gst/gst.h b/subprojects/gstreamer/gst/gst.h index 4423813aec..7bd59cd8a4 100644 --- a/subprojects/gstreamer/gst/gst.h +++ b/subprojects/gstreamer/gst/gst.h @@ -95,6 +95,13 @@ /* API compatibility stuff */ #include +#ifdef __APPLE__ +# include +# if TARGET_OS_MAC && !TARGET_OS_IPHONE +# include +# endif +#endif + G_BEGIN_DECLS GST_API diff --git a/subprojects/gstreamer/gst/gstmacos.h b/subprojects/gstreamer/gst/gstmacos.h new file mode 100644 index 0000000000..8e1f21ab58 --- /dev/null +++ b/subprojects/gstreamer/gst/gstmacos.h @@ -0,0 +1,43 @@ +#ifndef __GST_MACOS_H__ +#define __GST_MACOS_H__ + +#include +#include + +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__ */ diff --git a/subprojects/gstreamer/gst/gstmacos.m b/subprojects/gstreamer/gst/gstmacos.m new file mode 100644 index 0000000000..e0cd09bb93 --- /dev/null +++ b/subprojects/gstreamer/gst/gstmacos.m @@ -0,0 +1,101 @@ +#include "gstmacos.h" +#include + +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); +} diff --git a/subprojects/gstreamer/gst/meson.build b/subprojects/gstreamer/gst/meson.build index 3356b848d4..4293c78e4d 100644 --- a/subprojects/gstreamer/gst/meson.build +++ b/subprojects/gstreamer/gst/meson.build @@ -148,6 +148,11 @@ gst_headers = files( '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 = [] @@ -156,6 +161,10 @@ if host_system == 'android' 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') diff --git a/subprojects/gstreamer/meson.build b/subprojects/gstreamer/meson.build index 7331c66150..32cb7aef9a 100644 --- a/subprojects/gstreamer/meson.build +++ b/subprojects/gstreamer/meson.build @@ -16,8 +16,6 @@ else 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 @@ -33,6 +31,19 @@ libexecdir = get_option('libexecdir') 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 + #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()