registry/macos: retrieve plugins relative to location of libgstreamer.dylib
authorMatthew Waters <matthew@centricular.com>
Wed, 2 Feb 2022 07:06:49 +0000 (18:06 +1100)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Thu, 3 Feb 2022 10:40:42 +0000 (10:40 +0000)
Provides a relocatable directory structure for running GStreamer
applications as used in GStreamer.framework.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1627>

subprojects/gstreamer/gst/gst.c
subprojects/gstreamer/gst/gst_private.h
subprojects/gstreamer/gst/gstpluginloader.c
subprojects/gstreamer/gst/gstregistry.c

index a3b5897..c168d4d 100644 (file)
@@ -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);
index 3addaa7..a7452f7 100644 (file)
@@ -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__ */
index 4e0f646..1b6933c 100644 (file)
@@ -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) {
index 2e09033..1c5bc32 100644 (file)
 #include <windows.h>
 extern HMODULE _priv_gst_dll_handle;
 #endif
+#ifdef HAVE_DLFCN_H
+#include <dlfcn.h>
+#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;