Original commit message from CVS:
* check/Makefile.am:
* check/generic/states.c:
* gst/Makefile.am:
* gst/gst.c:
* gst/gst.h:
* gst/gst_private.h:
* gst/gstelementfactory.c:
* gst/gstindex.c:
* gst/gstinfo.c:
* gst/gstplugin.c:
* gst/gstplugin.h:
* gst/gstpluginfeature.c:
* gst/gstpluginfeature.h:
* gst/gstregistry.c:
* gst/gstregistry.h:
* gst/gstregistrypool.c: remove
* gst/gstregistrypool.h: remove
* gst/gsttypefind.c:
* gst/gsttypefindfactory.c:
* gst/gsturi.c:
* tools/Makefile.am:
* tools/gst-compprep.c:
* tools/gst-inspect.c:
* tools/gst-register.c: remove
* tools/gst-xmlinspect.c:
Registry rewrite.  Changes registry from being a file created
by a tool into a simple cache file created automatically by
libgstreamer.  Removed gst-register (because it's no longer
needed).  Remove registry pools, because we only have one
registry implementation (XML).  Fix up other subsystems as
necessary.
This commit is contained in:
David Schleef 2005-09-15 00:13:26 +00:00
parent d587018043
commit a3bac0703c
28 changed files with 671 additions and 1408 deletions

View file

@ -1,3 +1,37 @@
2005-09-14 David Schleef <ds@schleef.org>
* check/Makefile.am:
* check/generic/states.c:
* gst/Makefile.am:
* gst/gst.c:
* gst/gst.h:
* gst/gst_private.h:
* gst/gstelementfactory.c:
* gst/gstindex.c:
* gst/gstinfo.c:
* gst/gstplugin.c:
* gst/gstplugin.h:
* gst/gstpluginfeature.c:
* gst/gstpluginfeature.h:
* gst/gstregistry.c:
* gst/gstregistry.h:
* gst/gstregistrypool.c: remove
* gst/gstregistrypool.h: remove
* gst/gsttypefind.c:
* gst/gsttypefindfactory.c:
* gst/gsturi.c:
* tools/Makefile.am:
* tools/gst-compprep.c:
* tools/gst-inspect.c:
* tools/gst-register.c: remove
* tools/gst-xmlinspect.c:
Registry rewrite. Changes registry from being a file created
by a tool into a simple cache file created automatically by
libgstreamer. Removed gst-register (because it's no longer
needed). Remove registry pools, because we only have one
registry implementation (XML). Fix up other subsystems as
necessary.
2005-09-13 Michael Smith <msmith@fluendo.com> 2005-09-13 Michael Smith <msmith@fluendo.com>
* gst/gstconfig.h.in: * gst/gstconfig.h.in:

View file

@ -10,14 +10,10 @@ REGISTRY_ENVIRONMENT = \
TESTS_ENVIRONMENT = \ TESTS_ENVIRONMENT = \
$(REGISTRY_ENVIRONMENT) \ $(REGISTRY_ENVIRONMENT) \
GST_PLUGIN_PATH_ONLY=yes \ GST_PLUGIN_PATH_ONLY=yes \
GST_PLUGIN_PATH=$(top_builddir)/gst GST_PLUGIN_PATH=$(top_builddir)/gst/elements/.libs:$(top_builddir)/gst/indexers/.libs
plugindir = $(libdir)/gstreamer-@GST_MAJORMINOR@ plugindir = $(libdir)/gstreamer-@GST_MAJORMINOR@
# rebuild gst-register-@GST_MAJORMINOR@ if needed
$(top_builddir)/tools/gst-register-@GST_MAJORMINOR@$(EXEEXT):
cd $(top_builddir)/tools && make
# override to _not_ install the test plugins # override to _not_ install the test plugins
install-pluginLTLIBRARIES: install-pluginLTLIBRARIES:
@ -28,10 +24,6 @@ SUPPRESSIONS = $(top_srcdir)/common/gst.supp
clean-local: clean-local-check clean-local: clean-local-check
$(CHECK_REGISTRY):
$(TESTS_ENVIRONMENT) \
$(top_builddir)/tools/gst-register-@GST_MAJORMINOR@
check_PROGRAMS = \ check_PROGRAMS = \
gst/gst \ gst/gst \
gst/gstbin \ gst/gstbin \
@ -60,8 +52,7 @@ check_PROGRAMS = \
gst-libs/controller \ gst-libs/controller \
gst-libs/gdp gst-libs/gdp
TESTS = $(top_builddir)/tools/gst-register-@GST_MAJORMINOR@ \ TESTS = $(check_PROGRAMS)
$(check_PROGRAMS)
noinst_HEADERS = gst/capslist.h noinst_HEADERS = gst/capslist.h
@ -94,6 +85,5 @@ TESTS_THREADED = \
gst/gstobject gst/gstobject
VALGRIND_TESTS_DISABLE = \ VALGRIND_TESTS_DISABLE = \
$(top_builddir)/tools/gst-register-@GST_MAJORMINOR@ \
$(TESTS_THREADED) \ $(TESTS_THREADED) \
$(TESTS_TO_FIX) $(TESTS_TO_FIX)

View file

@ -29,7 +29,8 @@ GST_START_TEST (test_state_changes)
GstElement *element; GstElement *element;
GList *features, *f; GList *features, *f;
features = gst_registry_pool_feature_list (GST_TYPE_ELEMENT_FACTORY); features = gst_registry_get_feature_list (gst_registry_get_default (),
GST_TYPE_ELEMENT_FACTORY);
for (f = features; f; f = f->next) { for (f = features; f; f = f->next) {
GstPluginFeature *feature = f->data; GstPluginFeature *feature = f->data;

View file

@ -28,16 +28,6 @@ else
GST_TRACE_SRC = gsttrace.c GST_TRACE_SRC = gsttrace.c
endif endif
if GST_DISABLE_REGISTRY
GST_REGISTRY_SRC =
SUBDIRS_REGISTRY =
GST_REGISTRY_LA =
else
GST_REGISTRY_SRC = gstregistry.c
SUBDIRS_REGISTRY = registries
GST_REGISTRY_LA = registries/libgstxmlregistry.la
endif
if GST_DISABLE_ENUMTYPES if GST_DISABLE_ENUMTYPES
GST_ENUMTYPES_SRC = GST_ENUMTYPES_SRC =
else else
@ -64,8 +54,8 @@ else
GST_URI_SRC = gsturi.c GST_URI_SRC = gsturi.c
endif endif
SUBDIRS = $(SUBDIRS_PARSE) $(SUBDIRS_REGISTRY) . base elements $(SUBDIRS_INDEX) $(SUBDIRS_CHECK) SUBDIRS = $(SUBDIRS_PARSE) . base elements $(SUBDIRS_INDEX) $(SUBDIRS_CHECK)
DIST_SUBDIRS = base elements parse registries indexers check DIST_SUBDIRS = base elements parse indexers check
# make variables for all generated source and header files to make the # make variables for all generated source and header files to make the
# distinction clear # distinction clear
@ -107,6 +97,8 @@ libgstreamer_@GST_MAJORMINOR@_la_SOURCES = \
gstquery.c \ gstquery.c \
gstqueryutils.c \ gstqueryutils.c \
gstqueue.c \ gstqueue.c \
gstregistry.c \
gstregistryxml.c \
gststructure.c \ gststructure.c \
gstsystemclock.c \ gstsystemclock.c \
gsttaglist.c \ gsttaglist.c \
@ -120,8 +112,6 @@ libgstreamer_@GST_MAJORMINOR@_la_SOURCES = \
gsturitype.c \ gsturitype.c \
gstutils.c \ gstutils.c \
gstvalue.c \ gstvalue.c \
$(GST_REGISTRY_SRC) \
gstregistrypool.c \
$(GST_PARSE_SRC) \ $(GST_PARSE_SRC) \
$(GSTARCH_SRCS) \ $(GSTARCH_SRCS) \
$(GST_LOADSAVE_SRC) $(GST_LOADSAVE_SRC)
@ -145,10 +135,11 @@ libgstreamer_@GST_MAJORMINOR@_la_CFLAGS = \
-DG_LOG_DOMAIN=g_log_domain_gstreamer \ -DG_LOG_DOMAIN=g_log_domain_gstreamer \
-DGST_MAJORMINOR=\""$(GST_MAJORMINOR)"\" -DGST_MAJORMINOR=\""$(GST_MAJORMINOR)"\"
libgstreamer_@GST_MAJORMINOR@_la_LIBADD = \ libgstreamer_@GST_MAJORMINOR@_la_LIBADD = \
$(GST_LIB_LIBS) $(GST_PARSE_LA) $(GST_REGISTRY_LA) $(GST_LIB_LIBS) $(GST_PARSE_LA)
libgstreamer_@GST_MAJORMINOR@_la_LDFLAGS = \ libgstreamer_@GST_MAJORMINOR@_la_LDFLAGS = \
@GST_LT_LDFLAGS@ -version-info @GST_LIBVERSION@ \ @GST_LT_LDFLAGS@ -version-info @GST_LIBVERSION@ \
-export-symbols-regex [_]*\(gst_\|Gst\|GST_\).* -export-symbols-regex [_]*\(gst_\|Gst\|GST_\).* \
-no-undefined
libgstreamer_@GST_MAJORMINOR@includedir = $(includedir)/gstreamer-@GST_MAJORMINOR@/gst libgstreamer_@GST_MAJORMINOR@includedir = $(includedir)/gstreamer-@GST_MAJORMINOR@/gst
@ -198,7 +189,6 @@ gst_headers = \
gstutils.h \ gstutils.h \
gstvalue.h \ gstvalue.h \
gstregistry.h \ gstregistry.h \
gstregistrypool.h \
gstparse.h \ gstparse.h \
gstxml.h gstxml.h

173
gst/gst.c
View file

@ -102,10 +102,6 @@
#include "gst.h" #include "gst.h"
#include "gstqueue.h" #include "gstqueue.h"
#ifndef GST_DISABLE_REGISTRY
#include "registries/gstxmlregistry.h"
#endif /* GST_DISABLE_REGISTRY */
#include "gstregistrypool.h"
#define GST_CAT_DEFAULT GST_CAT_GST_INIT #define GST_CAT_DEFAULT GST_CAT_GST_INIT
@ -114,9 +110,6 @@
#ifndef GST_DISABLE_REGISTRY #ifndef GST_DISABLE_REGISTRY
gboolean _gst_registry_auto_load = TRUE; gboolean _gst_registry_auto_load = TRUE;
static GstRegistry *_global_registry;
static GstRegistry *_user_registry;
static gboolean _gst_registry_fixed = FALSE;
#endif #endif
static gboolean gst_initialized = FALSE; static gboolean gst_initialized = FALSE;
@ -165,8 +158,7 @@ enum
ARG_PLUGIN_SPEW, ARG_PLUGIN_SPEW,
ARG_PLUGIN_PATH, ARG_PLUGIN_PATH,
ARG_PLUGIN_LOAD, ARG_PLUGIN_LOAD,
ARG_SEGTRAP_DISABLE, ARG_SEGTRAP_DISABLE
ARG_REGISTRY
}; };
/* debug-spec ::= category-spec [, category-spec]* /* debug-spec ::= category-spec [, category-spec]*
@ -308,8 +300,6 @@ gst_init_get_popt_table (void)
ARG_SEGTRAP_DISABLE, ARG_SEGTRAP_DISABLE,
N_("Disable trapping of segmentation faults during plugin loading"), N_("Disable trapping of segmentation faults during plugin loading"),
NULL}, NULL},
{"gst-registry", NUL, POPT_ARG_STRING | POPT_ARGFLAG_STRIP, NULL,
ARG_REGISTRY, N_("Registry to use"), N_("REGISTRY")},
POPT_TABLEEND POPT_TABLEEND
}; };
static gboolean inited = FALSE; static gboolean inited = FALSE;
@ -501,9 +491,8 @@ gst_init_check_with_popt_table (int *argc, char **argv[],
static void static void
add_path_func (gpointer data, gpointer user_data) add_path_func (gpointer data, gpointer user_data)
{ {
GstRegistry *registry = GST_REGISTRY (user_data); GST_INFO ("Adding plugin path: \"%s\"", (gchar *) data);
gst_registry_scan_path (gst_registry_get_default (), (gchar *) data);
gst_registry_add_path (registry, (gchar *) data);
} }
#endif #endif
@ -527,7 +516,7 @@ load_plugin_func (gpointer data, gpointer user_data)
if (plugin) { if (plugin) {
GST_INFO ("Loaded plugin: \"%s\"", filename); GST_INFO ("Loaded plugin: \"%s\"", filename);
gst_registry_pool_add_plugin (plugin); gst_default_registry_add_plugin (plugin);
} else { } else {
if (err) { if (err) {
/* Report error to user, and free error */ /* Report error to user, and free error */
@ -571,8 +560,6 @@ split_and_iterate (const gchar * stringlist, gchar * separator, GFunc iterator,
static gboolean static gboolean
init_pre (void) init_pre (void)
{ {
const gchar *plugin_path;
g_type_init (); g_type_init ();
if (g_thread_supported ()) { if (g_thread_supported ()) {
@ -606,50 +593,6 @@ init_pre (void)
GST_INFO ("Initializing GStreamer Core Library version %s", VERSION); GST_INFO ("Initializing GStreamer Core Library version %s", VERSION);
GST_INFO ("Using library from %s", LIBDIR); GST_INFO ("Using library from %s", LIBDIR);
#ifndef GST_DISABLE_REGISTRY
{
gchar *user_reg;
const gchar *homedir;
_global_registry =
gst_xml_registry_new ("global_registry", GLOBAL_REGISTRY_FILE);
#ifdef PLUGINS_USE_BUILDDIR
/* location libgstelements.so */
gst_registry_add_path (_global_registry, PLUGINS_BUILDDIR "/libs/gst");
gst_registry_add_path (_global_registry, PLUGINS_BUILDDIR "/gst/elements");
gst_registry_add_path (_global_registry, PLUGINS_BUILDDIR "/gst/types");
gst_registry_add_path (_global_registry, PLUGINS_BUILDDIR "/gst/autoplug");
gst_registry_add_path (_global_registry, PLUGINS_BUILDDIR "/gst/indexers");
#endif /* PLUGINS_USE_BUILDDIR */
plugin_path = g_getenv ("GST_PLUGIN_PATH");
#ifndef GST_DISABLE_REGISTRY
split_and_iterate (plugin_path, G_SEARCHPATH_SEPARATOR_S, add_path_func,
_global_registry);
#endif /* GST_DISABLE_REGISTRY */
#ifndef PLUGINS_USE_BUILDDIR
/* add the main (installed) library path as the last path
* if GST_PLUGIN_PATH_ONLY not set */
if (g_getenv ("GST_PLUGIN_PATH_ONLY") == NULL) {
gst_registry_add_path (_global_registry, PLUGINS_DIR);
}
#endif
if (g_getenv ("GST_REGISTRY")) {
user_reg = g_strdup (g_getenv ("GST_REGISTRY"));
} else {
homedir = g_get_home_dir ();
user_reg = g_strjoin ("/", homedir, LOCAL_REGISTRY_FILE, NULL);
}
_user_registry = gst_xml_registry_new ("user_registry", user_reg);
g_free (user_reg);
}
#endif /* GST_DISABLE_REGISTRY */
return TRUE; return TRUE;
} }
@ -674,7 +617,6 @@ static GstPluginDesc plugin_desc = {
"gstcoreelements", "gstcoreelements",
"core elements of the GStreamer library", "core elements of the GStreamer library",
gst_register_core_elements, gst_register_core_elements,
NULL,
VERSION, VERSION,
GST_LICENSE, GST_LICENSE,
PACKAGE, PACKAGE,
@ -736,25 +678,66 @@ init_post (void)
_gst_tag_initialize (); _gst_tag_initialize ();
#ifndef GST_DISABLE_REGISTRY #ifndef GST_DISABLE_REGISTRY
if (!_gst_registry_fixed) { {
/* don't override command-line options */ char *registry_file;
if (g_getenv ("GST_REGISTRY")) { const char *plugin_path;
g_object_set (_global_registry, "location", g_getenv ("GST_REGISTRY"), GstRegistry *default_registry;
NULL);
_gst_registry_fixed = TRUE;
}
}
if (!_gst_registry_fixed) { default_registry = gst_registry_get_default ();
gst_registry_pool_add (_global_registry, 100); registry_file = g_strdup (g_getenv ("GST_REGISTRY"));
gst_registry_pool_add (_user_registry, 50); if (registry_file == NULL) {
registry_file = g_build_filename (g_get_home_dir (),
".gstreamer-0.9", "registry.xml", NULL);
}
gst_registry_xml_read_cache (default_registry, registry_file);
plugin_path = g_getenv ("GST_PLUGIN_SYSTEM_PATH");
if (plugin_path == NULL) {
#ifdef PLUGINS_USE_BUILDDIR
/* location libgstelements.so */
gst_registry_scan_path (default_registry,
PLUGINS_BUILDDIR "/gst/elements/.libs");
gst_registry_scan_path (default_registry,
PLUGINS_BUILDDIR "/gst/indexers/.libs");
#else
char *home_plugins;
/* add the main (installed) library path */
gst_registry_scan_path (default_registry, PLUGINS_DIR);
home_plugins = g_build_filename (g_get_home_dir (),
".gstreamer-0.9", "plugins", NULL);
gst_registry_scan_path (default_registry, home_plugins);
g_free (home_plugins);
#endif /* PLUGINS_USE_BUILDDIR */
} else { } else {
char **list;
int i;
gst_registry_pool_add (_global_registry, 100); /* FIXME this doesn't split paths correctly on windows */
list = g_strsplit (plugin_path, ":", 0);
for (i = 0; list[i]; i++) {
gst_registry_scan_path (default_registry, list[i]);
}
} }
if (_gst_registry_auto_load) { plugin_path = g_getenv ("GST_PLUGIN_PATH");
gst_registry_pool_load_all (); if (plugin_path) {
char **list;
int i;
/* FIXME this doesn't split paths correctly on windows */
list = g_strsplit (plugin_path, ":", 0);
for (i = 0; list[i]; i++) {
gst_registry_scan_path (default_registry, list[i]);
}
}
gst_registry_xml_write_cache (default_registry, registry_file);
_gst_registry_remove_cache_plugins (default_registry);
g_free (registry_file);
} }
#endif /* GST_DISABLE_REGISTRY */ #endif /* GST_DISABLE_REGISTRY */
@ -776,6 +759,12 @@ init_post (void)
} }
#ifndef GST_DISABLE_GST_DEBUG #ifndef GST_DISABLE_GST_DEBUG
static gboolean
select_all (GstPlugin * plugin, gpointer user_data)
{
return TRUE;
}
static gint static gint
sort_by_category_name (gconstpointer a, gconstpointer b) sort_by_category_name (gconstpointer a, gconstpointer b)
{ {
@ -786,29 +775,19 @@ static void
gst_debug_help (void) gst_debug_help (void)
{ {
GSList *list, *walk; GSList *list, *walk;
GList *list2, *walk2; GList *list2, *g;
if (!init_post ()) if (!init_post ())
exit (1); exit (1);
walk2 = list2 = gst_registry_pool_plugin_list (); list2 = gst_registry_plugin_filter (gst_registry_get_default (),
while (walk2) { select_all, FALSE, NULL);
GstPlugin *plugin = GST_PLUGIN (walk2->data);
walk2 = g_list_next (walk2); /* FIXME this is gross. why don't debug have categories PluginFeatures? */
for (g = list2; g; g = g_list_next (g)) {
GstPlugin *plugin = GST_PLUGIN (g->data);
if (!gst_plugin_is_loaded (plugin)) { gst_plugin_load (plugin);
#ifndef GST_DISABLE_REGISTRY
if (GST_IS_REGISTRY (plugin->manager)) {
GST_CAT_LOG (GST_CAT_PLUGIN_LOADING, "loading plugin %s",
plugin->desc.name);
if (gst_registry_load_plugin (GST_REGISTRY (plugin->manager),
plugin) != GST_REGISTRY_OK)
GST_CAT_WARNING (GST_CAT_PLUGIN_LOADING, "loading plugin %s failed",
plugin->desc.name);
}
#endif /* GST_DISABLE_REGISTRY */
}
} }
g_list_free (list2); g_list_free (list2);
@ -896,7 +875,7 @@ init_popt_callback (poptContext context, enum poptCallbackReason reason,
case ARG_PLUGIN_PATH: case ARG_PLUGIN_PATH:
#ifndef GST_DISABLE_REGISTRY #ifndef GST_DISABLE_REGISTRY
split_and_iterate (arg, G_SEARCHPATH_SEPARATOR_S, add_path_func, split_and_iterate (arg, G_SEARCHPATH_SEPARATOR_S, add_path_func,
_user_registry); NULL);
#endif /* GST_DISABLE_REGISTRY */ #endif /* GST_DISABLE_REGISTRY */
break; break;
case ARG_PLUGIN_LOAD: case ARG_PLUGIN_LOAD:
@ -905,12 +884,6 @@ init_popt_callback (poptContext context, enum poptCallbackReason reason,
case ARG_SEGTRAP_DISABLE: case ARG_SEGTRAP_DISABLE:
_gst_disable_segtrap = TRUE; _gst_disable_segtrap = TRUE;
break; break;
case ARG_REGISTRY:
#ifndef GST_DISABLE_REGISTRY
g_object_set (G_OBJECT (_user_registry), "location", arg, NULL);
_gst_registry_fixed = TRUE;
#endif /* GST_DISABLE_REGISTRY */
break;
default: default:
g_warning ("option %d not recognized", option->val); g_warning ("option %d not recognized", option->val);
break; break;

View file

@ -67,7 +67,6 @@
#include <gst/gstparse.h> #include <gst/gstparse.h>
#include <gst/gstregistry.h> #include <gst/gstregistry.h>
#include <gst/gstregistrypool.h>
/* API compatibility stuff */ /* API compatibility stuff */
#include <gst/gstcompat.h> #include <gst/gstcompat.h>

View file

@ -71,6 +71,7 @@ extern GstDebugCategory *GST_CAT_PARAMS;
extern GstDebugCategory *GST_CAT_CALL_TRACE; extern GstDebugCategory *GST_CAT_CALL_TRACE;
extern GstDebugCategory *GST_CAT_SIGNAL; extern GstDebugCategory *GST_CAT_SIGNAL;
extern GstDebugCategory *GST_CAT_PROBE; extern GstDebugCategory *GST_CAT_PROBE;
extern GstDebugCategory *GST_CAT_REGISTRY;
#else #else
@ -101,6 +102,7 @@ extern GstDebugCategory *GST_CAT_PROBE;
#define GST_CAT_CALL_TRACE NULL #define GST_CAT_CALL_TRACE NULL
#define GST_CAT_SIGNAL NULL #define GST_CAT_SIGNAL NULL
#define GST_CAT_PROBE NULL #define GST_CAT_PROBE NULL
#define GST_CAT_REGISTRY NULL
#endif #endif

View file

@ -67,12 +67,9 @@
#include "gst_private.h" #include "gst_private.h"
#include "gstelement.h" #include "gstelement.h"
#include "gstregistrypool.h"
#include "gstinfo.h" #include "gstinfo.h"
#include "gsturi.h" #include "gsturi.h"
#ifndef GST_DISABLE_REGISTRY #include "gstregistry.h"
#include "registries/gstxmlregistry.h" /* g_critical in gst_element_factory_create */
#endif
GST_DEBUG_CATEGORY_STATIC (element_factory_debug); GST_DEBUG_CATEGORY_STATIC (element_factory_debug);
#define GST_CAT_DEFAULT element_factory_debug #define GST_CAT_DEFAULT element_factory_debug
@ -80,8 +77,6 @@ GST_DEBUG_CATEGORY_STATIC (element_factory_debug);
static void gst_element_factory_class_init (GstElementFactoryClass * klass); static void gst_element_factory_class_init (GstElementFactoryClass * klass);
static void gst_element_factory_init (GstElementFactory * factory); static void gst_element_factory_init (GstElementFactory * factory);
static void gst_element_factory_unload_thyself (GstPluginFeature * feature);
static GstPluginFeatureClass *parent_class = NULL; static GstPluginFeatureClass *parent_class = NULL;
/* static guint gst_element_factory_signals[LAST_SIGNAL] = { 0 }; */ /* static guint gst_element_factory_signals[LAST_SIGNAL] = { 0 }; */
@ -126,8 +121,6 @@ gst_element_factory_class_init (GstElementFactoryClass * klass)
parent_class = g_type_class_peek_parent (klass); parent_class = g_type_class_peek_parent (klass);
gstpluginfeature_class->unload_thyself =
GST_DEBUG_FUNCPTR (gst_element_factory_unload_thyself);
} }
static void static void
gst_element_factory_init (GstElementFactory * factory) gst_element_factory_init (GstElementFactory * factory)
@ -156,7 +149,8 @@ gst_element_factory_find (const gchar * name)
g_return_val_if_fail (name != NULL, NULL); g_return_val_if_fail (name != NULL, NULL);
feature = gst_registry_pool_find_feature (name, GST_TYPE_ELEMENT_FACTORY); feature = gst_registry_find_feature (gst_registry_get_default (), name,
GST_TYPE_ELEMENT_FACTORY);
if (feature) if (feature)
return GST_ELEMENT_FACTORY (feature); return GST_ELEMENT_FACTORY (feature);
@ -265,21 +259,11 @@ gst_element_register (GstPlugin * plugin, const gchar * name, guint rank,
g_return_val_if_fail (name != NULL, FALSE); g_return_val_if_fail (name != NULL, FALSE);
g_return_val_if_fail (g_type_is_a (type, GST_TYPE_ELEMENT), FALSE); g_return_val_if_fail (g_type_is_a (type, GST_TYPE_ELEMENT), FALSE);
factory = gst_element_factory_find (name); factory = GST_ELEMENT_FACTORY (g_object_new (GST_TYPE_ELEMENT_FACTORY, NULL));
if (!factory) {
factory =
GST_ELEMENT_FACTORY (g_object_new (GST_TYPE_ELEMENT_FACTORY, NULL));
gst_plugin_feature_set_name (GST_PLUGIN_FEATURE (factory), name); gst_plugin_feature_set_name (GST_PLUGIN_FEATURE (factory), name);
GST_LOG_OBJECT (factory, "Created new elementfactory for type %s", GST_LOG_OBJECT (factory, "Created new elementfactory for type %s",
g_type_name (type)); g_type_name (type));
gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory)); gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
} else {
g_return_val_if_fail (factory->type == 0, FALSE);
gst_element_factory_cleanup (factory);
GST_LOG_OBJECT (factory, "Reuse existing elementfactory for type %s",
g_type_name (type));
}
klass = GST_ELEMENT_CLASS (g_type_class_ref (type)); klass = GST_ELEMENT_CLASS (g_type_class_ref (type));
factory->type = type; factory->type = type;
@ -348,8 +332,10 @@ gst_element_factory_create (GstElementFactory * factory, const gchar * name)
g_return_val_if_fail (factory != NULL, NULL); g_return_val_if_fail (factory != NULL, NULL);
if (!gst_plugin_feature_ensure_loaded (GST_PLUGIN_FEATURE (factory))) { factory =
GST_INFO ("could not load element factory for element \"%s\"", name); GST_ELEMENT_FACTORY (gst_plugin_feature_load (GST_PLUGIN_FEATURE
(factory)));
if (factory == NULL) {
return NULL; return NULL;
} }
@ -360,19 +346,8 @@ gst_element_factory_create (GstElementFactory * factory, const gchar * name)
GST_INFO ("creating \"%s\"", GST_PLUGIN_FEATURE_NAME (factory)); GST_INFO ("creating \"%s\"", GST_PLUGIN_FEATURE_NAME (factory));
if (factory->type == 0) { if (factory->type == 0) {
#ifndef GST_DISABLE_REGISTRY g_critical ("Plugin didn't set object type in feature.");
GstPlugin *plugin = GST_PLUGIN_FEATURE (factory)->manager;
g_critical
("Factory for `%s' has no type. This probably means the plugin wasn't found because the registry is broken. The plugin GStreamer was looking for is named '%s' and is expected in file '%s'. The registry for this plugin is located at '%s'",
GST_PLUGIN_FEATURE_NAME (factory),
gst_plugin_get_name (plugin), gst_plugin_get_filename (plugin),
GST_IS_XML_REGISTRY (plugin->manager) ? GST_XML_REGISTRY (plugin->
manager)->location : "Unknown");
#else
g_critical ("Factory for `%s' has no type",
GST_PLUGIN_FEATURE_NAME (factory));
#endif
return NULL; return NULL;
} }
@ -608,16 +583,3 @@ gst_element_factory_get_uri_protocols (GstElementFactory * factory)
return factory->uri_protocols; return factory->uri_protocols;
} }
static void
gst_element_factory_unload_thyself (GstPluginFeature * feature)
{
GstElementFactory *factory;
factory = GST_ELEMENT_FACTORY (feature);
if (factory->type) {
g_type_class_unref (g_type_class_peek (factory->type));
factory->type = 0;
}
}

View file

@ -23,9 +23,9 @@
#include "gst_private.h" #include "gst_private.h"
#include "gstinfo.h" #include "gstinfo.h"
#include "gstregistrypool.h"
#include "gstindex.h" #include "gstindex.h"
#include "gstmarshal.h" #include "gstmarshal.h"
#include "gstregistry.h"
/* for constructing an entry name */ /* for constructing an entry name */
#include "gstelement.h" #include "gstelement.h"
#include "gstpad.h" #include "gstpad.h"
@ -959,7 +959,8 @@ gst_index_factory_find (const gchar * name)
GST_DEBUG ("gstindex: find \"%s\"", name); GST_DEBUG ("gstindex: find \"%s\"", name);
feature = gst_registry_pool_find_feature (name, GST_TYPE_INDEX_FACTORY); feature = gst_registry_find_feature (gst_registry_get_default (), name,
GST_TYPE_INDEX_FACTORY);
if (feature) if (feature)
return GST_INDEX_FACTORY (feature); return GST_INDEX_FACTORY (feature);
@ -982,11 +983,13 @@ gst_index_factory_create (GstIndexFactory * factory)
g_return_val_if_fail (factory != NULL, NULL); g_return_val_if_fail (factory != NULL, NULL);
if (gst_plugin_feature_ensure_loaded (GST_PLUGIN_FEATURE (factory))) { factory =
g_return_val_if_fail (factory->type != 0, NULL); GST_INDEX_FACTORY (gst_plugin_feature_load (GST_PLUGIN_FEATURE
(factory)));
if (factory == NULL)
return NULL;
new = GST_INDEX (g_object_new (factory->type, NULL)); new = GST_INDEX (g_object_new (factory->type, NULL));
}
return new; return new;
} }

View file

@ -153,6 +153,7 @@ GstDebugCategory *GST_CAT_PARAMS = NULL;
GstDebugCategory *GST_CAT_CALL_TRACE = NULL; GstDebugCategory *GST_CAT_CALL_TRACE = NULL;
GstDebugCategory *GST_CAT_SIGNAL = NULL; GstDebugCategory *GST_CAT_SIGNAL = NULL;
GstDebugCategory *GST_CAT_PROBE = NULL; GstDebugCategory *GST_CAT_PROBE = NULL;
GstDebugCategory *GST_CAT_REGISTRY = NULL;
/* FIXME: export this? */ /* FIXME: export this? */
gboolean gboolean
@ -276,6 +277,7 @@ _gst_debug_init (void)
GST_DEBUG_BOLD | GST_DEBUG_FG_WHITE | GST_DEBUG_BG_RED, NULL); GST_DEBUG_BOLD | GST_DEBUG_FG_WHITE | GST_DEBUG_BG_RED, NULL);
GST_CAT_PROBE = _gst_debug_category_new ("GST_PROBE", GST_CAT_PROBE = _gst_debug_category_new ("GST_PROBE",
GST_DEBUG_BOLD | GST_DEBUG_FG_GREEN, "pad probes"); GST_DEBUG_BOLD | GST_DEBUG_FG_GREEN, "pad probes");
GST_CAT_REGISTRY = _gst_debug_category_new ("GST_REGISTRY", 0, "registry");
/* print out the valgrind message if we're in valgrind */ /* print out the valgrind message if we're in valgrind */

View file

@ -38,9 +38,9 @@
#include "gstplugin.h" #include "gstplugin.h"
#include "gstversion.h" #include "gstversion.h"
#include "gstregistrypool.h"
#include "gstinfo.h" #include "gstinfo.h"
#include "gstfilter.h" #include "gstfilter.h"
#include "gstregistry.h"
#define GST_CAT_DEFAULT GST_CAT_PLUGIN_LOADING #define GST_CAT_DEFAULT GST_CAT_PLUGIN_LOADING
@ -74,31 +74,27 @@ static gchar *valid_licenses[] = {
NULL NULL
}; };
static void gst_plugin_desc_copy (GstPluginDesc * dest,
const GstPluginDesc * src);
static GstPlugin *gst_plugin_register_func (GstPlugin * plugin, static GstPlugin *gst_plugin_register_func (GstPlugin * plugin,
GModule * module, GstPluginDesc * desc); GModule * module, GstPluginDesc * desc);
static void
gst_plugin_desc_copy (GstPluginDesc * dest, const GstPluginDesc * src);
static GstPlugin *
gst_plugin_copy (GstPlugin * plugin) G_DEFINE_TYPE (GstPlugin, gst_plugin, G_TYPE_OBJECT);
static void
gst_plugin_init (GstPlugin * plugin)
{ {
return g_memdup (plugin, sizeof (*plugin));
} }
GType static void
gst_plugin_get_type (void) gst_plugin_class_init (GstPluginClass * klass)
{ {
static GType plugin_type;
if (plugin_type == 0) {
plugin_type = g_boxed_type_register_static ("GstPlugin",
(GBoxedCopyFunc) gst_plugin_copy, g_free);
}
return plugin_type;
} }
GQuark GQuark
gst_plugin_error_quark (void) gst_plugin_error_quark (void)
{ {
@ -128,11 +124,11 @@ _gst_plugin_register_static (GstPluginDesc * desc)
if (GST_CAT_DEFAULT) if (GST_CAT_DEFAULT)
GST_LOG ("attempting to load static plugin \"%s\" now...", desc->name); GST_LOG ("attempting to load static plugin \"%s\" now...", desc->name);
plugin = g_new0 (GstPlugin, 1); plugin = g_object_new (GST_TYPE_PLUGIN, NULL);
if (gst_plugin_register_func (plugin, main_module, desc)) { if (gst_plugin_register_func (plugin, main_module, desc)) {
if (GST_CAT_DEFAULT) if (GST_CAT_DEFAULT)
GST_INFO ("loaded static plugin \"%s\"", desc->name); GST_INFO ("loaded static plugin \"%s\"", desc->name);
gst_registry_pool_add_plugin (plugin); gst_default_registry_add_plugin (plugin);
} }
} }
} }
@ -181,8 +177,6 @@ static GstPlugin *
gst_plugin_register_func (GstPlugin * plugin, GModule * module, gst_plugin_register_func (GstPlugin * plugin, GModule * module,
GstPluginDesc * desc) GstPluginDesc * desc)
{ {
g_assert (plugin->module == NULL);
if (!gst_plugin_check_version (desc->major_version, desc->minor_version)) { if (!gst_plugin_check_version (desc->major_version, desc->minor_version)) {
if (GST_CAT_DEFAULT) if (GST_CAT_DEFAULT)
GST_INFO ("plugin \"%s\" has incompatible version, not loading", GST_INFO ("plugin \"%s\" has incompatible version, not loading",
@ -209,7 +203,6 @@ gst_plugin_register_func (GstPlugin * plugin, GModule * module,
GST_LOG ("plugin \"%s\" looks good", GST_STR_NULL (plugin->filename)); GST_LOG ("plugin \"%s\" looks good", GST_STR_NULL (plugin->filename));
gst_plugin_desc_copy (&plugin->desc, desc); gst_plugin_desc_copy (&plugin->desc, desc);
plugin->module = module;
if (!((desc->plugin_init) (plugin))) { if (!((desc->plugin_init) (plugin))) {
if (GST_CAT_DEFAULT) if (GST_CAT_DEFAULT)
@ -301,94 +294,6 @@ _gst_plugin_fault_handler_setup (void)
static void _gst_plugin_fault_handler_setup (); static void _gst_plugin_fault_handler_setup ();
/**
* gst_plugin_check_module:
* @module: GModule handle to check for pluginness
* @error: pointer to a NULL-valued GError
* @pptr: pointer to a gpointer used to return the gst_plugin_desc symbol
* (can be NULL)
*
* Checks if the given module is a GStreamer plugin
*
* Returns: TRUE if the given module is a GStreamer plugin
*/
static gboolean
gst_plugin_check_module (GModule * module, const char *filename,
GError ** error, gpointer * pptr)
{
gpointer ptr;
if (pptr == NULL)
pptr = &ptr;
if (module == NULL) {
GST_DEBUG ("Error loading plugin %s, reason: %s", filename,
g_module_error ());
g_set_error (error, GST_PLUGIN_ERROR, GST_PLUGIN_ERROR_MODULE,
"Error loading plugin %s, reason: %s", filename, g_module_error ());
return FALSE;
}
if (!g_module_symbol (module, "gst_plugin_desc", pptr)) {
GST_DEBUG ("Could not find plugin entry point in \"%s\"", filename);
g_set_error (error,
GST_PLUGIN_ERROR,
GST_PLUGIN_ERROR_MODULE,
"Could not find plugin entry point in \"%s\"", filename);
return FALSE;
}
return TRUE;
}
/**
* gst_plugin_check_file:
* @filename: the plugin filename to check for pluginness
* @error: pointer to a NULL-valued GError
*
* Checks if the given path represents a GStreamer plugin.
*
* Returns: TRUE if the given path is a GStreamer plugin.
*/
gboolean
gst_plugin_check_file (const gchar * filename, GError ** error)
{
GModule *module;
struct stat file_status;
gboolean check;
g_return_val_if_fail (filename != NULL, FALSE);
if (g_module_supported () == FALSE) {
g_set_error (error,
GST_PLUGIN_ERROR,
GST_PLUGIN_ERROR_MODULE, "Dynamic loading not supported");
return FALSE;
}
if (stat (filename, &file_status)) {
g_set_error (error,
GST_PLUGIN_ERROR,
GST_PLUGIN_ERROR_MODULE, "Problem accessing file %s: %s\n", filename,
strerror (errno));
return FALSE;
}
module = g_module_open (filename, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
if (!module) {
check = FALSE;
goto beach;
}
check = gst_plugin_check_module (module, filename, error, NULL);
g_module_close (module);
beach:
GST_INFO ("file \"%s\" %s look like a gst plugin", filename,
check ? "does" : "doesn't");
return check;
}
/** /**
* gst_plugin_load_file: * gst_plugin_load_file:
* @filename: the plugin filename to load * @filename: the plugin filename to load
@ -403,66 +308,68 @@ gst_plugin_load_file (const gchar * filename, GError ** error)
{ {
GstPlugin *plugin; GstPlugin *plugin;
GModule *module; GModule *module;
GstPluginDesc *desc; gboolean ret;
gboolean free_plugin;
gpointer ptr; gpointer ptr;
struct stat file_status;
g_return_val_if_fail (filename != NULL, NULL); g_return_val_if_fail (filename != NULL, NULL);
plugin = gst_registry_lookup (gst_registry_get_default (), filename);
if (plugin && plugin->module) {
return plugin;
}
GST_CAT_DEBUG (GST_CAT_PLUGIN_LOADING, "attempt to load plugin \"%s\"", GST_CAT_DEBUG (GST_CAT_PLUGIN_LOADING, "attempt to load plugin \"%s\"",
filename); filename);
module = g_module_open (filename, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL); if (g_module_supported () == FALSE) {
GST_CAT_DEBUG (GST_CAT_PLUGIN_LOADING, "module loading not supported");
/* gst_plugin_check_module handles module == NULL case */ g_set_error (error,
if (!gst_plugin_check_module (module, filename, error, &ptr)) { GST_PLUGIN_ERROR,
if (module != NULL) GST_PLUGIN_ERROR_MODULE, "Dynamic loading not supported");
g_module_close (module);
return NULL; return NULL;
} }
desc = (GstPluginDesc *) ptr; if (stat (filename, &file_status)) {
GST_CAT_DEBUG (GST_CAT_PLUGIN_LOADING, "problem accessing file");
plugin = gst_registry_pool_find_plugin (desc->name); g_set_error (error,
if (!plugin) { GST_PLUGIN_ERROR,
free_plugin = TRUE; GST_PLUGIN_ERROR_MODULE, "Problem accessing file %s: %s\n", filename,
plugin = g_new0 (GstPlugin, 1); strerror (errno));
plugin->filename = g_strdup (filename);
GST_DEBUG ("created new GstPlugin %p for file \"%s\"", plugin, filename);
} else {
free_plugin = FALSE;
if (gst_plugin_is_loaded (plugin)) {
g_module_close (module);
if (plugin->filename && strcmp (plugin->filename, filename) != 0) {
GST_WARNING
("plugin %p from file \"%s\" with same name %s is already "
"loaded, aborting loading of \"%s\"", plugin, plugin->filename,
plugin->desc.name, filename);
g_set_error (error, GST_PLUGIN_ERROR,
GST_PLUGIN_ERROR_NAME_MISMATCH,
"plugin %p from file \"%s\" with same name %s is already "
"loaded, aborting loading of \"%s\"", plugin, plugin->filename,
plugin->desc.name, filename);
if (free_plugin)
g_free (plugin);
return NULL; return NULL;
} }
GST_LOG ("Plugin %p for file \"%s\" already loaded, returning it now",
plugin, filename); module = g_module_open (filename, G_MODULE_BIND_LOCAL);
return plugin; if (module == NULL) {
GST_CAT_ERROR (GST_CAT_PLUGIN_LOADING, "module_open failed: %s",
g_module_error ());
g_set_error (error,
GST_PLUGIN_ERROR, GST_PLUGIN_ERROR_MODULE, "Opening module failed");
return NULL;
} }
plugin = g_object_new (GST_TYPE_PLUGIN, NULL);
plugin->module = module;
plugin->filename = strdup (filename);
plugin->file_mtime = file_status.st_mtime;
plugin->file_size = file_status.st_size;
ret = g_module_symbol (module, "gst_plugin_desc", &ptr);
if (!ret) {
GST_DEBUG ("Could not find plugin entry point in \"%s\"", filename);
g_set_error (error,
GST_PLUGIN_ERROR,
GST_PLUGIN_ERROR_MODULE,
"Could not find plugin entry point in \"%s\"", filename);
g_object_unref (plugin);
return NULL;
} }
plugin->orig_desc = (GstPluginDesc *) ptr;
GST_LOG ("Plugin %p for file \"%s\" prepared, calling entry function...", GST_LOG ("Plugin %p for file \"%s\" prepared, calling entry function...",
plugin, filename); plugin, filename);
if (g_module_symbol (module, "plugin_init", &ptr)) {
GST_WARNING
("plugin %p from file \"%s\" exports a symbol named plugin_init\n",
plugin, plugin->filename);
g_set_error (error, GST_PLUGIN_ERROR, GST_PLUGIN_ERROR_NAME_MISMATCH,
"plugin \"%s\" exports a symbol named plugin_init", desc->name);
}
/* this is where we load the actual .so, so let's trap SIGSEGV */ /* this is where we load the actual .so, so let's trap SIGSEGV */
_gst_plugin_fault_handler_setup (); _gst_plugin_fault_handler_setup ();
_gst_plugin_fault_handler_filename = plugin->filename; _gst_plugin_fault_handler_filename = plugin->filename;
@ -470,13 +377,7 @@ gst_plugin_load_file (const gchar * filename, GError ** error)
GST_LOG ("Plugin %p for file \"%s\" prepared, registering...", GST_LOG ("Plugin %p for file \"%s\" prepared, registering...",
plugin, filename); plugin, filename);
if (gst_plugin_register_func (plugin, module, desc)) { if (!gst_plugin_register_func (plugin, module, plugin->orig_desc)) {
/* remove signal handler */
_gst_plugin_fault_handler_restore ();
_gst_plugin_fault_handler_filename = NULL;
GST_INFO ("plugin \"%s\" loaded", plugin->filename);
return plugin;
} else {
/* remove signal handler */ /* remove signal handler */
_gst_plugin_fault_handler_restore (); _gst_plugin_fault_handler_restore ();
GST_DEBUG ("gst_plugin_register_func failed for plugin \"%s\"", filename); GST_DEBUG ("gst_plugin_register_func failed for plugin \"%s\"", filename);
@ -486,10 +387,17 @@ gst_plugin_load_file (const gchar * filename, GError ** error)
GST_PLUGIN_ERROR_MODULE, GST_PLUGIN_ERROR_MODULE,
"gst_plugin_register_func failed for plugin \"%s\"", filename); "gst_plugin_register_func failed for plugin \"%s\"", filename);
g_module_close (module); g_module_close (module);
if (free_plugin)
g_free (plugin);
return NULL; return NULL;
} }
/* remove signal handler */
_gst_plugin_fault_handler_restore ();
_gst_plugin_fault_handler_filename = NULL;
GST_INFO ("plugin \"%s\" loaded", plugin->filename);
gst_default_registry_add_plugin (plugin);
return plugin;
} }
static void static void
@ -502,7 +410,6 @@ gst_plugin_desc_copy (GstPluginDesc * dest, const GstPluginDesc * src)
g_free (dest->description); g_free (dest->description);
dest->description = g_strdup (src->description); dest->description = g_strdup (src->description);
dest->plugin_init = src->plugin_init; dest->plugin_init = src->plugin_init;
dest->plugin_exit = src->plugin_exit;
g_free (dest->version); g_free (dest->version);
dest->version = g_strdup (src->version); dest->version = g_strdup (src->version);
g_free (dest->license); g_free (dest->license);
@ -843,6 +750,42 @@ gst_plugin_find_feature (GstPlugin * plugin, const gchar * name, GType type)
if (walk) if (walk)
result = GST_PLUGIN_FEATURE (walk->data); result = GST_PLUGIN_FEATURE (walk->data);
g_list_free (walk);
return result;
}
static gboolean
gst_plugin_feature_name_filter (GstPluginFeature * feature, const gchar * name)
{
return !strcmp (name, GST_PLUGIN_FEATURE_NAME (feature));
}
/**
* gst_plugin_find_feature_by_name:
* @plugin: plugin to get the feature from
* @name: The name of the feature to find
*
* Find a feature of the given name in the given plugin.
*
* Returns: a GstPluginFeature or NULL if the feature was not found.
*/
GstPluginFeature *
gst_plugin_find_feature_by_name (GstPlugin * plugin, const gchar * name)
{
GList *walk;
GstPluginFeature *result = NULL;
g_return_val_if_fail (name != NULL, NULL);
walk = gst_filter_run (plugin->features,
(GstFilterFunc) gst_plugin_feature_name_filter, TRUE, (void *) name);
if (walk)
result = GST_PLUGIN_FEATURE (walk->data);
g_list_free (walk);
return result; return result;
} }
@ -879,7 +822,7 @@ gst_plugin_add_feature (GstPlugin * plugin, GstPluginFeature * feature)
GST_PLUGIN_FEATURE_NAME (feature)); GST_PLUGIN_FEATURE_NAME (feature));
/* g_object_unref (feature); */ /* g_object_unref (feature); */
} else { } else {
feature->manager = plugin; feature->plugin = plugin;
plugin->features = g_list_prepend (plugin->features, feature); plugin->features = g_list_prepend (plugin->features, feature);
plugin->numfeatures++; plugin->numfeatures++;
} }
@ -902,7 +845,7 @@ gst_plugin_get_feature_list (GstPlugin * plugin)
} }
/** /**
* gst_plugin_load: * gst_plugin_load_1:
* @name: name of plugin to load * @name: name of plugin to load
* *
* Load the named plugin. * Load the named plugin.
@ -910,12 +853,12 @@ gst_plugin_get_feature_list (GstPlugin * plugin)
* Returns: whether the plugin was loaded or not * Returns: whether the plugin was loaded or not
*/ */
gboolean gboolean
gst_plugin_load (const gchar * name) gst_plugin_load_1 (const gchar * name)
{ {
GstPlugin *plugin; GstPlugin *plugin;
GError *error = NULL; GError *error = NULL;
plugin = gst_registry_pool_find_plugin (name); plugin = gst_registry_find_plugin (gst_registry_get_default (), name);
if (plugin) { if (plugin) {
plugin = gst_plugin_load_file (plugin->filename, &error); plugin = gst_plugin_load_file (plugin->filename, &error);
if (!plugin) { if (!plugin) {
@ -929,3 +872,26 @@ gst_plugin_load (const gchar * name)
GST_DEBUG ("Could not find %s in registry pool", name); GST_DEBUG ("Could not find %s in registry pool", name);
return FALSE; return FALSE;
} }
GstPlugin *
gst_plugin_load (GstPlugin * plugin)
{
GError *error = NULL;
if (gst_plugin_is_loaded (plugin)) {
return plugin;
}
if (!plugin->filename) {
return plugin;
}
plugin = gst_plugin_load_file (plugin->filename, &error);
if (!plugin) {
GST_WARNING ("load_plugin error: %s\n", error->message);
g_error_free (error);
return NULL;
}
return plugin;
}

View file

@ -32,6 +32,10 @@
G_BEGIN_DECLS G_BEGIN_DECLS
typedef struct _GstPlugin GstPlugin;
typedef struct _GstPluginClass GstPluginClass;
typedef struct _GstPluginDesc GstPluginDesc;
GQuark gst_plugin_error_quark (void); GQuark gst_plugin_error_quark (void);
#define GST_PLUGIN_ERROR gst_plugin_error_quark () #define GST_PLUGIN_ERROR gst_plugin_error_quark ()
@ -42,15 +46,13 @@ typedef enum
GST_PLUGIN_ERROR_NAME_MISMATCH GST_PLUGIN_ERROR_NAME_MISMATCH
} GstPluginError; } GstPluginError;
#define GST_PLUGIN(plugin) ((GstPlugin *) (plugin)) typedef enum
{
typedef struct _GstPlugin GstPlugin; GST_PLUGIN_FLAG_CACHED = (1<<0),
typedef struct _GstPluginDesc GstPluginDesc; } GstPluginFlags;
/* Initialiser function: returns TRUE if plugin initialised successfully */ /* Initialiser function: returns TRUE if plugin initialised successfully */
typedef gboolean (*GstPluginInitFunc) (GstPlugin *plugin); typedef gboolean (*GstPluginInitFunc) (GstPlugin *plugin);
/* exiting function when plugin is unloaded */
typedef void (*GstPluginExitFunc) (GstPlugin *plugin);
struct _GstPluginDesc { struct _GstPluginDesc {
gint major_version; /* major version of core that plugin was compiled for */ gint major_version; /* major version of core that plugin was compiled for */
@ -58,7 +60,6 @@ struct _GstPluginDesc {
gchar *name; /* unique name of plugin */ gchar *name; /* unique name of plugin */
gchar *description; /* description of plugin */ gchar *description; /* description of plugin */
GstPluginInitFunc plugin_init; /* pointer to plugin_init function */ GstPluginInitFunc plugin_init; /* pointer to plugin_init function */
GstPluginExitFunc plugin_exit; /* pointer to plugin_exit function */
gchar *version; /* version of the plugin */ gchar *version; /* version of the plugin */
gchar *license; /* effective license of plugin */ gchar *license; /* effective license of plugin */
gchar *source; /* source module plugin belongs to */ gchar *source; /* source module plugin belongs to */
@ -68,19 +69,42 @@ struct _GstPluginDesc {
gpointer _gst_reserved[GST_PADDING]; gpointer _gst_reserved[GST_PADDING];
}; };
#define GST_TYPE_PLUGIN (gst_plugin_get_type())
#define GST_IS_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_PLUGIN))
#define GST_IS_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_PLUGIN))
#define GST_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_PLUGIN, GstPluginClass))
#define GST_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_PLUGIN, GstPlugin))
#define GST_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_PLUGIN, GstPluginClass))
struct _GstPlugin { struct _GstPlugin {
GObject object;
GstPluginDesc desc; GstPluginDesc desc;
GstPluginDesc *orig_desc;
unsigned int flags;
gchar * filename; gchar * filename;
GList * features; /* list of features provided */ GList * features; /* list of features provided */
gint numfeatures; gint numfeatures;
gpointer manager; /* managing registry */
GModule * module; /* contains the module if plugin is loaded */ GModule * module; /* contains the module if plugin is loaded */
size_t file_size;
time_t file_mtime;
gpointer _gst_reserved[GST_PADDING]; gpointer _gst_reserved[GST_PADDING];
}; };
struct _GstPluginClass {
GObjectClass object_class;
};
#define GST_PLUGIN_DEFINE(major,minor,name,description,init,version,license,package,origin) \ #define GST_PLUGIN_DEFINE(major,minor,name,description,init,version,license,package,origin) \
GST_PLUGIN_EXPORT GstPluginDesc gst_plugin_desc = { \ GST_PLUGIN_EXPORT GstPluginDesc gst_plugin_desc = { \
major, \ major, \
@ -88,7 +112,6 @@ GST_PLUGIN_EXPORT GstPluginDesc gst_plugin_desc = { \
name, \ name, \
description, \ description, \
init, \ init, \
NULL, \
version, \ version, \
license, \ license, \
PACKAGE, \ PACKAGE, \
@ -107,7 +130,6 @@ _gst_plugin_static_init__ ##init (void) \
name, \ name, \
description, \ description, \
init, \ init, \
NULL, \
version, \ version, \
license, \ license, \
PACKAGE, \ PACKAGE, \
@ -125,8 +147,11 @@ _gst_plugin_static_init__ ##init (void) \
typedef gboolean (*GstPluginFilter) (GstPlugin *plugin, typedef gboolean (*GstPluginFilter) (GstPlugin *plugin,
gpointer user_data); gpointer user_data);
#define GST_TYPE_PLUGIN (gst_plugin_get_type())
GType gst_plugin_get_type (void); GType gst_plugin_get_type (void);
GstPlugin * gst_plugin_new (void);
void gst_plugin_free (GstPlugin *plugin);
void _gst_plugin_initialize (void); void _gst_plugin_initialize (void);
void _gst_plugin_register_static (GstPluginDesc *desc); void _gst_plugin_register_static (GstPluginDesc *desc);
@ -153,15 +178,17 @@ gboolean gst_plugin_name_filter (GstPlugin *plugin, const gchar *name);
GList* gst_plugin_get_feature_list (GstPlugin *plugin); GList* gst_plugin_get_feature_list (GstPlugin *plugin);
GstPluginFeature* gst_plugin_find_feature (GstPlugin *plugin, const gchar *name, GType type); GstPluginFeature* gst_plugin_find_feature (GstPlugin *plugin, const gchar *name, GType type);
GstPluginFeature* gst_plugin_find_feature_by_name (GstPlugin *plugin, const gchar *name);
gboolean gst_plugin_check_file (const gchar *filename, GError** error); gboolean gst_plugin_check_file (const gchar *filename, GError** error);
GstPlugin * gst_plugin_load_file (const gchar *filename, GError** error); GstPlugin * gst_plugin_load_file (const gchar *filename, GError** error);
gboolean gst_plugin_unload_plugin (GstPlugin *plugin);
void gst_plugin_add_feature (GstPlugin *plugin, GstPluginFeature *feature); void gst_plugin_add_feature (GstPlugin *plugin, GstPluginFeature *feature);
GstPlugin * gst_plugin_load (GstPlugin *plugin);
/* shortcuts to load from the registry pool */ /* shortcuts to load from the registry pool */
gboolean gst_plugin_load (const gchar *name); gboolean gst_plugin_load_1 (const gchar *name);
G_END_DECLS G_END_DECLS

View file

@ -75,74 +75,47 @@ gst_plugin_feature_class_init (GstPluginFeatureClass * klass)
static void static void
gst_plugin_feature_init (GstPluginFeature * feature) gst_plugin_feature_init (GstPluginFeature * feature)
{ {
feature->manager = NULL; feature->plugin = NULL;
} }
/** /**
* gst_plugin_feature_ensure_loaded: * gst_plugin_feature_load:
* @feature: the plugin feature to check * @feature: the plugin feature to check
* *
* Check if the plugin containing the feature is loaded, * Check if the plugin containing the feature is loaded,
* if not, the plugin will be loaded. * if not, the plugin will be loaded.
* *
* Returns: a boolean indicating the feature is loaded. * Returns: The new feature
*/ */
gboolean GstPluginFeature *
gst_plugin_feature_ensure_loaded (GstPluginFeature * feature) gst_plugin_feature_load (GstPluginFeature * feature)
{ {
GstPlugin *plugin; GstPlugin *plugin;
static GStaticMutex mutex = G_STATIC_MUTEX_INIT; GstPluginFeature *real_feature;
g_return_val_if_fail (feature != NULL, FALSE); g_return_val_if_fail (feature != NULL, FALSE);
g_return_val_if_fail (GST_IS_PLUGIN_FEATURE (feature), FALSE); g_return_val_if_fail (GST_IS_PLUGIN_FEATURE (feature), FALSE);
plugin = (GstPlugin *) (feature->manager); plugin = gst_plugin_load (feature->plugin);
g_static_mutex_lock (&mutex); if (!plugin) {
g_critical ("Failed to load plugin containing feature '%s'.",
if (plugin && !gst_plugin_is_loaded (plugin)) { GST_PLUGIN_FEATURE_NAME (feature));
#ifndef GST_DISABLE_REGISTRY return NULL;
if (GST_IS_REGISTRY (plugin->manager)) {
GST_CAT_DEBUG (GST_CAT_PLUGIN_LOADING,
"loading plugin %s for feature", plugin->desc.name);
if (gst_registry_load_plugin (GST_REGISTRY (plugin->manager),
plugin) != GST_REGISTRY_OK) {
g_static_mutex_unlock (&mutex);
return FALSE;
} }
} else { if (plugin == feature->plugin) {
g_static_mutex_unlock (&mutex); return feature;
return FALSE;
}
#else /* GST_DISABLE_REGISTRY */
g_static_mutex_unlock (&mutex);
return FALSE;
#endif
} }
g_static_mutex_unlock (&mutex); real_feature = gst_plugin_find_feature_by_name (plugin, feature->name);
return TRUE;
}
/** if (real_feature == NULL) {
* gst_plugin_feature_unload_thyself: g_critical
* @feature: the plugin feature to check ("Loaded plugin containing feature '%s', but feature disappeared.",
* feature->name);
* Unload the given feature. This will decrease the refcount return NULL;
* in the plugin and will eventually unload the plugin }
*/
void
gst_plugin_feature_unload_thyself (GstPluginFeature * feature)
{
GstPluginFeatureClass *oclass;
g_return_if_fail (feature != NULL); return real_feature;
g_return_if_fail (GST_IS_PLUGIN_FEATURE (feature));
oclass = GST_PLUGIN_FEATURE_GET_CLASS (feature);
if (oclass->unload_thyself)
oclass->unload_thyself (feature);
} }
gboolean gboolean

View file

@ -55,7 +55,7 @@ struct _GstPluginFeature {
gchar *name; gchar *name;
guint rank; guint rank;
gpointer manager; struct _GstPlugin *plugin;
/*< private >*/ /*< private >*/
gpointer _gst_reserved[GST_PADDING]; gpointer _gst_reserved[GST_PADDING];
@ -64,8 +64,6 @@ struct _GstPluginFeature {
struct _GstPluginFeatureClass { struct _GstPluginFeatureClass {
GObjectClass parent_class; GObjectClass parent_class;
void (*unload_thyself) (GstPluginFeature *feature);
/*< private >*/ /*< private >*/
gpointer _gst_reserved[GST_PADDING]; gpointer _gst_reserved[GST_PADDING];
}; };
@ -82,8 +80,8 @@ typedef gboolean (*GstPluginFeatureFilter) (GstPluginFeature *featu
/* normal GObject stuff */ /* normal GObject stuff */
GType gst_plugin_feature_get_type (void); GType gst_plugin_feature_get_type (void);
gboolean gst_plugin_feature_ensure_loaded (GstPluginFeature *feature); GstPluginFeature *
void gst_plugin_feature_unload_thyself (GstPluginFeature *feature); gst_plugin_feature_load (GstPluginFeature *feature);
gboolean gst_plugin_feature_type_name_filter (GstPluginFeature *feature, gboolean gst_plugin_feature_type_name_filter (GstPluginFeature *feature,
GstTypeNameData *data); GstTypeNameData *data);

View file

@ -1,6 +1,7 @@
/* GStreamer /* GStreamer
* Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu> * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
* 2000 Wim Taymans <wtay@chello.be> * 2000 Wim Taymans <wtay@chello.be>
* 2005 David A. Schleef <ds@schleef.org>
* *
* gstregistry.c: handle registry * gstregistry.c: handle registry
* *
@ -45,11 +46,66 @@
#include "gstinfo.h" #include "gstinfo.h"
#include "gstregistry.h" #include "gstregistry.h"
#include "gstregistrypool.h"
#include "gstmarshal.h" #include "gstmarshal.h"
#include "gstfilter.h" #include "gstfilter.h"
#define GST_CAT_DEFAULT GST_CAT_GST_INIT #define GST_CAT_DEFAULT GST_CAT_REGISTRY
/*
* Design:
*
* The GstRegistry object is a list of plugins and some functions
* for dealing with them. Plugins are matched 1-1 with a file on
* disk, and may or may not be loaded at a given time. There may
* be multiple GstRegistry objects, but the "default registry" is
* the only object that has any meaning to the core.
*
* The registry.xml file in 0.9 is actually a cache of plugin
* information. This is unlike previous versions, where the registry
* file was the primary source of plugin information, and was created
* by the gst-register command.
*
* In 0.9, the primary source, at all times, of plugin information
* is each plugin file itself. Thus, if an application wants
* information about a particular plugin, or wants to search for
* a feature that satisfies given criteria, the primary means of
* doing so is to load every plugin and look at the resulting
* information that is gathered in the default registry. Clearly,
* this is a time consuming process, so we cache information in
* the registry.xml file.
*
* On startup, plugins are searched for in the plugin search path.
* This path can be set directly using the GST_PLUGIN_PATH
* environment variable. The registry file is loaded from
* ~/.gstreamer-0.9/registry.xml or the file listed in the
* GST_REGISTRY env var. The only reason to change the registry
* location is for testing.
*
* For each plugin that is found in the plugin search path, there
* could be 3 possibilities for cached information:
* - the cache may not contain information about a given file.
* - the cache may have stale information.
* - the cache may have current information.
* In the first two cases, the plugin is loaded and the cache
* updated. In addition to these cases, the cache may have entries
* for plugins that are not relevant to the current process. These
* are marked as not available to the current process. If the
* cache is updated for whatever reason, it is marked dirty.
*
* A dirty cache is written out at the end of initialization. Each
* entry is checked to make sure the information is minimally valid.
* If not, the entry is simply dropped.
*
* Implementation notes:
*
* The "cache" and "default registry" are different concepts and
* can represent different sets of plugins. For various reasons,
* at init time, the cache is stored in the default registry, and
* plugins not relevant to the current process are marked with the
* GST_PLUGIN_FLAG_CACHED bit. These plugins are removed at the
* end of intitialization.
*
*/
/* Element signals and args */ /* Element signals and args */
enum enum
@ -84,7 +140,7 @@ gst_registry_get_type (void)
}; };
registry_type = g_type_register_static (G_TYPE_OBJECT, "GstRegistry", registry_type = g_type_register_static (G_TYPE_OBJECT, "GstRegistry",
&registry_info, G_TYPE_FLAG_ABSTRACT); &registry_info, 0);
} }
return registry_type; return registry_type;
} }
@ -109,117 +165,18 @@ gst_registry_class_init (GstRegistryClass * klass)
static void static void
gst_registry_init (GstRegistry * registry) gst_registry_init (GstRegistry * registry)
{ {
registry->priority = 0;
registry->loaded = FALSE;
registry->paths = NULL;
} }
/** GstRegistry *
* gst_registry_load: gst_registry_get_default (void)
* @registry: the registry to load
*
* Load the given registry
*
* Returns: TRUE on success.
*/
gboolean
gst_registry_load (GstRegistry * registry)
{ {
GstRegistryClass *rclass; static GstRegistry *_gst_registry_default;
g_return_val_if_fail (GST_IS_REGISTRY (registry), FALSE); if (!_gst_registry_default) {
_gst_registry_default = g_object_new (GST_TYPE_REGISTRY, NULL);
rclass = GST_REGISTRY_GET_CLASS (registry); }
return _gst_registry_default;
if (rclass->load)
return rclass->load (registry);
return FALSE;
}
/**
* gst_registry_is_loaded:
* @registry: the registry to check
*
* Check if the given registry is loaded
*
* Returns: TRUE if loaded.
*/
gboolean
gst_registry_is_loaded (GstRegistry * registry)
{
g_return_val_if_fail (GST_IS_REGISTRY (registry), FALSE);
return registry->loaded;
}
/**
* gst_registry_save:
* @registry: the registry to save
*
* Save the contents of the given registry
*
* Returns: TRUE on success
*/
gboolean
gst_registry_save (GstRegistry * registry)
{
GstRegistryClass *rclass;
g_return_val_if_fail (GST_IS_REGISTRY (registry), FALSE);
rclass = GST_REGISTRY_GET_CLASS (registry);
if (rclass->save)
return rclass->save (registry);
return FALSE;
}
/**
* gst_registry_rebuild:
* @registry: the registry to rebuild
*
* Rebuild the given registry
*
* Returns: TRUE on success
*/
gboolean
gst_registry_rebuild (GstRegistry * registry)
{
GstRegistryClass *rclass;
g_return_val_if_fail (GST_IS_REGISTRY (registry), FALSE);
rclass = GST_REGISTRY_GET_CLASS (registry);
if (rclass->rebuild)
return rclass->rebuild (registry);
return FALSE;
}
/**
* gst_registry_unload:
* @registry: the registry to unload
*
* Unload the given registry
*
* Returns: TRUE on success
*/
gboolean
gst_registry_unload (GstRegistry * registry)
{
GstRegistryClass *rclass;
g_return_val_if_fail (GST_IS_REGISTRY (registry), FALSE);
rclass = GST_REGISTRY_GET_CLASS (registry);
if (rclass->unload)
return rclass->unload (registry);
return FALSE;
} }
/** /**
@ -297,15 +254,18 @@ gst_registry_clear_paths (GstRegistry * registry)
gboolean gboolean
gst_registry_add_plugin (GstRegistry * registry, GstPlugin * plugin) gst_registry_add_plugin (GstRegistry * registry, GstPlugin * plugin)
{ {
GstPlugin *existing_plugin;
g_return_val_if_fail (GST_IS_REGISTRY (registry), FALSE); g_return_val_if_fail (GST_IS_REGISTRY (registry), FALSE);
if (gst_registry_pool_find_plugin (gst_plugin_get_name (plugin))) {
GST_WARNING_OBJECT (registry, "Not adding plugin %s, " existing_plugin = gst_registry_lookup (registry, plugin->filename);
"because a plugin with same name already exists", if (existing_plugin) {
gst_plugin_get_name (plugin)); GST_DEBUG ("Replacing existing plugin for filename \"%s\"",
return FALSE; plugin->filename);
registry->plugins = g_list_remove (registry->plugins, existing_plugin);
g_object_unref (existing_plugin);
} }
plugin->manager = registry;
registry->plugins = g_list_prepend (registry->plugins, plugin); registry->plugins = g_list_prepend (registry->plugins, plugin);
GST_DEBUG ("emitting plugin-added for filename %s", plugin->filename); GST_DEBUG ("emitting plugin-added for filename %s", plugin->filename);
@ -443,77 +403,140 @@ gst_registry_find_feature (GstRegistry * registry, const gchar * name,
} }
/** GList *
* gst_registry_load_plugin: gst_registry_get_feature_list (GstRegistry * registry, GType type)
* @registry: the registry to load the plugin from
* @plugin: the plugin to load
*
* Bring the plugin from the registry into memory.
*
* Returns: a value indicating the result
*/
GstRegistryReturn
gst_registry_load_plugin (GstRegistry * registry, GstPlugin * plugin)
{ {
GstRegistryClass *rclass; /* FIXME */
g_return_val_if_fail (GST_IS_REGISTRY (registry), return NULL;
GST_REGISTRY_PLUGIN_LOAD_ERROR); }
rclass = GST_REGISTRY_GET_CLASS (registry); GList *
gst_registry_get_plugin_list (GstRegistry * registry)
{
return g_list_copy (registry->plugins);
}
if (rclass->load_plugin) GstPlugin *
return rclass->load_plugin (registry, plugin); gst_registry_lookup (GstRegistry * registry, const char *filename)
{
GList *g;
GstPlugin *plugin;
return GST_REGISTRY_PLUGIN_LOAD_ERROR; for (g = registry->plugins; g; g = g_list_next (g)) {
plugin = GST_PLUGIN (g->data);
if (plugin->filename && strcmp (filename, plugin->filename) == 0) {
return plugin;
}
}
return NULL;
}
static void
gst_registry_scan_path_level (GstRegistry * registry, const gchar * path,
int level)
{
GDir *dir;
const gchar *dirent;
gchar *filename;
GstPlugin *plugin;
dir = g_dir_open (path, 0, NULL);
if (!dir)
return;
while ((dirent = g_dir_read_name (dir))) {
filename = g_strjoin ("/", path, dirent, NULL);
GST_DEBUG ("examining file: %s", filename);
if (g_file_test (filename, G_FILE_TEST_IS_DIR)) {
if (level > 0) {
GST_DEBUG ("found directory, recursing");
gst_registry_scan_path_level (registry, filename, level - 1);
} else {
GST_DEBUG ("found directory, but recursion level is too deep");
}
g_free (filename);
continue;
}
if (!g_file_test (filename, G_FILE_TEST_IS_REGULAR)) {
GST_DEBUG ("not a regular file, ignoring");
g_free (filename);
continue;
}
if (!g_str_has_suffix (filename, ".so") &&
!g_str_has_suffix (filename, ".dll") &&
!g_str_has_suffix (filename, ".dynlib")) {
GST_DEBUG ("extension is not recognized as module file, ignoring");
g_free (filename);
continue;
}
plugin = gst_registry_lookup (registry, filename);
if (plugin) {
struct stat file_status;
if (stat (filename, &file_status)) {
/* FIXME remove from cache */
g_free (filename);
continue;
}
if (plugin->file_mtime == file_status.st_mtime &&
plugin->file_size == file_status.st_size) {
GST_DEBUG ("file %s cached", filename);
plugin->flags &= ~GST_PLUGIN_FLAG_CACHED;
} else {
GST_DEBUG ("cached info for %s is stale", filename);
GST_DEBUG ("mtime %ld != %ld or size %" G_GSIZE_FORMAT " != %"
G_GSIZE_FORMAT, plugin->file_mtime, file_status.st_mtime,
plugin->file_size, file_status.st_size);
gst_registry_remove_plugin (gst_registry_get_default (), plugin);
gst_plugin_load_file (filename, NULL);
}
} else {
gst_plugin_load_file (filename, NULL);
}
g_free (filename);
}
g_dir_close (dir);
} }
/** /**
* gst_registry_unload_plugin: * gst_registry_scan_path:
* @registry: the registry to unload the plugin from * @registry: the registry to add the path to
* @plugin: the plugin to unload * @path: the path to add to the registry
* *
* Unload the plugin from the given registry. * Add the given path to the registry. The syntax of the
* * path is specific to the registry. If the path has already been
* Returns: a value indicating the result * added, do nothing.
*/ */
GstRegistryReturn void
gst_registry_unload_plugin (GstRegistry * registry, GstPlugin * plugin) gst_registry_scan_path (GstRegistry * registry, const gchar * path)
{ {
GstRegistryClass *rclass; gst_registry_scan_path_level (registry, path, 10);
g_return_val_if_fail (GST_IS_REGISTRY (registry),
GST_REGISTRY_PLUGIN_LOAD_ERROR);
rclass = GST_REGISTRY_GET_CLASS (registry);
if (rclass->unload_plugin)
return rclass->unload_plugin (registry, plugin);
return GST_REGISTRY_PLUGIN_LOAD_ERROR;
} }
/** void
* gst_registry_update_plugin: _gst_registry_remove_cache_plugins (GstRegistry * registry)
* @registry: the registry to update
* @plugin: the plugin to update
*
* Update the plugin in the given registry.
*
* Returns: a value indicating the result
*/
GstRegistryReturn
gst_registry_update_plugin (GstRegistry * registry, GstPlugin * plugin)
{ {
GstRegistryClass *rclass; GList *g;
GList *g_next;
GstPlugin *plugin;
g_return_val_if_fail (GST_IS_REGISTRY (registry), g = registry->plugins;
GST_REGISTRY_PLUGIN_LOAD_ERROR); while (g) {
g_next = g->next;
rclass = GST_REGISTRY_GET_CLASS (registry); plugin = g->data;
if (plugin->flags & GST_PLUGIN_FLAG_CACHED) {
if (rclass->update_plugin) registry->plugins = g_list_remove (registry->plugins, plugin);
return rclass->update_plugin (registry, plugin); g_object_unref (plugin);
}
return GST_REGISTRY_PLUGIN_LOAD_ERROR; g = g_next;
}
} }

View file

@ -26,59 +26,8 @@
#include <gst/gstplugin.h> #include <gst/gstplugin.h>
#define GLOBAL_REGISTRY_DIR GST_CACHE_DIR
#define GLOBAL_REGISTRY_FILE GLOBAL_REGISTRY_DIR"/registry.xml"
#define GLOBAL_REGISTRY_FILE_TMP GLOBAL_REGISTRY_DIR"/.registry.xml.tmp"
#define LOCAL_REGISTRY_DIR ".gstreamer-"GST_MAJORMINOR
#define LOCAL_REGISTRY_FILE LOCAL_REGISTRY_DIR"/registry.xml"
#define LOCAL_REGISTRY_FILE_TMP LOCAL_REGISTRY_DIR"/.registry.xml.tmp"
/* compatibility for pre-POSIX defines */
#ifdef S_IRUSR
#if defined(_WIN32) && defined(__MINGW32__)
#define REGISTRY_DIR_PERMS (S_ISGID | \
S_IRUSR | S_IWUSR | S_IXUSR)
#else
#define REGISTRY_DIR_PERMS (S_ISGID | \
S_IRUSR | S_IWUSR | S_IXUSR | \
S_IRGRP | S_IXGRP | \
S_IROTH | S_IXOTH)
#endif
#define REGISTRY_TMPFILE_PERMS (S_IRUSR | S_IWUSR)
#if defined(_WIN32) && defined(__MINGW32__)
#define REGISTRY_FILE_PERMS (S_IRUSR | S_IWUSR
#else
#define REGISTRY_FILE_PERMS (S_IRUSR | S_IWUSR | \
S_IRGRP | S_IWGRP | \
S_IROTH | S_IWOTH)
#endif
#else
#define REGISTRY_DIR_PERMS (S_ISGID | \
S_IREAD | S_IWRITE | S_IEXEC)
#define REGISTRY_TMPFILE_PERMS (S_IREAD | S_IWRITE)
#define REGISTRY_FILE_PERMS (S_IREAD | S_IWRITE)
#endif
G_BEGIN_DECLS G_BEGIN_DECLS
typedef enum {
GST_REGISTRY_OK = (0),
GST_REGISTRY_LOAD_ERROR = (1 << 1),
GST_REGISTRY_SAVE_ERROR = (1 << 2),
GST_REGISTRY_PLUGIN_LOAD_ERROR = (1 << 3),
GST_REGISTRY_PLUGIN_SIGNATURE_ERROR = (1 << 4)
} GstRegistryReturn;
typedef enum {
GST_REGISTRY_READABLE = (1 << 1),
GST_REGISTRY_WRITABLE = (1 << 2),
GST_REGISTRY_EXISTS = (1 << 3),
GST_REGISTRY_REMOTE = (1 << 4),
GST_REGISTRY_DELAYED_LOADING = (1 << 5)
} GstRegistryFlags;
#define GST_TYPE_REGISTRY (gst_registry_get_type ()) #define GST_TYPE_REGISTRY (gst_registry_get_type ())
#define GST_REGISTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_REGISTRY, GstRegistry)) #define GST_REGISTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_REGISTRY, GstRegistry))
#define GST_IS_REGISTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_REGISTRY)) #define GST_IS_REGISTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_REGISTRY))
@ -92,33 +41,19 @@ typedef struct _GstRegistryClass GstRegistryClass;
struct _GstRegistry { struct _GstRegistry {
GObject object; GObject object;
gint priority;
GstRegistryFlags flags;
gchar *name;
gchar *details;
gboolean loaded;
GList *plugins; GList *plugins;
GList *paths; GList *paths;
/* FIXME move elsewhere */
FILE *cache_file;
gpointer _gst_reserved[GST_PADDING]; gpointer _gst_reserved[GST_PADDING];
}; };
struct _GstRegistryClass { struct _GstRegistryClass {
GObjectClass parent_class; GObjectClass parent_class;
/* vtable */
gboolean (*load) (GstRegistry *registry);
gboolean (*save) (GstRegistry *registry);
gboolean (*rebuild) (GstRegistry *registry);
gboolean (*unload) (GstRegistry *registry);
GstRegistryReturn (*load_plugin) (GstRegistry *registry, GstPlugin *plugin);
GstRegistryReturn (*unload_plugin) (GstRegistry *registry, GstPlugin *plugin);
GstRegistryReturn (*update_plugin) (GstRegistry *registry, GstPlugin *plugin);
/* signals */ /* signals */
void (*plugin_added) (GstRegistry *registry, GstPlugin *plugin); void (*plugin_added) (GstRegistry *registry, GstPlugin *plugin);
@ -129,19 +64,16 @@ struct _GstRegistryClass {
/* normal GObject stuff */ /* normal GObject stuff */
GType gst_registry_get_type (void); GType gst_registry_get_type (void);
gboolean gst_registry_load (GstRegistry *registry); GstRegistry * gst_registry_get_default (void);
gboolean gst_registry_is_loaded (GstRegistry *registry);
gboolean gst_registry_save (GstRegistry *registry);
gboolean gst_registry_rebuild (GstRegistry *registry);
gboolean gst_registry_unload (GstRegistry *registry);
void gst_registry_add_path (GstRegistry *registry, const gchar *path); void gst_registry_scan_path (GstRegistry *registry, const gchar *path);
GList* gst_registry_get_path_list (GstRegistry *registry); GList* gst_registry_get_path_list (GstRegistry *registry);
void gst_registry_clear_paths (GstRegistry *registry); void gst_registry_clear_paths (GstRegistry *registry);
gboolean gst_registry_add_plugin (GstRegistry *registry, GstPlugin *plugin); gboolean gst_registry_add_plugin (GstRegistry *registry, GstPlugin *plugin);
void gst_registry_remove_plugin (GstRegistry *registry, GstPlugin *plugin); void gst_registry_remove_plugin (GstRegistry *registry, GstPlugin *plugin);
GList* gst_registry_get_plugin_list (GstRegistry *registry);
GList* gst_registry_plugin_filter (GstRegistry *registry, GList* gst_registry_plugin_filter (GstRegistry *registry,
GstPluginFilter filter, GstPluginFilter filter,
gboolean first, gboolean first,
@ -150,14 +82,35 @@ GList* gst_registry_feature_filter (GstRegistry *registry,
GstPluginFeatureFilter filter, GstPluginFeatureFilter filter,
gboolean first, gboolean first,
gpointer user_data); gpointer user_data);
GList * gst_registry_get_feature_list (GstRegistry *registry,
GType type);
GstPlugin* gst_registry_find_plugin (GstRegistry *registry, const gchar *name); GstPlugin* gst_registry_find_plugin (GstRegistry *registry, const gchar *name);
GstPluginFeature* gst_registry_find_feature (GstRegistry *registry, const gchar *name, GType type); GstPluginFeature* gst_registry_find_feature (GstRegistry *registry, const gchar *name, GType type);
GstPlugin * gst_registry_lookup (GstRegistry *registry, const char *filename);
GstRegistryReturn gst_registry_load_plugin (GstRegistry *registry, GstPlugin *plugin); gboolean gst_registry_xml_read_cache (GstRegistry * registry, const char *location);
GstRegistryReturn gst_registry_unload_plugin (GstRegistry *registry, GstPlugin *plugin); gboolean gst_registry_xml_write_cache (GstRegistry * registry, const char *location);
GstRegistryReturn gst_registry_update_plugin (GstRegistry *registry, GstPlugin *plugin);
void gst_registry_scan_paths (GstRegistry *registry);
void _gst_registry_remove_cache_plugins (GstRegistry *registry);
#define gst_default_registry_add_plugin(plugin) \
gst_registry_add_plugin (gst_registry_get_default(), plugin)
#define gst_default_registry_add_path(path) \
gst_registry_add_path (gst_registry_get_default(), path)
#define gst_default_registry_get_path_list() \
gst_registry_get_path_list (gst_registry_get_default())
#define gst_default_registry_get_plugin_list() \
gst_registry_get_plugin_list (gst_registry_get_default())
#define gst_default_registry_find_feature(name,type) \
gst_registry_find_feature (gst_registry_get_default(),name,type)
#define gst_default_registry_find_plugin(name) \
gst_registry_find_plugin (gst_registry_get_default(),name)
#define gst_default_registry_feature_filter(filter,first,user_data) \
gst_registry_feature_filter (gst_registry_get_default(),filter,first,user_data)
G_END_DECLS G_END_DECLS
#endif /* __GST_REGISTRY_H__ */ #endif /* __GST_REGISTRY_H__ */

View file

@ -1,350 +0,0 @@
/* GStreamer
* Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
* 2000 Wim Taymans <wtay@chello.be>
*
* gstregistry.c: handle registry
*
* 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.
*/
/**
* SECTION:gstregistrypool
* @short_description: Management of a group of #GstRegistry objects
* @see_also: #GstRegistry
*
* The registry pool manages the available registries and plugins in the system.
*/
#include <string.h>
#include "gst_private.h"
#include "gstinfo.h"
#include "gstregistrypool.h"
#include "gstfilter.h"
/* list of registries in the pool */
static GList *_gst_registry_pool = NULL;
/* list of plugins without a registry, like statically linked
* plugins */
static GList *_gst_registry_pool_plugins = NULL;
/**
* gst_registry_pool_list:
*
* Get a list of all registries in the pool
*
* Returns: a Glist of GstRegistries, g_list_free after use.
*/
GList *
gst_registry_pool_list (void)
{
return g_list_copy (_gst_registry_pool);
}
#ifndef GST_DISABLE_REGISTRY
static gint
gst_registry_compare_func (gconstpointer a, gconstpointer b)
{
return GST_REGISTRY (a)->priority - GST_REGISTRY (b)->priority;
}
/**
* gst_registry_pool_add:
* @registry: the registry to add
* @priority: the priority of the registry
*
* Add the registry to the pool with the given priority.
*/
void
gst_registry_pool_add (GstRegistry * registry, guint priority)
{
g_return_if_fail (GST_IS_REGISTRY (registry));
registry->priority = priority;
_gst_registry_pool =
g_list_insert_sorted (_gst_registry_pool, registry,
gst_registry_compare_func);
}
/**
* gst_registry_pool_remove:
* @registry: the registry to remove
*
* Remove the registry from the pool.
*/
void
gst_registry_pool_remove (GstRegistry * registry)
{
g_return_if_fail (GST_IS_REGISTRY (registry));
_gst_registry_pool = g_list_remove (_gst_registry_pool, registry);
}
#endif /* GST_DISABLE_REGISTRY */
/**
* gst_registry_pool_add_plugin:
* @plugin: the plugin to add
*
* Add the plugin to the global pool of plugins.
*/
void
gst_registry_pool_add_plugin (GstPlugin * plugin)
{
_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_DELAYED_LOADING)) {
gst_registry_load (registry);
}
}
#endif /* GST_DISABLE_REGISTRY */
/**
* gst_registry_pool_load_all:
*
* Load all the registries in the pool. Registries with the
* GST_REGISTRY_DELAYED_LOADING will not be loaded.
*/
void
gst_registry_pool_load_all (void)
{
#ifndef GST_DISABLE_REGISTRY
g_list_foreach (_gst_registry_pool, (GFunc) _registry_load_func, NULL);
#endif /* GST_DISABLE_REGISTRY */
}
/**
* gst_registry_pool_plugin_list:
*
* Get a list of all plugins in the pool.
*
* Returns: a newly allocated GList of #GstPlugin.
*/
GList *
gst_registry_pool_plugin_list (void)
{
return gst_registry_pool_plugin_filter (NULL, FALSE, NULL);
}
/**
* gst_registry_pool_plugin_filter:
* @filter: the filter to use
* @first: only return first match
* @user_data: user data passed to the filter function
*
* Runs a filter against all plugins in all registries and returns a GList with
* the results. If the first flag is set, only the first match is
* returned (as a list with a single object).
*
* Returns: a newly allocated GList of #GstPlugin.
*/
GList *
gst_registry_pool_plugin_filter (GstPluginFilter filter, gboolean first,
gpointer user_data)
{
GList *result = NULL;
GList *temp;
#ifndef GST_DISABLE_REGISTRY
GList *walk;
walk = _gst_registry_pool;
while (walk) {
GstRegistry *registry = GST_REGISTRY (walk->data);
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 */
temp =
gst_filter_run (_gst_registry_pool_plugins, (GstFilterFunc) filter, first,
user_data);
result = g_list_concat (result, temp);
return result;
}
/**
* gst_registry_pool_feature_list:
* @type: the type of the features to list.
*
* Get a list of all pluginfeatures of the given type in the pool.
*
* Returns: a newly allocated #GList of #GstPluginFeature.
*/
GList *
gst_registry_pool_feature_list (GType type)
{
GstTypeNameData data;
data.name = NULL;
data.type = type;
return gst_registry_pool_feature_filter (
(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. 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, gboolean first,
gpointer user_data)
{
GList *result = NULL;
GList *temp;
#ifndef GST_DISABLE_REGISTRY
GList *walk;
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);
}
#endif /* GST_DISABLE_REGISTRY */
temp =
gst_plugin_list_feature_filter (_gst_registry_pool_plugins, filter, first,
user_data);
result = g_list_concat (result, temp);
return result;
}
/**
* gst_registry_pool_find_plugin:
* @name: the name of the plugin to find
*
* Get the named plugin from the registry pool
*
* Returns: The plugin with the given name or NULL if the plugin
* was not found.
*/
GstPlugin *
gst_registry_pool_find_plugin (const gchar * name)
{
GstPlugin *result = NULL;
GList *walk;
g_return_val_if_fail (name != NULL, NULL);
walk =
gst_registry_pool_plugin_filter ((GstPluginFilter) gst_plugin_name_filter,
TRUE, (gpointer) name);
if (walk)
result = GST_PLUGIN (walk->data);
g_list_free (walk);
return result;
}
/**
* gst_registry_pool_find_feature:
* @name: the name of the pluginfeature to find
* @type: the type of the pluginfeature to find
*
* Get the pluginfeature with the given name and type from the pool of
* registries.
*
* Returns: A pluginfeature with the given name and type or NULL if the feature
* was not found.
*/
GstPluginFeature *
gst_registry_pool_find_feature (const gchar * name, GType type)
{
GstPluginFeature *result = NULL;
GList *walk;
GstTypeNameData data;
g_return_val_if_fail (name != NULL, NULL);
data.type = type;
data.name = name;
walk = gst_registry_pool_feature_filter ((GstPluginFeatureFilter)
gst_plugin_feature_type_name_filter, TRUE, &data);
if (walk)
result = GST_PLUGIN_FEATURE (walk->data);
g_list_free (walk);
return result;
}
/**
* gst_registry_pool_get_prefered:
* @flags: The flags for the prefered registry
*
* Get the prefered registry with the given flags
*
* Returns: The registry with the flags.
*/
GstRegistry *
gst_registry_pool_get_prefered (GstRegistryFlags flags)
{
#ifndef GST_DISABLE_REGISTRY
GList *walk = _gst_registry_pool;
while (walk) {
GstRegistry *registry = GST_REGISTRY (walk->data);
if (registry->flags & flags)
return registry;
walk = g_list_next (walk);
}
#endif /* GST_DISABLE_REGISTRY */
return NULL;
}

View file

@ -1,59 +0,0 @@
/* GStreamer
* Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
* 2000 Wim Taymans <wim.taymans@chello.be>
*
* gstregistrypool.h: maintain list of registries and plugins
*
* 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.
*/
#ifndef __GST_REGISTRY_POOL_H__
#define __GST_REGISTRY_POOL_H__
G_BEGIN_DECLS
#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_add_plugin (GstPlugin *plugin);
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);
GstPlugin* gst_registry_pool_find_plugin (const gchar *name);
GstPluginFeature* gst_registry_pool_find_feature (const gchar *name, GType type);
GstRegistry* gst_registry_pool_get_prefered (GstRegistryFlags flags);
G_END_DECLS
#endif /* __GST_REGISTRY_POOL_H__ */

View file

@ -27,8 +27,8 @@
#include "gst_private.h" #include "gst_private.h"
#include "gstinfo.h" #include "gstinfo.h"
#include "gsttypefind.h" #include "gsttypefind.h"
#include "gstregistry.h"
#include "gsttypefindfactory.h" #include "gsttypefindfactory.h"
#include "gstregistrypool.h"
GST_DEBUG_CATEGORY_EXTERN (gst_type_find_debug); GST_DEBUG_CATEGORY_EXTERN (gst_type_find_debug);
#define GST_CAT_DEFAULT gst_type_find_debug #define GST_CAT_DEFAULT gst_type_find_debug
@ -63,8 +63,8 @@ gst_type_find_register (GstPlugin * plugin, const gchar * name, guint rank,
GST_INFO ("registering typefind function for %s", name); GST_INFO ("registering typefind function for %s", name);
factory = factory =
GST_TYPE_FIND_FACTORY (gst_registry_pool_find_feature (name, GST_TYPE_FIND_FACTORY (gst_registry_find_feature (gst_registry_get_default
GST_TYPE_TYPE_FIND_FACTORY)); (), name, GST_TYPE_TYPE_FIND_FACTORY));
if (!factory) { if (!factory) {
factory = g_object_new (GST_TYPE_TYPE_FIND_FACTORY, NULL); factory = g_object_new (GST_TYPE_TYPE_FIND_FACTORY, NULL);
GST_DEBUG_OBJECT (factory, "using new typefind factory for %s", name); GST_DEBUG_OBJECT (factory, "using new typefind factory for %s", name);

View file

@ -81,7 +81,7 @@
#include "gstinfo.h" #include "gstinfo.h"
#include "gsttypefind.h" #include "gsttypefind.h"
#include "gsttypefindfactory.h" #include "gsttypefindfactory.h"
#include "gstregistrypool.h" #include "gstregistry.h"
GST_DEBUG_CATEGORY (gst_type_find_debug); GST_DEBUG_CATEGORY (gst_type_find_debug);
#define GST_CAT_DEFAULT gst_type_find_debug #define GST_CAT_DEFAULT gst_type_find_debug
@ -92,8 +92,6 @@ static void gst_type_find_factory_init (GTypeInstance * instance,
gpointer g_class); gpointer g_class);
static void gst_type_find_factory_dispose (GObject * object); static void gst_type_find_factory_dispose (GObject * object);
static void gst_type_find_factory_unload_thyself (GstPluginFeature * feature);
static void gst_type_find_load_plugin (GstTypeFind * find, gpointer data); static void gst_type_find_load_plugin (GstTypeFind * find, gpointer data);
static GstPluginFeatureClass *parent_class = NULL; static GstPluginFeatureClass *parent_class = NULL;
@ -128,16 +126,11 @@ gst_type_find_factory_get_type (void)
static void static void
gst_type_find_factory_class_init (gpointer g_class, gpointer class_data) gst_type_find_factory_class_init (gpointer g_class, gpointer class_data)
{ {
GstPluginFeatureClass *gstpluginfeature_class =
GST_PLUGIN_FEATURE_CLASS (g_class);
GObjectClass *object_class = G_OBJECT_CLASS (g_class); GObjectClass *object_class = G_OBJECT_CLASS (g_class);
parent_class = g_type_class_peek_parent (g_class); parent_class = g_type_class_peek_parent (g_class);
object_class->dispose = gst_type_find_factory_dispose; object_class->dispose = gst_type_find_factory_dispose;
gstpluginfeature_class->unload_thyself =
GST_DEBUG_FUNCPTR (gst_type_find_factory_unload_thyself);
} }
static void static void
gst_type_find_factory_init (GTypeInstance * instance, gpointer g_class) gst_type_find_factory_init (GTypeInstance * instance, gpointer g_class)
@ -162,14 +155,6 @@ gst_type_find_factory_dispose (GObject * object)
} }
} }
static void static void
gst_type_find_factory_unload_thyself (GstPluginFeature * feature)
{
GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (feature);
factory->function = gst_type_find_load_plugin;
factory->user_data = factory;
}
static void
gst_type_find_load_plugin (GstTypeFind * find, gpointer data) gst_type_find_load_plugin (GstTypeFind * find, gpointer data)
{ {
GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (data); GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (data);
@ -177,7 +162,10 @@ gst_type_find_load_plugin (GstTypeFind * find, gpointer data)
GST_DEBUG_OBJECT (factory, "need to load typefind function %s", GST_DEBUG_OBJECT (factory, "need to load typefind function %s",
GST_PLUGIN_FEATURE_NAME (factory)); GST_PLUGIN_FEATURE_NAME (factory));
if (gst_plugin_feature_ensure_loaded (GST_PLUGIN_FEATURE (factory))) { factory =
GST_TYPE_FIND_FACTORY (gst_plugin_feature_load (GST_PLUGIN_FEATURE
(factory)));
if (factory) {
if (factory->function == gst_type_find_load_plugin) { if (factory->function == gst_type_find_load_plugin) {
/* looks like we didn't get a real typefind function */ /* looks like we didn't get a real typefind function */
g_warning ("could not load valid typefind function for feature '%s'\n", g_warning ("could not load valid typefind function for feature '%s'\n",
@ -200,7 +188,8 @@ gst_type_find_load_plugin (GstTypeFind * find, gpointer data)
GList * GList *
gst_type_find_factory_get_list (void) gst_type_find_factory_get_list (void)
{ {
return gst_registry_pool_feature_list (GST_TYPE_TYPE_FIND_FACTORY); return gst_registry_get_feature_list (gst_registry_get_default (),
GST_TYPE_TYPE_FIND_FACTORY);
} }
/** /**

View file

@ -35,8 +35,8 @@
#include "gst_private.h" #include "gst_private.h"
#include "gsturi.h" #include "gsturi.h"
#include "gstinfo.h" #include "gstinfo.h"
#include "gstregistrypool.h"
#include "gstmarshal.h" #include "gstmarshal.h"
#include "gstregistry.h"
#include <string.h> #include <string.h>
@ -474,8 +474,8 @@ gst_element_make_from_uri (const GstURIType type, const gchar * uri,
entry.type = type; entry.type = type;
entry.protocol = gst_uri_get_protocol (uri); entry.protocol = gst_uri_get_protocol (uri);
possibilities = possibilities = gst_registry_feature_filter (gst_registry_get_default (),
gst_registry_pool_feature_filter (search_by_entry, FALSE, &entry); search_by_entry, FALSE, &entry);
g_free (entry.protocol); g_free (entry.protocol);
if (!possibilities) { if (!possibilities) {

View file

@ -10,14 +10,10 @@ REGISTRY_ENVIRONMENT = \
TESTS_ENVIRONMENT = \ TESTS_ENVIRONMENT = \
$(REGISTRY_ENVIRONMENT) \ $(REGISTRY_ENVIRONMENT) \
GST_PLUGIN_PATH_ONLY=yes \ GST_PLUGIN_PATH_ONLY=yes \
GST_PLUGIN_PATH=$(top_builddir)/gst GST_PLUGIN_PATH=$(top_builddir)/gst/elements/.libs:$(top_builddir)/gst/indexers/.libs
plugindir = $(libdir)/gstreamer-@GST_MAJORMINOR@ plugindir = $(libdir)/gstreamer-@GST_MAJORMINOR@
# rebuild gst-register-@GST_MAJORMINOR@ if needed
$(top_builddir)/tools/gst-register-@GST_MAJORMINOR@$(EXEEXT):
cd $(top_builddir)/tools && make
# override to _not_ install the test plugins # override to _not_ install the test plugins
install-pluginLTLIBRARIES: install-pluginLTLIBRARIES:
@ -28,10 +24,6 @@ SUPPRESSIONS = $(top_srcdir)/common/gst.supp
clean-local: clean-local-check clean-local: clean-local-check
$(CHECK_REGISTRY):
$(TESTS_ENVIRONMENT) \
$(top_builddir)/tools/gst-register-@GST_MAJORMINOR@
check_PROGRAMS = \ check_PROGRAMS = \
gst/gst \ gst/gst \
gst/gstbin \ gst/gstbin \
@ -60,8 +52,7 @@ check_PROGRAMS = \
gst-libs/controller \ gst-libs/controller \
gst-libs/gdp gst-libs/gdp
TESTS = $(top_builddir)/tools/gst-register-@GST_MAJORMINOR@ \ TESTS = $(check_PROGRAMS)
$(check_PROGRAMS)
noinst_HEADERS = gst/capslist.h noinst_HEADERS = gst/capslist.h
@ -94,6 +85,5 @@ TESTS_THREADED = \
gst/gstobject gst/gstobject
VALGRIND_TESTS_DISABLE = \ VALGRIND_TESTS_DISABLE = \
$(top_builddir)/tools/gst-register-@GST_MAJORMINOR@ \
$(TESTS_THREADED) \ $(TESTS_THREADED) \
$(TESTS_TO_FIX) $(TESTS_TO_FIX)

View file

@ -29,7 +29,8 @@ GST_START_TEST (test_state_changes)
GstElement *element; GstElement *element;
GList *features, *f; GList *features, *f;
features = gst_registry_pool_feature_list (GST_TYPE_ELEMENT_FACTORY); features = gst_registry_get_feature_list (gst_registry_get_default (),
GST_TYPE_ELEMENT_FACTORY);
for (f = features; f; f = f->next) { for (f = features; f; f = f->next) {
GstPluginFeature *feature = f->data; GstPluginFeature *feature = f->data;

View file

@ -1,11 +1,4 @@
### assemble a list of programs we want to build and install ### assemble a list of programs we want to build and install
if GST_DISABLE_REGISTRY
GST_REGISTRY_SRC =
GST_REGISTRY_SRC_V =
else
GST_REGISTRY_SRC = gst-register
GST_REGISTRY_SRC_V = gst-register-@GST_MAJORMINOR@
endif
if GST_DISABLE_LOADSAVE if GST_DISABLE_LOADSAVE
GST_LOADSAVE_SRC = GST_LOADSAVE_SRC =
@ -34,17 +27,11 @@ GST_OTHER_SRC_V = \
### so all of the programs we want to build ### so all of the programs we want to build
bin_PROGRAMS = \ bin_PROGRAMS = \
$(GST_REGISTRY_SRC) $(GST_REGISTRY_SRC_V) \
$(GST_LOADSAVE_SRC) $(GST_LOADSAVE_SRC_V) \ $(GST_LOADSAVE_SRC) $(GST_LOADSAVE_SRC_V) \
$(GST_OTHER_SRC) $(GST_OTHER_SRC_V) $(GST_OTHER_SRC) $(GST_OTHER_SRC_V)
bin_SCRIPTS = gst-feedback-@GST_MAJORMINOR@ bin_SCRIPTS = gst-feedback-@GST_MAJORMINOR@
# make sure each versioned tool has the right source file and flags # make sure each versioned tool has the right source file and flags
if !GST_DISABLE_REGISTRY
gst_register_@GST_MAJORMINOR@_SOURCES = gst-register.c
gst_register_@GST_MAJORMINOR@_CFLAGS = $(GST_OBJ_CFLAGS)
gst_register_@GST_MAJORMINOR@_LDFLAGS = $(GST_OBJ_LIBS)
endif
if !GST_DISABLE_LOADSAVE if !GST_DISABLE_LOADSAVE
gst_complete_@GST_MAJORMINOR@_SOURCES = gst-complete.c gst_complete_@GST_MAJORMINOR@_SOURCES = gst-complete.c
gst_complete_@GST_MAJORMINOR@_CFLAGS = $(GST_OBJ_CFLAGS) gst_complete_@GST_MAJORMINOR@_CFLAGS = $(GST_OBJ_CFLAGS)
@ -77,9 +64,6 @@ gst-feedback-@GST_MAJORMINOR@: gst-feedback-m.m
chmod +x $@ chmod +x $@
# make sure each unversioned tool comes from gst-run.c # make sure each unversioned tool comes from gst-run.c
if !GST_DISABLE_REGISTRY
gst_register_SOURCES = gst-run.c
endif
if !GST_DISABLE_LOADSAVE if !GST_DISABLE_LOADSAVE
gst_complete_SOURCES = gst-run.c gst_complete_SOURCES = gst-run.c
gst_compprep_SOURCES = gst-run.c gst_compprep_SOURCES = gst-run.c
@ -99,12 +83,6 @@ LDADD = $(GLIB_ONLY_LIBS) $(POPT_LIBS)
AM_CPPFLAGS = $(GLIB_ONLY_CFLAGS) $(POPT_CFLAGS) AM_CPPFLAGS = $(GLIB_ONLY_CFLAGS) $(POPT_CFLAGS)
### man pages we want to install ### man pages we want to install
if GST_DISABLE_REGISTRY
GST_REGISTRY_MAN=
else
GST_REGISTRY_MAN = gst-register-@GST_MAJORMINOR@.1
endif
if GST_DISABLE_LOADSAVE if GST_DISABLE_LOADSAVE
GST_LOADSAVE_MAN= GST_LOADSAVE_MAN=
else else
@ -122,7 +100,7 @@ GST_OTHER_MAN = \
gst-typefind-@GST_MAJORMINOR@.1 \ gst-typefind-@GST_MAJORMINOR@.1 \
gst-xmlinspect-@GST_MAJORMINOR@.1 gst-xmlinspect-@GST_MAJORMINOR@.1
manpages = $(GST_REGISTRY_MAN) $(GST_LOADSAVE_MAN) $(GST_OTHER_MAN) manpages = $(GST_LOADSAVE_MAN) $(GST_OTHER_MAN)
CLEANFILES = $(manpages) $(bin_SCRIPTS) CLEANFILES = $(manpages) $(bin_SCRIPTS)
man_MANS = $(manpages) man_MANS = $(manpages)
@ -138,7 +116,6 @@ EXTRA_DIST = \
gst-inspect.1.in \ gst-inspect.1.in \
gst-launch.1.in \ gst-launch.1.in \
gst-md5sum.1.in \ gst-md5sum.1.in \
gst-register.1.in \
gst-typefind.1.in \ gst-typefind.1.in \
gst-xmlinspect.1.in \ gst-xmlinspect.1.in \
gst-xmllaunch.1.in \ gst-xmllaunch.1.in \
@ -152,7 +129,6 @@ EXTRA_DIST = \
-e s,gst-inspect,gst-inspect-@GST_MAJORMINOR@,g \ -e s,gst-inspect,gst-inspect-@GST_MAJORMINOR@,g \
-e s,gst-launch,gst-launch-@GST_MAJORMINOR@,g \ -e s,gst-launch,gst-launch-@GST_MAJORMINOR@,g \
-e s,gst-md5sum,gst-md5sum-@GST_MAJORMINOR@,g \ -e s,gst-md5sum,gst-md5sum-@GST_MAJORMINOR@,g \
-e s,gst-register,gst-register-@GST_MAJORMINOR@,g \
-e s,gst-typefind,gst-typefind-@GST_MAJORMINOR@,g \ -e s,gst-typefind,gst-typefind-@GST_MAJORMINOR@,g \
-e s,gst-xmlinspect,gst-xmlinspect-@GST_MAJORMINOR@,g \ -e s,gst-xmlinspect,gst-xmlinspect-@GST_MAJORMINOR@,g \
-e s,gst-xmllaunch,gst-xmllaunch-@GST_MAJORMINOR@,g \ -e s,gst-xmllaunch,gst-xmllaunch-@GST_MAJORMINOR@,g \

View file

@ -26,7 +26,7 @@ main (int argc, char *argv[])
{ {
xmlDocPtr doc; xmlDocPtr doc;
xmlNodePtr factorynode, padnode, argnode, optionnode; xmlNodePtr factorynode, padnode, argnode, optionnode;
GList *plugins, *features, *padtemplates; GList *element_factories, *padtemplates, *g;
const GList *pads; const GList *pads;
GstElement *element; GstElement *element;
GstPad *pad; GstPad *pad;
@ -44,25 +44,13 @@ main (int argc, char *argv[])
doc->xmlRootNode = xmlNewDocNode (doc, NULL, doc->xmlRootNode = xmlNewDocNode (doc, NULL,
(xmlChar *) "GST-CompletionRegistry", NULL); (xmlChar *) "GST-CompletionRegistry", NULL);
plugins = g_list_copy (gst_registry_pool_plugin_list ()); element_factories =
while (plugins) { gst_registry_get_feature_list (gst_registry_get_default (),
GstPlugin *plugin; GST_TYPE_ELEMENT_FACTORY);
for (g = element_factories; g; g = g_list_next (g)) {
plugin = (GstPlugin *) (plugins->data);
plugins = g_list_next (plugins);
features = g_list_copy (gst_plugin_get_feature_list (plugin));
while (features) {
GstPluginFeature *feature;
GstElementFactory *factory; GstElementFactory *factory;
feature = GST_PLUGIN_FEATURE (features->data); factory = GST_ELEMENT_FACTORY (g->data);
features = g_list_next (features);
if (!GST_IS_ELEMENT_FACTORY (feature))
continue;
factory = GST_ELEMENT_FACTORY (feature);
factorynode = xmlNewChild (doc->xmlRootNode, NULL, (xmlChar *) "element", factorynode = xmlNewChild (doc->xmlRootNode, NULL, (xmlChar *) "element",
NULL); NULL);
@ -132,7 +120,6 @@ main (int argc, char *argv[])
g_free (value); g_free (value);
} }
} }
}
g_free (property_specs); g_free (property_specs);
} }
} }

View file

@ -827,7 +827,7 @@ print_element_list (gboolean print_all)
{ {
GList *plugins; GList *plugins;
plugins = gst_registry_pool_plugin_list (); plugins = gst_default_registry_get_plugin_list ();
while (plugins) { while (plugins) {
GList *features; GList *features;
GstPlugin *plugin; GstPlugin *plugin;
@ -990,21 +990,22 @@ print_element_features (const gchar * element_name)
/* FIXME implement other pretty print function for these */ /* FIXME implement other pretty print function for these */
#ifndef GST_DISABLE_INDEX #ifndef GST_DISABLE_INDEX
feature = gst_registry_pool_find_feature (element_name, feature = gst_default_registry_find_feature (element_name,
GST_TYPE_INDEX_FACTORY); GST_TYPE_INDEX_FACTORY);
if (feature) { if (feature) {
n_print ("%s: an index\n", element_name); n_print ("%s: an index\n", element_name);
return 0; return 0;
} }
#endif #endif
feature = gst_registry_pool_find_feature (element_name, feature = gst_default_registry_find_feature (element_name,
GST_TYPE_TYPE_FIND_FACTORY); GST_TYPE_TYPE_FIND_FACTORY);
if (feature) { if (feature) {
n_print ("%s: a typefind function\n", element_name); n_print ("%s: a typefind function\n", element_name);
return 0; return 0;
} }
#ifndef GST_DISABLE_URI #ifndef GST_DISABLE_URI
feature = gst_registry_pool_find_feature (element_name, GST_TYPE_URI_HANDLER); feature = gst_default_registry_find_feature (element_name,
GST_TYPE_URI_HANDLER);
if (feature) { if (feature) {
n_print ("%s: an uri handler\n", element_name); n_print ("%s: an uri handler\n", element_name);
return 0; return 0;
@ -1020,6 +1021,10 @@ print_element_info (GstElementFactory * factory, gboolean print_names)
GstElement *element; GstElement *element;
gint maxlevel = 0; gint maxlevel = 0;
factory =
GST_ELEMENT_FACTORY (gst_plugin_feature_load (GST_PLUGIN_FEATURE
(factory)));
element = gst_element_factory_create (factory, NULL); element = gst_element_factory_create (factory, NULL);
if (!element) { if (!element) {
g_print ("couldn't construct element for some reason\n"); g_print ("couldn't construct element for some reason\n");
@ -1032,8 +1037,8 @@ print_element_info (GstElementFactory * factory, gboolean print_names)
_name = ""; _name = "";
print_factory_details_info (factory); print_factory_details_info (factory);
if (GST_PLUGIN_FEATURE (factory)->manager) { if (GST_PLUGIN_FEATURE (factory)->plugin) {
GstPlugin *plugin = (GstPlugin *) GST_PLUGIN_FEATURE (factory)->manager; GstPlugin *plugin = (GstPlugin *) GST_PLUGIN_FEATURE (factory)->plugin;
print_plugin_info (plugin); print_plugin_info (plugin);
} }
@ -1100,7 +1105,7 @@ main (int argc, char *argv[])
/* otherwise check if it's a plugin */ /* otherwise check if it's a plugin */
if (retval) { if (retval) {
plugin = gst_registry_pool_find_plugin (arg); plugin = gst_default_registry_find_plugin (arg);
/* if there is such a plugin, print out info */ /* if there is such a plugin, print out info */
if (plugin) { if (plugin) {

View file

@ -1,172 +0,0 @@
/* GStreamer
* Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
* 2000 Wim Taymans <wtay@chello.be>
*
* gst-register.c: Plugin subsystem for loading elements, types, and libs
*
* 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.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <gst/gst.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <string.h>
#include <errno.h>
#include <locale.h>
#include "gst/gst-i18n-app.h"
static gint num_features = 0;
static gint num_plugins = 0;
static void
plugin_added_func (GstRegistry * registry, GstPlugin * plugin,
gpointer user_data)
{
g_print (_("Added plugin %s with %d %s.\n"), plugin->desc.name,
plugin->numfeatures,
ngettext ("feature", "features", plugin->numfeatures));
num_features += plugin->numfeatures;
num_plugins++;
}
static void
spawn_all_in_dir (const char *dirname)
{
char *argv[2] = { NULL, NULL };
GDir *dir;
const char *file;
/* g_print("spawning all in %s\n", dirname); */
dir = g_dir_open (dirname, 0, NULL);
if (dir == NULL)
return;
while ((file = g_dir_read_name (dir))) {
argv[0] = g_build_filename (dirname, file, NULL);
g_print ("running %s\n", argv[0]);
g_spawn_sync (NULL, argv, NULL, G_SPAWN_FILE_AND_ARGV_ZERO, NULL, NULL,
NULL, NULL, NULL, NULL);
g_free (argv[0]);
}
g_dir_close (dir);
}
int
main (int argc, char *argv[])
{
GList *registries;
GList *path_spill = NULL; /* used for path spill from failing registries */
#ifdef GETTEXT_PACKAGE
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
#endif
/* Init gst */
_gst_registry_auto_load = FALSE;
gst_init (&argc, &argv);
registries = gst_registry_pool_list ();
registries = g_list_reverse (registries);
while (registries) {
GstRegistry *registry = GST_REGISTRY (registries->data);
GList *dir_list;
GList *iter;
char *dir;
if (path_spill) {
GList *iter;
/* add spilled paths to this registry;
* since they're spilled they probably weren't loaded correctly
* so we should give a lower priority registry the chance to do them */
for (iter = path_spill; iter; iter = iter->next) {
g_print (_("Added path %s to %s \n"),
(const char *) iter->data, registry->name);
gst_registry_add_path (registry, (const gchar *) iter->data);
}
g_list_free (path_spill);
path_spill = NULL;
}
g_signal_connect (G_OBJECT (registry), "plugin_added",
G_CALLBACK (plugin_added_func), NULL);
if (registry->flags & GST_REGISTRY_WRITABLE) {
char *location;
g_object_get (registry, "location", &location, NULL);
g_print (_("Rebuilding %s (%s) ...\n"), registry->name, location);
g_free (location);
gst_registry_rebuild (registry);
gst_registry_save (registry);
} else {
g_print (_("Trying to load %s ...\n"), registry->name);
if (!gst_registry_load (registry)) {
g_print (_("Error loading %s\n"), registry->name);
/* move over paths from this registry to the next one */
path_spill = g_list_concat (path_spill,
gst_registry_get_path_list (registry));
/* this assertion triggers for a non-readable/writable user registry,
* see #148283 */
/* g_assert (path_spill != NULL); */
}
/* also move over paths if the registry wasn't writable
* FIXME: we should check if the paths that were loaded from this
registry get removed from the path_list so we only try to
spill paths that could not be registered */
/* Until that is done, don't spill paths when registry is not writable
(e.g. case of user running gst-register and sysreg not writable) */
/*
path_spill = g_list_concat (path_spill,
gst_registry_get_path_list (registry));
*/
}
dir_list = gst_registry_get_path_list (registry);
for (iter = dir_list; iter; iter = iter->next) {
dir =
g_build_filename ((const char *) iter->data, "register-scripts",
NULL);
spawn_all_in_dir (dir);
g_free (dir);
}
g_list_free (dir_list);
registries = g_list_next (registries);
}
g_print (_("Loaded %d plugins with %d %s.\n"), num_plugins, num_features,
ngettext ("feature", "features", num_features));
return (0);
}

View file

@ -612,7 +612,7 @@ print_element_list (void)
{ {
GList *plugins; GList *plugins;
plugins = gst_registry_pool_plugin_list (); plugins = gst_default_registry_get_plugin_list ();
while (plugins) { while (plugins) {
GList *features; GList *features;
GstPlugin *plugin; GstPlugin *plugin;
@ -796,21 +796,21 @@ main (int argc, char *argv[])
/* FIXME implement other pretty print function for these */ /* FIXME implement other pretty print function for these */
#ifndef GST_DISABLE_INDEX #ifndef GST_DISABLE_INDEX
feature = gst_registry_pool_find_feature (argv[1], feature = gst_default_registry_find_feature (argv[1],
GST_TYPE_INDEX_FACTORY); GST_TYPE_INDEX_FACTORY);
if (feature) { if (feature) {
g_print ("%s: an index\n", argv[1]); g_print ("%s: an index\n", argv[1]);
return 0; return 0;
} }
#endif #endif
feature = gst_registry_pool_find_feature (argv[1], feature = gst_default_registry_find_feature (argv[1],
GST_TYPE_TYPE_FIND_FACTORY); GST_TYPE_TYPE_FIND_FACTORY);
if (feature) { if (feature) {
g_print ("%s: a type find function\n", argv[1]); g_print ("%s: a type find function\n", argv[1]);
return 0; return 0;
} }
#ifndef GST_DISABLE_URI #ifndef GST_DISABLE_URI
feature = gst_registry_pool_find_feature (argv[1], feature = gst_default_registry_find_feature (argv[1],
GST_TYPE_URI_HANDLER); GST_TYPE_URI_HANDLER);
if (feature) { if (feature) {
g_print ("%s: an uri handler\n", argv[1]); g_print ("%s: an uri handler\n", argv[1]);
@ -825,7 +825,7 @@ main (int argc, char *argv[])
} }
/* otherwise assume it's a plugin */ /* otherwise assume it's a plugin */
plugin = gst_registry_pool_find_plugin (argv[1]); plugin = gst_default_registry_find_plugin (argv[1]);
/* if there is such a plugin, print out info */ /* if there is such a plugin, print out info */