--- /dev/null
+/* GStreamer
+ * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <gst/gstfilter.h>
+
+GList*
+gst_filter_run (const GList *list, GstFilterFunc func, gboolean first, gpointer user_data)
+{
+ const GList *walk = list;
+ GList *result = NULL;
+
+ while (walk) {
+ gboolean res = TRUE;
+ gpointer data = walk->data;
+
+ walk = g_list_next (walk);
+
+ if (func)
+ res = func (data, user_data);
+
+ if (res) {
+ result = g_list_prepend (result, data);
+
+ if (first)
+ break;
+ }
+ }
+
+ return result;
+}
--- /dev/null
+/* GStreamer
+ * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <glib.h>
+
+typedef gboolean (*GstFilterFunc) (gpointer obj, gpointer user_data);
+
+GList* gst_filter_run (const GList *list, GstFilterFunc func, gboolean first, gpointer user_data);
#include "gstregistrypool.h"
#include "gstlog.h"
#include "config.h"
+#include "gstfilter.h"
static GModule *main_module = NULL;
static GList *_gst_plugin_static = NULL;
void
_gst_plugin_initialize (void)
{
- GList *walk;
-
main_module = g_module_open (NULL, G_MODULE_BIND_LAZY);
/* now register all static plugins */
- walk = _gst_plugin_static;
- while (walk) {
- GstPluginDesc *desc = (GstPluginDesc *) walk->data;
-
- _gst_plugin_register_static (desc);
-
- walk = g_list_next (walk);
- }
+ g_list_foreach (_gst_plugin_static, (GFunc) _gst_plugin_register_static, NULL);
}
static gboolean
{
g_return_if_fail (plugin != NULL);
- if (plugin->name)
- g_free (plugin->name);
+ g_free (plugin->name);
plugin->name = g_strdup (name);
}
{
g_return_if_fail(plugin != NULL);
- if (plugin->longname)
- g_free(plugin->longname);
+ g_free(plugin->longname);
plugin->longname = g_strdup(longname);
}
return (plugin->module != NULL);
}
+GList*
+gst_plugin_feature_filter (GstPlugin *plugin,
+ GstPluginFeatureFilter filter,
+ gboolean first,
+ gpointer user_data)
+{
+ return gst_filter_run (plugin->features, (GstFilterFunc) filter, first, user_data);
+}
+
+typedef struct
+{
+ GstPluginFeatureFilter filter;
+ gboolean first;
+ gpointer user_data;
+ GList *result;
+} FeatureFilterData;
+
+gboolean
+_feature_filter (GstPlugin *plugin, gpointer user_data)
+{
+ GList *result;
+ FeatureFilterData *data = (FeatureFilterData *) user_data;
+
+ result = gst_plugin_feature_filter (plugin, data->filter, data->first, data->user_data);
+ if (result) {
+ data->result = g_list_concat (data->result, result);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+GList*
+gst_plugin_list_feature_filter (GList *list,
+ GstPluginFeatureFilter filter,
+ gboolean first,
+ gpointer user_data)
+{
+ FeatureFilterData data;
+ GList *result;
+
+ data.filter = filter;
+ data.first = first;
+ data.user_data = user_data;
+ data.result = NULL;
+
+ result = gst_filter_run (list, (GstFilterFunc) _feature_filter, first, &data);
+ g_list_free (result);
+
+ return data.result;
+}
+
+
+gboolean
+gst_plugin_name_filter (GstPlugin *plugin, const gchar *name)
+{
+ return (plugin->name && !strcmp (plugin->name, name));
+}
+
/**
* gst_plugin_find_feature:
* @plugin: plugin to get the feature from
GstPluginFeature*
gst_plugin_find_feature (GstPlugin *plugin, const gchar *name, GType type)
{
- GList *features = plugin->features;
+ GList *walk;
+ GstPluginFeature *result = NULL;
+ GstTypeNameData data;
g_return_val_if_fail (name != NULL, NULL);
- while (features) {
- GstPluginFeature *feature = GST_PLUGIN_FEATURE (features->data);
+ data.type = type;
+ data.name = name;
+
+ walk = gst_filter_run (plugin->features,
+ (GstFilterFunc) gst_plugin_feature_type_name_filter, TRUE,
+ &data);
- if (!strcmp(GST_PLUGIN_FEATURE_NAME (feature), name) && G_OBJECT_TYPE (feature) == type) {
- return GST_PLUGIN_FEATURE (feature);
- }
+ if (walk)
+ result = GST_PLUGIN_FEATURE (walk->data);
- features = g_list_next (features);
- }
- return NULL;
+ return result;
}
/**
*
* get a list of all the features that this plugin provides
*
- * Returns: a GList of features
+ * Returns: a GList of features, use g_list_free to free the list.
*/
GList*
gst_plugin_get_feature_list (GstPlugin *plugin)
{
g_return_val_if_fail (plugin != NULL, NULL);
- return plugin->features;
+ return g_list_copy (plugin->features);
}
/**
GST_DEBUG (GST_CAT_PLUGIN_LOADING, "Could not find %s in registry pool",
name);
+
return FALSE;
}
GST_PLUGIN_DESC_DYNAMIC (major,minor,name,init) \
GST_PLUGIN_DESC_STATIC (major,minor,name,init)
+/* function for filters */
+typedef gboolean (*GstPluginFilter) (GstPlugin *plugin,
+ gpointer user_data);
+
void _gst_plugin_initialize (void);
void _gst_plugin_register_static (GstPluginDesc *desc);
const gchar* gst_plugin_get_filename (GstPlugin *plugin);
gboolean gst_plugin_is_loaded (GstPlugin *plugin);
+GList* gst_plugin_feature_filter (GstPlugin *plugin,
+ GstPluginFeatureFilter filter,
+ gboolean first,
+ gpointer user_data);
+GList* gst_plugin_list_feature_filter (GList *list,
+ GstPluginFeatureFilter filter,
+ gboolean first,
+ gpointer user_data);
+gboolean gst_plugin_name_filter (GstPlugin *plugin, const gchar *name);
+
GList* gst_plugin_get_feature_list (GstPlugin *plugin);
GstPluginFeature* gst_plugin_find_feature (GstPlugin *plugin, const gchar *name, GType type);
oclass->unload_thyself (feature);
}
-
+gboolean
+gst_plugin_feature_type_name_filter (GstPluginFeature *feature,
+ GstTypeNameData *data)
+{
+ return ((data->type == 0 || data->type == G_OBJECT_TYPE (feature)) &&
+ (data->name == NULL || !strcmp (data->name, GST_PLUGIN_FEATURE_NAME (feature))));
+}
void (*unload_thyself) (GstPluginFeature *feature);
};
+typedef struct {
+ const gchar *name;
+ GType type;
+} GstTypeNameData;
+
+/* filter */
+typedef gboolean (*GstPluginFeatureFilter) (GstPluginFeature *feature,
+ gpointer user_data);
/* normal GObject stuff */
GType gst_plugin_feature_get_type (void);
gboolean gst_plugin_feature_ensure_loaded (GstPluginFeature *feature);
void gst_plugin_feature_unload_thyself (GstPluginFeature *feature);
+gboolean gst_plugin_feature_type_name_filter (GstPluginFeature *feature,
+ GstTypeNameData *data);
+
G_END_DECLS
#include "gstregistry.h"
#include "gstlog.h"
#include "gstmarshal.h"
+#include "gstfilter.h"
/* Element signals and args */
enum {
void
gst_registry_add_path (GstRegistry *registry, const gchar *path)
{
- GList *l;
-
g_return_if_fail (GST_IS_REGISTRY (registry));
g_return_if_fail (path != NULL);
- l = registry->paths;
- while (l) {
- if (strcmp (l->data, path) == 0)
- return;
-
- l = g_list_next (l);
+ if (g_list_find_custom (registry->paths, path, (GCompareFunc) strcmp)) {
+ g_warning ("path %s already added to registry", path);
+ return;
}
-
+
registry->paths = g_list_append (registry->paths, g_strdup (path));
}
}
-static void
-free_list_strings_func (gpointer data, gpointer user_data)
-{
- g_free (data);
-}
-
/**
* gst_registry_clear_paths:
* @registry: the registry to clear the paths of
{
g_return_if_fail (GST_IS_REGISTRY (registry));
- g_list_foreach (registry->paths, free_list_strings_func, NULL);
+ g_list_foreach (registry->paths, (GFunc) g_free, NULL);
g_list_free (registry->paths);
registry->paths = NULL;
registry->plugins = g_list_remove (registry->plugins, plugin);
}
+GList*
+gst_registry_plugin_filter (GstRegistry *registry,
+ GstPluginFilter filter,
+ gboolean first,
+ gpointer user_data)
+{
+ g_return_val_if_fail (GST_IS_REGISTRY (registry), NULL);
+
+ return gst_filter_run (registry->plugins, (GstFilterFunc) filter, first, user_data);
+}
+
+GList*
+gst_registry_feature_filter (GstRegistry *registry,
+ GstPluginFeatureFilter filter,
+ gboolean first,
+ gpointer user_data)
+{
+ g_return_val_if_fail (GST_IS_REGISTRY (registry), NULL);
+
+ return gst_plugin_list_feature_filter (registry->plugins, filter, first, user_data);
+}
+
/**
* gst_registry_find_plugin:
* @registry: the registry to search
GstPlugin*
gst_registry_find_plugin (GstRegistry *registry, const gchar *name)
{
- GList *plugins;
+ GList *walk;
+ GstPlugin *result = NULL;
g_return_val_if_fail (GST_IS_REGISTRY (registry), NULL);
g_return_val_if_fail (name != NULL, NULL);
- plugins = registry->plugins;
-
- while (plugins) {
- GstPlugin *plugin = (GstPlugin *) (plugins->data);
+ walk = gst_registry_plugin_filter (registry,
+ (GstPluginFilter) gst_plugin_name_filter,
+ TRUE,
+ (gpointer) name);
+ if (walk)
+ result = GST_PLUGIN (walk->data);
- if (plugin->name && !strcmp (plugin->name, name))
- return plugin;
-
- plugins = g_list_next (plugins);
- }
- return NULL;
+ g_list_free (walk);
+
+ return result;
}
/**
gst_registry_find_feature (GstRegistry *registry, const gchar *name, GType type)
{
GstPluginFeature *feature = NULL;
- GList *plugins;
+ GList *walk;
+ GstTypeNameData data;
g_return_val_if_fail (GST_IS_REGISTRY (registry), NULL);
g_return_val_if_fail (name != NULL, NULL);
- plugins = registry->plugins;
+ data.name = name;
+ data.type = type;
- while (plugins) {
- GstPlugin *plugin = (GstPlugin *) (plugins->data);
+ walk = gst_registry_feature_filter (registry,
+ (GstPluginFeatureFilter) gst_plugin_feature_type_name_filter,
+ TRUE,
+ &data);
+
+ if (walk)
+ feature = GST_PLUGIN_FEATURE (walk->data);
+
+ g_list_free (walk);
- feature = gst_plugin_find_feature (plugin, name, type);
- if (feature)
- return feature;
-
- plugins = g_list_next (plugins);
- }
return feature;
}
gboolean gst_registry_add_plugin (GstRegistry *registry, GstPlugin *plugin);
void gst_registry_remove_plugin (GstRegistry *registry, GstPlugin *plugin);
+GList* gst_registry_plugin_filter (GstRegistry *registry,
+ GstPluginFilter filter,
+ gboolean first,
+ gpointer user_data);
+GList* gst_registry_feature_filter (GstRegistry *registry,
+ GstPluginFeatureFilter filter,
+ gboolean first,
+ gpointer user_data);
+
GstPlugin* gst_registry_find_plugin (GstRegistry *registry, const gchar *name);
GstPluginFeature* gst_registry_find_feature (GstRegistry *registry, const gchar *name, GType type);
#include "gstinfo.h"
#include "gstregistrypool.h"
#include "gstlog.h"
+#include "gstfilter.h"
static GList *_gst_registry_pool = NULL;
static GList *_gst_registry_pool_plugins = NULL;
_gst_registry_pool_plugins = g_list_prepend (_gst_registry_pool_plugins, plugin);
}
+#ifndef GST_DISABLE_REGISTRY
+static void
+_registry_load_func (GstRegistry *registry, gpointer user_data)
+{
+ if (registry->flags & GST_REGISTRY_READABLE &&
+ !(registry->flags & GST_REGISTRY_DELAYED_LOADING)) {
+ gst_registry_load (registry);
+ }
+}
+#endif /* GST_DISABLE_REGISTRY */
/**
* gst_registry_pool_load_all:
gst_registry_pool_load_all (void)
{
#ifndef GST_DISABLE_REGISTRY
- GList *walk = _gst_registry_pool;
-
- while (walk) {
- GstRegistry *registry = GST_REGISTRY (walk->data);
-
- if (registry->flags & GST_REGISTRY_READABLE &&
- !(registry->flags & GST_REGISTRY_DELAYED_LOADING)) {
- gst_registry_load (registry);
- }
-
- walk = g_list_next (walk);
- }
+ g_list_foreach (_gst_registry_pool, (GFunc) _registry_load_func, NULL);
#endif /* GST_DISABLE_REGISTRY */
}
GList*
gst_registry_pool_plugin_list (void)
{
+ return gst_registry_pool_plugin_filter (NULL, FALSE, NULL);
+}
+
+GList*
+gst_registry_pool_plugin_filter (GstPluginFilter filter, gboolean first, gpointer user_data)
+{
GList *result = NULL;
+ GList *walk, *temp;
+
#ifndef GST_DISABLE_REGISTRY
- GList *walk = _gst_registry_pool;
+ walk = _gst_registry_pool;
while (walk) {
GstRegistry *registry = GST_REGISTRY (walk->data);
- /* FIXME only include highest priority plugins */
- result = g_list_concat (result, g_list_copy (registry->plugins));
+ temp = gst_registry_plugin_filter (registry, filter, first, user_data);
+ if (temp && first)
+ return temp;
+
+ result = g_list_concat (result, temp);
walk = g_list_next (walk);
}
#endif /* GST_DISABLE_REGISTRY */
-
- return g_list_concat (_gst_registry_pool_plugins, result);
-}
-GstFeatureFilterResult
-gst_registry_pool_feature_type_filter (GstPluginFeature *feature, GType type)
-{
- if (type == 0 || G_OBJECT_TYPE (feature) == type)
- return GST_FEATURE_FILTER_OK;
+ temp = gst_filter_run (_gst_registry_pool_plugins, (GstFilterFunc) filter, first, user_data);
- return GST_FEATURE_FILTER_NOK;
+ result = g_list_concat (result, temp);
+
+ return result;
}
/**
GList*
gst_registry_pool_feature_list (GType type)
{
+ GstTypeNameData data;
+
+ data.name = NULL;
+ data.type = type;
+
return gst_registry_pool_feature_filter (
- (GstPluginFeatureFilter) gst_registry_pool_feature_type_filter,
- GINT_TO_POINTER (type));
+ (GstPluginFeatureFilter) gst_plugin_feature_type_name_filter,
+ FALSE,
+ &data);
}
/**
* gst_registry_pool_feature_filter:
* @filter: the filter to apply to the feature list
+ * @first: return the first matching feature
* @user_data: data passed to the filter function
*
* Apply the filter function to all features and return a list
- * of those features that satisfy the filter.
+ * of those features that satisfy the filter. If the first flag
+ * is TRUE, only the first match is returned in a GList with
+ * one element.
*
* Returns: a GList of pluginfeatures, g_list_free after use.
*/
GList*
-gst_registry_pool_feature_filter (GstPluginFeatureFilter filter, gpointer user_data)
+gst_registry_pool_feature_filter (GstPluginFeatureFilter filter, gboolean first, gpointer user_data)
{
GList *result = NULL;
- GList *plugins, *orig;
- gboolean done = FALSE;
-
- orig = plugins = gst_registry_pool_plugin_list ();
-
- while (plugins && !done) {
- GstPlugin *plugin = GST_PLUGIN (plugins->data);
- GList *features = plugin->features;
-
- plugins = g_list_next (plugins);
-
- while (features && !done) {
- GstPluginFeature *feature = GST_PLUGIN_FEATURE (features->data);
- gboolean res = GST_FEATURE_FILTER_OK;
-
- features = g_list_next (features);
-
- if (filter)
- res = filter (feature, user_data);
-
- switch (res) {
- case GST_FEATURE_FILTER_DONE:
- done = TRUE;
- /* fallthrough */
- case GST_FEATURE_FILTER_OK:
- result = g_list_prepend (result, feature);
- break;
- case GST_FEATURE_FILTER_NOK:
- default:
- break;
- }
- }
+ GList *walk, *temp;
+
+#ifndef GST_DISABLE_REGISTRY
+ walk = _gst_registry_pool;
+
+ while (walk) {
+ GstRegistry *registry = GST_REGISTRY (walk->data);
+
+ temp = gst_registry_feature_filter (registry, filter, first, user_data);
+ if (temp && first)
+ return temp;
+
+ result = g_list_concat (result, temp);
+
+ walk = g_list_next (walk);
}
- result = g_list_reverse (result);
+#endif /* GST_DISABLE_REGISTRY */
+
+ temp = gst_plugin_list_feature_filter (_gst_registry_pool_plugins, filter, first, user_data);
+
+ result = g_list_concat (result, temp);
- g_list_free (orig);
-
return result;
}
-
/**
* gst_registry_pool_find_plugin:
* @name: the name of the plugin to find
GList *walk;
g_return_val_if_fail (name != NULL, NULL);
+
+ walk = gst_registry_pool_plugin_filter ((GstPluginFilter) gst_plugin_name_filter, TRUE, (gpointer) name);
- walk = _gst_registry_pool_plugins;
- while (walk) {
- result = (GstPlugin *) (walk->data);
+ if (walk)
+ result = GST_PLUGIN (walk->data);
- if (result->name && !strcmp (result->name, name))
- return result;
-
- walk = g_list_next (walk);
- }
+ g_list_free (walk);
-#ifndef GST_DISABLE_REGISTRY
- walk = _gst_registry_pool;
- while (walk) {
- GstRegistry *registry = GST_REGISTRY (walk->data);
-
- /* FIXME only include highest priority plugins */
- result = gst_registry_find_plugin (registry, name);
- if (result)
- return result;
-
- walk = g_list_next (walk);
- }
-#endif /* GST_DISABLE_REGISTRY */
- return NULL;
+ return result;
}
/**
{
GstPluginFeature *result = NULL;
GList *walk;
+ GstTypeNameData data;
g_return_val_if_fail (name != NULL, NULL);
-
- walk = _gst_registry_pool_plugins;
- while (walk) {
- GstPlugin *plugin = (GstPlugin *) (walk->data);
- result = gst_plugin_find_feature (plugin, name, type);
- if (result)
- return result;
+ data.type = type;
+ data.name = name;
- walk = g_list_next (walk);
- }
+ walk = gst_registry_pool_feature_filter ((GstPluginFeatureFilter) gst_plugin_feature_type_name_filter,
+ TRUE, &data);
+
+ if (walk)
+ result = GST_PLUGIN_FEATURE (walk->data);
-#ifndef GST_DISABLE_REGISTRY
- walk = _gst_registry_pool;
- while (walk) {
- GstRegistry *registry = GST_REGISTRY (walk->data);
+ g_list_free (walk);
- /* FIXME only include highest priority plugins */
- result = gst_registry_find_feature (registry, name, type);
- if (result)
- return result;
-
- walk = g_list_next (walk);
- }
-#endif /* GST_DISABLE_REGISTRY */
- return NULL;
+ return result;
}
/**
#ifndef __GST_REGISTRY_POOL_H__
#define __GST_REGISTRY_POOL_H__
-#include <gst/gstregistry.h>
-
G_BEGIN_DECLS
-typedef enum
-{
- GST_FEATURE_FILTER_OK, /* include feature in list */
- GST_FEATURE_FILTER_NOK, /* does not include filter in list */
- GST_FEATURE_FILTER_DONE, /* includes filter in list and stop processing */
-} GstFeatureFilterResult;
-
-typedef GstFeatureFilterResult (*GstPluginFeatureFilter) (GstPluginFeature *feature,
- gpointer user_data);
-
+#include <gst/gstplugin.h>
+#include <gst/gstregistry.h>
/* the pool of registries */
GList* gst_registry_pool_list (void);
+
void gst_registry_pool_add (GstRegistry *registry, guint priority);
void gst_registry_pool_remove (GstRegistry *registry);
void gst_registry_pool_load_all (void);
+/* query the plugins/features */
+GList* gst_registry_pool_plugin_filter (GstPluginFilter filter,
+ gboolean first, gpointer user_data);
+GList* gst_registry_pool_feature_filter (GstPluginFeatureFilter filter,
+ gboolean first, gpointer user_data);
+
+/* some predefined filters */
GList* gst_registry_pool_plugin_list (void);
GList* gst_registry_pool_feature_list (GType type);
-GList* gst_registry_pool_feature_filter (GstPluginFeatureFilter filter, gpointer user_data);
-
-GstFeatureFilterResult gst_registry_pool_feature_type_filter (GstPluginFeature *feature, GType type);
-
GstPlugin* gst_registry_pool_find_plugin (const gchar *name);
GstPluginFeature* gst_registry_pool_find_feature (const gchar *name, GType type);
return FALSE;
}
+gboolean
+gst_uri_handler_uri_filter (GstPluginFeature *feature, const gchar *uri)
+{
+ if (G_OBJECT_TYPE (feature) == GST_TYPE_URI_HANDLER) {
+ GstURIHandler *handler = GST_URI_HANDLER (feature);
+
+ if (g_str_has_prefix_glib22 ((gchar *) uri, handler->uri)) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
/**
* gst_uri_handler_find_by_uri:
* @uri: the uri to find a handler for
GstURIHandler*
gst_uri_handler_find_by_uri (const gchar *uri)
{
- GList *walk, *orig;
+ GList *walk;
GstURIHandler *result = NULL;
g_return_val_if_fail (uri != NULL, NULL);
- orig = walk = gst_registry_pool_feature_list (GST_TYPE_URI_HANDLER);
-
- while (walk) {
- GstURIHandler *handler = GST_URI_HANDLER (walk->data);
+ walk = gst_registry_pool_feature_filter (
+ (GstPluginFeatureFilter) gst_uri_handler_uri_filter, TRUE, (gpointer) uri);
- if (g_str_has_prefix_glib22 ((gchar *) uri, handler->uri)) {
- result = handler;
- break;
- }
- walk = g_list_next (walk);
+ if (walk) {
+ result = GST_URI_HANDLER (walk->data);
}
- g_list_free (orig);
+ g_list_free (walk);
return result;
}
GstElement* gst_uri_handler_create (GstURIHandler *handler, const gchar *name);
GstElement* gst_uri_handler_make_by_uri (const gchar *uri, const gchar *name);
+/* filters */
+gboolean gst_uri_handler_uri_filter (GstPluginFeature *feature, const gchar *uri);
+
G_END_DECLS
#endif /* __GST_URI_H */