gstreamer源码阅读笔记:gst_registry_scan_path_internal gst_registry_scan_path_level

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重新加载插件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值