X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gst%2Fgstplugin.c;h=129f60c339fb0b97c57d8b8a12c894964d3008cf;hb=f34472822c257359d69ebf671b81d85646a40618;hp=6285983de90af815082de43e15c7bf7c1147cf0e;hpb=a87b4551a6090663a1714f263d4e20fe75eb46ca;p=platform%2Fupstream%2Fgstreamer.git diff --git a/gst/gstplugin.c b/gst/gstplugin.c index 6285983..129f60c 100644 --- a/gst/gstplugin.c +++ b/gst/gstplugin.c @@ -109,13 +109,12 @@ static void gst_plugin_desc_copy (GstPluginDesc * dest, static void gst_plugin_ext_dep_free (GstPluginDep * dep); -G_DEFINE_TYPE (GstPlugin, gst_plugin, GST_TYPE_OBJECT); +G_DEFINE_TYPE_WITH_PRIVATE (GstPlugin, gst_plugin, GST_TYPE_OBJECT); static void gst_plugin_init (GstPlugin * plugin) { - plugin->priv = - G_TYPE_INSTANCE_GET_PRIVATE (plugin, GST_TYPE_PLUGIN, GstPluginPrivate); + plugin->priv = gst_plugin_get_instance_private (plugin); } static void @@ -154,8 +153,6 @@ static void gst_plugin_class_init (GstPluginClass * klass) { G_OBJECT_CLASS (klass)->finalize = gst_plugin_finalize; - - g_type_class_add_private (klass, sizeof (GstPluginPrivate)); } GQuark @@ -220,7 +217,7 @@ gst_plugin_register_static (gint major_version, gint minor_version, g_return_val_if_fail (_gst_plugin_inited != FALSE, FALSE); GST_LOG ("attempting to load static plugin \"%s\" now...", name); - plugin = g_object_newv (GST_TYPE_PLUGIN, 0, NULL); + plugin = g_object_new (GST_TYPE_PLUGIN, NULL); if (gst_plugin_register_func (plugin, &desc, NULL) != NULL) { GST_INFO ("registered static plugin \"%s\"", name); res = gst_registry_add_plugin (gst_registry_get (), plugin); @@ -287,7 +284,7 @@ gst_plugin_register_static_full (gint major_version, gint minor_version, g_return_val_if_fail (_gst_plugin_inited != FALSE, FALSE); GST_LOG ("attempting to load static plugin \"%s\" now...", name); - plugin = g_object_newv (GST_TYPE_PLUGIN, 0, NULL); + plugin = g_object_new (GST_TYPE_PLUGIN, NULL); if (gst_plugin_register_func (plugin, &desc, user_data) != NULL) { GST_INFO ("registered static plugin \"%s\"", name); res = gst_registry_add_plugin (gst_registry_get (), plugin); @@ -344,7 +341,7 @@ _priv_gst_plugin_initialize (void) * name and the plugin's source package name, to keep the format simple. */ static gboolean -gst_plugin_desc_matches_whitelist_entry (GstPluginDesc * desc, +gst_plugin_desc_matches_whitelist_entry (const GstPluginDesc * desc, const gchar * filename, const gchar * pattern) { const gchar *sep; @@ -406,7 +403,7 @@ done: } gboolean -priv_gst_plugin_desc_is_whitelisted (GstPluginDesc * desc, +priv_gst_plugin_desc_is_whitelisted (const GstPluginDesc * desc, const gchar * filename) { gchar **entry; @@ -667,7 +664,7 @@ static GMutex gst_plugin_loading_mutex; /** * gst_plugin_load_file: - * @filename: the plugin filename to load + * @filename: (type filename): the plugin filename to load * @error: pointer to a %NULL-valued GError * * Loads the given plugin and refs it. Caller needs to unref after use. @@ -681,12 +678,55 @@ gst_plugin_load_file (const gchar * filename, GError ** error) return _priv_gst_plugin_load_file_for_registry (filename, NULL, error); } +static gchar * +extract_symname (const char *filename) +{ + gchar *bname, *name, *symname; + const gchar *dot; + gsize prefix_len, len; + int i; + + bname = g_path_get_basename (filename); + for (i = 0; bname[i]; ++i) { + if (bname[i] == '-') + bname[i] = '_'; + } + + if (g_str_has_prefix (bname, "libgst")) + prefix_len = 6; + else if (g_str_has_prefix (bname, "lib")) + prefix_len = 3; + else if (g_str_has_prefix (bname, "gst")) + prefix_len = 3; + else + prefix_len = 0; /* use whole name (minus suffix) as plugin name */ + + dot = g_utf8_strchr (bname, -1, '.'); + if (dot) + len = dot - bname - prefix_len; + else + len = strlen (bname + prefix_len); + + name = g_strndup (bname + prefix_len, len); + g_free (bname); + + symname = g_strconcat ("gst_plugin_", name, "_get_desc", NULL); + g_free (name); + + return symname; +} + +/* Note: The return value is (transfer full) although we work with floating + * references here. If a new plugin instance is created, it is always sinked + * in the registry first and a new reference is returned + */ GstPlugin * _priv_gst_plugin_load_file_for_registry (const gchar * filename, GstRegistry * registry, GError ** error) { - GstPluginDesc *desc; + const GstPluginDesc *desc; GstPlugin *plugin; + gchar *symname; GModule *module; gboolean ret; gpointer ptr; @@ -757,7 +797,20 @@ _priv_gst_plugin_load_file_for_registry (const gchar * filename, goto return_error; } - ret = g_module_symbol (module, "gst_plugin_desc", &ptr); + symname = extract_symname (filename); + ret = g_module_symbol (module, symname, &ptr); + + if (ret) { + GstPluginDesc *(*get_desc) (void) = ptr; + ptr = get_desc (); + } else { + GST_DEBUG ("Could not find symbol '%s', falling back to gst_plugin_desc", + symname); + ret = g_module_symbol (module, "gst_plugin_desc", &ptr); + } + + g_free (symname); + if (!ret) { GST_DEBUG ("Could not find plugin entry point in \"%s\"", filename); g_set_error (error, @@ -768,7 +821,7 @@ _priv_gst_plugin_load_file_for_registry (const gchar * filename, goto return_error; } - desc = (GstPluginDesc *) ptr; + desc = (const GstPluginDesc *) ptr; if (priv_gst_plugin_loading_have_whitelist () && !priv_gst_plugin_desc_is_whitelisted (desc, filename)) { @@ -781,7 +834,7 @@ _priv_gst_plugin_load_file_for_registry (const gchar * filename, } if (new_plugin) { - plugin = g_object_newv (GST_TYPE_PLUGIN, 0, NULL); + plugin = g_object_new (GST_TYPE_PLUGIN, NULL); plugin->file_mtime = file_status.st_mtime; plugin->file_size = file_status.st_size; plugin->filename = g_strdup (filename); @@ -789,28 +842,30 @@ _priv_gst_plugin_load_file_for_registry (const gchar * filename, } plugin->module = module; - plugin->orig_desc = desc; if (new_plugin) { /* check plugin description: complain about bad values and fail */ - CHECK_PLUGIN_DESC_FIELD (plugin->orig_desc, name, filename); - CHECK_PLUGIN_DESC_FIELD (plugin->orig_desc, description, filename); - CHECK_PLUGIN_DESC_FIELD (plugin->orig_desc, version, filename); - CHECK_PLUGIN_DESC_FIELD (plugin->orig_desc, license, filename); - CHECK_PLUGIN_DESC_FIELD (plugin->orig_desc, source, filename); - CHECK_PLUGIN_DESC_FIELD (plugin->orig_desc, package, filename); - CHECK_PLUGIN_DESC_FIELD (plugin->orig_desc, origin, filename); - - if (plugin->orig_desc->name != NULL && plugin->orig_desc->name[0] == '"') { + CHECK_PLUGIN_DESC_FIELD (desc, name, filename); + CHECK_PLUGIN_DESC_FIELD (desc, description, filename); + CHECK_PLUGIN_DESC_FIELD (desc, version, filename); + CHECK_PLUGIN_DESC_FIELD (desc, license, filename); + CHECK_PLUGIN_DESC_FIELD (desc, source, filename); + CHECK_PLUGIN_DESC_FIELD (desc, package, filename); + CHECK_PLUGIN_DESC_FIELD (desc, origin, filename); + + if (desc->name != NULL && desc->name[0] == '"') { g_warning ("Invalid plugin name '%s' - fix your GST_PLUGIN_DEFINE " - "(remove quotes around plugin name)", plugin->orig_desc->name); + "(remove quotes around plugin name)", desc->name); } - if (plugin->orig_desc->release_datetime != NULL && - !check_release_datetime (plugin->orig_desc->release_datetime)) { - GST_ERROR ("GstPluginDesc for '%s' has invalid datetime '%s'", - filename, plugin->orig_desc->release_datetime); - plugin->orig_desc->release_datetime = NULL; + if (desc->release_datetime != NULL && + !check_release_datetime (desc->release_datetime)) { + g_warning ("GstPluginDesc for '%s' has invalid datetime '%s'", + filename, desc->release_datetime); + g_set_error (error, GST_PLUGIN_ERROR, GST_PLUGIN_ERROR_MODULE, + "Plugin %s has invalid plugin description field 'release_datetime'", + filename); + goto return_error; } } @@ -824,7 +879,7 @@ _priv_gst_plugin_load_file_for_registry (const gchar * filename, GST_LOG ("Plugin %p for file \"%s\" prepared, registering...", plugin, filename); - if (!gst_plugin_register_func (plugin, plugin->orig_desc, NULL)) { + if (!gst_plugin_register_func (plugin, desc, NULL)) { /* remove signal handler */ _gst_plugin_fault_handler_restore (); GST_DEBUG ("gst_plugin_register_func failed for plugin \"%s\"", filename); @@ -913,7 +968,7 @@ gst_plugin_get_description (GstPlugin * plugin) * * get the filename of the plugin * - * Returns: the filename of the plugin + * Returns: (type filename): the filename of the plugin */ const gchar * gst_plugin_get_filename (GstPlugin * plugin) @@ -1251,7 +1306,8 @@ gst_plugin_find_feature_by_name (GstPlugin * plugin, const gchar * name) * * Load the named plugin. Refs the plugin. * - * Returns: (transfer full): a reference to a loaded plugin, or %NULL on error. + * Returns: (transfer full) (nullable): a reference to a loaded plugin, or + * %NULL on error. */ GstPlugin * gst_plugin_load_by_name (const gchar * name) @@ -1294,7 +1350,8 @@ gst_plugin_load_by_name (const gchar * name) * plugin = loaded_plugin; * ]| * - * Returns: (transfer full): a reference to a loaded plugin, or %NULL on error. + * Returns: (transfer full) (nullable): a reference to a loaded plugin, or + * %NULL on error. */ GstPlugin * gst_plugin_load (GstPlugin * plugin) @@ -1303,7 +1360,7 @@ gst_plugin_load (GstPlugin * plugin) GstPlugin *newplugin; if (gst_plugin_is_loaded (plugin)) { - return plugin; + return gst_object_ref (plugin); } if (!(newplugin = gst_plugin_load_file (plugin->filename, &error))) @@ -1644,6 +1701,7 @@ static guint 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; @@ -1652,6 +1710,8 @@ gst_plugin_ext_dep_get_stat_hash (GstPlugin * plugin, GstPluginDep * dep) 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); @@ -1660,12 +1720,30 @@ gst_plugin_ext_dep_get_stat_hash (GstPlugin * plugin, GstPluginDep * dep) 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)) { + gchar *appdir; + + if (!_gst_executable_path) { + GST_FIXME_OBJECT (plugin, + "Path dependency %s relative to executable path but could not retrieve executable path", + path); + continue; + } + appdir = g_path_get_dirname (_gst_executable_path); + full_path = g_build_filename (appdir, path, NULL); + g_free (appdir); + } 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); } } } @@ -1733,15 +1811,15 @@ gst_plugin_ext_dep_equals (GstPluginDep * dep, const gchar ** env_vars, /** * gst_plugin_add_dependency: * @plugin: a #GstPlugin - * @env_vars: (allow-none): %NULL-terminated array of environment variables affecting the + * @env_vars: (allow-none) (array zero-terminated=1): %NULL-terminated array of environment variables affecting the * feature set of the plugin (e.g. an environment variable containing * paths where to look for additional modules/plugins of a library), * or %NULL. Environment variable names may be followed by a path component * which will be added to the content of the environment variable, e.g. * "HOME/.mystuff/plugins". - * @paths: (allow-none): %NULL-terminated array of directories/paths where dependent files + * @paths: (allow-none) (array zero-terminated=1): %NULL-terminated array of directories/paths where dependent files * may be, or %NULL. - * @names: (allow-none): %NULL-terminated array of file names (or file name suffixes, + * @names: (allow-none) (array zero-terminated=1): %NULL-terminated array of file names (or file name suffixes, * depending on @flags) to be used in combination with the paths from * @paths and/or the paths extracted from the environment variables in * @env_vars, or %NULL.