#define WIN32_LEAN_AND_MEAN /* prevents from including too many things */
#include <windows.h> /* GetStdHandle, windows console */
#endif
+#if defined (__APPLE__)
+#include <errno.h>
+#include <libproc.h> /* proc_pidpath, PROC_PIDPATHINFO_MAXSIZE */
+#endif
#include "gst-i18n-lib.h"
#include <locale.h> /* for LC_ALL */
extern gboolean _priv_gst_disable_registry_update;
#endif
+gchar *_gst_executable_path = NULL;
+
#ifndef GST_DISABLE_GST_DEBUG
const gchar *priv_gst_dump_dot_dir;
#endif
#endif
}
+#if defined(__linux__)
+static void
+find_executable_path (void)
+{
+ GError *error = NULL;
+ gchar *path;
+
+ if (_gst_executable_path)
+ return;
+
+ path = g_file_read_link ("/proc/self/exe", &error);
+
+ if (path) {
+ _gst_executable_path = g_path_get_dirname (path);
+ g_free (path);
+ }
+}
+#elif defined(G_OS_WIN32)
+static void
+find_executable_path (void)
+{
+ char buffer[MAX_PATH];
+
+ if (!GetModuleFilename (NULL, buffer, MAX_PATH))
+ return;
+
+ _gst_executable_path = g_strdup (buffer);
+}
+#elif defined(__APPLE__)
+static void
+find_executable_path (void)
+{
+ int ret;
+ pid_t pid;
+ char pathbuf[PROC_PIDPATHINFO_MAXSIZE];
+
+ pid = getpid ();
+ ret = proc_pidpath (pid, pathbuf, sizeof (pathbuf));
+ if (ret > 0)
+ _gst_executable_path = g_strdup (pathbuf)
+ }
+#else
+static void
+find_executable_path (void)
+{
+ GST_FIXME ("Couldn't look up executable path, add support for this platform");
+}
+#endif
+
+
/**
* gst_init_check:
* @argc: (inout) (allow-none): pointer to application's argc
g_mutex_unlock (&init_lock);
return TRUE;
}
+
+ find_executable_path ();
+
#ifndef GST_DISABLE_OPTION_PARSING
ctx = g_option_context_new ("- GStreamer initialization");
g_option_context_set_ignore_unknown_options (ctx, TRUE);
_priv_gst_plugin_paths = NULL;
#endif
+ if (_gst_executable_path) {
+ g_free (_gst_executable_path);
+ _gst_executable_path = NULL;
+ }
+
clock = gst_system_clock_obtain ();
gst_object_unref (clock);
gst_object_unref (clock);
GST_EXPORT gboolean _gst_disable_registry_cache;
#endif
+/* Secret variable to let the plugin scanner use the same base path
+ * as the main application in order to determine dependencies */
+GST_EXPORT gchar *_gst_executable_path;
+
/* provide inline gst_g_value_get_foo_unchecked(), used in gststructure.c */
#define DEFINE_INLINE_G_VALUE_GET_UNCHECKED(ret_type,name_type,v_field) \
static inline ret_type \
gst_plugin_ext_dep_get_stat_hash (GstPlugin * plugin, GstPluginDep * dep)
{
gboolean paths_are_default_only;
+ gboolean paths_are_relative_to_exe;
GQueue scan_paths = G_QUEUE_INIT;
guint scan_hash = 0;
gchar *path;
paths_are_default_only =
dep->flags & GST_PLUGIN_DEPENDENCY_FLAG_PATHS_ARE_DEFAULT_ONLY;
+ paths_are_relative_to_exe =
+ dep->flags & GST_PLUGIN_DEPENDENCY_FLAG_PATHS_ARE_RELATIVE_TO_EXE;
gst_plugin_ext_dep_extract_env_vars_paths (plugin, dep, &scan_paths);
for (paths = dep->paths; paths != NULL && *paths != NULL; ++paths) {
const gchar *path = *paths;
+ gchar *full_path;
+
+ if (paths_are_relative_to_exe && !g_path_is_absolute (path)) {
+ if (!_gst_executable_path) {
+ GST_FIXME_OBJECT (plugin,
+ "Path dependency %s relative to executable path but could not retrieve executable path",
+ path);
+ continue;
+ }
+ full_path = g_build_filename (_gst_executable_path, path, NULL);
+ } else {
+ full_path = g_strdup (path);
+ }
- if (!g_queue_find_custom (&scan_paths, path, (GCompareFunc) strcmp)) {
- GST_LOG_OBJECT (plugin, "path: '%s'", path);
- g_queue_push_tail (&scan_paths, g_strdup (path));
+ if (!g_queue_find_custom (&scan_paths, full_path, (GCompareFunc) strcmp)) {
+ GST_LOG_OBJECT (plugin, "path: '%s'", full_path);
+ g_queue_push_tail (&scan_paths, full_path);
} else {
- GST_LOG_OBJECT (plugin, "path: '%s' (duplicate, ignoring)", path);
+ GST_LOG_OBJECT (plugin, "path: '%s' (duplicate, ignoring)", full_path);
+ g_free (full_path);
}
}
}
* @GST_PLUGIN_DEPENDENCY_FLAG_FILE_NAME_IS_PREFIX : interpret
* filename argument as filter prefix and check all matching files in
* the directory. Since 1.8.
+ * @GST_PLUGIN_DEPENDENCY_FLAG_PATHS_ARE_RELATIVE_TO_EXE : interpret
+ * non-absolute paths as relative to the main executable directory. Since
+ * 1.14.
*
* Flags used in connection with gst_plugin_add_dependency().
*/
GST_PLUGIN_DEPENDENCY_FLAG_RECURSE = (1 << 0),
GST_PLUGIN_DEPENDENCY_FLAG_PATHS_ARE_DEFAULT_ONLY = (1 << 1),
GST_PLUGIN_DEPENDENCY_FLAG_FILE_NAME_IS_SUFFIX = (1 << 2),
- GST_PLUGIN_DEPENDENCY_FLAG_FILE_NAME_IS_PREFIX = (1 << 3)
+ GST_PLUGIN_DEPENDENCY_FLAG_FILE_NAME_IS_PREFIX = (1 << 3),
+ GST_PLUGIN_DEPENDENCY_FLAG_PATHS_ARE_RELATIVE_TO_EXE = (1 << 4)
} GstPluginDependencyFlags;
/**
static gboolean
gst_plugin_loader_try_helper (GstPluginLoader * loader, gchar * location)
{
- char *argv[5] = { NULL, };
+ char *argv[6] = { NULL, };
int c = 0;
#if defined (__APPLE__) && defined (USR_BIN_ARCH_SWITCH)
#endif
argv[c++] = location;
argv[c++] = (char *) "-l";
+ argv[c++] = _gst_executable_path;
argv[c++] = NULL;
- if (c > 3) {
+ if (c > 4) {
GST_LOG ("Trying to spawn gst-plugin-scanner helper at %s with arch %s",
location, argv[1]);
} else {
char **my_argv;
int my_argc;
- if (argc != 2 || strcmp (argv[1], "-l"))
+ if (argc != 3 || strcmp (argv[1], "-l"))
return 1;
my_argc = 2;
_gst_disable_registry_cache = TRUE;
#endif
+ _gst_executable_path = g_strdup (argv[2]);
res = gst_init_check (&my_argc, &my_argv, NULL);
g_free (my_argv);
_gst_debug_nameof_funcptr
_gst_debug_register_funcptr
_gst_disable_registry_cache DATA
+ _gst_executable_path DATA
_gst_double_range_type DATA
_gst_element_error_printf
_gst_event_type DATA