gstregistry.c
static gboolean
gst_registry_scan_path_level (GstRegistryScanContext * context,
const gchar * path, int level)
{
GDir *dir;
const gchar *dirent;
gchar *filename;
GstPlugin *plugin;
gboolean changed = FALSE;
dir = g_dir_open (path, 0, NULL);
if (!dir)
return FALSE;
while ((dirent = g_dir_read_name (dir))) {
GStatBuf file_status;
filename = g_build_filename (path, dirent, NULL);
if (g_stat (filename, &file_status) < 0) {
/* Plugin will be removed from cache after the scan completes if it
* is still marked 'cached' */
g_free (filename);
continue;
}
if (file_status.st_mode & S_IFDIR) {
if (G_UNLIKELY (is_blacklisted_hidden_directory (dirent))) {
GST_TRACE_OBJECT (context->registry, "ignoring %s directory", dirent);
g_free (filename);
continue;
}
/* FIXME 0.11: Don't recurse into directories, this behaviour
* is inconsistent with other PATH environment variables
*/
if (level > 0) {
GST_LOG_OBJECT (context->registry, "recursing into directory %s",
filename);
changed |= gst_registry_scan_path_level (context, filename, level - 1);
} else {
GST_LOG_OBJECT (context->registry, "not recursing into directory %s, "
"recursion level too deep", filename);
}
g_free (filename);
continue;
}
if (!(file_status.st_mode & S_IFREG)) {
GST_TRACE_OBJECT (context->registry, "%s is not a regular file, ignoring",
filename);
g_free (filename);
continue;
}
if (!g_str_has_suffix (dirent, G_MODULE_SUFFIX)
#ifdef GST_EXTRA_MODULE_SUFFIX
&& !g_str_has_suffix (dirent, GST_EXTRA_MODULE_SUFFIX)
#endif
) {
GST_TRACE_OBJECT (context->registry,
"extension is not recognized as module file, ignoring file %s",
filename);
g_free (filename);
continue;
}
GST_LOG_OBJECT (context->registry, "file %s looks like a possible module",
filename);
/* try to avoid unnecessary plugin-move pain */
if (g_str_has_prefix (dirent, "libgstvalve") ||
g_str_has_prefix (dirent, "libgstselector")) {
GST_WARNING_OBJECT (context->registry, "ignoring old plugin %s which "
"has been merged into the corelements plugin", filename);
/* Plugin will be removed from cache after the scan completes if it
* is still marked 'cached' */
g_free (filename);
continue;
}
/* plug-ins are considered unique by basename; if the given name
* was already seen by the registry, we ignore it */
plugin = gst_registry_lookup_bn (context->registry, dirent);
if (plugin) {
gboolean env_vars_changed, deps_changed = FALSE;
if (plugin->registered) {
GST_DEBUG_OBJECT (context->registry,
"plugin already registered from path \"%s\"",
GST_STR_NULL (plugin->filename));
g_free (filename);
gst_object_unref (plugin);
continue;
}
env_vars_changed = _priv_plugin_deps_env_vars_changed (plugin);
/* If a file with a certain basename is seen on a different path,
* update the plugin to ensure the registry cache will reflect up
* to date information */
if (plugin->file_mtime == file_status.st_mtime &&
plugin->file_size == file_status.st_size && !env_vars_changed &&
!(deps_changed = _priv_plugin_deps_files_changed (plugin)) &&
!strcmp (plugin->filename, filename)) {
GST_LOG_OBJECT (context->registry, "file %s cached", filename);
GST_OBJECT_FLAG_UNSET (plugin, GST_PLUGIN_FLAG_CACHED);
GST_LOG_OBJECT (context->registry,
"marking plugin %p as registered as %s", plugin, filename);
plugin->registered = TRUE;
} else {
GST_INFO_OBJECT (context->registry, "cached info for %s is stale",
filename);
GST_DEBUG_OBJECT (context->registry, "mtime %" G_GINT64_FORMAT " != %"
G_GINT64_FORMAT " or size %" G_GINT64_FORMAT " != %"
G_GINT64_FORMAT " or external dependency env_vars changed: %d or"
" external dependencies changed: %d or old path %s != new path %s",
(gint64) plugin->file_mtime, (gint64) file_status.st_mtime,
(gint64) plugin->file_size, (gint64) file_status.st_size,
env_vars_changed, deps_changed, plugin->filename, filename);
gst_registry_remove_plugin (context->registry, plugin);
changed |= gst_registry_scan_plugin_file (context, filename,
file_status.st_size, file_status.st_mtime);
}
gst_object_unref (plugin);
} else {
GST_DEBUG_OBJECT (context->registry, "file %s not yet in registry",
filename);
changed |= gst_registry_scan_plugin_file (context, filename,
file_status.st_size, file_status.st_mtime);
}
g_free (filename);
}
g_dir_close (dir);
return changed;
}
static gboolean
gst_registry_scan_path_internal (GstRegistryScanContext * context,
const gchar * path)
{
gboolean changed;
GST_DEBUG_OBJECT (context->registry, "scanning path %s", path);
changed = gst_registry_scan_path_level (context, path, 10);
GST_DEBUG_OBJECT (context->registry, "registry changed in path %s: %d", path,
changed);
return changed;
}
dirent = g_dir_read_name (dir) 读取文件夹下的子模块
如果子模块是文件夹,如果文件夹在黑名单上,忽略,文件夹深度没有达到10,即level>0,遍历该文件夹,在该文件夹下继续搜索;
如果不是普通文件,忽略;如果是普通文件,但是文件的后缀扩展不是G_MODULE_SUFFIX,忽略;如果包含libgstvalve前缀或者libgstselector前缀,忽略
如果插件已经存在,且修改插件的修改时间、文件尺寸、依赖插件或者环境变量发生了变化都要调用gst_registry_scan_plugin_file重新加载插件