From 747a82006cfc0223a53d44edfa56362b6177f0c9 Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Wed, 2 Feb 2022 18:06:49 +1100 Subject: [PATCH] registry/macos: retrieve plugins relative to location of libgstreamer.dylib Provides a relocatable directory structure for running GStreamer applications as used in GStreamer.framework. Part-of: --- subprojects/gstreamer/gst/gst.c | 4 +- subprojects/gstreamer/gst/gst_private.h | 2 + subprojects/gstreamer/gst/gstpluginloader.c | 31 ++++++++----- subprojects/gstreamer/gst/gstregistry.c | 69 ++++++++++++++++++++--------- 4 files changed, 73 insertions(+), 33 deletions(-) diff --git a/subprojects/gstreamer/gst/gst.c b/subprojects/gstreamer/gst/gst.c index a3b5897..c168d4d 100644 --- a/subprojects/gstreamer/gst/gst.c +++ b/subprojects/gstreamer/gst/gst.c @@ -585,7 +585,9 @@ init_pre (GOptionContext * context, GOptionGroup * group, gpointer data, g_free (basedir); } #else - libdir = g_strdup (LIBDIR); + libdir = priv_gst_get_relocated_libgstreamer (); + if (!libdir) + libdir = g_strdup (LIBDIR); #endif GST_INFO ("Initializing GStreamer Core Library version %s", VERSION); GST_INFO ("Using library installed in %s", libdir); diff --git a/subprojects/gstreamer/gst/gst_private.h b/subprojects/gstreamer/gst/gst_private.h index 3addaa7..a7452f7 100644 --- a/subprojects/gstreamer/gst/gst_private.h +++ b/subprojects/gstreamer/gst/gst_private.h @@ -525,5 +525,7 @@ struct _GstClockEntryImpl * virtual functions on the clock */ }; +char * priv_gst_get_relocated_libgstreamer (void); + G_END_DECLS #endif /* __GST_PRIVATE_H__ */ diff --git a/subprojects/gstreamer/gst/gstpluginloader.c b/subprojects/gstreamer/gst/gstpluginloader.c index 4e0f646..1b6933c 100644 --- a/subprojects/gstreamer/gst/gstpluginloader.c +++ b/subprojects/gstreamer/gst/gstpluginloader.c @@ -476,26 +476,33 @@ gst_plugin_loader_spawn (GstPluginLoader * loader) res = gst_plugin_loader_try_helper (loader, helper_bin); g_free (helper_bin); } else { + char *relocated_libgstreamer; + /* use the installed version */ GST_LOG ("Trying installed plugin scanner"); #ifdef G_OS_WIN32 - { - gchar *basedir; - - basedir = - g_win32_get_package_installation_directory_of_module - (_priv_gst_dll_handle); - helper_bin = - g_build_filename (basedir, GST_PLUGIN_SCANNER_SUBDIR, - "gstreamer-" GST_API_VERSION, "gst-plugin-scanner.exe", NULL); - g_free (basedir); - } +#define EXESUFFIX ".exe" #else - helper_bin = g_strdup (GST_PLUGIN_SCANNER_INSTALLED); +#define EXESUFFIX #endif + + relocated_libgstreamer = priv_gst_get_relocated_libgstreamer (); + if (relocated_libgstreamer) { + GST_DEBUG ("found libgstreamer-" GST_API_VERSION " library " + "at %s", relocated_libgstreamer); + helper_bin = g_build_filename (relocated_libgstreamer, + "..", GST_PLUGIN_SCANNER_SUBDIR, "gstreamer-" GST_API_VERSION, + "gst-plugin-scanner" EXESUFFIX, NULL); + } else { + helper_bin = g_strdup (GST_PLUGIN_SCANNER_INSTALLED); + } + + GST_DEBUG ("using system plugin scanner at %s", helper_bin); + res = gst_plugin_loader_try_helper (loader, helper_bin); g_free (helper_bin); + g_free (relocated_libgstreamer); } if (!res) { diff --git a/subprojects/gstreamer/gst/gstregistry.c b/subprojects/gstreamer/gst/gstregistry.c index 2e09033..1c5bc32 100644 --- a/subprojects/gstreamer/gst/gstregistry.c +++ b/subprojects/gstreamer/gst/gstregistry.c @@ -121,6 +121,9 @@ #include extern HMODULE _priv_gst_dll_handle; #endif +#ifdef HAVE_DLFCN_H +#include +#endif /* Use a toolchain-dependent suffix on Windows */ #ifdef G_OS_WIN32 @@ -1543,6 +1546,39 @@ load_plugin_func (gpointer data, gpointer user_data) } } +char * +priv_gst_get_relocated_libgstreamer (void) +{ + char *dir = NULL; + +#ifdef G_OS_WIN32 + { + char *base_dir; + + base_dir = + g_win32_get_package_installation_directory_of_module + (_priv_gst_dll_handle); + + dir = g_build_filename (base_dir, GST_PLUGIN_SUBDIR, NULL); + GST_DEBUG ("using DLL dir %s", dir); + + g_free (base_dir); + } +#elif defined(__APPLE__) && defined(HAVE_DLADDR) + { + Dl_info info; + + if (dladdr (&gst_init, &info)) { + dir = g_path_get_dirname (info.dli_fname); + } else { + return NULL; + } + } +#endif + + return dir; +} + #ifndef GST_DISABLE_REGISTRY /* Unref all plugins marked 'cached', to clear old plugins that no * longer exist. Returns %TRUE if any plugins were removed */ @@ -1654,7 +1690,7 @@ scan_and_update_registry (GstRegistry * default_registry, if (plugin_path == NULL) plugin_path = g_getenv ("GST_PLUGIN_SYSTEM_PATH"); if (plugin_path == NULL) { - char *home_plugins; + char *home_plugins, *relocated_libgstreamer, *system_plugindir; GST_DEBUG ("GST_PLUGIN_SYSTEM_PATH not set"); @@ -1669,28 +1705,21 @@ scan_and_update_registry (GstRegistry * default_registry, /* add the main (installed) library path */ -#ifdef G_OS_WIN32 - { - char *base_dir; - char *dir; - - base_dir = - g_win32_get_package_installation_directory_of_module - (_priv_gst_dll_handle); - - dir = g_build_filename (base_dir, GST_PLUGIN_SUBDIR, + relocated_libgstreamer = priv_gst_get_relocated_libgstreamer (); + if (relocated_libgstreamer) { + GST_DEBUG ("found libgstreamer-" GST_API_VERSION " library " + "at %s", relocated_libgstreamer); + system_plugindir = g_build_filename (relocated_libgstreamer, "gstreamer-" GST_API_VERSION, NULL); - GST_DEBUG ("scanning DLL dir %s", dir); + } else { + system_plugindir = g_strdup (PLUGINDIR); + } - changed |= gst_registry_scan_path_internal (&context, dir); + GST_DEBUG ("using plugin dir %s", system_plugindir); + changed |= gst_registry_scan_path_internal (&context, system_plugindir); - g_free (dir); - g_free (base_dir); - } -#else - GST_DEBUG ("scanning main plugins %s", PLUGINDIR); - changed |= gst_registry_scan_path_internal (&context, PLUGINDIR); -#endif + g_clear_pointer (&system_plugindir, g_free); + g_clear_pointer (&relocated_libgstreamer, g_free); } else { gchar **list; gint i; -- 2.7.4