Totally rewritten registry handling.
authorWim Taymans <wim.taymans@gmail.com>
Wed, 8 May 2002 20:40:48 +0000 (20:40 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Wed, 8 May 2002 20:40:48 +0000 (20:40 +0000)
Original commit message from CVS:
Totally rewritten registry handling.
- move the registry save/load code into a gstregistry subclass, this
will make it possible to use other registries (flat file, web based,
RDBMS type, etc..)
- a simple GMarkup xml registry is implemented
- use standard statically linked plugins for core elements.
- GstPlugin has a very well defined set of functions now
A little bytestream hack..
Added more info to -inspect.
Some more debugging info for clocking.
Small cleanups

I use ./gst-register --gst-plugin-path=/opt/src/sourceforge/gst-plugins/gst-libs:/opt/src/sourceforge/gst-plugins/
to register core and gst-plugins now.

44 files changed:
configure.ac
gst/Makefile.am
gst/autoplug/gstautoplugcache.c
gst/autoplug/gstspider.c
gst/autoplug/gststaticautoplug.c
gst/autoplug/gststaticautoplugrender.c
gst/elements/gstfilesrc.c
gst/gst.c
gst/gst.h
gst/gstautoplug.c
gst/gstautoplug.h
gst/gstclock.c
gst/gstelement.h
gst/gstelementfactory.c
gst/gstevent.c
gst/gstevent.h
gst/gstpad.c
gst/gstpad.h
gst/gstplugin.c
gst/gstplugin.h
gst/gstpluginfeature.c
gst/gstpluginfeature.h
gst/gstregistry.c
gst/gstregistry.h
gst/gstscheduler.c
gst/gstscheduler.h
gst/gsttype.c
gst/gsttype.h
gst/gsttypefind.c
gst/registries/Makefile.am [new file with mode: 0644]
gst/registries/gstxmlregistry.c [new file with mode: 0644]
gst/registries/gstxmlregistry.h [new file with mode: 0644]
gst/registries/registrytest.c [new file with mode: 0644]
gst/schedulers/gstbasicscheduler.c
libs/gst/bytestream/bytestream.c
ltmain.sh
plugins/elements/gstfilesrc.c
tests/old/testsuite/cleanup/cleanup5.c
tests/sched/dynamic-pipeline.c
testsuite/cleanup/cleanup5.c
tools/gst-compprep.c
tools/gst-inspect.c
tools/gst-launch.c
tools/gst-register.c

index 95d581a..af35907 100644 (file)
@@ -401,6 +401,7 @@ gst/elements/Makefile
 gst/parse/Makefile
 gst/schedulers/Makefile
 gst/types/Makefile
+gst/registries/Makefile
 libs/Makefile
 libs/gst/Makefile
 libs/gst/bytestream/Makefile
index 3ddcf3c..fc1acbe 100644 (file)
@@ -44,7 +44,7 @@ endif
 
 EXTRA_libgstreamer_la_SOURCES = gstcpuid_i386.s gstmarshal.list gstxml.c gsttypefind.c gstparse.c gstautoplug.c gsttrace.c
 
-SUBDIRS = parse . $(GST_AUTOPLUG_DIRS) elements schedulers types
+SUBDIRS = parse registries . $(GST_AUTOPLUG_DIRS) elements schedulers types 
 DIST_SUBDIRS = autoplug elements parse types schedulers
 
 libcothreads_la_SOURCES = cothreads.c
@@ -157,7 +157,7 @@ libgstreamer_la_CFLAGS = -D_GNU_SOURCE -DGST_CONFIG_DIR=\""$(GST_CONFIG_DIR)"\"
 # the compiler shoots cothreads.c in the head at -O6
 libcothreads_la_CFLAGS = $(libgstreamer_la_CFLAGS) -O2 
 
-libgstreamer_la_LIBADD = $(LIBGST_LIBS) parse/libgstparse.la
+libgstreamer_la_LIBADD = $(LIBGST_LIBS) parse/libgstparse.la registries/libgstxmlregistry.la
 libgstreamer_la_LDFLAGS = @GST_LT_LDFLAGS@ -version-info @GST_LIBVERSION@ 
 
 EXTRA_DIST = ROADMAP
index 783f9a1..7601e02 100644 (file)
@@ -237,6 +237,7 @@ gst_autoplugcache_loop (GstElement *element)
         gst_object_ref (GST_OBJECT (cache));
         GST_DEBUG(GST_CAT_AUTOPLUG, "state changed during signal, aborting");
         gst_element_yield (GST_ELEMENT (cache));
+       return;
       }
       gst_object_unref (GST_OBJECT (cache));
     }
index a8f90fe..9546617 100644 (file)
@@ -178,7 +178,8 @@ gst_spider_init (GstSpider *spider)
 {
   /* use only elements which have sources and sinks and where the sinks have caps */
   /* FIXME: How do we handle factories that are added after the spider was constructed? */
-  spider->factories = gst_autoplug_factories_filters_with_sink_caps ((GList *) gst_element_factory_get_list ());
+  spider->factories = gst_autoplug_factories_filters_with_sink_caps ((GList *) 
+                 gst_registry_pool_feature_list (GST_TYPE_ELEMENT_FACTORY));
 
   spider->connections = NULL;
 }
index d4d8f1b..9fb3d3c 100644 (file)
@@ -236,7 +236,7 @@ gst_autoplug_pads_autoplug (GstElement *src, GstElement *sink)
 static const GList*
 gst_autoplug_element_factory_get_list (gpointer data)
 {
-  return gst_element_factory_get_list ();
+  return gst_registry_pool_feature_list (GST_TYPE_ELEMENT_FACTORY);
 }
 
 typedef struct {
index fee73cc..ec60b56 100644 (file)
@@ -154,7 +154,7 @@ gst_autoplug_can_match (GstElementFactory *src, GstElementFactory *dest)
       if (desttemp->direction == GST_PAD_SINK && desttemp->presence != GST_PAD_REQUEST) {
        if (gst_caps_check_compatibility (GST_PAD_TEMPLATE_CAPS (srctemp), GST_PAD_TEMPLATE_CAPS (desttemp))) {
          GST_DEBUG (GST_CAT_AUTOPLUG_ATTEMPT,
-                         "factory \"%s\" can connect with factory \"%s\"\n", 
+                         "factory \"%s\" can connect with factory \"%s\"", 
                          GST_OBJECT_NAME (src), GST_OBJECT_NAME (dest));
           return TRUE;
        }
@@ -163,7 +163,7 @@ gst_autoplug_can_match (GstElementFactory *src, GstElementFactory *dest)
     }
   }
   GST_DEBUG (GST_CAT_AUTOPLUG_ATTEMPT,
-                 "factory \"%s\" cannot connect with factory \"%s\"\n", 
+                 "factory \"%s\" cannot connect with factory \"%s\"", 
                          GST_OBJECT_NAME (src), GST_OBJECT_NAME (dest));
   return FALSE;
 }
@@ -240,7 +240,7 @@ gst_autoplug_pads_autoplug (GstElement *src, GstElement *sink)
 static GList*
 gst_autoplug_element_factory_get_list (gpointer data)
 {
-  return (GList *) gst_element_factory_get_list ();
+  return (GList *) gst_registry_pool_feature_list (GST_TYPE_ELEMENT_FACTORY);
 }
 
 typedef struct {
index 90d635c..f67bd0f 100644 (file)
@@ -569,15 +569,17 @@ gst_filesrc_open_file (GstFileSrc *src)
                       src->filename, strerror (errno), NULL);
     return FALSE;
   } else {
-               /* check if it is a regular file, otherwise bail out */
-               struct stat stat_results;
-               fstat(src->fd, &stat_results);
-               if (!S_ISREG(stat_results.st_mode)) {
-                       gst_element_error (GST_ELEMENT (src), "opening file \"%s\" failed. it isn't a regular file", 
-                                                                                                src->filename, NULL);
-                       close(src->fd);
-                       return FALSE;
-               }
+    /* check if it is a regular file, otherwise bail out */
+    struct stat stat_results;
+
+    fstat(src->fd, &stat_results);
+
+    if (!S_ISREG(stat_results.st_mode)) {
+      gst_element_error (GST_ELEMENT (src), "opening file \"%s\" failed. it isn't a regular file", 
+                                       src->filename, NULL);
+      close(src->fd);
+      return FALSE;
+    }
                
     /* find the file length */
     src->filelen = lseek (src->fd, 0, SEEK_END);
index 2e69147..4fd4b04 100644 (file)
--- a/gst/gst.c
+++ b/gst/gst.c
 #ifndef GST_DISABLE_TYPE_FIND
 #include "gsttypefind.h"
 #endif
+#include "registries/gstxmlregistry.h"
 
 #define MAX_PATH_SPLIT 16
 #define GST_PLUGIN_SEPARATOR ","
 
 gchar *_gst_progname;
 
+gboolean _gst_registry_auto_load = TRUE;
+static GstRegistry *_global_registry;
+static GstRegistry *_user_registry;
 
 extern gint _gst_trace_on;
-extern gboolean _gst_plugin_spew;
 
 static void            load_plugin_func        (gpointer data, gpointer user_data);
 static void            init_popt_callback      (poptContext context, enum poptCallbackReason reason,
@@ -141,14 +144,14 @@ gst_init_with_popt_table (int *argc, char **argv[], const struct poptOption *pop
   const struct poptOption *options;
   /* this is probably hacky, no? */
   const struct poptOption options_with[] = {
-    {NULL,              NUL, POPT_ARG_INCLUDE_TABLE, poptHelpOptions,          0, "Help options:", NULL},
-    {NULL,              NUL, POPT_ARG_INCLUDE_TABLE, (struct poptOption *) gst_init_get_popt_table(), 0, "GStreamer options:", NULL},
-    {NULL,              NUL, POPT_ARG_INCLUDE_TABLE, (struct poptOption *) popt_options,               0, "Application options:", NULL},
+    {NULL, NUL, POPT_ARG_INCLUDE_TABLE, poptHelpOptions,                                0, "Help options:", NULL},
+    {NULL, NUL, POPT_ARG_INCLUDE_TABLE, (struct poptOption *) gst_init_get_popt_table(), 0, "GStreamer options:", NULL},
+    {NULL, NUL, POPT_ARG_INCLUDE_TABLE, (struct poptOption *) popt_options,             0, "Application options:", NULL},
     POPT_TABLEEND
   };
   const struct poptOption options_without[] = {
-    {NULL,              NUL, POPT_ARG_INCLUDE_TABLE, poptHelpOptions,          0, "Help options:", NULL},
-    {NULL,              NUL, POPT_ARG_INCLUDE_TABLE, (struct poptOption *) gst_init_get_popt_table(), 0, "GStreamer options:", NULL},
+    {NULL, NUL, POPT_ARG_INCLUDE_TABLE, poptHelpOptions,                                0, "Help options:", NULL},
+    {NULL, NUL, POPT_ARG_INCLUDE_TABLE, (struct poptOption *) gst_init_get_popt_table(), 0, "GStreamer options:", NULL},
     POPT_TABLEEND
   };
 
@@ -199,8 +202,10 @@ gst_init_with_popt_table (int *argc, char **argv[], const struct poptOption *pop
 static void 
 add_path_func (gpointer data, gpointer user_data)
 {
+  GstRegistry *registry = GST_REGISTRY (user_data);
+  
   GST_INFO (GST_CAT_GST_INIT, "Adding plugin path: \"%s\"", (gchar *)data);
-  gst_plugin_add_path ((gchar *)data);
+  gst_registry_add_path (registry, (gchar *)data);
 }
 
 static void 
@@ -213,7 +218,9 @@ static void
 load_plugin_func (gpointer data, gpointer user_data)
 {
   gboolean ret;
-  ret = gst_plugin_load ((gchar *)data);
+  //ret = gst_plugin_load ((gchar *)data);
+  ret = FALSE;
+
   if (ret)
     GST_INFO (GST_CAT_GST_INIT, "Loaded plugin: \"%s\"", (gchar *)data);
   else
@@ -234,7 +241,7 @@ parse_number (const gchar *number, guint32 *val)
 }
 
 static void
-split_and_iterate (const gchar *stringlist, gchar *separator, GFunc iterator) 
+split_and_iterate (const gchar *stringlist, gchar *separator, GFunc iterator, gpointer user_data
 {
   gchar **strings;
   gint j = 0;
@@ -246,7 +253,7 @@ split_and_iterate (const gchar *stringlist, gchar *separator, GFunc iterator)
     lastlist = NULL;
 
     while (strings[j]) {
-      iterator (strings[j], NULL);
+      iterator (strings[j], user_data);
       if (++j == MAX_PATH_SPLIT) {
         lastlist = g_strdup (strings[j]);
         g_strfreev (strings); 
@@ -260,12 +267,67 @@ split_and_iterate (const gchar *stringlist, gchar *separator, GFunc iterator)
 static void
 init_pre (void)
 {
+  const gchar *homedir;
+  gchar *user_reg;
+
   if (!g_thread_supported ())
     g_thread_init (NULL);
   
   g_type_init();
+
+  _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_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/schedulers");
+#else
+  /* add the main (installed) library path */
+  gst_registry_add_path (_global_registry, PLUGINS_DIR);
+#endif /* PLUGINS_USE_BUILDDIR */
+
+  gst_registry_pool_add (_global_registry, 100);
+
+  homedir = g_get_home_dir ();
+  user_reg = g_strjoin ("/", homedir, LOCAL_REGISTRY_FILE, NULL);
+  _user_registry = gst_xml_registry_new ("user_registry", user_reg);
+  gst_registry_pool_add (_user_registry, 50);
+
+  g_free (user_reg);
+}
+
+static gboolean
+gst_register_core_elements (GModule *module, GstPlugin *plugin)
+{
+  GstElementFactory *factory;
+
+  /* register some standard builtin types */
+  factory = gst_element_factory_new ("bin", gst_bin_get_type (), &gst_bin_details);
+  gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
+  factory = gst_element_factory_new ("pipeline", gst_pipeline_get_type (), &gst_pipeline_details);
+  gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
+  factory = gst_element_factory_new ("thread", gst_thread_get_type (), &gst_thread_details);
+  gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
+  factory = gst_element_factory_new ("queue", gst_queue_get_type (), &gst_queue_details);
+  gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
+#ifndef GST_DISABLE_TYPE_FIND
+  factory = gst_element_factory_new ("typefind", gst_type_find_get_type (), &gst_type_find_details);
+  gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
+#endif
+
+  return TRUE;
 }
 
+static GstPluginDesc plugin_desc = {
+  GST_VERSION_MAJOR,           
+  GST_VERSION_MINOR,  
+  "gst_core_plugins",
+  gst_register_core_elements
+};                         
+
 static void
 init_post (void)
 {
@@ -294,8 +356,12 @@ init_post (void)
   gst_autoplug_factory_get_type ();
 #endif
 
+
   plugin_path = g_getenv("GST_PLUGIN_PATH");
-  split_and_iterate (plugin_path, G_SEARCHPATH_SEPARATOR_S, add_path_func);
+  split_and_iterate (plugin_path, G_SEARCHPATH_SEPARATOR_S, add_path_func, _global_registry);
+
+  /* register core plugins */
+  _gst_plugin_register_static (&plugin_desc);
  
   _gst_cpu_initialize ();
   _gst_props_initialize ();
@@ -305,6 +371,10 @@ init_post (void)
   _gst_buffer_initialize ();
   _gst_buffer_pool_initialize ();
 
+  if (_gst_registry_auto_load) {
+    gst_registry_pool_load_all ();
+  }
+
   /* if we need to preload plugins */
   if (preload_plugins) {
     g_slist_foreach (preload_plugins, load_plugin_func, NULL);
@@ -312,15 +382,6 @@ init_post (void)
     preload_plugins = NULL;
   }
 
-  /* register some standard builtin types */
-  gst_element_factory_new ("bin", gst_bin_get_type (), &gst_bin_details);
-  gst_element_factory_new ("pipeline", gst_pipeline_get_type (), &gst_pipeline_details);
-  gst_element_factory_new ("thread", gst_thread_get_type (), &gst_thread_details);
-  gst_element_factory_new ("queue", gst_queue_get_type (), &gst_queue_details);
-#ifndef GST_DISABLE_TYPE_FIND
-  gst_element_factory_new ("typefind", gst_type_find_get_type (), &gst_type_find_details);
-#endif
-
 #ifndef GST_DISABLE_TRACE
   _gst_trace_on = 0;
   if (_gst_trace_on) {
@@ -395,13 +456,12 @@ init_popt_callback (poptContext context, enum poptCallbackReason reason,
       gst_mask_help ();
       exit (0);
     case ARG_PLUGIN_SPEW:
-      _gst_plugin_spew = TRUE;
       break;
     case ARG_PLUGIN_PATH:
-      split_and_iterate (arg, G_SEARCHPATH_SEPARATOR_S, add_path_func);
+      split_and_iterate (arg, G_SEARCHPATH_SEPARATOR_S, add_path_func, _user_registry);
       break;
     case ARG_PLUGIN_LOAD:
-      split_and_iterate (arg, ",", prepare_for_load_plugin_func);
+      split_and_iterate (arg, ",", prepare_for_load_plugin_func, NULL);
       break;
     case ARG_SCHEDULER:
       gst_scheduler_factory_set_default_name (arg);
index 00935dc..473e401 100644 (file)
--- a/gst/gst.h
+++ b/gst/gst.h
@@ -62,12 +62,13 @@ extern "C" {
 #endif /* __cplusplus */
 
 /* initialize GST */
-void                    gst_init                (int *argc, char **argv[]);
-void                    gst_init_with_popt_table (int *argc, char **argv[], const struct poptOption *popt_options);
-const struct poptOption *gst_init_get_popt_table (void);
+void                           gst_init                        (int *argc, char **argv[]);
+void                           gst_init_with_popt_table        (int *argc, char **argv[], 
+                                                                const struct poptOption *popt_options);
+const struct poptOption*       gst_init_get_popt_table         (void);
 
-void                    gst_main                (void);
-void                    gst_main_quit           (void);
+void                           gst_main                        (void);
+void                           gst_main_quit                   (void);
 
 #ifdef __cplusplus
 }
index f2ef2c2..e0439b2 100644 (file)
@@ -27,8 +27,7 @@
 #include "gst_private.h"
 
 #include "gstautoplug.h"
-
-static GList* _gst_autoplugfactories;
+#include "gstregistry.h"
 
 enum {
   NEW_OBJECT,
@@ -171,11 +170,6 @@ gst_autoplug_to_renderers (GstAutoplug *autoplug, GstCaps *srccaps, GstElement *
 static void            gst_autoplug_factory_class_init                 (GstAutoplugFactoryClass *klass);
 static void            gst_autoplug_factory_init               (GstAutoplugFactory *factory);
 
-#ifndef GST_DISABLE_REGISTRY
-static xmlNodePtr      gst_autoplug_factory_save_thyself       (GstObject *object, xmlNodePtr parent);
-static void            gst_autoplug_factory_restore_thyself    (GstObject *object, xmlNodePtr parent);
-#endif
-
 static GstPluginFeatureClass *factory_parent_class = NULL;
 /* static guint gst_autoplug_factory_signals[LAST_SIGNAL] = { 0 }; */
 
@@ -215,19 +209,11 @@ gst_autoplug_factory_class_init (GstAutoplugFactoryClass *klass)
   gstpluginfeature_class = (GstPluginFeatureClass*) klass;
 
   factory_parent_class = g_type_class_ref (GST_TYPE_PLUGIN_FEATURE);
-
-#ifndef GST_DISABLE_REGISTRY
-  gstobject_class->save_thyself =      GST_DEBUG_FUNCPTR (gst_autoplug_factory_save_thyself);
-  gstobject_class->restore_thyself =   GST_DEBUG_FUNCPTR (gst_autoplug_factory_restore_thyself);
-#endif
-
-  _gst_autoplugfactories = NULL;
 }
 
 static void
 gst_autoplug_factory_init (GstAutoplugFactory *factory)
 {
-  _gst_autoplugfactories = g_list_prepend (_gst_autoplugfactories, factory);
 }
        
 
@@ -252,7 +238,7 @@ gst_autoplug_factory_new (const gchar *name, const gchar *longdesc, GType type)
     factory = GST_AUTOPLUG_FACTORY (g_object_new (GST_TYPE_AUTOPLUG_FACTORY, NULL));
   }
 
-  gst_object_set_name (GST_OBJECT (factory), name);
+  GST_PLUGIN_FEATURE_NAME (factory) = g_strdup (name);
   if (factory->longdesc)
     g_free (factory->longdesc);
   factory->longdesc = g_strdup (longdesc);
@@ -272,8 +258,6 @@ gst_autoplug_factory_destroy (GstAutoplugFactory *factory)
 {
   g_return_if_fail (factory != NULL);
 
-  _gst_autoplugfactories = g_list_remove (_gst_autoplugfactories, factory);
-
   /* we don't free the struct bacause someone might  have a handle to it.. */
 }
 
@@ -288,38 +272,20 @@ gst_autoplug_factory_destroy (GstAutoplugFactory *factory)
 GstAutoplugFactory*
 gst_autoplug_factory_find (const gchar *name)
 {
-  GList *walk;
-  GstAutoplugFactory *factory;
+  GstPluginFeature *feature;
 
-  g_return_val_if_fail(name != NULL, NULL);
+  g_return_val_if_fail (name != NULL, NULL);
 
   GST_DEBUG (0,"gstautoplug: find \"%s\"", name);
 
-  walk = _gst_autoplugfactories;
-  while (walk) {
-    factory = (GstAutoplugFactory *)(walk->data);
-    if (!strcmp (name, GST_OBJECT_NAME (factory)))
-      return factory;
-    walk = g_list_next (walk);
-  }
+  feature = gst_registry_pool_find_feature (name, GST_TYPE_AUTOPLUG_FACTORY);
+  if (feature)
+    return GST_AUTOPLUG_FACTORY (feature);
 
   return NULL;
 }
 
 /**
- * gst_autoplug_factory_get_list:
- *
- * Get the global list of autoplugfactories.
- *
- * Returns: GList of type #GstAutoplugFactory
- */
-const GList*
-gst_autoplug_factory_get_list (void)
-{
-  return _gst_autoplugfactories;
-}
-
-/**
  * gst_autoplug_factory_create:
  * @factory: the factory used to create the instance
  *
@@ -367,52 +333,3 @@ gst_autoplug_factory_make (const gchar *name)
 
   return gst_autoplug_factory_create (factory);
 }
-
-#ifndef GST_DISABLE_REGISTRY
-static xmlNodePtr
-gst_autoplug_factory_save_thyself (GstObject *object, xmlNodePtr parent)
-{
-  GstAutoplugFactory *factory;
-
-  g_return_val_if_fail(GST_IS_AUTOPLUG_FACTORY (object), parent);
-
-  factory = GST_AUTOPLUG_FACTORY (object);
-
-  if (GST_OBJECT_CLASS (factory_parent_class)->save_thyself) {
-    GST_OBJECT_CLASS (factory_parent_class)->save_thyself (object, parent);
-  }
-
-  xmlNewChild(parent,NULL,"longdesc", factory->longdesc);
-
-  return parent;
-}
-
-/**
- * gst_autoplug_factory_load_thyself:
- * @parent: the parent XML node pointer
- *
- * Load an autoplugfactory from the given XML parent node.
- *
- * Returns: A new factory based on the XML node.
- */
-static void
-gst_autoplug_factory_restore_thyself (GstObject *object, xmlNodePtr parent)
-{
-  GstAutoplugFactory *factory = GST_AUTOPLUG_FACTORY (object);
-  xmlNodePtr children = parent->xmlChildrenNode;
-
-  if (GST_OBJECT_CLASS (factory_parent_class)->restore_thyself) {
-    GST_OBJECT_CLASS (factory_parent_class)->restore_thyself (object, parent);
-  }
-
-  while (children) {
-    if (!strcmp(children->name, "name")) {
-      gst_object_set_name (GST_OBJECT (factory), xmlNodeGetContent(children));
-    }
-    if (!strcmp(children->name, "longdesc")) {
-      factory->longdesc = xmlNodeGetContent(children);
-    }
-    children = children->next;
-  }
-}
-#endif /* GST_DISABLE_REGISTRY */
index 3b50b2b..c8a750b 100644 (file)
@@ -110,11 +110,10 @@ struct _GstAutoplugFactoryClass {
 
 GType                  gst_autoplug_factory_get_type           (void);
 
-GstAutoplugFactory*    gst_autoplug_factory_new                        (const gchar *name, const gchar *longdesc, GType type);
+GstAutoplugFactory*    gst_autoplug_factory_new                (const gchar *name, const gchar *longdesc, GType type);
 void                    gst_autoplug_factory_destroy           (GstAutoplugFactory *factory);
 
 GstAutoplugFactory*    gst_autoplug_factory_find               (const gchar *name);
-const GList*           gst_autoplug_factory_get_list           (void);
 
 GstAutoplug*           gst_autoplug_factory_create             (GstAutoplugFactory *factory);
 GstAutoplug*           gst_autoplug_factory_make               (const gchar *name);
index 41f3cac..fa72ac2 100644 (file)
@@ -330,6 +330,7 @@ gst_clock_wait_async_func (GstClock *clock, GstClockTime time,
   g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
 
   if (!clock->active) {
+    GST_DEBUG (GST_CAT_CLOCK, "blocking on clock\n");
     g_mutex_lock (clock->active_mutex);        
     g_cond_wait (clock->active_cond, clock->active_mutex);     
     g_mutex_unlock (clock->active_mutex);      
@@ -478,7 +479,7 @@ gst_clock_wait_id (GstClock *clock, GstClockID id)
   entry->func = gst_clock_unlock_func;
   target = GST_CLOCK_ENTRY_TIME (entry) - current + current_real;
 
-  /* g_print ("%lld %lld %lld\n", target, current, current_real); */
+  GST_DEBUG (GST_CAT_CLOCK, "%llu %llu %llu\n", target, current, current_real); 
   
   if (target > current_real) {
     timeval.tv_usec = target % 1000000;
index ed1dc12..7b02291 100644 (file)
@@ -249,7 +249,7 @@ const gchar*                gst_element_state_get_name      (GstElementState state);
 GstElementFactory*     gst_element_get_factory         (GstElement *element);
 
 void                    gst_element_class_install_std_props    (GstElementClass *klass,
-                                                        const char      *first_name, ...);
+                                                                const char      *first_name, ...);
 
 GstBin*                        gst_element_get_managing_bin    (GstElement *element);
 
@@ -297,16 +297,14 @@ struct _GstElementFactoryClass {
 
 GType                  gst_element_factory_get_type            (void);
 
-GstElementFactory*     gst_element_factory_new                 (const gchar *name,GType type,
+GstElementFactory*     gst_element_factory_new                 (const gchar *name, GType type,
                                                                  GstElementDetails *details);
-
-GstElementFactory*     gst_element_factory_find                        (const gchar *name);
-const GList*           gst_element_factory_get_list            (void);
+GstElementFactory*     gst_element_factory_find                (const gchar *name);
 
 void                   gst_element_factory_add_pad_template    (GstElementFactory *elementfactory,
                                                                 GstPadTemplate *templ);
 
-gboolean               gst_element_factory_can_src_caps                (GstElementFactory *factory,
+gboolean               gst_element_factory_can_src_caps        (GstElementFactory *factory,
                                                                 GstCaps *caps);
 gboolean               gst_element_factory_can_sink_caps       (GstElementFactory *factory,
                                                                 GstCaps *caps);
@@ -314,7 +312,7 @@ gboolean            gst_element_factory_can_sink_caps       (GstElementFactory *factory,
 GstElement*            gst_element_factory_create              (GstElementFactory *factory,
                                                                 const gchar *name);
 /* FIXME this name is wrong, probably so is the one above it */
-GstElement*            gst_element_factory_make                        (const gchar *factoryname, const gchar *name);
+GstElement*            gst_element_factory_make                (const gchar *factoryname, const gchar *name);
 
 #ifdef __cplusplus
 }
index 00b8dda..8505d04 100644 (file)
 #include "gst_private.h"
 
 #include "gstelement.h"
+#include "gstregistry.h"
 
 static void            gst_element_factory_class_init          (GstElementFactoryClass *klass);
 static void            gst_element_factory_init                (GstElementFactory *factory);
 
-#ifndef GST_DISABLE_REGISTRY
-static void            gst_element_factory_restore_thyself     (GstObject *object, xmlNodePtr parent);
-static xmlNodePtr      gst_element_factory_save_thyself        (GstObject *object, xmlNodePtr parent);
-#endif
-
 static void            gst_element_factory_unload_thyself      (GstPluginFeature *feature);
 
-/* global list of registered elementfactories */
-static GList* _gst_elementfactories;
-
 static GstPluginFeatureClass *parent_class = NULL;
 /* static guint gst_element_factory_signals[LAST_SIGNAL] = { 0 }; */
 
@@ -78,14 +71,8 @@ gst_element_factory_class_init (GstElementFactoryClass *klass)
 
   parent_class = g_type_class_ref (GST_TYPE_PLUGIN_FEATURE);
 
-#ifndef GST_DISABLE_REGISTRY
-  gstobject_class->save_thyself =      GST_DEBUG_FUNCPTR (gst_element_factory_save_thyself);
-  gstobject_class->restore_thyself =   GST_DEBUG_FUNCPTR (gst_element_factory_restore_thyself);
-#endif
-
   gstpluginfeature_class->unload_thyself =     GST_DEBUG_FUNCPTR (gst_element_factory_unload_thyself);
 
-  _gst_elementfactories = NULL;
 }
 
 static void
@@ -93,8 +80,6 @@ gst_element_factory_init (GstElementFactory *factory)
 {
   factory->padtemplates = NULL;
   factory->numpadtemplates = 0;
-
-  _gst_elementfactories = g_list_prepend (_gst_elementfactories, factory);
 }
 
 /**
@@ -108,37 +93,19 @@ gst_element_factory_init (GstElementFactory *factory)
 GstElementFactory*
 gst_element_factory_find (const gchar *name)
 {
-  GList *walk;
-  GstElementFactory *factory;
+  GstPluginFeature *feature;
 
   g_return_val_if_fail(name != NULL, NULL);
 
-  walk = _gst_elementfactories;
-  while (walk) {
-    factory = (GstElementFactory *)(walk->data);
-    if (!strcmp(name, GST_OBJECT_NAME (factory)))
-      return factory;
-    walk = g_list_next(walk);
-  }
+  feature = gst_registry_pool_find_feature (name, GST_TYPE_ELEMENT_FACTORY);
+  if (feature)
+    return GST_ELEMENT_FACTORY (feature);
 
   /* this should be an ERROR */
   GST_DEBUG (GST_CAT_ELEMENT_FACTORY,"no such elementfactory \"%s\"", name);
   return NULL;
 }
 
-/**
- * gst_element_factory_get_list:
- *
- * Get the global list of element factories.
- *
- * Returns: GList of type #GstElementFactory
- */
-const GList*
-gst_element_factory_get_list (void)
-{
-  return _gst_elementfactories;
-}
-
 static void
 gst_element_details_free (GstElementDetails *dp)
 {
@@ -185,11 +152,10 @@ gst_element_factory_new (const gchar *name, GType type,
   if (!factory)
     factory = GST_ELEMENT_FACTORY (g_object_new (GST_TYPE_ELEMENT_FACTORY, NULL));
 
-  if (factory->details_dynamic)
-    {
-      gst_element_details_free (factory->details);
-      factory->details_dynamic = FALSE;
-    }
+  if (factory->details_dynamic) {
+    gst_element_details_free (factory->details);
+    factory->details_dynamic = FALSE;
+  }
 
   factory->details = details;
 
@@ -198,7 +164,7 @@ gst_element_factory_new (const gchar *name, GType type,
   else if (factory->type != type)
     g_critical ("`%s' requested type change (!)", name);
 
-  gst_object_set_name (GST_OBJECT (factory), name);
+  GST_PLUGIN_FEATURE (factory)->name = g_strdup (name);
 
   return factory;
 }
@@ -231,7 +197,7 @@ gst_element_factory_create (GstElementFactory *factory,
 
   if (factory->type == 0) {
       g_critical ("Factory for `%s' has no type",
-                 gst_object_get_name (GST_OBJECT (factory)));
+                 GST_PLUGIN_FEATURE_NAME (factory));
       return NULL;
   }
 
@@ -246,7 +212,8 @@ gst_element_factory_create (GstElementFactory *factory,
     oclass->elementfactory = factory;
 
     /* copy pad template pointers to the element class, allow for custom padtemplates */
-    oclass->padtemplates = g_list_concat (oclass->padtemplates, factory->padtemplates);
+    oclass->padtemplates = g_list_concat (oclass->padtemplates, 
+                   g_list_copy (factory->padtemplates));
     oclass->numpadtemplates += factory->numpadtemplates;
   }
 
@@ -402,93 +369,3 @@ gst_element_factory_unload_thyself (GstPluginFeature *feature)
 
   factory->type = 0;
 }
-
-#ifndef GST_DISABLE_REGISTRY
-static xmlNodePtr
-gst_element_factory_save_thyself (GstObject *object,
-                                xmlNodePtr parent)
-{
-  GList *pads;
-  GstElementFactory *factory;
-
-  factory = GST_ELEMENT_FACTORY (object);
-  
-  if (GST_OBJECT_CLASS (parent_class)->save_thyself) {
-    GST_OBJECT_CLASS (parent_class)->save_thyself (object, parent);
-  }
-
-  g_return_val_if_fail(factory != NULL, NULL);
-
-  if (factory->details)
-    {
-      xmlNewChild(parent,NULL,"longname", factory->details->longname);
-      xmlNewChild(parent,NULL,"class", factory->details->klass);
-      xmlNewChild(parent,NULL,"description", factory->details->description);
-      xmlNewChild(parent,NULL,"version", factory->details->version);
-      xmlNewChild(parent,NULL,"author", factory->details->author);
-      xmlNewChild(parent,NULL,"copyright", factory->details->copyright);
-    }
-  else
-    g_warning ("elementfactory `%s' is missing details",
-              object->name);
-
-  pads = factory->padtemplates;
-  if (pads) {
-    while (pads) {
-      xmlNodePtr subtree;
-      GstPadTemplate *padtemplate = (GstPadTemplate *)pads->data;
-
-      subtree = xmlNewChild(parent, NULL, "padtemplate", NULL);
-      gst_pad_template_save_thyself(padtemplate, subtree);
-
-      pads = g_list_next (pads);
-    }
-  }
-  return parent;
-}
-
-static void
-gst_element_factory_restore_thyself (GstObject *object, xmlNodePtr parent)
-{
-  GstElementFactory *factory = GST_ELEMENT_FACTORY (object);
-  xmlNodePtr children = parent->xmlChildrenNode;
-  
-  factory->details_dynamic = TRUE;
-  factory->details = g_new0(GstElementDetails, 1);
-  factory->padtemplates = NULL;
-
-  if (GST_OBJECT_CLASS (parent_class)->restore_thyself) {
-    GST_OBJECT_CLASS (parent_class)->restore_thyself (object, parent);
-  }
-
-  while (children) {
-    if (!strcmp(children->name, "longname")) {
-      factory->details->longname = xmlNodeGetContent(children);
-    }
-    if (!strcmp(children->name, "class")) {
-      factory->details->klass = xmlNodeGetContent(children);
-    }
-    if (!strcmp(children->name, "description")) {
-      factory->details->description = xmlNodeGetContent(children);
-    }
-    if (!strcmp(children->name, "version")) {
-      factory->details->version = xmlNodeGetContent(children);
-    }
-    if (!strcmp(children->name, "author")) {
-      factory->details->author = xmlNodeGetContent(children);
-    }
-    if (!strcmp(children->name, "copyright")) {
-      factory->details->copyright = xmlNodeGetContent(children);
-    }
-    if (!strcmp(children->name, "padtemplate")) {
-       GstPadTemplate *template;
-
-       template = gst_pad_template_load_thyself (children);
-
-       gst_element_factory_add_pad_template (factory, template);
-    }
-
-    children = children->next;
-  }
-}
-#endif /* GST_DISABLE_REGISTRY */
index 3dbec8e..880dd68 100644 (file)
@@ -124,9 +124,6 @@ gst_event_free (GstEvent* event)
     gst_object_unref (GST_EVENT_SRC (event));
   }
   switch (GST_EVENT_TYPE (event)) {
-    case GST_EVENT_INFO:
-      gst_props_unref (GST_EVENT_INFO_PROPS (event));
-      break;
     default:
       break;
   }
@@ -157,29 +154,4 @@ gst_event_new_seek (GstSeekType type, gint64 offset, gboolean flush)
   return event;
 }
 
-/**
- * gst_event_new_info:
- * @firstname: the first property name
- * @...: properties
- *
- * Allocate a new info event with the given props.
- *
- * Returns: A new info event.
- */
-GstEvent*       
-gst_event_new_info (const gchar *firstname, ...)
-{
-  GstEvent *event;
-  va_list var_args;
-      
-  event = gst_event_new (GST_EVENT_INFO);
-  va_start (var_args, firstname); 
-
-  GST_EVENT_INFO_PROPS (event) = gst_props_newv (firstname, var_args);
-         
-  va_end (var_args);
-
-  return event;
-}
-
 
index 4c3d72d..46166ff 100644 (file)
@@ -36,16 +36,12 @@ extern "C" {
 
 typedef enum {
   GST_EVENT_UNKNOWN,
-  /* horizontal events */
   GST_EVENT_EOS,
   GST_EVENT_FLUSH,
   GST_EVENT_EMPTY,
   GST_EVENT_SEEK,
   GST_EVENT_DISCONTINUOUS,
   GST_EVENT_NEW_MEDIA,
-  /* vertical events */
-  GST_EVENT_INFO,
-  GST_EVENT_ERROR,
 } GstEventType;
 
 extern GType _gst_event_type;
@@ -61,7 +57,9 @@ extern GType _gst_event_type;
 /* seek events */
 typedef enum {
   GST_SEEK_ANY,
+  GST_SEEK_TIMEOFFSET_CUR,
   GST_SEEK_TIMEOFFSET_SET,
+  GST_SEEK_TIMEOFFSET_END,
   GST_SEEK_BYTEOFFSET_SET,
   GST_SEEK_BYTEOFFSET_CUR,
   GST_SEEK_BYTEOFFSET_END,
@@ -71,8 +69,6 @@ typedef enum {
 #define GST_EVENT_SEEK_OFFSET(event)   (GST_EVENT(event)->event_data.seek.offset)
 #define GST_EVENT_SEEK_FLUSH(event)    (GST_EVENT(event)->event_data.seek.flush)
 
-#define GST_EVENT_INFO_PROPS(event)    (GST_EVENT(event)->event_data.info.props)
-
 struct _GstEvent {
   GstData data;
 
@@ -86,13 +82,6 @@ struct _GstEvent {
       gint64      offset;
       gboolean   flush;
     } seek;
-    struct {
-      GstProps *props;
-    } info;
-    struct {
-      GstElementState old_state;
-      GstElementState new_state;
-    } state;
   } event_data;
 };
 
@@ -108,9 +97,6 @@ GstEvent*    gst_event_new_seek      (GstSeekType type, gint64 offset, gboolean flush);
 /* flush events */
 #define                gst_event_new_flush()   gst_event_new(GST_EVENT_FLUSH)
 
-/* info events */
-GstEvent*      gst_event_new_info      (const gchar *firstname, ...);
-
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index 836f465..361cafa 100644 (file)
@@ -2066,7 +2066,7 @@ name_is_valid (const gchar *name, GstPadPresence presence)
  * Returns: the new padtemplate
  */
 GstPadTemplate*
-gst_pad_template_new (gchar *name_template,
+gst_pad_template_new (const gchar *name_template,
                     GstPadDirection direction, GstPadPresence presence,
                     GstCaps *caps, ...)
 {
@@ -2083,7 +2083,7 @@ gst_pad_template_new (gchar *name_template,
                       "name", name_template,
                       NULL);
 
-  GST_PAD_TEMPLATE_NAME_TEMPLATE (new) = name_template;
+  GST_PAD_TEMPLATE_NAME_TEMPLATE (new) = g_strdup (name_template);
   GST_PAD_TEMPLATE_DIRECTION (new) = direction;
   GST_PAD_TEMPLATE_PRESENCE (new) = presence;
 
@@ -2117,111 +2117,6 @@ gst_pad_template_get_caps (GstPadTemplate *templ)
   return GST_PAD_TEMPLATE_CAPS (templ);
 }
 
-#ifndef GST_DISABLE_LOADSAVE
-/**
- * gst_pad_template_save_thyself:
- * @templ: the padtemplate to save
- * @parent: the parent XML tree
- *
- * Saves the padtemplate into XML.
- *
- * Returns: the new XML tree
- */
-xmlNodePtr
-gst_pad_template_save_thyself (GstPadTemplate *templ, xmlNodePtr parent)
-{
-  xmlNodePtr subtree;
-  guchar *presence;
-
-  GST_DEBUG (GST_CAT_XML,"saving padtemplate %s", templ->name_template);
-
-  xmlNewChild(parent,NULL,"nametemplate", templ->name_template);
-  xmlNewChild(parent,NULL,"direction", (templ->direction == GST_PAD_SINK? "sink":"src"));
-
-  switch (templ->presence) {
-    case GST_PAD_ALWAYS:
-      presence = "always";
-      break;
-    case GST_PAD_SOMETIMES:
-      presence = "sometimes";
-      break;
-    case GST_PAD_REQUEST:
-      presence = "request";
-      break;
-    default:
-      presence = "unknown";
-      break;
-  }
-  xmlNewChild(parent,NULL,"presence", presence);
-
-  if (GST_PAD_TEMPLATE_CAPS (templ)) {
-    subtree = xmlNewChild (parent, NULL, "caps", NULL);
-    gst_caps_save_thyself (GST_PAD_TEMPLATE_CAPS (templ), subtree);
-  }
-
-  return parent;
-}
-
-/**
- * gst_pad_template_load_thyself:
- * @parent: the source XML tree
- *
- * Loads a padtemplate from the XML tree.
- *
- * Returns: the new padtemplate
- */
-GstPadTemplate*
-gst_pad_template_load_thyself (xmlNodePtr parent)
-{
-  xmlNodePtr field = parent->xmlChildrenNode;
-  GstPadTemplate *factory;
-  gchar *name_template = NULL;
-  GstPadDirection direction = GST_PAD_UNKNOWN;
-  GstPadPresence presence = GST_PAD_ALWAYS;
-  GstCaps *caps = NULL;
-
-  while (field) {
-    if (!strcmp(field->name, "nametemplate")) {
-      name_template = xmlNodeGetContent(field);
-    }
-    if (!strcmp(field->name, "direction")) {
-      gchar *value = xmlNodeGetContent(field);
-
-      if (!strcmp(value, "sink")) {
-        direction = GST_PAD_SINK;
-      }
-      else if (!strcmp(value, "src")) {
-        direction = GST_PAD_SRC;
-      }
-      g_free (value);
-    }
-    if (!strcmp(field->name, "presence")) {
-      gchar *value = xmlNodeGetContent(field);
-
-      if (!strcmp(value, "always")) {
-        presence = GST_PAD_ALWAYS;
-      }
-      else if (!strcmp(value, "sometimes")) {
-        presence = GST_PAD_SOMETIMES;
-      }
-      else if (!strcmp(value, "request")) {
-        presence = GST_PAD_REQUEST;
-      }
-      g_free (value);
-    }
-    else if (!strcmp(field->name, "caps")) {
-      caps = gst_caps_load_thyself (field);
-    }
-    field = field->next;
-  }
-
-  factory = gst_pad_template_new (name_template, direction, presence, caps, NULL);
-
-  return factory;
-}
-#endif /* !GST_DISABLE_LOADSAVE */
-
-
 /**
  * gst_pad_set_element_private:
  * @pad: the pad to set the private data to
index edc6693..5bab8ac 100644 (file)
@@ -278,7 +278,7 @@ struct _GstGhostPadClass {
 #define GST_TYPE_PAD_TEMPLATE          (gst_pad_template_get_type ())
 #define GST_PAD_TEMPLATE(obj)          (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_PAD_TEMPLATE,GstPadTemplate))
 #define GST_PAD_TEMPLATE_CLASS(klass)  (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_PAD_TEMPLATE,GstPadTemplateClass))
-#define GST_IS_PAD_TEMPLATE(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_PAD_TEMPLATE))
+#define GST_IS_PAD_TEMPLATE(obj)       (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_PAD_TEMPLATE))
 #define GST_IS_PAD_TEMPLATE_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_PAD_TEMPLATE))
 
 typedef enum {
@@ -289,11 +289,11 @@ typedef enum {
 
 #define GST_PAD_TEMPLATE_NAME_TEMPLATE(templ)  (((GstPadTemplate *)(templ))->name_template)
 #define GST_PAD_TEMPLATE_DIRECTION(templ)      (((GstPadTemplate *)(templ))->direction)
-#define GST_PAD_TEMPLATE_PRESENCE(templ)               (((GstPadTemplate *)(templ))->presence)
+#define GST_PAD_TEMPLATE_PRESENCE(templ)       (((GstPadTemplate *)(templ))->presence)
 #define GST_PAD_TEMPLATE_CAPS(templ)           (((GstPadTemplate *)(templ))->caps)
 #define GST_PAD_TEMPLATE_FIXED(templ)          (((GstPadTemplate *)(templ))->fixed)
 
-#define GST_PAD_TEMPLATE_IS_FIXED(templ)               (GST_PAD_TEMPLATE_FIXED(templ) == TRUE)
+#define GST_PAD_TEMPLATE_IS_FIXED(templ)       (GST_PAD_TEMPLATE_FIXED(templ) == TRUE)
 
 struct _GstPadTemplate {
   GstObject      object;
@@ -314,7 +314,7 @@ struct _GstPadTemplateClass {
 
 /* CR1: the space after 'a' is necessary because of preprocessing in gcc */
 #define GST_PAD_TEMPLATE_NEW(padname, dir, pres, a...) \
-  gst_pad_template_new (                         \
+  gst_pad_template_new (                        \
     padname,                                    \
     dir,                                        \
     pres,                                       \
@@ -331,7 +331,7 @@ name (void)                                     \
       padname,                                 \
       dir,                                      \
       pres,                                     \
-      a );                                     \
+      a );                                      \
   }                                             \
   return templ;                                \
 }
@@ -445,18 +445,13 @@ GstPad*                   gst_ghost_pad_new                       (gchar *name,GstPad *pad);
 /* templates and factories */
 GType                  gst_pad_template_get_type               (void);
 
-GstPadTemplate*                gst_pad_template_new                    (gchar *name_template,
+GstPadTemplate*                gst_pad_template_new                    (const gchar *name_template,
                                                                 GstPadDirection direction, GstPadPresence presence,
                                                                 GstCaps *caps, ...);
 
 GstCaps*               gst_pad_template_get_caps               (GstPadTemplate *templ);
 GstCaps*               gst_pad_template_get_caps_by_name       (GstPadTemplate *templ, const gchar *name);
 
-#ifndef GST_DISABLE_LOADSAVE
-xmlNodePtr             gst_pad_template_save_thyself           (GstPadTemplate *templ, xmlNodePtr parent);
-GstPadTemplate*                gst_pad_template_load_thyself           (xmlNodePtr parent);
-#endif
-
 xmlNodePtr              gst_pad_ghost_save_thyself             (GstPad *pad,
                                                                 GstElement *bin,
                                                                 xmlNodePtr parent);
index 6746f66..c6bd2bb 100644 (file)
@@ -35,116 +35,14 @@ static GModule *main_module;
 
 GList *_gst_plugin_static = NULL;
 
-/* global list of plugins and its sequence number */
-GList *_gst_plugins = NULL;
-gint _gst_plugins_seqno = 0;
-/* list of paths to check for plugins */
-GList *_gst_plugin_paths = NULL;
-
-GList *_gst_libraries = NULL;
-gint _gst_libraries_seqno = 0;
-
-/* whether or not to spew library load issues */
-gboolean _gst_plugin_spew = FALSE;
-
-/* whether or not to warn if registry needs rebuild (gst-register sets
- * this to false.) */
-gboolean _gst_warn_old_registry = TRUE;
-/* whether or not the main app will be writing to the registry */
-gboolean _gst_init_registry_write = FALSE;
-
-#ifndef GST_DISABLE_REGISTRY
-static gboolean        plugin_times_older_than         (time_t regtime);
-static time_t          get_time                        (const char * path);
-#endif
 static void            gst_plugin_register_statics     (GModule *module);
 static GstPlugin*      gst_plugin_register_func        (GstPluginDesc *desc, GstPlugin *plugin, 
                                                         GModule *module);
 void
 _gst_plugin_initialize (void)
 {
-  GList *gst_plugin_default_paths = NULL;
-#ifndef GST_DISABLE_REGISTRY
-  GstRegistryRead *gst_reg;
-  gchar *gst_registry;
-  xmlDocPtr doc = NULL;
-#endif
-
   main_module =  g_module_open (NULL, G_MODULE_BIND_LAZY);
   gst_plugin_register_statics (main_module);
-
-#ifdef PLUGINS_USE_BUILDDIR
-  /* location libgstelements.so */
-  gst_plugin_default_paths = g_list_prepend (gst_plugin_default_paths,
-                                             PLUGINS_BUILDDIR "/gst/elements");
-  gst_plugin_default_paths = g_list_prepend (gst_plugin_default_paths,
-                                             PLUGINS_BUILDDIR "/gst/types");
-  gst_plugin_default_paths = g_list_prepend (gst_plugin_default_paths,
-                                             PLUGINS_BUILDDIR "/gst/autoplug");
-  gst_plugin_default_paths = g_list_prepend (gst_plugin_default_paths,
-                                             PLUGINS_BUILDDIR "/gst/schedulers");
-#else
-  /* add the main (installed) library path */
-  gst_plugin_default_paths = g_list_prepend (gst_plugin_default_paths, PLUGINS_DIR);
-#endif /* PLUGINS_USE_BUILDDIR */
-
-#ifndef GST_DISABLE_REGISTRY
-  /* FIXME:
-   * we want to check both the global and the local registry here
-   * at first, we check if there is a local one, and if there is only use
-   * that one.
-   * Later, we would like to read the global one first, then have each
-   * plugin also in the local one override the global one.
-   */
-  
-  gst_reg = gst_registry_read_get ();
-  if (gst_reg->local_reg)
-    gst_registry = gst_reg->local_reg;
-  else
-    gst_registry = gst_reg->global_reg;
-  
-  if (_gst_init_registry_write)
-  {
-    /* delete it before writing */
-    GST_INFO (GST_CAT_PLUGIN_LOADING, " Removing registry %s if it exists", gst_registry);
-    unlink (gst_registry);
-  }
-  if (g_file_test (gst_registry, G_FILE_TEST_EXISTS))
-  {
-    doc = xmlParseFile (gst_registry);
-    GST_INFO (GST_CAT_PLUGIN_LOADING, " Reading registry from %s", gst_registry);
-  }
-  else
-  {
-    GST_INFO (GST_CAT_PLUGIN_LOADING, " Not reading registry");
-    doc = NULL;
-  }
-
-  if (!doc || 
-      !doc->xmlRootNode ||
-      doc->xmlRootNode->name == 0 ||
-      strcmp (doc->xmlRootNode->name, "GST-PluginRegistry") ||
-      !plugin_times_older_than(get_time(gst_registry))) 
-  {
-    if (_gst_warn_old_registry &&
-       !plugin_times_older_than(get_time(gst_registry))) 
-       g_warning ("gstplugin: registry needs rebuild: run gst-register\n");
-    _gst_plugin_paths = g_list_concat (_gst_plugin_paths, gst_plugin_default_paths);
-#ifdef PLUGINS_USE_BUILDDIR
-    /* we prepend the lib dir first for performance reasons */
-    _gst_plugin_paths = g_list_prepend (_gst_plugin_paths, PLUGINS_BUILDDIR "/libs/gst");
-#endif
-    gst_plugin_load_all ();
-    /* gst_plugin_unload_all (); */
-    return;
-  }
-  /* this will pull in the plugin paths for us */
-  gst_plugin_load_thyself (doc->xmlRootNode);
-
-  xmlFreeDoc (doc);
-#else
-  _gst_plugin_paths = g_list_concat (_gst_plugin_paths, gst_plugin_default_paths);
-#endif /* GST_DISABLE_REGISTRY */
 }
 
 void
@@ -168,315 +66,14 @@ gst_plugin_register_statics (GModule *module)
     plugin = gst_plugin_register_func (desc, plugin, module);
 
     if (plugin) {
-      _gst_plugins = g_list_prepend (_gst_plugins, plugin);
-      _gst_plugins_seqno++;
       plugin->module = module;
+      gst_registry_pool_add_plugin (plugin);
     }
     
     walk = g_list_next (walk);
   }
 }
 
-/**
- * gst_plugin_add_path:
- * @path: the directory to add to the search path
- *
- * Add a directory to the path searched for plugins.
- */
-void
-gst_plugin_add_path (const gchar *path)
-{
-  _gst_plugin_paths = g_list_prepend (_gst_plugin_paths,g_strdup(path));
-}
-
-#ifndef GST_DISABLE_REGISTRY
-static time_t
-get_time(const char * path)
-{
-  struct stat statbuf;
-  if (stat(path, &statbuf)) return 0;
-  if (statbuf.st_mtime > statbuf.st_ctime) return statbuf.st_mtime;
-  return statbuf.st_ctime;
-}
-
-static gboolean
-plugin_times_older_than_recurse(gchar *path, time_t regtime)
-{
-  DIR *dir;
-  struct dirent *dirent;
-  gchar *pluginname;
-
-  time_t pathtime = get_time(path);
-
-  if (pathtime > regtime) {
-    GST_INFO (GST_CAT_PLUGIN_LOADING,
-              "time for %s was %ld; more recent than registry time of %ld\n",
-              path, (long)pathtime, (long)regtime);
-    return FALSE;
-  }
-
-  dir = opendir(path);
-  if (dir) {
-    while ((dirent = readdir(dir))) {
-      /* don't want to recurse in place or backwards */
-      if (strcmp(dirent->d_name,".") && strcmp(dirent->d_name,"..")) {
-       pluginname = g_strjoin("/",path,dirent->d_name,NULL);
-       if (!plugin_times_older_than_recurse(pluginname , regtime)) {
-          g_free (pluginname);
-          closedir(dir);
-          return FALSE;
-        }
-        g_free (pluginname);
-      }
-    }
-    closedir(dir);
-  }
-  return TRUE;
-}
-
-static gboolean
-plugin_times_older_than(time_t regtime)
-{
-  /* return true iff regtime is more recent than the times of all the files
-   * in the plugin dirs.
-   */
-
-  GList *path;
-  path = _gst_plugin_paths;
-  while (path != NULL) {
-    GST_DEBUG (GST_CAT_PLUGIN_LOADING,
-              "comparing plugin times from %s with %ld\n",
-              (gchar *)path->data, (long) regtime);
-    if(!plugin_times_older_than_recurse(path->data, regtime))
-       return FALSE;
-    path = g_list_next(path);
-  }
-  return TRUE;
-}
-#endif
-
-static gboolean
-gst_plugin_load_recurse (gchar *directory, gchar *name)
-{
-  DIR *dir;
-  struct dirent *dirent;
-  gboolean loaded = FALSE;
-  gchar *dirname;
-
-  /* g_print("recursive load of '%s' in '%s'\n", name, directory); */
-  dir = opendir(directory);
-  if (dir) {
-    while ((dirent = readdir(dir))) {
-      /* don't want to recurse in place or backwards */
-      if (strcmp(dirent->d_name,".") && strcmp(dirent->d_name,"..")) {
-        dirname = g_strjoin("/",directory,dirent->d_name,NULL);
-        loaded = gst_plugin_load_recurse(dirname,name);
-        g_free(dirname);
-       if (loaded && name) {
-          closedir(dir);
-          return TRUE;
-        }
-      }
-    }
-    closedir(dir);
-  } else {
-    if (strstr(directory,".so")) {
-      gchar *temp;
-      if (name) {
-        if ((temp = strstr(directory,name)) &&
-            (!strcmp(temp,name))) {
-          loaded = gst_plugin_load_absolute(directory);
-        }
-      } else if ((temp = strstr(directory,".so")) &&
-                 (!strcmp(temp,".so"))) {
-        loaded = gst_plugin_load_absolute(directory);
-      }
-    }
-  }
-  return loaded;
-}
-
-/**
- * gst_plugin_load_all:
- *
- * Load all plugins in the path (in the global GList* _gst_plugin_paths).
- */
-void
-gst_plugin_load_all (void)
-{
-  GList *path;
-
-  path = _gst_plugin_paths;
-  if (path == NULL) { g_warning ("gst_plugin_load_all: path is NULL !"); }
-  while (path != NULL) {
-    GST_DEBUG (GST_CAT_PLUGIN_LOADING,"loading plugins from %s",(gchar *)path->data);
-    gst_plugin_load_recurse(path->data,NULL);
-    path = g_list_next(path);
-  }
-  GST_INFO (GST_CAT_PLUGIN_LOADING,"loaded %d plugins", _gst_plugins_seqno);
-}
-
-/**
- * gst_plugin_unload_all:
- *
- * Unload all plugins in memory.
- */
-void
-gst_plugin_unload_all (void)
-{
-  GList *walk = _gst_plugins;
-
-  while (walk) {
-    GstPlugin *plugin = (GstPlugin *) walk->data;
-
-    GST_INFO (GST_CAT_PLUGIN_LOADING, "unloading plugin %s", plugin->name);
-    if (plugin->module) {
-      GList *features = gst_plugin_get_feature_list (plugin);
-
-      while (features) {
-        GstPluginFeature *feature = GST_PLUGIN_FEATURE (features->data);
-
-       GST_INFO (GST_CAT_PLUGIN_LOADING, "unloading feature %s", GST_OBJECT_NAME (feature));
-       gst_plugin_feature_unload_thyself (feature);
-
-       features = g_list_next (features);
-      }
-      if (g_module_close (plugin->module)) {
-        plugin->module = NULL;
-      }
-      else {
-       g_warning ("error closing module");
-      }
-    }
-    
-    walk = g_list_next (walk);
-  }
-}
-
-/**
- * gst_library_load:
- * @name: name of library to load
- *
- * Load the named library.  Name should be given as
- * &quot;liblibrary.so&quot;.
- *
- * Returns: whether the library was loaded or not
- */
-gboolean
-gst_library_load (const gchar *name)
-{
-  gboolean res;
-  GList *libraries = _gst_libraries;
-
-  while (libraries) {
-    if (!strcmp((gchar *)libraries->data, name)) return TRUE;
-
-    libraries = g_list_next(libraries);
-  }
-
-  /* for now this is the same */
-  res = gst_plugin_load(name);
-
-  if (res) {
-    _gst_libraries = g_list_prepend(_gst_libraries, g_strdup (name));
-  }
-
-  return res;
-}
-
-/**
- * gst_plugin_load:
- * @name: name of plugin to load
- *
- * Load the named plugin.  Name should be given as
- * &quot;libplugin.so&quot;.
- *
- * Returns: whether the plugin was loaded or not
- */
-gboolean
-gst_plugin_load (const gchar *name)
-{
-  GList *path;
-  gchar *libspath;
-  gchar *pluginname;
-  GstPlugin *plugin;
-  
-  g_return_val_if_fail (name != NULL, FALSE);
-
-  plugin = gst_plugin_find (name);
-  
-  if (plugin && plugin->module) 
-    return TRUE;
-
-  path = _gst_plugin_paths;
-  while (path != NULL) {
-    pluginname = g_module_build_path(path->data,name);
-    if (gst_plugin_load_absolute(pluginname)) {
-      g_free(pluginname);
-      return TRUE;
-    }
-    g_free(pluginname);
-    libspath = g_strconcat(path->data,"/.libs",NULL);
-    /* g_print("trying to load '%s'\n",g_module_build_path(libspath,name)); */
-    pluginname = g_module_build_path(libspath,name);
-    g_free(libspath);
-    if (gst_plugin_load_absolute(pluginname)) {
-      g_free(pluginname);
-      return TRUE;
-    }
-    g_free(pluginname);
-    /* g_print("trying to load '%s' from '%s'\n",name,path->data); */
-    pluginname = g_module_build_path("",name);
-    if (gst_plugin_load_recurse(path->data,pluginname)) {
-      g_free(pluginname);
-      return TRUE;
-    }
-    g_free(pluginname);
-    path = g_list_next(path);
-  }
-  return FALSE;
-}
-
-/**
- * gst_plugin_load_absolute:
- * @name: name of plugin to load
- *
- * Load the named plugin.  Name should be given as
- * &quot;/path/to/plugin/libplugin.so&quot;.
- *
- * Returns: whether the plugin was loaded or not
- */
-gboolean
-gst_plugin_load_absolute (const gchar *filename)
-{
-  GstPlugin *plugin = NULL;
-  GList *plugins = _gst_plugins;
-
-  g_return_val_if_fail (filename != NULL, FALSE);
-
-  GST_DEBUG (GST_CAT_PLUGIN_LOADING, "plugin \"%s\" absolute loading", filename);
-
-  while (plugins) {
-    GstPlugin *testplugin = (GstPlugin *)plugins->data;
-
-    if (testplugin->filename) {
-      if (!strcmp (testplugin->filename, filename)) {
-       plugin = testplugin;
-       break;
-      }
-    }
-    plugins = g_list_next (plugins);
-  }
-  if (!plugin) {
-    plugin = g_new0 (GstPlugin, 1);
-    plugin->filename = g_strdup (filename);
-    _gst_plugins = g_list_prepend (_gst_plugins, plugin);
-    _gst_plugins_seqno++;
-  }
-
-  return gst_plugin_load_plugin (plugin);
-}
-
 static gboolean
 gst_plugin_check_version (gint major, gint minor)
 {
@@ -494,19 +91,18 @@ gst_plugin_register_func (GstPluginDesc *desc, GstPlugin *plugin, GModule *modul
   if (!gst_plugin_check_version (desc->major_version, desc->minor_version)) {
     GST_INFO (GST_CAT_PLUGIN_LOADING,"plugin \"%s\" has incompatible version, not loading",
        plugin->filename);
-    g_free(plugin);
     return NULL;
   }
 
+  g_free (plugin->name);
   plugin->name = g_strdup(desc->name);
 
   if (!((desc->plugin_init) (module, plugin))) {
     GST_INFO (GST_CAT_PLUGIN_LOADING,"plugin \"%s\" failed to initialise",
        plugin->filename);
-    g_free(plugin);
     return NULL;
   }
-  
+
   return plugin;
 }
 
@@ -533,7 +129,7 @@ gst_plugin_load_plugin (GstPlugin *plugin)
 
   filename = plugin->filename;
 
-  GST_DEBUG (GST_CAT_PLUGIN_LOADING, "plugin \"%s\" loading", filename);
+  GST_DEBUG (GST_CAT_PLUGIN_LOADING, "attempt to load plugin \"%s\"", filename);
 
   if (g_module_supported () == FALSE) {
     g_warning ("gstplugin: wow, you built this on a platform without dynamic loading???\n");
@@ -541,7 +137,7 @@ gst_plugin_load_plugin (GstPlugin *plugin)
   }
 
   if (stat (filename, &file_status)) {
-    /* g_print("problem opening file %s\n",filename); */
+    g_warning ("problem opening file %s (plugin %s)\n", filename, plugin->name); 
     return FALSE;
   }
 
@@ -549,23 +145,22 @@ gst_plugin_load_plugin (GstPlugin *plugin)
 
   if (module != NULL) {
     if (g_module_symbol (module, "plugin_desc", (gpointer *)&desc)) {
-      GST_DEBUG (GST_CAT_PLUGIN_LOADING,"loading plugin \"%s\"...", filename);
+      GST_DEBUG (GST_CAT_PLUGIN_LOADING, "plugin \"%s\" loaded, called entry function...", filename);
 
       plugin->filename = g_strdup (filename);
       plugin = gst_plugin_register_func (desc, plugin, module);
 
       if (plugin != NULL) {
-        GST_INFO (GST_CAT_PLUGIN_LOADING,"plugin \"%s\" loaded",
-             plugin->filename);
+        GST_INFO (GST_CAT_PLUGIN_LOADING, "plugin \"%s\" loaded", plugin->filename);
         plugin->module = module;
         return TRUE;
       }
     }
-    return TRUE;
-  } else if (_gst_plugin_spew) {
-    /* FIXME this should be some standard gst mechanism!!! */
-    g_printerr ("error loading plugin %s, reason: %s\n", filename, g_module_error());
-  }
+    else {
+      GST_DEBUG (GST_CAT_PLUGIN_LOADING, "could not find plugin_desc in \"%s\"", filename);
+    }
+    return FALSE;
+  } 
   else {
     GST_INFO (GST_CAT_PLUGIN_LOADING, "error loading plugin %s, reason: %s\n", filename, g_module_error());
   }
@@ -575,6 +170,33 @@ gst_plugin_load_plugin (GstPlugin *plugin)
 
 
 /**
+ * gst_plugin_unload_plugin:
+ * @plugin: The plugin to unload
+ *
+ * Unload the given plugin.
+ *
+ * Returns: whether or not the plugin unloaded
+ */
+gboolean
+gst_plugin_unload_plugin (GstPlugin *plugin)
+{
+  g_return_val_if_fail (plugin != NULL, FALSE);
+
+  if (!plugin->module) 
+    return TRUE;
+
+  if (g_module_close (plugin->module)) {
+    plugin->module = NULL;
+    GST_INFO (GST_CAT_PLUGIN_LOADING, "plugin \"%s\" unloaded", plugin->filename);
+    return TRUE;
+  }
+  else {
+    GST_INFO (GST_CAT_PLUGIN_LOADING, "failed to unload plugin \"%s\"", plugin->filename);
+    return FALSE;
+  }
+}
+
+/**
  * gst_plugin_get_name:
  * @plugin: plugin to get the name of
  *
@@ -674,37 +296,8 @@ gst_plugin_is_loaded (GstPlugin *plugin)
   return (plugin->module != NULL);
 }
 
-
-/**
- * gst_plugin_find:
- * @name: name of plugin to find
- *
- * Search the list of registered plugins for one of the given name
- *
- * Returns: pointer to the #GstPlugin if found, NULL otherwise
- */
-GstPlugin*
-gst_plugin_find (const gchar *name)
-{
-  GList *plugins = _gst_plugins;
-
-  g_return_val_if_fail (name != NULL, NULL);
-
-  while (plugins) {
-    GstPlugin *plugin = (GstPlugin *)plugins->data;
-
-    if (plugin->name) {
-      if (!strcmp (plugin->name, name)) {
-        return plugin;
-      }
-    }
-    plugins = g_list_next (plugins);
-  }
-  return NULL;
-}
-
-static GstPluginFeature*
-gst_plugin_find_feature_func (GstPlugin *plugin, const gchar *name, GType type)
+GstPluginFeature*
+gst_plugin_find_feature (GstPlugin *plugin, const gchar *name, GType type)
 {
   GList *features = plugin->features;
 
@@ -713,33 +306,12 @@ gst_plugin_find_feature_func (GstPlugin *plugin, const gchar *name, GType type)
   while (features) {
     GstPluginFeature *feature = GST_PLUGIN_FEATURE (features->data);
 
-
-    if (!strcmp(GST_OBJECT_NAME (feature), name) && G_OBJECT_TYPE (feature) == type)
-      return  GST_PLUGIN_FEATURE (feature);
+    if (!strcmp(GST_PLUGIN_FEATURE_NAME (feature), name) && G_OBJECT_TYPE (feature) == type) {
+      return GST_PLUGIN_FEATURE (feature);
+    }
 
     features = g_list_next (features);
   }
-
-  return NULL;
-}
-
-G_GNUC_UNUSED static GstPluginFeature*
-gst_plugin_find_feature (const gchar *name, GType type)
-{
-  GList *plugins;
-
-  plugins = _gst_plugins;
-  while (plugins) {
-    GstPlugin *plugin = (GstPlugin *)plugins->data;
-    GstPluginFeature *feature;
-
-    feature = gst_plugin_find_feature_func (plugin, name, type);
-    if (feature)
-      return feature;
-    
-    plugins = g_list_next(plugins);
-  }
-
   return NULL;
 }
 
@@ -761,7 +333,8 @@ gst_plugin_add_feature (GstPlugin *plugin, GstPluginFeature *feature)
   g_return_if_fail (GST_IS_PLUGIN_FEATURE (feature));
   g_return_if_fail (feature != NULL);
 
-  oldfeature = gst_plugin_find_feature_func (plugin, GST_OBJECT_NAME (feature), G_OBJECT_TYPE (feature));
+  oldfeature = gst_plugin_find_feature (plugin, 
+                 GST_PLUGIN_FEATURE_NAME (feature), G_OBJECT_TYPE (feature));
 
   if (!oldfeature) {
     feature->manager = plugin;
@@ -771,157 +344,58 @@ gst_plugin_add_feature (GstPlugin *plugin, GstPluginFeature *feature)
 }
 
 /**
- * gst_plugin_get_list:
+ * gst_plugin_get_feature_list:
+ * @plugin: the plugin to get the features from
  *
- * get the currently loaded plugins
+ * get a list of all the features that this plugin provides
  *
- * Returns; a GList of GstPlugin elements
+ * Returns: a GList of features
  */
-const GList*
-gst_plugin_get_list (void)
+GList*
+gst_plugin_get_feature_list (GstPlugin *plugin)
 {
-  return _gst_plugins;
+  g_return_val_if_fail (plugin != NULL, NULL);
+
+  return plugin->features;
 }
 
-#ifndef GST_DISABLE_REGISTRY
 /**
- * gst_plugin_save_thyself:
- * @parent: the parent node to save the plugin to
+ * gst_plugin_load:
+ * @name: name of plugin to load
  *
- * saves the plugin into an XML representation
+ * Load the named plugin.  
  *
- * Returns: the new XML node
+ * Returns: whether the plugin was loaded or not
  */
-xmlNodePtr
-gst_plugin_save_thyself (xmlNodePtr parent)
+gboolean
+gst_plugin_load (const gchar *name)
 {
-  xmlNodePtr tree, subtree;
-  GList *l = NULL, *plugins = NULL;
-
-  plugins = _gst_plugins;
-  while (plugins) {
-    GstPlugin *plugin = (GstPlugin *)plugins->data;
-    GList *features;
-
-    plugins = g_list_next (plugins);
-
-    if (!plugin->name) 
-      continue;
-    
-    tree = xmlNewChild (parent, NULL, "plugin", NULL);
-    xmlNewChild (tree, NULL, "name", plugin->name);
-    xmlNewChild (tree, NULL, "longname", plugin->longname);
-    xmlNewChild (tree, NULL, "filename", plugin->filename);
-
-    features = plugin->features;
-    while (features) {
-      GstPluginFeature *feature = GST_PLUGIN_FEATURE (features->data);
-
-      subtree = xmlNewChild(tree, NULL, "feature", NULL);
-      xmlNewProp (subtree, "typename", g_type_name (G_OBJECT_TYPE (feature)));
-
-      gst_object_save_thyself (GST_OBJECT (feature), subtree);
+  GstPlugin *plugin;
 
-      features = g_list_next (features);
-    }
-  }
-  
-  /* save the plugin search path in reverse order (because they are cons'd back on) */
-  l=g_list_last(_gst_plugin_paths);
-  while(l) {
-    xmlNewChild (parent, NULL, "plugin-path", l->data);
-    l = l->prev;
-  }
-    
-  return parent;
-}
+  plugin = gst_registry_pool_find_plugin (name);
+  if (plugin)
+    return gst_plugin_load_plugin (plugin);
 
-/**
- * gst_plugin_load_thyself:
- * @parent: the parent node to load the plugin from
- *
- * load the plugin from an XML representation
- */
-void
-gst_plugin_load_thyself (xmlNodePtr parent)
-{
-  xmlNodePtr kinderen;
-  gint featurecount = 0;
-  gchar *pluginname;
-
-  kinderen = parent->xmlChildrenNode; /* Dutch invasion :-) */
-  while (kinderen) {
-    if (!strcmp (kinderen->name, "plugin")) {
-      xmlNodePtr field = kinderen->xmlChildrenNode;
-      GstPlugin *plugin = g_new0 (GstPlugin, 1);
-      
-      plugin->numfeatures = 0;
-      plugin->features = NULL;
-      plugin->module = NULL;
-      
-      while (field) {
-       if (!strcmp (field->name, "name")) {
-          pluginname = xmlNodeGetContent (field);
-         if (gst_plugin_find (pluginname)) {
-            g_free (pluginname);
-            g_free (plugin);
-           plugin = NULL;
-            break;
-         } else {
-           plugin->name = pluginname;
-         }
-       }
-       else if (!strcmp (field->name, "longname")) {
-         plugin->longname = xmlNodeGetContent (field);
-       }
-       else if (!strcmp (field->name, "filename")) {
-         plugin->filename = xmlNodeGetContent (field);
-       }
-       else if (!strcmp (field->name, "feature")) {
-         GstPluginFeature *feature;
-         gchar *prop;
-         
-         prop = xmlGetProp (field, "typename");
-         feature = GST_PLUGIN_FEATURE (g_object_new (g_type_from_name (prop), NULL));
-         
-         if (feature) {
-           gst_object_restore_thyself (GST_OBJECT (feature), field);
-           gst_plugin_add_feature (plugin, feature);
-           featurecount++;
-         }
-       }
-
-       field = field->next;
-      }
-
-      if (plugin) {
-        _gst_plugins = g_list_prepend (_gst_plugins, plugin);
-        _gst_plugins_seqno++;
-      }
-    } else if (!strcmp (kinderen->name, "plugin-path")) {
-      _gst_plugin_paths = g_list_prepend (_gst_plugin_paths,
-                                          xmlNodeGetContent (kinderen));
-    }
-    
-    kinderen = kinderen->next;
-  }
-  GST_INFO (GST_CAT_PLUGIN_LOADING, " added %d features ", featurecount);
+  return FALSE;
 }
-#endif /* GST_DISABLE_REGISTRY */
-
 
 /**
- * gst_plugin_get_feature_list:
- * @plugin: the plugin to get the features from
+ * gst_library_load:
+ * @name: name of library to load
  *
- * get a list of all the features that this plugin provides
+ * Load the named library.  Name should be given as
+ * &quot;liblibrary.so&quot;.
  *
- * Returns: a GList of features
+ * Returns: whether the library was loaded or not
  */
-GList*
-gst_plugin_get_feature_list (GstPlugin *plugin)
+gboolean
+gst_library_load (const gchar *name)
 {
-  g_return_val_if_fail (plugin != NULL, NULL);
+  gboolean res;
 
-  return plugin->features;
+  /* for now this is the same */
+  res = gst_plugin_load(name);
+
+  return res;
 }
+
index fba15df..80dbd9e 100644 (file)
 
 #include <gst/gstpluginfeature.h>
 
+#define GST_PLUGIN(plugin)             ((GstPlugin *) (plugin))
+
 typedef struct _GstPlugin              GstPlugin;
 typedef struct _GstPluginDesc          GstPluginDesc;
 
 struct _GstPlugin {
-  gchar *name;                 /* name of the plugin */
-  gchar *longname;             /* long name of plugin */
-  gchar *filename;             /* filename it came from */
+  gchar        *name;                  /* name of the plugin */
+  gchar        *longname;              /* long name of plugin */
+  gchar        *filename;              /* filename it came from */
 
-  GList *features;             /* list of features provided */
-  gint numfeatures;
+  GList        *features;              /* list of features provided */
+  gint                  numfeatures;
 
-  GModule *module;             /* contains the module if the plugin is loaded */
+  gpointer      manager;               /* managing registry */
+  GModule      *module;                /* contains the module if the plugin is loaded */
+  gboolean      init_called;           /* if the init function has been called */
 };
 
 /* Initialiser function: returns TRUE if plugin initialised successfully */
@@ -85,38 +89,24 @@ _gst_plugin_static_init__ ##init (void)                             \
 void                   _gst_plugin_initialize          (void);
 void                   _gst_plugin_register_static     (GstPluginDesc *desc);
 
-void                   gst_plugin_add_path             (const gchar *path);
-
 const gchar*           gst_plugin_get_name             (GstPlugin *plugin);
 void                   gst_plugin_set_name             (GstPlugin *plugin, const gchar *name);
 const gchar*           gst_plugin_get_longname         (GstPlugin *plugin);
 void                   gst_plugin_set_longname         (GstPlugin *plugin, const gchar *longname);
-
 const gchar*           gst_plugin_get_filename         (GstPlugin *plugin);
 gboolean               gst_plugin_is_loaded            (GstPlugin *plugin);
 
 GList*                 gst_plugin_get_feature_list     (GstPlugin *plugin);
+GstPluginFeature*      gst_plugin_find_feature         (GstPlugin *plugin, const gchar *name, GType type);
 
-void                   gst_plugin_load_all             (void);
-void                   gst_plugin_unload_all           (void);
-
-gboolean               gst_plugin_load                 (const gchar *name);
-gboolean               gst_plugin_load_absolute        (const gchar *name);
-gboolean               gst_library_load                (const gchar *name);
 gboolean               gst_plugin_load_plugin          (GstPlugin *plugin);
+gboolean               gst_plugin_unload_plugin        (GstPlugin *plugin);
 
 void                   gst_plugin_add_feature          (GstPlugin *plugin, GstPluginFeature *feature);
 
-GstPlugin*             gst_plugin_find                 (const gchar *name);
-const GList*           gst_plugin_get_list             (void);
-
+/* shortcuts to load from the registry pool */
+gboolean               gst_plugin_load                 (const gchar *name);
+gboolean               gst_library_load                (const gchar *name);
 
-#ifndef GST_DISABLE_REGISTRY
-xmlNodePtr             gst_plugin_save_thyself         (xmlNodePtr parent);
-void                   gst_plugin_load_thyself         (xmlNodePtr parent);
-#else
-#pragma GCC poison gst_plugin_save_thyself
-#pragma GCC poison gst_plugin_load_thyself
-#endif
 
 #endif /* __GST_PLUGIN_H__ */
index 7baa983..ae29f0d 100644 (file)
 #include "gst_private.h"
 #include "gstpluginfeature.h"
 #include "gstplugin.h"
+#include "gstregistry.h"
 
 static void            gst_plugin_feature_class_init           (GstPluginFeatureClass *klass);
 static void            gst_plugin_feature_init                 (GstPluginFeature *feature);
 
-#ifndef GST_DISABLE_REGISTRY
-static xmlNodePtr      gst_plugin_feature_save_thyself         (GstObject *object, xmlNodePtr parent);
-static void            gst_plugin_feature_restore_thyself      (GstObject *object, xmlNodePtr parent);
-#endif /* GST_DISABLE_REGISTRY */
-
 static GstObjectClass *parent_class = NULL;
 /* static guint gst_plugin_feature_signals[LAST_SIGNAL] = { 0 }; */
 
@@ -42,18 +38,18 @@ gst_plugin_feature_get_type (void)
 
   if (!plugin_feature_type) {
     static const GTypeInfo plugin_feature_info = {
-      sizeof (GstObjectClass),
+      sizeof (GObjectClass),
       NULL,
       NULL,
       (GClassInitFunc) gst_plugin_feature_class_init,
       NULL,
       NULL,
-      sizeof (GstObject),
+      sizeof (GObject),
       32,
       (GInstanceInitFunc) gst_plugin_feature_init,
       NULL
     };
-    plugin_feature_type = g_type_register_static (GST_TYPE_OBJECT, "GstPluginFeature", 
+    plugin_feature_type = g_type_register_static (G_TYPE_OBJECT, "GstPluginFeature", 
                                                  &plugin_feature_info, G_TYPE_FLAG_ABSTRACT);
   }
   return plugin_feature_type;
@@ -63,17 +59,10 @@ static void
 gst_plugin_feature_class_init (GstPluginFeatureClass *klass)
 {
   GObjectClass *gobject_class;
-  GstObjectClass *gstobject_class;
 
   gobject_class = (GObjectClass*) klass;
-  gstobject_class = (GstObjectClass*) klass;
-
-  parent_class = g_type_class_ref (GST_TYPE_OBJECT);
 
-#ifndef GST_DISABLE_REGISTRY
-  gstobject_class->save_thyself =      GST_DEBUG_FUNCPTR (gst_plugin_feature_save_thyself);
-  gstobject_class->restore_thyself =   GST_DEBUG_FUNCPTR (gst_plugin_feature_restore_thyself);
-#endif /* GST_DISABLE_REGISTRY */
+  parent_class = g_type_class_ref (G_TYPE_OBJECT);
 }
 
 static void
@@ -82,34 +71,6 @@ gst_plugin_feature_init (GstPluginFeature *feature)
   feature->manager = NULL;
 }
 
-#ifndef GST_DISABLE_REGISTRY
-static xmlNodePtr
-gst_plugin_feature_save_thyself (GstObject *object, xmlNodePtr parent)
-{
-  g_return_val_if_fail (GST_IS_PLUGIN_FEATURE (object), parent);
-
-  xmlNewChild (parent, NULL, "name", GST_OBJECT_NAME (object));
-
-  return parent;
-}
-
-static void
-gst_plugin_feature_restore_thyself (GstObject *object, xmlNodePtr parent)
-{
-  xmlNodePtr field = parent->xmlChildrenNode;
-
-  g_return_if_fail (GST_IS_PLUGIN_FEATURE (object));
-
-  while (field) {
-    if (!strcmp (field->name, "name")) {
-      gst_object_set_name (object, xmlNodeGetContent (field));
-      break;
-    }
-    field = field->next;
-  }
-}
-#endif /* GST_DISABLE_REGISTRY */
-
 /**
  * gst_plugin_feature_ensure_loaded:
  * @feature: the plugin feature to check
@@ -125,9 +86,14 @@ gst_plugin_feature_ensure_loaded (GstPluginFeature *feature)
   GstPlugin *plugin = (GstPlugin *) (feature->manager);
 
   if (plugin && !gst_plugin_is_loaded (plugin)) {
-    GST_DEBUG (GST_CAT_PLUGIN_LOADING, "loading plugin %s for feature", plugin->name);
-    
-    return gst_plugin_load_plugin (plugin);
+    if (GST_IS_REGISTRY (plugin->manager)) {
+      GST_DEBUG (GST_CAT_PLUGIN_LOADING, "loading plugin %s for feature", plugin->name);
+
+      if (gst_registry_load_plugin (GST_REGISTRY (plugin->manager), plugin) != GST_REGISTRY_OK)
+       return FALSE;
+    }
+    else
+      return FALSE;
   }
   return TRUE;
 }
index 8e3b8b9..e369a09 100644 (file)
@@ -41,17 +41,21 @@ extern "C" {
 #define GST_IS_PLUGIN_FEATURE_CLASS(obj) \
   (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_PLUGIN_FEATURE))
 
+#define GST_PLUGIN_FEATURE_NAME(feature)  (GST_PLUGIN_FEATURE (feature)->name)
+
 typedef struct _GstPluginFeature GstPluginFeature;
 typedef struct _GstPluginFeatureClass GstPluginFeatureClass;
 
 struct _GstPluginFeature {
-  GstObject object;
+  GObject object;
+
+  gchar *name;
 
   gpointer manager;
 };
 
 struct _GstPluginFeatureClass {
-  GstObjectClass       parent_class;
+  GObjectClass parent_class;
 
   void          (*unload_thyself)      (GstPluginFeature *feature);
 };
index 5dbd907..a4cabaf 100644 (file)
 #include "gstinfo.h"
 #include "gstregistry.h"
 
+#define CLASS(registry)  GST_REGISTRY_CLASS (G_OBJECT_GET_CLASS (registry))
+
+/* Element signals and args */
+enum {
+  PLUGIN_ADDED,
+  LAST_SIGNAL
+};
+
+
+static GList *_gst_registry_pool = NULL;
+static GList *_gst_registry_pool_plugins = NULL;
+
+static void             gst_registry_class_init           (GstRegistryClass *klass);
+static void             gst_registry_init                 (GstRegistry *registry);
+
+static GObjectClass *parent_class = NULL;
+static guint gst_registry_signals[LAST_SIGNAL] = { 0 }; 
+
+GType
+gst_registry_get_type (void)
+{
+  static GType registry_type = 0;
+
+  if (!registry_type) {
+    static const GTypeInfo registry_info = {
+      sizeof (GstRegistryClass),
+      NULL,
+      NULL,
+      (GClassInitFunc) gst_registry_class_init,
+      NULL,
+      NULL,
+      sizeof (GstRegistry),
+      32,
+      (GInstanceInitFunc) gst_registry_init,
+      NULL
+    };
+    registry_type = g_type_register_static (G_TYPE_OBJECT, "GstRegistry",
+                                            &registry_info, G_TYPE_FLAG_ABSTRACT);
+  }
+  return registry_type;
+}
+
+static void
+gst_registry_class_init (GstRegistryClass *klass)
+{
+  GObjectClass *gobject_class;
+
+  gobject_class = (GObjectClass*) klass;
+
+  parent_class = g_type_class_ref (G_TYPE_OBJECT);
+
+  gst_registry_signals[PLUGIN_ADDED] =
+    g_signal_new ("plugin_added", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (GstRegistryClass, plugin_added), NULL, NULL,
+                  gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+                  G_TYPE_POINTER);
+
+  gobject_class->dispose = NULL;
+}
+
+static void
+gst_registry_init (GstRegistry *registry)
+{
+  registry->priority = 0;
+  registry->loaded = FALSE;
+  registry->paths = NULL;
+}
+
+/**
+ * gst_registry_load:
+ * @registry: the registry to load
+ *
+ * Load the given registry
+ *
+ * Returns: TRUE on success.
+ */
+gboolean
+gst_registry_load (GstRegistry *registry)
+{
+  g_return_val_if_fail (GST_IS_REGISTRY (registry), FALSE);
+
+  if (CLASS (registry)->load)
+    return CLASS (registry)->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)
+{
+  g_return_val_if_fail (GST_IS_REGISTRY (registry), FALSE);
+
+  if (CLASS (registry)->save)
+    return CLASS (registry)->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)
+{
+  g_return_val_if_fail (GST_IS_REGISTRY (registry), FALSE);
+
+  if (CLASS (registry)->rebuild)
+    return CLASS (registry)->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)
+{
+  g_return_val_if_fail (GST_IS_REGISTRY (registry), FALSE);
+
+  if (CLASS (registry)->unload)
+    return CLASS (registry)->unload (registry);
+
+  return FALSE;
+}
+
+/**
+ * gst_registry_add_path:
+ * @registry: the registry to add the path to
+ *
+ * Add the given pathstring to the registry. The syntax of the
+ * pathstring is specific to the registry.
+ */
+void
+gst_registry_add_path (GstRegistry *registry, const gchar *path)
+{
+  g_return_if_fail (GST_IS_REGISTRY (registry));
+  g_return_if_fail (path != NULL);
+
+  registry->paths = g_list_append (registry->paths, g_strdup (path));
+}
+
+/**
+ * gst_registry_get_path_list:
+ * @registry: the registry to get the pathlist of
+ *
+ * Get the list of paths for the given registry.
+ *
+ * Returns: A Glist of paths as strings. g_list_free after use.
+ */
+GList*
+gst_registry_get_path_list (GstRegistry *registry)
+{
+  g_return_val_if_fail (GST_IS_REGISTRY (registry), NULL);
+
+  return g_list_copy (registry->paths);
+}
+
+
+static void
+free_list_strings_func (gpointer data, gpointer user_data)
+{
+  g_free (data);
+}
+
+/**
+ * gst_registry_clear_paths:
+ * @registry: the registry to clear the paths of
+ *
+ * Clear the paths of the given registry
+ */
+void
+gst_registry_clear_paths (GstRegistry *registry)
+{
+  g_return_if_fail (GST_IS_REGISTRY (registry));
+
+  g_list_foreach (registry->paths, free_list_strings_func, NULL);
+  g_list_free (registry->paths);
+
+  registry->paths = NULL;
+}
+
+/**
+ * gst_registry_add_plugin:
+ * @registry: the registry to add the plugin to
+ * @plugin: the plugin to add
+ *
+ * Add the plugin to the registry. The plugin-added signal 
+ * will be emitted.
+ *
+ * Returns: TRUE on success.
+ */
+gboolean 
+gst_registry_add_plugin (GstRegistry *registry, GstPlugin *plugin)
+{
+  g_return_val_if_fail (GST_IS_REGISTRY (registry), FALSE);
+  
+  plugin->manager = registry;
+  registry->plugins = g_list_prepend (registry->plugins, plugin);
+
+  g_signal_emit (G_OBJECT (registry), gst_registry_signals[PLUGIN_ADDED], 0, plugin);
+
+  return TRUE;
+}
+
+/**
+ * gst_registry_remove_plugin:
+ * @registry: the registry to remove the plugin from
+ * @plugin: the plugin to remove
+ *
+ * Remove the plugin from the registry.
+ */
+void
+gst_registry_remove_plugin (GstRegistry *registry, GstPlugin *plugin)
+{
+  g_return_if_fail (GST_IS_REGISTRY (registry));
+
+  registry->plugins = g_list_remove (registry->plugins, plugin);
+}
+
+/**
+ * gst_registry_find_plugin:
+ * @registry: the registry to search
+ * @name: the plugin name to find
+ *
+ * Find the plugin with the given name in the registry.
+ *
+ * Returns: The plugin with the given name or NULL if the plugin was not found.
+ */
+GstPlugin*
+gst_registry_find_plugin (GstRegistry *registry, const gchar *name)
+{
+  GList *walk;
+
+  g_return_val_if_fail (GST_IS_REGISTRY (registry), NULL);
+  g_return_val_if_fail (name != NULL, NULL);
+  
+  walk = registry->plugins;
+
+  while (walk) {
+    GstPlugin *plugin = (GstPlugin *) (walk->data);
+
+    if (plugin->name && !strcmp (plugin->name, name))
+      return plugin;
+    
+    walk = g_list_next (walk);
+  }
+  return NULL;
+}
+
+static GstPluginFeature*
+gst_plugin_list_find_feature (GList *plugins, const gchar *name, GType type)
+{
+  GstPluginFeature *feature = NULL;
+
+  g_return_val_if_fail (name != NULL, NULL);
+  
+  while (plugins) {
+    GstPlugin *plugin = (GstPlugin *) (plugins->data);
+
+    feature = gst_plugin_find_feature (plugin, name, type);
+    if (feature)
+      return feature;
+    
+    plugins = g_list_next (plugins);
+  }
+  return feature;
+}
+
+/**
+ * gst_registry_find_feature:
+ * @registry: the registry to search
+ * @name: the pluginfeature name to find
+ * @type: the pluginfeature type to find
+ *
+ * Find the pluginfeature with the given name and type in the registry.
+ *
+ * Returns: The pluginfeature with the given name and type or NULL 
+ * if the plugin was not found.
+ */
+GstPluginFeature*
+gst_registry_find_feature (GstRegistry *registry, const gchar *name, GType type)
+{
+  g_return_val_if_fail (GST_IS_REGISTRY (registry), NULL);
+  g_return_val_if_fail (name != NULL, NULL);
+  
+  return gst_plugin_list_find_feature (registry->plugins, name, type);
+}
+
+
+/**
+ * gst_registry_load_plugin:
+ * @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)
+{
+  g_return_val_if_fail (GST_IS_REGISTRY (registry), GST_REGISTRY_PLUGIN_LOAD_ERROR);
+
+  if (CLASS (registry)->load_plugin)
+    return CLASS (registry)->load_plugin (registry, plugin);
+
+  return GST_REGISTRY_PLUGIN_LOAD_ERROR;
+}
+
+/**
+ * gst_registry_unload_plugin:
+ * @registry: the registry to unload the plugin from
+ * @plugin: the plugin to unload
+ *
+ * Unload the plugin from the given registry.
+ *
+ * Returns: a value indicating the result 
+ */
+GstRegistryReturn
+gst_registry_unload_plugin (GstRegistry *registry, GstPlugin *plugin)
+{
+  g_return_val_if_fail (GST_IS_REGISTRY (registry), GST_REGISTRY_PLUGIN_LOAD_ERROR);
+
+  if (CLASS (registry)->unload_plugin)
+    return CLASS (registry)->unload_plugin (registry, plugin);
+
+  return GST_REGISTRY_PLUGIN_LOAD_ERROR;
+}
+
+/**
+ * gst_registry_update_plugin:
+ * @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)
+{
+  g_return_val_if_fail (GST_IS_REGISTRY (registry), GST_REGISTRY_PLUGIN_LOAD_ERROR);
+
+  if (CLASS (registry)->update_plugin)
+    return CLASS (registry)->update_plugin (registry, plugin);
+
+  return GST_REGISTRY_PLUGIN_LOAD_ERROR;
+}
+
+/**
+ * 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);
+}
+
+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);
+}
+
+/**
+ * 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);
+}
+
+
+/**
+ * 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)
+{
+  GList *walk = _gst_registry_pool;
+
+  while (walk) {
+    GstRegistry *registry = GST_REGISTRY (walk->data);
+
+    if (registry->flags & GST_REGISTRY_READABLE &&
+        !(registry->flags & GST_REGISTRY_DELAYED_LOADING)) {
+      gst_registry_load (registry);
+    }
+    
+    walk = g_list_next (walk);
+  }
+}
+
+/**
+ * gst_registry_pool_plugin_list:
+ *
+ * Get a list of all plugins in the pool.
+ * 
+ * Returns: a GList of plugins, g_list_free after use.
+ */
+GList*
+gst_registry_pool_plugin_list (void)
+{
+  GList *result = NULL;
+  GList *walk = _gst_registry_pool;
+
+  while (walk) {
+    GstRegistry *registry = GST_REGISTRY (walk->data);
+
+    /* FIXME only include highest priority plugins */
+    result = g_list_concat (result, g_list_copy (registry->plugins));
+    
+    walk = g_list_next (walk);
+  }
+  
+  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 GList of pluginfeatures, g_list_free after use.
+ */
+GList*
+gst_registry_pool_feature_list (GType type)
+{
+  GList *result = NULL;
+  GList *plugins = gst_registry_pool_plugin_list ();
+
+  while (plugins) {
+    GstPlugin *plugin = GST_PLUGIN (plugins->data);
+    GList *features = plugin->features;
+      
+    while (features) {
+      GstPluginFeature *feature = GST_PLUGIN_FEATURE (features->data);
+
+      if (type == 0 || G_OBJECT_TYPE (feature) == type) {
+        result = g_list_prepend (result, feature);
+      }
+      features = g_list_next (features);
+    }
+    plugins = g_list_next (plugins);
+  }
+  result = g_list_reverse (result);
+  
+  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 = _gst_registry_pool;
+
+  while (walk) {
+    GstRegistry *registry = GST_REGISTRY (walk->data);
+
+    /* FIXME only include highest priority plugins */
+    result = gst_registry_find_plugin (registry, name);
+    if (result)
+      return result;
+    
+    walk = g_list_next (walk);
+  }
+  return NULL;
+}
+
+/**
+ * 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;
+  
+  result = gst_plugin_list_find_feature (_gst_registry_pool_plugins, name, type);
+  if (result)
+    return result;
+  
+  walk = _gst_registry_pool;
+
+  while (walk) {
+    GstRegistry *registry = GST_REGISTRY (walk->data);
+
+    /* FIXME only include highest priority plugins */
+    result = gst_registry_find_feature (registry, name, type);
+    if (result)
+      return result;
+    
+    walk = g_list_next (walk);
+  }
+  return NULL;
+}
+
+/**
+ * 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)
+{
+  GList *walk = _gst_registry_pool;
+
+  while (walk) {
+    GstRegistry *registry = GST_REGISTRY (walk->data);
+
+    if (registry->flags & flags)
+      return registry;
+    
+    walk = g_list_next (walk);
+  }
+  return NULL;
+}
+
+
+
 static gchar *gst_registry_option = NULL;
 
 /* save the registry specified as an option */
index fc876d6..ec768a8 100644 (file)
@@ -24,6 +24,8 @@
 #ifndef __GST_REGISTRY_H__
 #define __GST_REGISTRY_H__
 
+#include <gst/gstplugin.h>
+
 #define GLOBAL_REGISTRY_DIR      GST_CONFIG_DIR
 #define GLOBAL_REGISTRY_FILE     GLOBAL_REGISTRY_DIR"/registry.xml"
 #define GLOBAL_REGISTRY_FILE_TMP GLOBAL_REGISTRY_DIR"/.registry.xml.tmp"
@@ -41,9 +43,7 @@
                              S_IRGRP | S_IWGRP | \
                             S_IROTH | S_IWOTH)
 
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
+G_BEGIN_DECLS
 
 typedef struct _GstRegistryWrite GstRegistryWrite;
 struct _GstRegistryWrite {
@@ -61,9 +61,112 @@ struct _GstRegistryRead {
 GstRegistryWrite       *gst_registry_write_get         (void);
 GstRegistryRead        *gst_registry_read_get          (void);
 void                   gst_registry_option_set         (const gchar *registry);
+
+
+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_REMOTE                  = (1 << 3),
+  GST_REGISTRY_DELAYED_LOADING         = (1 << 4),
+} GstRegistryFlags;
+
   
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
+#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_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_REGISTRY,GstRegistryClass))
+#define GST_IS_REGISTRY(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_REGISTRY))
+#define GST_IS_REGISTRY_CLASS(obj) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_REGISTRY))
+
+typedef struct _GstRegistry GstRegistry;
+typedef struct _GstRegistryClass GstRegistryClass;
+
+struct _GstRegistry {
+  GObject       object;
+
+  gint                  priority;
+  GstRegistryFlags flags;
+
+  gchar        *name;
+  gchar        *details;
+
+  gboolean      loaded;
+  GList                *plugins;
+
+  GList        *paths;
+};
+
+struct _GstRegistryClass {
+  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 */
+  void                         (*plugin_added)         (GstRegistry *registry, GstPlugin *plugin);
+};
+
+
+/* normal GObject stuff */
+GType                  gst_registry_get_type           (void);
+
+gboolean               gst_registry_load               (GstRegistry *registry);
+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);
+GList*                 gst_registry_get_path_list      (GstRegistry *registry);
+void                   gst_registry_clear_paths        (GstRegistry *registry);
+
+gboolean               gst_registry_add_plugin         (GstRegistry *registry, GstPlugin *plugin);
+void                   gst_registry_remove_plugin      (GstRegistry *registry, GstPlugin *plugin);
+
+GstPlugin*             gst_registry_find_plugin        (GstRegistry *registry, const gchar *name);
+GstPluginFeature*      gst_registry_find_feature       (GstRegistry *registry, const gchar *name, GType type);
+
+GstRegistryReturn      gst_registry_load_plugin        (GstRegistry *registry, GstPlugin *plugin);
+GstRegistryReturn      gst_registry_unload_plugin      (GstRegistry *registry, GstPlugin *plugin);
+GstRegistryReturn      gst_registry_update_plugin      (GstRegistry *registry, GstPlugin *plugin);
+
+/* 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_add           (GstRegistry *registry, guint priority);
+void                   gst_registry_pool_load_all      (void);
+
+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_H__ */
index 225c46a..0963b7d 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "gstsystemclock.h"
 #include "gstscheduler.h"
+#include "gstregistry.h"
 
 static void    gst_scheduler_class_init        (GstSchedulerClass *klass);
 static void    gst_scheduler_init              (GstScheduler *sched);
@@ -181,9 +182,11 @@ gst_scheduler_add_element (GstScheduler *sched, GstElement *element)
 
   if (element->getclockfunc) {
     sched->clock_providers = g_list_prepend (sched->clock_providers, element);
+    GST_DEBUG (GST_CAT_CLOCK, "added clock provider %s", GST_ELEMENT_NAME (element));
   }
   if (element->setclockfunc) {
     sched->clock_receivers = g_list_prepend (sched->clock_receivers, element);
+    GST_DEBUG (GST_CAT_CLOCK, "added clock receiver %s", GST_ELEMENT_NAME (element));
   }
 
   if (CLASS (sched)->add_element)
@@ -247,11 +250,21 @@ gst_scheduler_state_transition (GstScheduler *sched, GstElement *element, gint t
         if (clock)
           gst_clock_reset (clock);
 
+        GST_DEBUG (GST_CAT_CLOCK, "scheduler READY to PAUSED clock is %p (%s)", clock, 
+                       (clock ? GST_OBJECT_NAME (clock) : "nil"));
+
        sched->current_clock = clock;
         break;
       }
       case GST_STATE_PAUSED_TO_PLAYING:
       {
+        GstClock *clock = gst_scheduler_get_clock (sched);
+
+        GST_DEBUG (GST_CAT_CLOCK, "scheduler PAUSED to PLAYING clock is %p (%s)", clock, 
+                       (clock ? GST_OBJECT_NAME (clock) : "nil"));
+
+       sched->current_clock = clock;
+
        gst_scheduler_set_clock (sched, sched->current_clock);
         if (sched->current_clock)
           gst_clock_set_active (sched->current_clock, TRUE);
@@ -415,20 +428,21 @@ gst_scheduler_get_clock (GstScheduler *sched)
   
   if (GST_FLAG_IS_SET (sched, GST_SCHEDULER_FLAG_FIXED_CLOCK)) {
     clock = sched->clock;  
+
+    GST_DEBUG (GST_CAT_CLOCK, "scheduler using fixed clock %p (%s)", clock, 
+                       (clock ? GST_OBJECT_NAME (clock) : "nil"));
   }
   else {
-    if (sched->schedulers) {
-      GList *schedulers = sched->schedulers;
+    GList *schedulers = sched->schedulers;
 
-      while (schedulers) {
-        GstScheduler *scheduler = GST_SCHEDULER (schedulers->data);
+    while (schedulers) {
+      GstScheduler *scheduler = GST_SCHEDULER (schedulers->data);
       
-        clock = gst_scheduler_get_clock (scheduler);
-        if (clock)
-         break;
+      clock = gst_scheduler_get_clock (scheduler);
+      if (clock)
+        break;
 
-        schedulers = g_list_next (schedulers);
-      }
+      schedulers = g_list_next (schedulers);
     }
     if (!clock && sched->clock_providers) {
       clock = gst_element_get_clock (GST_ELEMENT (sched->clock_providers->data));
@@ -437,6 +451,8 @@ gst_scheduler_get_clock (GstScheduler *sched)
       clock = gst_system_clock_obtain ();
     }
   }
+  GST_DEBUG (GST_CAT_CLOCK, "scheduler selected clock %p (%s)", clock, 
+               (clock ? GST_OBJECT_NAME (clock) : "nil"));
 
   return clock;
 }
@@ -458,6 +474,9 @@ gst_scheduler_use_clock (GstScheduler *sched, GstClock *clock)
 
   GST_FLAG_SET (sched, GST_SCHEDULER_FLAG_FIXED_CLOCK);
   sched->clock = clock;
+
+  GST_DEBUG (GST_CAT_CLOCK, "scheduler using fixed clock %p (%s)", clock, 
+               (clock ? GST_OBJECT_NAME (clock) : "nil"));
 }
 
 /**
@@ -482,6 +501,9 @@ gst_scheduler_set_clock (GstScheduler *sched, GstClock *clock)
 
   sched->current_clock = clock;
 
+  GST_DEBUG (GST_CAT_CLOCK, "scheduler setting clock %p (%s)", clock, 
+               (clock ? GST_OBJECT_NAME (clock) : "nil"));
+
   while (receivers) {
     GstElement *element = GST_ELEMENT (receivers->data);
 
@@ -510,6 +532,8 @@ gst_scheduler_auto_clock (GstScheduler *sched)
 
   GST_FLAG_UNSET (sched, GST_SCHEDULER_FLAG_FIXED_CLOCK);
   sched->clock = NULL;
+
+  GST_DEBUG (GST_CAT_CLOCK, "scheduler using automatic clock");
 }
 
 /**
@@ -573,17 +597,9 @@ gst_scheduler_show (GstScheduler *sched)
  * Factory stuff starts here
  *
  */
-
-static GList* _gst_schedulerfactories;
-
 static void            gst_scheduler_factory_class_init                (GstSchedulerFactoryClass *klass);
 static void            gst_scheduler_factory_init              (GstSchedulerFactory *factory);
 
-#ifndef GST_DISABLE_REGISTRY
-static xmlNodePtr      gst_scheduler_factory_save_thyself      (GstObject *object, xmlNodePtr parent);
-static void            gst_scheduler_factory_restore_thyself   (GstObject *object, xmlNodePtr parent);
-#endif
-
 static GstPluginFeatureClass *factory_parent_class = NULL;
 /* static guint gst_scheduler_factory_signals[LAST_SIGNAL] = { 0 }; */
 
@@ -624,12 +640,6 @@ gst_scheduler_factory_class_init (GstSchedulerFactoryClass *klass)
 
   factory_parent_class = g_type_class_ref (GST_TYPE_PLUGIN_FEATURE);
 
-#ifndef GST_DISABLE_REGISTRY
-  gstobject_class->save_thyself =      GST_DEBUG_FUNCPTR (gst_scheduler_factory_save_thyself);
-  gstobject_class->restore_thyself =   GST_DEBUG_FUNCPTR (gst_scheduler_factory_restore_thyself);
-#endif
-
-  _gst_schedulerfactories = NULL;
   if (!_default_name)
     _default_name = g_strdup ("basic");
 }
@@ -637,7 +647,6 @@ gst_scheduler_factory_class_init (GstSchedulerFactoryClass *klass)
 static void
 gst_scheduler_factory_init (GstSchedulerFactory *factory)
 {
-  _gst_schedulerfactories = g_list_prepend (_gst_schedulerfactories, factory);
 }
        
 
@@ -662,7 +671,7 @@ gst_scheduler_factory_new (const gchar *name, const gchar *longdesc, GType type)
     factory = GST_SCHEDULER_FACTORY (g_object_new (GST_TYPE_SCHEDULER_FACTORY, NULL));
   }
 
-  gst_object_set_name (GST_OBJECT (factory), name);
+  GST_PLUGIN_FEATURE_NAME (factory) = g_strdup (name);
   if (factory->longdesc)
     g_free (factory->longdesc);
   factory->longdesc = g_strdup (longdesc);
@@ -682,8 +691,6 @@ gst_scheduler_factory_destroy (GstSchedulerFactory *factory)
 {
   g_return_if_fail (factory != NULL);
 
-  _gst_schedulerfactories = g_list_remove (_gst_schedulerfactories, factory);
-
   /* we don't free the struct bacause someone might  have a handle to it.. */
 }
 
@@ -698,38 +705,20 @@ gst_scheduler_factory_destroy (GstSchedulerFactory *factory)
 GstSchedulerFactory*
 gst_scheduler_factory_find (const gchar *name)
 {
-  GList *walk;
-  GstSchedulerFactory *factory;
+  GstPluginFeature *feature;
 
   g_return_val_if_fail(name != NULL, NULL);
 
   GST_DEBUG (0,"gstscheduler: find \"%s\"", name);
 
-  walk = _gst_schedulerfactories;
-  while (walk) {
-    factory = (GstSchedulerFactory *)(walk->data);
-    if (!strcmp (name, GST_OBJECT_NAME (factory)))
-      return factory;
-    walk = g_list_next (walk);
-  }
+  feature = gst_registry_pool_find_feature (name, GST_TYPE_SCHEDULER_FACTORY);
+  if (feature)
+    return GST_SCHEDULER_FACTORY (feature);
 
   return NULL;
 }
 
 /**
- * gst_scheduler_factory_get_list:
- *
- * Get the global list of schedulerfactories.
- *
- * Returns: GList of type #GstSchedulerFactory
- */
-const GList*
-gst_scheduler_factory_get_list (void)
-{
-  return _gst_schedulerfactories;
-}
-
-/**
  * gst_scheduler_factory_create:
  * @factory: the factory used to create the instance
  * @parent: the parent element of this scheduler
@@ -820,52 +809,3 @@ gst_scheduler_factory_get_default_name (void)
 {
   return _default_name;
 }
-
-#ifndef GST_DISABLE_REGISTRY
-static xmlNodePtr
-gst_scheduler_factory_save_thyself (GstObject *object, xmlNodePtr parent)
-{
-  GstSchedulerFactory *factory;
-
-  g_return_val_if_fail (GST_IS_SCHEDULER_FACTORY (object), parent);
-
-  factory = GST_SCHEDULER_FACTORY (object);
-
-  if (GST_OBJECT_CLASS (factory_parent_class)->save_thyself) {
-    GST_OBJECT_CLASS (factory_parent_class)->save_thyself (object, parent);
-  }
-
-  xmlNewChild (parent, NULL, "longdesc", factory->longdesc);
-
-  return parent;
-}
-
-/**
- * gst_scheduler_factory_load_thyself:
- * @parent: the parent XML node pointer
- *
- * Load an schedulerfactory from the given XML parent node.
- *
- * Returns: A new factory based on the XML node.
- */
-static void
-gst_scheduler_factory_restore_thyself (GstObject *object, xmlNodePtr parent)
-{
-  GstSchedulerFactory *factory = GST_SCHEDULER_FACTORY (object);
-  xmlNodePtr children = parent->xmlChildrenNode;
-
-  if (GST_OBJECT_CLASS (factory_parent_class)->restore_thyself) {
-    GST_OBJECT_CLASS (factory_parent_class)->restore_thyself (object, parent);
-  }
-
-  while (children) {
-    if (!strcmp(children->name, "name")) {
-      gst_object_set_name (GST_OBJECT (factory), xmlNodeGetContent (children));
-    }
-    if (!strcmp(children->name, "longdesc")) {
-      factory->longdesc = xmlNodeGetContent (children);
-    }
-    children = children->next;
-  }
-}
-#endif /* GST_DISABLE_REGISTRY */
index 49a0986..ba61ffe 100644 (file)
@@ -174,7 +174,6 @@ GstSchedulerFactory*        gst_scheduler_factory_new               (const gchar *name, const gchar
 void                    gst_scheduler_factory_destroy          (GstSchedulerFactory *factory);
 
 GstSchedulerFactory*   gst_scheduler_factory_find              (const gchar *name);
-const GList*           gst_scheduler_factory_get_list          (void);
 
 GstScheduler*          gst_scheduler_factory_create            (GstSchedulerFactory *factory, GstElement *parent);
 GstScheduler*          gst_scheduler_factory_make              (const gchar *name, GstElement *parent);
index 0b986cc..7c6893b 100644 (file)
 #include "gst_private.h"
 
 #include "gsttype.h"
+#include "gstregistry.h"
 
 
 /* global list of registered types */
 static GList *_gst_types;
 static guint16 _gst_maxtype;
 
-static GList *_gst_typefactories;
-
 static void            gst_type_factory_class_init     (GstTypeFactoryClass *klass);
 static void            gst_type_factory_init           (GstTypeFactory *factory);
 
 static GstCaps*                gst_type_type_find_dummy                (GstBuffer *buffer, gpointer priv);
 
-#ifndef GST_DISABLE_REGISTRY
-static xmlNodePtr      gst_type_factory_save_thyself   (GstObject *object, xmlNodePtr parent);
-static void            gst_type_factory_restore_thyself (GstObject *object, xmlNodePtr parent);
-#endif /* GST_DISABLE_REGISTRY */
-
 static void            gst_type_factory_unload_thyself         (GstPluginFeature *feature);
 
 static GstPluginFeatureClass *parent_class = NULL;
@@ -90,23 +84,16 @@ gst_type_factory_class_init (GstTypeFactoryClass *klass)
 
   parent_class = g_type_class_ref (GST_TYPE_PLUGIN_FEATURE);
 
-#ifndef GST_DISABLE_REGISTRY
-  gstobject_class->save_thyself =      GST_DEBUG_FUNCPTR (gst_type_factory_save_thyself);
-  gstobject_class->restore_thyself =   GST_DEBUG_FUNCPTR (gst_type_factory_restore_thyself);
-#endif /* GST_DISABLE_REGISTRY */
-
   gstpluginfeature_class->unload_thyself = GST_DEBUG_FUNCPTR (gst_type_factory_unload_thyself);
 
   _gst_types = NULL;
   _gst_maxtype = 1;            /* type 0 is undefined */
 
-  _gst_typefactories = NULL;
 }
 
 static void
 gst_type_factory_init (GstTypeFactory *factory)
 {
-  _gst_typefactories = g_list_prepend (_gst_typefactories, factory);
 }
 
 /**
@@ -132,7 +119,8 @@ gst_type_factory_new (GstTypeDefinition *definition)
     factory = GST_TYPE_FACTORY (g_object_new (GST_TYPE_TYPE_FACTORY, NULL));
   }
 
-  gst_object_set_name (GST_OBJECT (factory), definition->name);
+
+  GST_PLUGIN_FEATURE_NAME (factory) = g_strdup (definition->name);
   factory->mime = g_strdup (definition->mime);
   factory->exts = g_strdup (definition->exts);
   factory->typefindfunc = definition->typefindfunc;
@@ -291,19 +279,6 @@ gst_type_get_list (void)
 }
 
 /**
- * gst_type_factory_get_list:
- *
- * Return a list of all typefactories
- *
- * Returns: a list of GstTypeFactories
- */
-const GList*
-gst_type_factory_get_list (void)
-{
-  return _gst_typefactories;
-}
-
-/**
  * gst_type_factory_find:
  * @name: the name of the typefactory to find
  *
@@ -314,15 +289,14 @@ gst_type_factory_get_list (void)
 GstTypeFactory*
 gst_type_factory_find (const gchar *name)
 {
-  GList *walk = _gst_typefactories;
-  GstTypeFactory *factory;
+  GstPluginFeature *feature;
+
+  g_return_val_if_fail (name != NULL, NULL);
+
+  feature = gst_registry_pool_find_feature (name, GST_TYPE_TYPE_FACTORY);
+  if (feature)
+    return GST_TYPE_FACTORY (feature);
 
-  while (walk) {
-    factory = GST_TYPE_FACTORY (walk->data);
-    if (!strcmp (GST_OBJECT_NAME (factory), name))
-      return factory;
-    walk = g_list_next (walk);
-  }
   return NULL;
 }
 
@@ -356,64 +330,3 @@ gst_type_type_find_dummy (GstBuffer *buffer, gpointer priv)
 
   return NULL;
 }
-
-#ifndef GST_DISABLE_REGISTRY
-static xmlNodePtr
-gst_type_factory_save_thyself (GstObject *object, xmlNodePtr parent)
-{
-  GstTypeFactory *factory;
-
-  g_return_val_if_fail (GST_IS_TYPE_FACTORY (object), parent);
-
-  factory = GST_TYPE_FACTORY (object);
-
-  if (GST_OBJECT_CLASS (parent_class)->save_thyself) {
-    GST_OBJECT_CLASS (parent_class)->save_thyself (object, parent);
-  }
-
-  xmlNewChild (parent, NULL, "mime", factory->mime);
-  if (factory->exts) {
-    xmlNewChild (parent, NULL, "extensions", factory->exts);
-  }
-  if (factory->typefindfunc) {
-    xmlNewChild (parent, NULL, "typefind", NULL);
-  }
-
-  return parent;
-}
-
-/**
- * gst_type_factory_restore_thyself:
- * @parent: the parent node to load from
- *
- * Load a typefactory from an XML representation.
- *
- * Returns: the new typefactory
- */
-static void
-gst_type_factory_restore_thyself (GstObject *object, xmlNodePtr parent)
-{
-  GstTypeFactory *factory = GST_TYPE_FACTORY (object);
-  xmlNodePtr field = parent->xmlChildrenNode;
-  factory->typefindfunc = NULL;
-
-  if (GST_OBJECT_CLASS (parent_class)->restore_thyself) {
-    GST_OBJECT_CLASS (parent_class)->restore_thyself (object, parent);
-  }
-
-  while (field) {
-    if (!strcmp (field->name, "mime")) {
-      factory->mime = xmlNodeGetContent (field);
-    }
-    else if (!strcmp (field->name, "extensions")) {
-      factory->exts = xmlNodeGetContent (field);
-    }
-    else if (!strcmp (field->name, "typefind")) {
-      factory->typefindfunc = gst_type_type_find_dummy;
-    }
-    field = field->next;
-  }
-
-  gst_type_register (factory);
-}
-#endif /* GST_DISABLE_REGISTRY */
index ca7b73d..3080c03 100644 (file)
@@ -44,7 +44,6 @@ struct _GstType {
   gchar *exts;                 /* space-delimited list of extensions */
 
   GSList *factories;           /* factories providing this type */
-
 };
 
 struct _GstTypeDefinition {
@@ -83,7 +82,6 @@ GType                 gst_type_factory_get_type       (void);
 GstTypeFactory*                gst_type_factory_new            (GstTypeDefinition *definition);
 
 GstTypeFactory*                gst_type_factory_find           (const gchar *name);
-const GList*           gst_type_factory_get_list       (void);
 
 
 /* create a new type, or find/merge an existing one */
index b2c311e..cd2101a 100644 (file)
@@ -181,7 +181,7 @@ gst_type_find_chain (GstPad *pad, GstBuffer *buf)
       GstTypeFindFunc typefindfunc = (GstTypeFindFunc)factory->typefindfunc;
       GstCaps *caps;
 
-      GST_DEBUG (0,"try type :%d \"%s\"", type->id, type->mime);
+      GST_DEBUG (0,"try type (%p) :%d \"%s\" %p", factory, type->id, type->mime, typefindfunc);
       if (typefindfunc && (caps = typefindfunc (buf, factory))) {
         GST_DEBUG (0,"found type :%d \"%s\" \"%s\"", caps->id, type->mime, 
                        gst_caps_get_name (caps));
diff --git a/gst/registries/Makefile.am b/gst/registries/Makefile.am
new file mode 100644 (file)
index 0000000..9fb1d0d
--- /dev/null
@@ -0,0 +1,13 @@
+noinst_LTLIBRARIES = libgstxmlregistry.la
+
+libgstxmlregistry_la_SOURCES = gstxmlregistry.c
+
+libgstxmlregistry_la_CFLAGS = $(LIBGST_CFLAGS)
+libgstxmlregistry_la_LIBADD = $(LIBGST_LIBS)
+
+noinst_HEADERS = gstxmlregistry.h
+check_PROGRAMS = registrytest
+
+registrytest_SOURCES = registrytest.c
+registrytest_CFLAGS = $(GST_CFLAGS)
+registrytest_LDADD = $(GST_LIBS) libgstxmlregistry.la
diff --git a/gst/registries/gstxmlregistry.c b/gst/registries/gstxmlregistry.c
new file mode 100644 (file)
index 0000000..96bcdfc
--- /dev/null
@@ -0,0 +1,1074 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *                    2000 Wim Taymans <wtay@chello.be>
+ *
+ * gstxml_registry.c: GstXMLRegistry object, support routines
+ *
+ * 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.
+ */
+
+/* #define DEBUG_ENABLED */
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <unistd.h>
+
+#include <gst/gst_private.h>
+#include <gst/gstelement.h>
+#include <gst/gsttype.h>
+#include <gst/gstscheduler.h>
+#include <gst/gstautoplug.h>
+
+#include "gstxmlregistry.h"
+
+#define BLOCK_SIZE 1024*10
+
+#define CLASS(registry)  GST_XML_REGISTRY_CLASS (G_OBJECT_GET_CLASS (registry))
+
+
+static void            gst_xml_registry_class_init             (GstXMLRegistryClass *klass);
+static void            gst_xml_registry_init                   (GstXMLRegistry *registry);
+
+static gboolean                gst_xml_registry_load                   (GstRegistry *registry);
+static gboolean                gst_xml_registry_save                   (GstRegistry *registry);
+static gboolean        gst_xml_registry_rebuild                (GstRegistry *registry);
+
+static gboolean        gst_xml_registry_open_func              (GstXMLRegistry *registry, GstXMLRegistryMode mode);
+static gboolean        gst_xml_registry_load_func              (GstXMLRegistry *registry, gchar *data, gssize *size);
+static gboolean        gst_xml_registry_save_func              (GstXMLRegistry *registry, gchar *format, ...);
+static gboolean        gst_xml_registry_close_func             (GstXMLRegistry *registry);
+
+
+static GstRegistryReturn gst_xml_registry_load_plugin          (GstRegistry *registry, GstPlugin *plugin);
+
+static void            gst_xml_registry_start_element          (GMarkupParseContext *context,
+                                                                const gchar         *element_name,
+                                                                const gchar        **attribute_names,
+                                                                const gchar        **attribute_values,
+                                                                gpointer             user_data,
+                                                                GError             **error);
+static void            gst_xml_registry_end_element            (GMarkupParseContext *context,
+                                                                const gchar         *element_name,
+                                                                gpointer             user_data,
+                                                                GError             **error);
+static void            gst_xml_registry_text                   (GMarkupParseContext *context,
+                                                                const gchar         *text,
+                                                                gsize                text_len,  
+                                                                gpointer             user_data,
+                                                                GError             **error);
+static void            gst_xml_registry_passthrough            (GMarkupParseContext *context,
+                                                                const gchar         *passthrough_text,
+                                                                gsize                text_len,  
+                                                                gpointer             user_data,
+                                                                GError             **error);
+static void            gst_xml_registry_error                  (GMarkupParseContext *context,
+                                                                GError              *error,
+                                                                gpointer             user_data);
+
+static GstRegistryClass *parent_class = NULL;
+/* static guint gst_xml_registry_signals[LAST_SIGNAL] = { 0 }; */
+
+static const GMarkupParser 
+gst_xml_registry_parser = 
+{
+  gst_xml_registry_start_element,
+  gst_xml_registry_end_element,
+  gst_xml_registry_text,
+  gst_xml_registry_passthrough,
+  gst_xml_registry_error,
+};
+
+
+GType 
+gst_xml_registry_get_type (void) 
+{
+  static GType xml_registry_type = 0;
+
+  if (!xml_registry_type) {
+    static const GTypeInfo xml_registry_info = {
+      sizeof (GstXMLRegistryClass),
+      NULL,
+      NULL,
+      (GClassInitFunc) gst_xml_registry_class_init,
+      NULL,
+      NULL,
+      sizeof(GstXMLRegistry),
+      0,
+      (GInstanceInitFunc) gst_xml_registry_init,
+      NULL
+    };
+    xml_registry_type = g_type_register_static (GST_TYPE_REGISTRY, 
+                                               "GstXMLRegistry", &xml_registry_info, 0);
+  }
+  return xml_registry_type;
+}
+
+static void
+gst_xml_registry_class_init (GstXMLRegistryClass *klass)
+{
+  GObjectClass *gobject_class;
+  GstRegistryClass *gstregistry_class;
+  GstXMLRegistryClass *gstxmlregistry_class;
+
+  gobject_class = (GObjectClass*)klass;
+  gstregistry_class = (GstRegistryClass*)klass;
+  gstxmlregistry_class = (GstXMLRegistryClass*)klass;
+
+  parent_class = g_type_class_ref (GST_TYPE_REGISTRY);
+
+  gstregistry_class->load        = GST_DEBUG_FUNCPTR (gst_xml_registry_load);
+  gstregistry_class->save        = GST_DEBUG_FUNCPTR (gst_xml_registry_save);
+  gstregistry_class->rebuild     = GST_DEBUG_FUNCPTR (gst_xml_registry_rebuild);
+  
+  gstregistry_class->load_plugin  = GST_DEBUG_FUNCPTR (gst_xml_registry_load_plugin);
+
+  gstxmlregistry_class->open_func      = GST_DEBUG_FUNCPTR (gst_xml_registry_open_func);
+  gstxmlregistry_class->load_func      = GST_DEBUG_FUNCPTR (gst_xml_registry_load_func);
+  gstxmlregistry_class->save_func      = GST_DEBUG_FUNCPTR (gst_xml_registry_save_func);
+  gstxmlregistry_class->close_func     = GST_DEBUG_FUNCPTR (gst_xml_registry_close_func);
+}
+
+static void
+gst_xml_registry_init (GstXMLRegistry *registry)
+{
+  registry->location = NULL;
+  registry->context = NULL;
+  registry->state = GST_XML_REGISTRY_NONE;
+  registry->current_plugin = NULL;
+  registry->current_feature = NULL;
+  registry->open_tags = NULL;
+}
+
+/**
+ * gst_xml_registry_new:
+ * @name: the name of the registry
+ * @location: the location of the registry file
+ *
+ * Create a new xml registry with the given name and location.
+ *
+ * Returns: a new GstXMLRegistry with the given name an location.
+ */
+GstRegistry*
+gst_xml_registry_new (const gchar *name, const gchar *location) 
+{
+  GstXMLRegistry *xmlregistry;
+  
+  xmlregistry = GST_XML_REGISTRY (g_object_new (GST_TYPE_XML_REGISTRY, NULL));
+  
+  xmlregistry->location = g_strdup (location);
+
+  GST_REGISTRY (xmlregistry)->name = g_strdup (name);
+  GST_REGISTRY (xmlregistry)->flags = GST_REGISTRY_READABLE | GST_REGISTRY_WRITABLE;
+
+  return GST_REGISTRY (xmlregistry);
+}
+
+static gboolean
+gst_xml_registry_open_func (GstXMLRegistry *registry, GstXMLRegistryMode mode)
+{
+  if (mode == GST_XML_REGISTRY_READ)
+    registry->regfile = fopen (registry->location, "r");
+  else if (mode == GST_XML_REGISTRY_WRITE)
+    registry->regfile = fopen (registry->location, "w");
+
+  if (!registry->regfile)
+    return FALSE;
+
+  return TRUE;
+}
+
+static gboolean
+gst_xml_registry_load_func (GstXMLRegistry *registry, gchar *data, gssize *size)
+{
+  *size = fread (data, 1, *size, registry->regfile);
+  
+  return TRUE;
+}
+
+static gboolean
+gst_xml_registry_save_func (GstXMLRegistry *registry, gchar *format, ...)
+{
+  va_list var_args;
+
+  va_start (var_args, format);
+
+  vfprintf (registry->regfile, format, var_args);
+
+  va_end (var_args);
+
+  return TRUE;
+}
+
+static gboolean
+gst_xml_registry_close_func (GstXMLRegistry *registry)
+{
+  fclose (registry->regfile);
+
+  return TRUE;
+}
+
+static gboolean
+gst_xml_registry_load (GstRegistry *registry)
+{
+  GstXMLRegistry *xmlregistry = GST_XML_REGISTRY (registry);
+  gchar *text;
+  gssize size;
+  GError *error = NULL;
+  GTimer *timer;
+  gdouble seconds;
+
+  timer = g_timer_new();
+  
+  xmlregistry->context = g_markup_parse_context_new (&gst_xml_registry_parser, 0, registry, NULL);
+
+  if (!CLASS (xmlregistry)->open_func (xmlregistry, GST_XML_REGISTRY_READ)) {
+    return FALSE;
+  }
+
+  text = g_malloc (BLOCK_SIZE);
+
+  size = BLOCK_SIZE;
+  CLASS (xmlregistry)->load_func (xmlregistry, text, &size);
+
+  while (size) {
+    g_markup_parse_context_parse (xmlregistry->context, text, size, &error);
+
+    size = BLOCK_SIZE;
+    CLASS (xmlregistry)->load_func (xmlregistry, text, &size);
+  }
+
+  g_free (text);
+
+  if (error) {
+    fprintf(stderr, "ERROR: parsing registry: %s\n", error->message);
+    return FALSE;
+  }
+
+  g_timer_stop (timer);
+
+  seconds = g_timer_elapsed (timer, NULL);
+
+  g_print ("loaded registry %s in %f seconds\n", registry->name, seconds);
+
+  CLASS (xmlregistry)->close_func (xmlregistry);
+
+  
+  return TRUE;
+}
+
+static GstRegistryReturn 
+gst_xml_registry_load_plugin (GstRegistry *registry, GstPlugin *plugin)
+{
+  if (!gst_plugin_load_plugin (plugin)) {
+    return GST_REGISTRY_PLUGIN_LOAD_ERROR;
+  }
+
+  return GST_REGISTRY_OK;
+}
+
+static gboolean
+gst_xml_registry_parse_plugin (GMarkupParseContext *context, const gchar *tag, const gchar *text,
+                               gsize text_len, GstXMLRegistry *registry, GError **error)
+{
+  GstPlugin *plugin = registry->current_plugin;
+  
+  if (!strcmp (tag, "name")) {
+    plugin->name = g_strndup (text, text_len);
+  }
+  else if (!strcmp (tag, "longname")) {
+    plugin->longname = g_strndup (text, text_len);
+  }
+  else if (!strcmp (tag, "filename")) {
+    plugin->filename = g_strndup (text, text_len);
+  }
+  
+  return TRUE;
+}
+
+static gboolean
+gst_xml_registry_parse_element_factory (GMarkupParseContext *context, const gchar *tag, const gchar *text,
+                                        gsize text_len, GstXMLRegistry *registry, GError **error)
+{
+  GstElementFactory *factory = GST_ELEMENT_FACTORY (registry->current_feature);
+
+  if (!strcmp (tag, "name")) {
+    registry->current_feature->name = g_strndup (text, text_len);
+  }
+  else if (!strcmp (tag, "longname")) {
+    factory->details->longname = g_strndup (text, text_len);
+  }
+  else if (!strcmp(tag, "class")) {
+    factory->details->klass = g_strndup (text, text_len);
+  }
+  else if (!strcmp(tag, "description")) {
+    factory->details->description = g_strndup (text, text_len);
+  }
+  else if (!strcmp(tag, "version")) {
+    factory->details->version = g_strndup (text, text_len);
+  }
+  else if (!strcmp(tag, "author")) {
+    factory->details->author = g_strndup (text, text_len);
+  }
+  else if (!strcmp(tag, "copyright")) {
+    factory->details->copyright = g_strndup (text, text_len);
+  }
+
+  return TRUE;
+}
+
+static GstCaps*
+gst_type_type_find_dummy (GstBuffer *buffer, gpointer priv)
+{
+  GstTypeFactory *factory = (GstTypeFactory *)priv;
+
+  GST_DEBUG (GST_CAT_TYPES,"gsttype: need to load typefind function for %s", factory->mime);
+
+  if (gst_plugin_feature_ensure_loaded (GST_PLUGIN_FEATURE (factory))) {
+    if (factory->typefindfunc) {
+      GstCaps *res = factory->typefindfunc (buffer, factory);
+      if (res)
+        return res;
+    }
+  }
+  return NULL;
+}
+
+
+static gboolean
+gst_xml_registry_parse_type_factory (GMarkupParseContext *context, const gchar *tag, const gchar *text,
+                                     gsize text_len, GstXMLRegistry *registry, GError **error)
+{
+  GstTypeFactory *factory = GST_TYPE_FACTORY (registry->current_feature);
+
+  if (!strcmp (tag, "name")) {
+    registry->current_feature->name = g_strndup (text, text_len);
+  }
+  else if (!strcmp (tag, "mime")) {
+    factory->mime = g_strndup (text, text_len);
+  }
+  else if (!strcmp(tag, "extensions")) {
+    factory->exts = g_strndup (text, text_len);
+  }
+
+  return TRUE;
+}
+
+static gboolean
+gst_xml_registry_parse_scheduler_factory (GMarkupParseContext *context, const gchar *tag, const gchar *text,
+                                          gsize text_len, GstXMLRegistry *registry, GError **error)
+{
+  GstSchedulerFactory *factory = GST_SCHEDULER_FACTORY (registry->current_feature);
+
+  if (!strcmp (tag, "name")) {
+    registry->current_feature->name = g_strndup (text, text_len);
+  }
+  else if (!strcmp (tag, "longdesc")) {
+    factory->longdesc = g_strndup (text, text_len);
+  }
+  return TRUE;
+}
+
+static gboolean
+gst_xml_registry_parse_autoplug_factory (GMarkupParseContext *context, const gchar *tag, const gchar *text,
+                                         gsize text_len, GstXMLRegistry *registry, GError **error)
+{
+  //GstAutoplugFactory *factory = GST_AUTOPLUG_FACTORY (registry->current_feature);
+
+  if (!strcmp (tag, "name")) {
+    registry->current_feature->name = g_strndup (text, text_len);
+  }
+  return TRUE;
+}
+
+static gboolean
+gst_xml_registry_parse_padtemplate (GMarkupParseContext *context, const gchar *tag, const gchar *text,
+                                    gsize text_len, GstXMLRegistry *registry, GError **error)
+{
+  if (!strcmp (tag, "nametemplate")) {
+    registry->name_template = g_strndup (text, text_len);
+  }
+  else if (!strcmp (tag, "direction")) {
+    if (!strncmp(text, "sink", text_len)) {
+      registry->direction = GST_PAD_SINK;
+    }
+    else if (!strncmp(text, "src", text_len)) {
+      registry->direction = GST_PAD_SRC;
+    }
+  }
+  else if (!strcmp (tag, "presence")) {
+    if (!strncmp(text, "always", text_len)) {
+      registry->presence = GST_PAD_ALWAYS;
+    }
+    else if (!strncmp(text, "sometimes", text_len)) {
+      registry->presence = GST_PAD_SOMETIMES;
+    }
+    else if (!strncmp(text, "request", text_len)) {
+      registry->presence = GST_PAD_REQUEST;
+    }
+  }
+  return TRUE;
+}
+
+static gboolean
+gst_xml_registry_parse_capscomp (GMarkupParseContext *context, const gchar *tag, const gchar *text,
+                                 gsize text_len, GstXMLRegistry *registry, GError **error)
+{
+  if (!strcmp (tag, "name")) {
+    registry->caps_name = g_strndup (text, text_len);
+  }
+  else if (!strcmp (tag, "type")) {
+    registry->caps_mime = g_strndup (text, text_len);
+  }
+  return TRUE;
+}
+
+static gint
+find_index_for (const gchar *name, const gchar **attribute_names)
+{
+  gint i=0;
+  
+  while (attribute_names[i]) {
+    if (!strcmp (attribute_names[i], name))
+      return i;
+    i++;
+  }
+  return -1;
+}
+
+static void
+gst_xml_registry_start_element (GMarkupParseContext *context, const gchar *element_name,
+                              const gchar **attribute_names, const gchar **attribute_values,
+                              gpointer user_data, GError **error)
+{
+  GstXMLRegistry *xmlregistry = GST_XML_REGISTRY (user_data);
+
+  xmlregistry->open_tags = g_list_prepend (xmlregistry->open_tags, g_strdup (element_name));
+
+  switch (xmlregistry->state) {
+    case GST_XML_REGISTRY_NONE:
+      if (!strcmp (element_name, "GST-PluginRegistry")) {
+       xmlregistry->state = GST_XML_REGISTRY_TOP;
+      }
+      break;
+    case GST_XML_REGISTRY_TOP:
+      if (!strncmp (element_name, "plugin", 6)) {
+       xmlregistry->state = GST_XML_REGISTRY_PLUGIN;
+       xmlregistry->parser = gst_xml_registry_parse_plugin;
+       xmlregistry->current_plugin = (GstPlugin *)g_new0 (GstPlugin, 1);
+      }
+      break;
+    case GST_XML_REGISTRY_PLUGIN:
+      if (!strncmp (element_name, "feature", 7)) {
+       gint i = 0;
+       GstPluginFeature *feature = NULL;
+       
+       xmlregistry->state = GST_XML_REGISTRY_FEATURE;
+
+       while (attribute_names[i]) {
+          if (!strncmp (attribute_names[i], "typename", 8)) {
+           feature = GST_PLUGIN_FEATURE (g_object_new (g_type_from_name (attribute_values[i]), NULL));
+           break;
+         }
+          i++;
+       }
+       if (feature) {
+         xmlregistry->current_feature = feature;
+         if (GST_IS_ELEMENT_FACTORY (feature)) {
+           GstElementFactory *factory = GST_ELEMENT_FACTORY (feature);
+
+           factory->details_dynamic = TRUE;
+           factory->details = g_new0(GstElementDetails, 1);
+           factory->padtemplates = NULL;
+           xmlregistry->parser = gst_xml_registry_parse_element_factory;
+         }
+         else if (GST_IS_TYPE_FACTORY (feature))
+           xmlregistry->parser = gst_xml_registry_parse_type_factory;
+         else if (GST_IS_SCHEDULER_FACTORY (feature)) {
+           xmlregistry->parser = gst_xml_registry_parse_scheduler_factory;
+            GST_SCHEDULER_FACTORY (feature)->type = 0;
+         }
+         else if (GST_IS_AUTOPLUG_FACTORY (feature))
+           xmlregistry->parser = gst_xml_registry_parse_autoplug_factory;
+       }
+      }
+      break;
+    case GST_XML_REGISTRY_FEATURE:
+      if (!strncmp (element_name, "padtemplate", 11)) {
+       xmlregistry->state = GST_XML_REGISTRY_PADTEMPLATE;
+       xmlregistry->parser = gst_xml_registry_parse_padtemplate;
+       xmlregistry->name_template = NULL;
+       xmlregistry->direction = 0;
+       xmlregistry->presence = 0;
+       xmlregistry->caps = NULL;
+      }
+      break;
+    case GST_XML_REGISTRY_PADTEMPLATE:
+      if (!strncmp (element_name, "caps", 4)) {
+       xmlregistry->state = GST_XML_REGISTRY_CAPS;
+       xmlregistry->parser = NULL;
+      }
+      break;
+    case GST_XML_REGISTRY_CAPS:
+      if (!strncmp (element_name, "capscomp", 8)) {
+       xmlregistry->state = GST_XML_REGISTRY_CAPSCOMP;
+       xmlregistry->parser = gst_xml_registry_parse_capscomp;
+      }
+      break;
+    case GST_XML_REGISTRY_CAPSCOMP:
+      if (!strncmp (element_name, "properties", 10)) {
+       xmlregistry->state = GST_XML_REGISTRY_PROPERTIES;
+       xmlregistry->parser = NULL;
+       xmlregistry->props = gst_props_empty_new ();
+      }
+      break;
+    case GST_XML_REGISTRY_PROPERTIES:
+    {
+      gint name_index;
+      
+      name_index = find_index_for ("name", attribute_names);
+      if (name_index < 0)
+       break;
+
+      if (!strncmp (element_name, "int", 3)) {
+       gint value;
+        gint index;
+
+       if ((index = find_index_for ("value", attribute_names)) < 0) 
+          break;
+       sscanf (attribute_values[index], "%d", &value);
+       gst_props_add_entry (xmlregistry->props, 
+                       gst_props_entry_new (attribute_values[name_index], GST_PROPS_INT (value)));
+      }
+      else if (!strncmp (element_name, "range", 5)) {
+       gint min, max;
+        gint min_idx, max_idx;
+
+       if ((min_idx = find_index_for ("min", attribute_names)) < 0) 
+          break;
+       if ((max_idx = find_index_for ("max", attribute_names)) < 0) 
+          break;
+       sscanf (attribute_values[min_idx], "%d", &min);
+       sscanf (attribute_values[max_idx], "%d", &max);
+       gst_props_add_entry (xmlregistry->props, 
+                       gst_props_entry_new (attribute_values[name_index], GST_PROPS_INT_RANGE (min, max)));
+      }
+      else if (!strncmp (element_name, "float", 5)) {
+       gfloat value;
+        gint index;
+
+       if ((index = find_index_for ("value", attribute_names)) < 0) 
+          break;
+       sscanf (attribute_values[index], "%f", &value);
+       gst_props_add_entry (xmlregistry->props, 
+                       gst_props_entry_new (attribute_values[name_index], GST_PROPS_FLOAT (value)));
+      }
+      else if (!strncmp (element_name, "floatrange", 10)) {
+       gfloat min, max;
+        gint min_idx, max_idx;
+
+       if ((min_idx = find_index_for ("min", attribute_names)) < 0) 
+          break;
+       if ((max_idx = find_index_for ("max", attribute_names)) < 0) 
+          break;
+       sscanf (attribute_values[min_idx], "%f", &min);
+       sscanf (attribute_values[max_idx], "%f", &max);
+       gst_props_add_entry (xmlregistry->props, 
+                       gst_props_entry_new (attribute_values[name_index], GST_PROPS_FLOAT_RANGE (min, max)));
+      }
+      else if (!strncmp (element_name, "boolean", 7)) {
+       gboolean value = TRUE;
+        gint index;
+
+       if ((index = find_index_for ("value", attribute_names)) < 0) 
+          break;
+       if (!strcmp (attribute_values[index], "false")) 
+          value = FALSE;
+       gst_props_add_entry (xmlregistry->props, 
+                       gst_props_entry_new (attribute_values[name_index], GST_PROPS_BOOLEAN (value)));
+      }
+      else if (!strncmp (element_name, "fourcc", 6)) {
+       guint32 value;
+        gint index;
+
+       if ((index = find_index_for ("hexvalue", attribute_names)) < 0) 
+          break;
+       sscanf (attribute_values[index], "%08x", &value);
+       gst_props_add_entry (xmlregistry->props, 
+                       gst_props_entry_new (attribute_values[name_index], GST_PROPS_FOURCC (value)));
+      }
+      else if (!strncmp (element_name, "string", 6)) {
+        gint index;
+
+       if ((index = find_index_for ("value", attribute_names)) < 0) 
+          break;
+       gst_props_add_entry (xmlregistry->props, 
+                       gst_props_entry_new (attribute_values[name_index], 
+                                             GST_PROPS_STRING (attribute_values[index])));
+      }
+      break;
+    }
+    default:
+      break;
+  }
+}
+
+static void
+gst_xml_registry_end_element (GMarkupParseContext *context, const gchar *element_name,
+                             gpointer user_data, GError **error)
+{
+  GstXMLRegistry *xmlregistry = GST_XML_REGISTRY (user_data);
+  gchar *open_tag = (gchar *)xmlregistry->open_tags->data;
+
+  xmlregistry->open_tags = g_list_remove (xmlregistry->open_tags, open_tag);
+  g_free (open_tag);
+
+  switch (xmlregistry->state) {
+    case GST_XML_REGISTRY_TOP:
+      if (!strcmp (element_name, "GST-PluginRegistry")) {
+       xmlregistry->state = GST_XML_REGISTRY_NONE;
+      }
+      break;
+    case GST_XML_REGISTRY_PLUGIN:
+      if (!strcmp (element_name, "plugin")) {
+       xmlregistry->state = GST_XML_REGISTRY_TOP;
+       xmlregistry->parser = NULL;
+       gst_registry_add_plugin (GST_REGISTRY (xmlregistry), xmlregistry->current_plugin);
+      }
+      break;
+    case GST_XML_REGISTRY_FEATURE:
+      if (!strcmp (element_name, "feature")) {
+       if (GST_IS_TYPE_FACTORY (xmlregistry->current_feature)) {
+          GstTypeFactory *factory = GST_TYPE_FACTORY (xmlregistry->current_feature);
+         gst_type_register (factory);
+       }
+       xmlregistry->state = GST_XML_REGISTRY_PLUGIN;
+       xmlregistry->parser = gst_xml_registry_parse_plugin;
+       gst_plugin_add_feature (xmlregistry->current_plugin, xmlregistry->current_feature);
+       xmlregistry->current_feature = NULL;
+      }
+      else if (!strcmp (element_name, "typefind")) {
+        GstTypeFactory *factory = GST_TYPE_FACTORY (xmlregistry->current_feature);
+
+        factory->typefindfunc = gst_type_type_find_dummy;
+      }
+      break;
+    case GST_XML_REGISTRY_PADTEMPLATE:
+      if (!strcmp (element_name, "padtemplate")) {
+       GstPadTemplate *template;
+
+        template = gst_pad_template_new (xmlregistry->name_template,
+                                        xmlregistry->direction,
+                                        xmlregistry->presence,
+                                        xmlregistry->caps, NULL);
+
+       g_free (xmlregistry->name_template);
+       xmlregistry->name_template = NULL;
+       xmlregistry->caps = NULL;
+
+       gst_element_factory_add_pad_template (GST_ELEMENT_FACTORY (xmlregistry->current_feature),
+                                             template);
+       xmlregistry->state = GST_XML_REGISTRY_FEATURE;
+       xmlregistry->parser = gst_xml_registry_parse_element_factory;
+      }
+      break;
+    case GST_XML_REGISTRY_CAPS:
+      if (!strcmp (element_name, "caps")) {
+       xmlregistry->state = GST_XML_REGISTRY_PADTEMPLATE;
+       xmlregistry->parser = gst_xml_registry_parse_padtemplate;
+      }
+      break;
+    case GST_XML_REGISTRY_CAPSCOMP:
+      if (!strcmp (element_name, "capscomp")) {
+       GstCaps *caps;
+       
+       xmlregistry->state = GST_XML_REGISTRY_CAPS;
+       xmlregistry->parser = gst_xml_registry_parse_padtemplate;
+
+       caps = gst_caps_new (xmlregistry->caps_name, xmlregistry->caps_mime, xmlregistry->props);
+
+       xmlregistry->caps = gst_caps_append (xmlregistry->caps, caps);
+       xmlregistry->props = NULL;
+      }
+      break;
+    case GST_XML_REGISTRY_PROPERTIES:
+      if (!strcmp (element_name, "properties")) {
+       xmlregistry->state = GST_XML_REGISTRY_CAPSCOMP;
+       xmlregistry->parser = NULL;
+      }
+      break;
+    default:
+      break;
+  }
+}
+
+static void
+gst_xml_registry_text (GMarkupParseContext *context, const gchar *text,
+                       gsize text_len, gpointer user_data, GError **error)
+{
+  GstXMLRegistry *xmlregistry = GST_XML_REGISTRY (user_data);
+  gchar *open_tag;
+  
+  if (xmlregistry->open_tags) {
+    open_tag = (gchar *)xmlregistry->open_tags->data;
+
+    if (!strcmp (open_tag, "plugin-path")) {
+      //gst_plugin_add_path (g_strndup (text, text_len));
+    }
+    else if (xmlregistry->parser) {
+      xmlregistry->parser (context, open_tag, text, text_len, xmlregistry, error);
+    }
+  }
+}
+
+static void
+gst_xml_registry_passthrough (GMarkupParseContext *context, const gchar *passthrough_text,
+                              gsize text_len, gpointer user_data, GError **error)
+{
+}
+
+static void
+gst_xml_registry_error (GMarkupParseContext *context, GError *error,
+                        gpointer user_data)
+{
+  g_print ("error %s\n", error->message);
+}
+/*
+ * Save
+ */
+#define PUT_ESCAPED(tag,value)                                         \
+G_STMT_START{                                                  \
+  const gchar *toconv = value;                                 \
+  if (value) {                                                 \
+    gchar *v = g_markup_escape_text (toconv, strlen (toconv)); \
+    CLASS (xmlregistry)->save_func (xmlregistry, "<%s>%s</%s>\n", tag, v, tag);                        \
+    g_free (v);                                                        \
+  }                                                            \
+}G_STMT_END
+
+static gboolean
+gst_xml_registry_save_props_func (GstPropsEntry *entry, GstXMLRegistry *xmlregistry)
+{
+  const gchar *name;
+
+  name = gst_props_entry_get_name (entry);
+
+  switch (gst_props_entry_get_type (entry)) {
+    case GST_PROPS_INT_TYPE:
+    {
+      gint value;
+      gst_props_entry_get_int (entry, &value);
+      CLASS (xmlregistry)->save_func (xmlregistry, "<int name=\"%s\" value=\"%d\"/>\n", name, value);
+      break;
+    }
+    case GST_PROPS_INT_RANGE_TYPE:
+    {
+      gint min, max;
+      gst_props_entry_get_int_range (entry, &min, &max);
+      CLASS (xmlregistry)->save_func (xmlregistry, "<range name=\"%s\" min=\"%d\" max=\"%d\"/>\n", name, min, max);
+      break;
+    }
+    case GST_PROPS_FLOAT_TYPE:
+    {
+      gfloat value;
+      gst_props_entry_get_float (entry, &value);
+      CLASS (xmlregistry)->save_func (xmlregistry, "<float name=\"%s\" value=\"%f\"/>\n", name, value);
+      break;
+    }
+    case GST_PROPS_FLOAT_RANGE_TYPE:
+    {
+      gfloat min, max;
+      gst_props_entry_get_float_range (entry, &min, &max);
+      CLASS (xmlregistry)->save_func (xmlregistry, "<floatrange name=\"%s\" min=\"%f\" max=\"%f\"/>\n", name, min, max);
+      break;
+    }
+    case GST_PROPS_FOURCC_TYPE:
+    {
+      guint32 fourcc;
+      gst_props_entry_get_fourcc_int (entry, &fourcc);
+      CLASS (xmlregistry)->save_func (xmlregistry, "<!--%4.4s-->\n", (gchar *)&fourcc);
+      CLASS (xmlregistry)->save_func (xmlregistry, "<fourcc name=\"%s\" hexvalue=\"%08x\"/>\n", name, fourcc);
+      break;
+    }
+    case GST_PROPS_BOOL_TYPE:
+    {
+      gboolean value;
+      gst_props_entry_get_boolean (entry, &value);
+      CLASS (xmlregistry)->save_func (xmlregistry, "<boolean name=\"%s\" value=\"%s\"/>\n", name, (value ? "true" : "false"));
+      break;
+    }
+    case GST_PROPS_STRING_TYPE:
+    {
+      const gchar *value;
+      gst_props_entry_get_string (entry, &value);
+      CLASS (xmlregistry)->save_func (xmlregistry, "<string name=\"%s\" value=\"%s\"/>\n", name, value);
+      break;
+    }
+    default:
+      g_warning ("trying to save unknown property type %d", gst_props_entry_get_type (entry));
+      return FALSE;
+  }
+  return TRUE;
+}
+
+static gboolean
+gst_xml_registry_save_props (GstXMLRegistry *xmlregistry, GstProps *props)
+{
+  GList *proplist;
+
+  proplist = props->properties;
+
+  while (proplist) {
+    GstPropsEntry *entry = (GstPropsEntry *) proplist->data;
+
+    switch (gst_props_entry_get_type (entry)) {
+      case GST_PROPS_LIST_TYPE: 
+      {
+       const GList *list;
+
+       gst_props_entry_get_list (entry, &list);
+       
+        CLASS (xmlregistry)->save_func (xmlregistry, "<list name=\"%s\">\n", gst_props_entry_get_name (entry));
+        g_list_foreach ((GList *)list, (GFunc) gst_xml_registry_save_props_func, xmlregistry);
+        CLASS (xmlregistry)->save_func (xmlregistry, "</list>\n");
+               break;
+      }
+      default:
+       gst_xml_registry_save_props_func (entry, xmlregistry);
+               break;
+    }
+    proplist = g_list_next (proplist);
+  }
+  return TRUE;
+}
+
+static gboolean
+gst_xml_registry_save_caps (GstXMLRegistry *xmlregistry, GstCaps *caps)
+{
+  while (caps) {
+    CLASS (xmlregistry)->save_func (xmlregistry, "<capscomp>\n");
+    PUT_ESCAPED ("name", caps->name);
+    PUT_ESCAPED ("type", gst_type_find_by_id (caps->id)->mime);
+
+    if (caps->properties) {
+      CLASS (xmlregistry)->save_func (xmlregistry, "<properties>\n");
+      gst_xml_registry_save_props (xmlregistry, caps->properties);
+      CLASS (xmlregistry)->save_func (xmlregistry, "</properties>\n");
+    }
+    CLASS (xmlregistry)->save_func (xmlregistry, "</capscomp>\n");
+    caps = caps->next;
+  }
+  return TRUE;
+}
+
+static gboolean
+gst_xml_registry_save_pad_template (GstXMLRegistry *xmlregistry, GstPadTemplate *template)
+{
+  gchar *presence;
+  
+  PUT_ESCAPED ("nametemplate", template->name_template);
+  CLASS (xmlregistry)->save_func (xmlregistry, "<direction>%s</direction>\n", (template->direction == GST_PAD_SINK? "sink":"src"));
+
+  switch (template->presence) {
+    case GST_PAD_ALWAYS:
+      presence = "always";
+      break;
+    case GST_PAD_SOMETIMES:
+      presence = "sometimes";
+      break;
+    case GST_PAD_REQUEST:
+      presence = "request";
+      break;
+    default:
+      presence = "unknown";
+      break;
+  }
+  CLASS (xmlregistry)->save_func (xmlregistry, "<presence>%s</presence>\n", presence);
+
+  if (GST_PAD_TEMPLATE_CAPS (template)) {
+    CLASS (xmlregistry)->save_func (xmlregistry, "<caps>\n");
+    gst_xml_registry_save_caps (xmlregistry, GST_PAD_TEMPLATE_CAPS (template));
+    CLASS (xmlregistry)->save_func (xmlregistry, "</caps>\n");
+  }
+  return TRUE;
+}
+
+static gboolean
+gst_xml_registry_save_feature (GstXMLRegistry *xmlregistry, GstPluginFeature *feature)
+{
+  PUT_ESCAPED ("name", feature->name);
+
+  if (GST_IS_ELEMENT_FACTORY (feature)) {
+    GstElementFactory *factory = GST_ELEMENT_FACTORY (feature);
+    GList *templates;
+
+    PUT_ESCAPED ("longname", factory->details->longname);
+    PUT_ESCAPED ("class", factory->details->klass);
+    PUT_ESCAPED ("description", factory->details->description);
+    PUT_ESCAPED ("version", factory->details->version);
+    PUT_ESCAPED ("author", factory->details->author);
+    PUT_ESCAPED ("copyright", factory->details->copyright);
+    
+    templates = factory->padtemplates;
+
+    while (templates) {
+      GstPadTemplate *template = GST_PAD_TEMPLATE (templates->data);
+
+      CLASS (xmlregistry)->save_func (xmlregistry, "<padtemplate>\n");
+      gst_xml_registry_save_pad_template (xmlregistry, template);
+      CLASS (xmlregistry)->save_func (xmlregistry, "</padtemplate>\n");
+      
+      templates = g_list_next (templates);
+    }
+  }
+  else if (GST_IS_TYPE_FACTORY (feature)) {
+    GstTypeFactory *factory = GST_TYPE_FACTORY (feature);
+
+    PUT_ESCAPED ("mime", factory->mime);
+    PUT_ESCAPED ("extensions", factory->exts);
+    if (factory->typefindfunc) {
+      CLASS (xmlregistry)->save_func (xmlregistry, "<typefind/>\n");
+    }
+  }
+  else if (GST_IS_SCHEDULER_FACTORY (feature)) {
+    PUT_ESCAPED ("longdesc", GST_SCHEDULER_FACTORY (feature)->longdesc);
+  }
+  else if (GST_IS_AUTOPLUG_FACTORY (feature)) {
+    PUT_ESCAPED ("longdesc", GST_AUTOPLUG_FACTORY (feature)->longdesc);
+  }
+  return TRUE;
+}
+
+
+static gboolean
+gst_xml_registry_save_plugin (GstXMLRegistry *xmlregistry, GstPlugin *plugin)
+{
+  GList *walk;
+  
+  PUT_ESCAPED ("name", plugin->name);
+  PUT_ESCAPED ("longname", plugin->longname);
+  PUT_ESCAPED ("filename", plugin->filename);
+
+  walk = plugin->features;
+
+  while (walk) {
+    GstPluginFeature *feature = GST_PLUGIN_FEATURE (walk->data);
+
+    CLASS (xmlregistry)->save_func (xmlregistry, "<feature typename=\"%s\">\n", g_type_name (G_OBJECT_TYPE (feature)));
+    gst_xml_registry_save_feature (xmlregistry, feature);
+    CLASS (xmlregistry)->save_func (xmlregistry, "</feature>\n");
+    
+    walk = g_list_next (walk);
+  }
+  return TRUE;
+}
+
+
+static gboolean
+gst_xml_registry_save (GstRegistry *registry)
+{
+  GList *walk;
+  GstXMLRegistry *xmlregistry;
+  
+  g_return_val_if_fail (GST_IS_REGISTRY (registry), FALSE);
+  g_return_val_if_fail (registry->flags & GST_REGISTRY_WRITABLE, FALSE);
+  
+  xmlregistry = GST_XML_REGISTRY (registry);
+
+  if (!CLASS (xmlregistry)->open_func (xmlregistry, GST_XML_REGISTRY_WRITE)) {
+    return FALSE;
+  }
+
+  walk = g_list_last (registry->plugins);
+
+  CLASS (xmlregistry)->save_func (xmlregistry, "<?xml version=\"1.0\"?>\n");
+  CLASS (xmlregistry)->save_func (xmlregistry, "<GST-PluginRegistry>\n");
+  
+  while (walk) {
+    GstPlugin *plugin = GST_PLUGIN (walk->data);
+
+    CLASS (xmlregistry)->save_func (xmlregistry, "<plugin>\n");
+    gst_xml_registry_save_plugin (xmlregistry, plugin);
+    CLASS (xmlregistry)->save_func (xmlregistry, "</plugin>\n");
+    
+    walk = g_list_previous (walk);
+  }
+  CLASS (xmlregistry)->save_func (xmlregistry, "</GST-PluginRegistry>\n");
+
+  CLASS (xmlregistry)->close_func (xmlregistry);
+
+  return TRUE;
+}
+
+static void
+gst_xml_registry_rebuild_recurse (GstXMLRegistry *registry, const gchar *directory)
+{
+  GDir *dir;
+  gboolean loaded = FALSE;
+
+  dir = g_dir_open (directory, 0, NULL);
+
+  if (dir) {
+    const gchar *dirent;
+
+    while ((dirent = g_dir_read_name (dir))) {
+      gchar *dirname;
+       
+      dirname = g_strjoin ("/", directory, dirent, NULL);
+      gst_xml_registry_rebuild_recurse (registry, dirname);
+      g_free(dirname);
+    }
+    g_dir_close (dir);
+  } else {
+    if (strstr (directory, ".so")) {
+      gchar *temp;
+
+      if ((temp = strstr (directory, ".so")) &&
+          (!strcmp (temp, ".so"))) {
+       GstPlugin *plugin = g_new0 (GstPlugin, 1);
+       plugin->filename = g_strdup (directory);
+
+        loaded = gst_plugin_load_plugin (plugin);
+       if (!loaded) {
+          g_free (plugin->filename);
+         g_free (plugin);
+       }
+       else {
+         gst_registry_add_plugin (GST_REGISTRY (registry), plugin);
+       }
+      }
+    }
+  }
+}
+
+static gboolean
+gst_xml_registry_rebuild (GstRegistry *registry)
+{
+  GList *walk = NULL;
+  GstXMLRegistry *xmlregistry = GST_XML_REGISTRY (registry);
+  walk = registry->paths;
+
+  while (walk) {
+    gchar *path = (gchar *) walk->data;
+    
+    gst_xml_registry_rebuild_recurse (xmlregistry, path);
+
+    walk = g_list_next (walk);
+  }
+  
+  return TRUE;
+}
diff --git a/gst/registries/gstxmlregistry.h b/gst/registries/gstxmlregistry.h
new file mode 100644 (file)
index 0000000..14894ce
--- /dev/null
@@ -0,0 +1,126 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *                    2000 Wim Taymans <wtay@chello.be>
+ *
+ * gstpluginfeature.h: Header for base GstXMLRegistry
+ *
+ * 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_XML_REGISTRY_H__
+#define __GST_XML_REGISTRY_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <gst/gstregistry.h>
+
+#define GST_TYPE_XML_REGISTRY \
+  (gst_xml_registry_get_type())
+#define GST_XML_REGISTRY(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_XML_REGISTRY,GstXMLRegistry))
+#define GST_XML_REGISTRY_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_XML_REGISTRY,GstXMLRegistryClass))
+#define GST_IS_XML_REGISTRY(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_XML_REGISTRY))
+#define GST_IS_XML_REGISTRY_CLASS(obj) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_XML_REGISTRY))
+
+typedef struct _GstXMLRegistry GstXMLRegistry;
+typedef struct _GstXMLRegistryClass GstXMLRegistryClass;
+
+typedef enum {
+  GST_XML_REGISTRY_NONE,
+  GST_XML_REGISTRY_TOP,
+  GST_XML_REGISTRY_PLUGIN,
+  GST_XML_REGISTRY_FEATURE,
+  GST_XML_REGISTRY_PADTEMPLATE,
+  GST_XML_REGISTRY_CAPS,
+  GST_XML_REGISTRY_CAPSCOMP,
+  GST_XML_REGISTRY_PROPERTIES,
+} GstXMLRegistryState;
+
+typedef enum {
+  GST_XML_REGISTRY_READ,
+  GST_XML_REGISTRY_WRITE,
+} GstXMLRegistryMode;
+
+typedef gboolean (*GstXMLRegistryParser) (GMarkupParseContext *context,
+                                         const gchar         *tag,
+                                         const gchar         *text,
+                                         gsize                text_len,
+                                         GstXMLRegistry      *registry,
+                                         GError             **error);
+
+typedef gboolean (*GstXMLRegistryOpen)   (GstXMLRegistry      *registry,
+                                         GstXMLRegistryMode   mode);
+typedef gboolean (*GstXMLRegistryLoad)   (GstXMLRegistry      *registry,
+                                         gchar               *dest,
+                                         gssize              *size);
+typedef gboolean (*GstXMLRegistrySave)   (GstXMLRegistry      *registry,
+                                         gchar               *format, 
+                                         ...);
+typedef gboolean (*GstXMLRegistryClose)  (GstXMLRegistry      *registry);
+
+struct _GstXMLRegistry {
+  GstRegistry           object;
+
+  gchar                *location;
+  FILE                         *regfile;
+  gchar                        *buffer;
+
+  GMarkupParseContext  *context;
+  GList                        *open_tags;
+  GstXMLRegistryState   state;
+  GstXMLRegistryParser  parser;
+
+  GstPlugin            *current_plugin;
+  GstPluginFeature     *current_feature;
+
+  gchar                        *name_template;
+  GstPadDirection       direction;
+  GstPadPresence        presence;
+  GstCaps              *caps;
+
+  gchar                        *caps_name;
+  gchar                        *caps_mime;
+  GstProps             *props;
+};
+
+struct _GstXMLRegistryClass {
+  GstRegistryClass      parent_class;
+
+  GstXMLRegistryOpen    open_func;
+  GstXMLRegistryLoad    load_func;
+  GstXMLRegistrySave    save_func;
+  GstXMLRegistryClose   close_func;
+};
+
+
+/* normal GObject stuff */
+GType          gst_xml_registry_get_type               (void);
+
+GstRegistry*   gst_xml_registry_new                    (const gchar *name, const gchar *location);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GST_XML_REGISTRY_H__ */
+
diff --git a/gst/registries/registrytest.c b/gst/registries/registrytest.c
new file mode 100644 (file)
index 0000000..5da6ecb
--- /dev/null
@@ -0,0 +1,19 @@
+#include <gst/gst.h>
+
+#include "gstxmlregistry.h"
+
+gint
+main (gint argc, gchar *argv[])
+{
+  GstRegistry *registry;
+  
+  gst_init (&argc, &argv);
+
+  registry = gst_xml_registry_new ("reg.xml");
+
+  gst_registry_load (registry);
+
+  
+  return 0;
+  
+}
index 4aac1d9..0df5c83 100644 (file)
@@ -254,6 +254,7 @@ gst_basic_scheduler_chain_wrapper (int argc, char *argv[])
 
   GST_DEBUG (GST_CAT_DATAFLOW, "stepping through pads");
 
+  gst_object_ref (GST_OBJECT (element));
   do {
     GList *pads = element->pads;
 
@@ -292,6 +293,7 @@ gst_basic_scheduler_chain_wrapper (int argc, char *argv[])
     }
   } while (!GST_ELEMENT_IS_COTHREAD_STOPPING (element));
   GST_FLAG_UNSET (element, GST_ELEMENT_COTHREAD_STOPPING);
+  gst_object_unref (GST_OBJECT (element));
 
   GST_DEBUG_LEAVE ("(%d,'%s')", argc, name);
   return 0;
index eb1887c..4660329 100644 (file)
@@ -26,7 +26,7 @@
 #include <gst/gstinfo.h>
 #include "bytestream.h"
 
-/*#define BS_DEBUG */
+/* #define BS_DEBUG */
 
 #ifdef BS_DEBUG
 # define bs_print(format,args...)      GST_DEBUG (GST_CAT_BUFFER,  format, ## args)
@@ -403,7 +403,15 @@ gst_bytestream_seek (GstByteStream *bs, GstSeekType type, gint64 offset)
   GstRealPad *peer = GST_RPAD_PEER (bs->pad);
 
   if (gst_pad_send_event (GST_PAD (peer), gst_event_new_seek (type, offset, TRUE))) {
+    GstBuffer *nextbuf;
+    
     gst_bytestream_flush_fast (bs, bs->listavail);
+    
+    do {
+      nextbuf = gst_pad_pull (bs->pad);
+    }
+    while (!GST_IS_EVENT (nextbuf));
+    
     return TRUE;
   }
   return FALSE;
index 6aa99d1..a926477 100644 (file)
--- a/ltmain.sh
+++ b/ltmain.sh
@@ -55,8 +55,8 @@ modename="$progname"
 # Constants.
 PROGRAM=ltmain.sh
 PACKAGE=libtool
-VERSION=1.4
-TIMESTAMP=" (1.920 2001/04/24 23:26:18)"
+VERSION=1.4.2a
+TIMESTAMP=" (1.922.2.79 2001/11/28 21:50:31)"
 
 default_mode=
 help="Try \`$progname --help' for more information."
@@ -84,6 +84,9 @@ if test "${LANG+set}" = set; then
   save_LANG="$LANG"; LANG=C; export LANG
 fi
 
+# Make sure IFS has a sensible default
+: ${IFS="      "}
+
 if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
   echo "$modename: not configured to build any kind of library" 1>&2
   echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
@@ -174,6 +177,8 @@ do
   --mode) prevopt="--mode" prev=mode ;;
   --mode=*) mode="$optarg" ;;
 
+  --preserve-dup-deps) duplicate_deps="yes" ;;
+
   --quiet | --silent)
     show=:
     ;;
@@ -202,6 +207,11 @@ if test -n "$prevopt"; then
   exit 1
 fi
 
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end.  This prevents here-documents from being
+# left over by shells.
+exec_cmd=
+
 if test -z "$show_help"; then
 
   # Infer the operation mode.
@@ -329,7 +339,7 @@ if test -z "$show_help"; then
       -Wc,*)
        args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"`
        lastarg=
-       IFS="${IFS=     }"; save_ifs="$IFS"; IFS=','
+       save_ifs="$IFS"; IFS=','
        for arg in $args; do
          IFS="$save_ifs"
 
@@ -459,7 +469,7 @@ if test -z "$show_help"; then
       pic_mode=default
       ;;
     esac
-    if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
+    if test $pic_mode = no && test "$deplibs_check_method" != pass_all; then
       # non-PIC code in shared libraries is not supported
       pic_mode=default
     fi
@@ -615,6 +625,10 @@ compiler."
        # Now arrange that obj and lo_libobj become the same file
        $show "(cd $xdir && $LN_S $baseobj $libobj)"
        if $run eval '(cd $xdir && $LN_S $baseobj $libobj)'; then
+         # Unlock the critical section if it was locked
+         if test "$need_locks" != no; then
+           $run $rm "$lockfile"
+         fi
          exit 0
        else
          error=$?
@@ -980,7 +994,7 @@ compiler."
       # so, if we see these flags be careful not to treat them like -L
       -L[A-Z][A-Z]*:*)
        case $with_gcc/$host in
-       no/*-*-irix*)
+       no/*-*-irix* | no/*-*-nonstopux*)
          compile_command="$compile_command $arg"
          finalize_command="$finalize_command $arg"
          ;;
@@ -1031,6 +1045,17 @@ compiler."
            # These systems don't actually have a C library (as such)
            test "X$arg" = "X-lc" && continue
            ;;
+         *-*-openbsd* | *-*-freebsd*)
+           # Do not include libc due to us having libc/libc_r.
+           test "X$arg" = "X-lc" && continue
+           ;;
+         esac
+        elif test "X$arg" = "X-lc_r"; then
+         case $host in
+        *-*-openbsd* | *-*-freebsd*)
+           # Do not include libc_r directly, use -pthread flag.
+           continue
+           ;;
          esac
        fi
        deplibs="$deplibs $arg"
@@ -1122,7 +1147,7 @@ compiler."
       -Wc,*)
        args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'`
        arg=
-       IFS="${IFS=     }"; save_ifs="$IFS"; IFS=','
+       save_ifs="$IFS"; IFS=','
        for flag in $args; do
          IFS="$save_ifs"
          case $flag in
@@ -1140,7 +1165,7 @@ compiler."
       -Wl,*)
        args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'`
        arg=
-       IFS="${IFS=     }"; save_ifs="$IFS"; IFS=','
+       save_ifs="$IFS"; IFS=','
        for flag in $args; do
          IFS="$save_ifs"
          case $flag in
@@ -1307,9 +1332,11 @@ compiler."
     # Find all interdependent deplibs by searching for libraries
     # that are linked more than once (e.g. -la -lb -la)
     for deplib in $deplibs; do
-      case "$libs " in
-      *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
-      esac
+      if test "X$duplicate_deps" = "Xyes" ; then
+       case "$libs " in
+       *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+       esac
+      fi
       libs="$libs $deplib"
     done
     deplibs=
@@ -1343,7 +1370,7 @@ compiler."
        ;;
     esac
     for pass in $passes; do
-      if test "$linkmode" = prog; then
+      if test $linkmode = prog; then
        # Determine which files to process
        case $pass in
        dlopen)
@@ -1360,11 +1387,11 @@ compiler."
        found=no
        case $deplib in
        -l*)
-         if test "$linkmode" = oldlib && test "$linkmode" = obj; then
+         if test $linkmode = oldlib && test $linkmode = obj; then
            $echo "$modename: warning: \`-l' is ignored for archives/objects: $deplib" 1>&2
            continue
          fi
-         if test "$pass" = conv; then
+         if test $pass = conv; then
            deplibs="$deplib $deplibs"
            continue
          fi
@@ -1384,7 +1411,7 @@ compiler."
              finalize_deplibs="$deplib $finalize_deplibs"
            else
              deplibs="$deplib $deplibs"
-             test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+             test $linkmode = lib && newdependency_libs="$deplib $newdependency_libs"
            fi
            continue
          fi
@@ -1393,16 +1420,16 @@ compiler."
          case $linkmode in
          lib)
            deplibs="$deplib $deplibs"
-           test "$pass" = conv && continue
+           test $pass = conv && continue
            newdependency_libs="$deplib $newdependency_libs"
            newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`
            ;;
          prog)
-           if test "$pass" = conv; then
+           if test $pass = conv; then
              deplibs="$deplib $deplibs"
              continue
            fi
-           if test "$pass" = scan; then
+           if test $pass = scan; then
              deplibs="$deplib $deplibs"
              newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`
            else
@@ -1417,7 +1444,7 @@ compiler."
          continue
          ;; # -L
        -R*)
-         if test "$pass" = link; then
+         if test $pass = link; then
            dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'`
            # Make sure the xrpath contains only unique directories.
            case "$xrpath " in
@@ -1430,7 +1457,7 @@ compiler."
          ;;
        *.la) lib="$deplib" ;;
        *.$libext)
-         if test "$pass" = conv; then
+         if test $pass = conv; then
            deplibs="$deplib $deplibs"
            continue
          fi
@@ -1438,10 +1465,12 @@ compiler."
          lib)
            if test "$deplibs_check_method" != pass_all; then
              echo
-             echo "*** Warning: This library needs some functionality provided by $deplib."
+             echo "*** Warning: Trying to link with static lib archive $deplib."
              echo "*** I have the capability to make that library automatically link in when"
              echo "*** you link to this library.  But I can only do this if you have a"
-             echo "*** shared version of the library, which you do not appear to have."
+             echo "*** shared version of the library, which you do not appear to have"
+             echo "*** because the file extensions .$libext of this argument makes me believe"
+             echo "*** that it is just a static archive that I should not used here."
            else
              echo
              echo "*** Warning: Linking the shared library $output against the"
@@ -1451,7 +1480,7 @@ compiler."
            continue
            ;;
          prog)
-           if test "$pass" != link; then
+           if test $pass != link; then
              deplibs="$deplib $deplibs"
            else
              compile_deplibs="$deplib $compile_deplibs"
@@ -1462,7 +1491,7 @@ compiler."
          esac # linkmode
          ;; # *.$libext
        *.lo | *.$objext)
-         if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+         if test $pass = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
            # If there is no dlopen support or we're linking statically,
            # we need to preload.
            newdlprefiles="$newdlprefiles $deplib"
@@ -1512,13 +1541,13 @@ compiler."
 
        if test "$linkmode,$pass" = "lib,link" ||
           test "$linkmode,$pass" = "prog,scan" ||
-          { test "$linkmode" = oldlib && test "$linkmode" = obj; }; then
+          { test $linkmode = oldlib && test $linkmode = obj; }; then
           # Add dl[pre]opened files of deplib
          test -n "$dlopen" && dlfiles="$dlfiles $dlopen"
          test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen"
        fi
 
-       if test "$pass" = conv; then
+       if test $pass = conv; then
          # Only check for convenience libraries
          deplibs="$lib $deplibs"
          if test -z "$libdir"; then
@@ -1532,12 +1561,14 @@ compiler."
            tmp_libs=
            for deplib in $dependency_libs; do
              deplibs="$deplib $deplibs"
-             case "$tmp_libs " in
-             *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
-             esac
+              if test "X$duplicate_deps" = "Xyes" ; then
+               case "$tmp_libs " in
+               *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+               esac
+              fi
              tmp_libs="$tmp_libs $deplib"
            done
-         elif test "$linkmode" != prog && test "$linkmode" != lib; then
+         elif test $linkmode != prog && test $linkmode != lib; then
            $echo "$modename: \`$lib' is not a convenience library" 1>&2
            exit 1
          fi
@@ -1555,7 +1586,7 @@ compiler."
        fi
 
        # This library was specified with -dlopen.
-       if test "$pass" = dlopen; then
+       if test $pass = dlopen; then
          if test -z "$libdir"; then
            $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2
            exit 1
@@ -1604,7 +1635,7 @@ compiler."
        name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
 
        # This library was specified with -dlpreopen.
-       if test "$pass" = dlpreopen; then
+       if test $pass = dlpreopen; then
          if test -z "$libdir"; then
            $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2
            exit 1
@@ -1623,7 +1654,7 @@ compiler."
 
        if test -z "$libdir"; then
          # Link the convenience library
-         if test "$linkmode" = lib; then
+         if test $linkmode = lib; then
            deplibs="$dir/$old_library $deplibs"
          elif test "$linkmode,$pass" = "prog,link"; then
            compile_deplibs="$dir/$old_library $compile_deplibs"
@@ -1634,7 +1665,7 @@ compiler."
          continue
        fi
 
-       if test "$linkmode" = prog && test "$pass" != link; then
+       if test $linkmode = prog && test $pass != link; then
          newlib_search_path="$newlib_search_path $ladir"
          deplibs="$lib $deplibs"
 
@@ -1657,9 +1688,11 @@ compiler."
              # or/and link against static libraries
              newdependency_libs="$deplib $newdependency_libs"
            fi
-           case "$tmp_libs " in
-           *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
-           esac
+           if test "X$duplicate_deps" = "Xyes" ; then
+             case "$tmp_libs " in
+             *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+             esac
+           fi
            tmp_libs="$tmp_libs $deplib"
          done # for deplib
          continue
@@ -1671,7 +1704,7 @@ compiler."
          # Link against this shared library
 
          if test "$linkmode,$pass" = "prog,link" ||
-          { test "$linkmode" = lib && test "$hardcode_into_libs" = yes; }; then
+          { test $linkmode = lib && test $hardcode_into_libs = yes; }; then
            # Hardcode the library path.
            # Skip directories that are in the system default run-time
            # search path.
@@ -1693,7 +1726,7 @@ compiler."
              esac
              ;;
            esac
-           if test "$linkmode" = prog; then
+           if test $linkmode = prog; then
              # We need to hardcode the library path
              if test -n "$shlibpath_var"; then
                # Make sure the rpath contains only unique directories.
@@ -1750,7 +1783,7 @@ compiler."
            if test -f "$output_objdir/$soname-def"; then :
            else
              $show "extracting exported symbol list from \`$soname'"
-             IFS="${IFS=       }"; save_ifs="$IFS"; IFS='~'
+             save_ifs="$IFS"; IFS='~'
              eval cmds=\"$extract_expsyms_cmds\"
              for cmd in $cmds; do
                IFS="$save_ifs"
@@ -1763,7 +1796,7 @@ compiler."
            # Create $newlib
            if test -f "$output_objdir/$newlib"; then :; else
              $show "generating import library for \`$soname'"
-             IFS="${IFS=       }"; save_ifs="$IFS"; IFS='~'
+             save_ifs="$IFS"; IFS='~'
              eval cmds=\"$old_archive_from_expsyms_cmds\"
              for cmd in $cmds; do
                IFS="$save_ifs"
@@ -1777,7 +1810,7 @@ compiler."
            linklib=$newlib
          fi # test -n $old_archive_from_expsyms_cmds
 
-         if test "$linkmode" = prog || test "$mode" != relink; then
+         if test $linkmode = prog || test "$mode" != relink; then
            add_shlibpath=
            add_dir=
            add=
@@ -1826,7 +1859,7 @@ compiler."
              *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;;
              esac
            fi
-           if test "$linkmode" = prog; then
+           if test $linkmode = prog; then
              test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
              test -n "$add" && compile_deplibs="$add $compile_deplibs"
            else
@@ -1843,7 +1876,7 @@ compiler."
            fi
          fi
 
-         if test "$linkmode" = prog || test "$mode" = relink; then
+         if test $linkmode = prog || test "$mode" = relink; then
            add_shlibpath=
            add_dir=
            add=
@@ -1862,11 +1895,10 @@ compiler."
            else
              # We cannot seem to hardcode it, guess we'll fake it.
              add_dir="-L$libdir"
-              test -d $ladir/.libs && add_dir="$add_dir -L$ladir/.libs"
              add="-l$name"
            fi
 
-           if test "$linkmode" = prog; then
+           if test $linkmode = prog; then
              test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
              test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
            else
@@ -1874,7 +1906,7 @@ compiler."
              test -n "$add" && deplibs="$add $deplibs"
            fi
          fi
-       elif test "$linkmode" = prog; then
+       elif test $linkmode = prog; then
          if test "$alldeplibs" = yes &&
             { test "$deplibs_check_method" = pass_all ||
               { test "$build_libtool_libs" = yes &&
@@ -1904,25 +1936,26 @@ compiler."
            # Just print a warning and add the library to dependency_libs so
            # that the program can be linked against the static library.
            echo
-           echo "*** Warning: This library needs some functionality provided by $lib."
+           echo "*** Warning: This system can not link to static lib archive $lib."
            echo "*** I have the capability to make that library automatically link in when"
            echo "*** you link to this library.  But I can only do this if you have a"
            echo "*** shared version of the library, which you do not appear to have."
            if test "$module" = yes; then
-             echo "*** Therefore, libtool will create a static module, that should work "
-             echo "*** as long as the dlopening application is linked with the -dlopen flag."
+             echo "*** But as you try to build a module library, libtool will still create "
+             echo "*** a static module, that should work as long as the dlopening application"
+             echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
              if test -z "$global_symbol_pipe"; then
-               echo
-               echo "*** However, this would only work if libtool was able to extract symbol"
-               echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
-               echo "*** not find such a program.  So, this module is probably useless."
-               echo "*** \`nm' from GNU binutils and a full rebuild may help."
+               echo
+               echo "*** However, this would only work if libtool was able to extract symbol"
+               echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+               echo "*** not find such a program.  So, this module is probably useless."
+               echo "*** \`nm' from GNU binutils and a full rebuild may help."
              fi
              if test "$build_old_libs" = no; then
-               build_libtool_libs=module
-               build_old_libs=yes
+               build_libtool_libs=module
+               build_old_libs=yes
              else
-               build_libtool_libs=no
+               build_libtool_libs=no
              fi
            fi
          else
@@ -1933,9 +1966,9 @@ compiler."
          fi
        fi # link shared/static library?
 
-       if test "$linkmode" = lib; then
+       if test $linkmode = lib; then
          if test -n "$dependency_libs" &&
-            { test "$hardcode_into_libs" != yes || test $build_old_libs = yes ||
+            { test $hardcode_into_libs != yes || test $build_old_libs = yes ||
               test $link_static = yes; }; then
            # Extract -R from dependency_libs
            temp_deplibs=
@@ -1959,13 +1992,15 @@ compiler."
          tmp_libs=
          for deplib in $dependency_libs; do
            newdependency_libs="$deplib $newdependency_libs"
-           case "$tmp_libs " in
-           *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
-           esac
+           if test "X$duplicate_deps" = "Xyes" ; then
+             case "$tmp_libs " in
+             *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+             esac
+           fi
            tmp_libs="$tmp_libs $deplib"
          done
 
-         if test "$link_all_deplibs" != no; then
+         if test $link_all_deplibs != no; then
            # Add the search paths of all dependency libraries
            for deplib in $dependency_libs; do
              case $deplib in
@@ -2008,15 +2043,15 @@ compiler."
          fi # link_all_deplibs != no
        fi # linkmode = lib
       done # for deplib in $libs
-      if test "$pass" = dlpreopen; then
+      if test $pass = dlpreopen; then
        # Link the dlpreopened libraries before other libraries
        for deplib in $save_deplibs; do
          deplibs="$deplib $deplibs"
        done
       fi
-      if test "$pass" != dlopen; then
-       test "$pass" != scan && dependency_libs="$newdependency_libs"
-       if test "$pass" != conv; then
+      if test $pass != dlopen; then
+       test $pass != scan && dependency_libs="$newdependency_libs"
+       if test $pass != conv; then
          # Make sure lib_search_path contains only unique directories.
          lib_search_path=
          for dir in $newlib_search_path; do
@@ -2074,7 +2109,7 @@ compiler."
        deplibs=
       fi
     done # for pass
-    if test "$linkmode" = prog; then
+    if test $linkmode = prog; then
       dlfiles="$newdlfiles"
       dlprefiles="$newdlprefiles"
     fi
@@ -2176,7 +2211,7 @@ compiler."
       else
 
        # Parse the version information argument.
-       IFS="${IFS=     }"; save_ifs="$IFS"; IFS=':'
+       save_ifs="$IFS"; IFS=':'
        set dummy $vinfo 0 0 0
        IFS="$save_ifs"
 
@@ -2251,16 +2286,21 @@ compiler."
          versuffix=".$current";
          ;;
 
-       irix)
+       irix | nonstopux)
+         case $version_type in
+           nonstopux) verstring_prefix=nonstopux ;;
+           *)         verstring_prefix=sgi ;;
+         esac
+         verstring="$verstring_prefix$major.$revision"
+
          major=`expr $current - $age + 1`
-         verstring="sgi$major.$revision"
 
          # Add in all the interfaces that we are compatible with.
          loop=$revision
          while test $loop != 0; do
            iface=`expr $revision - $loop`
            loop=`expr $loop - 1`
-           verstring="sgi$major.$iface:$verstring"
+           verstring="$verstring_prefix$major.$iface:$verstring"
          done
 
          # Before this point, $major must not contain `.'.
@@ -2313,6 +2353,16 @@ compiler."
        if test -z "$vinfo" && test -n "$release"; then
          major=
          verstring="0.0"
+         case $version_type in
+         darwin)
+           # we can't check for "0.0" in archive_cmds due to quoting
+           # problems, so we reset it completely
+           verstring=""
+           ;;
+         *)
+           verstring="0.0"
+           ;;
+         esac
          if test "$need_version" = no; then
            versuffix=
          else
@@ -2409,9 +2459,12 @@ compiler."
          *-*-netbsd*)
            # Don't link with libc until the a.out ld.so is fixed.
            ;;
+         *-*-openbsd* | *-*-freebsd*)
+           # Do not include libc due to us having libc/libc_r.
+           ;;
          *)
            # Add libc to deplibs on all other systems if necessary.
-           if test "$build_libtool_need_lc" = "yes"; then
+           if test $build_libtool_need_lc = "yes"; then
              deplibs="$deplibs -lc"
            fi
            ;;
@@ -2467,18 +2520,20 @@ EOF
                else
                  droppeddeps=yes
                  echo
-                 echo "*** Warning: This library needs some functionality provided by $i."
+                 echo "*** Warning: dynamic linker does not accept needed library $i."
                  echo "*** I have the capability to make that library automatically link in when"
                  echo "*** you link to this library.  But I can only do this if you have a"
-                 echo "*** shared version of the library, which you do not appear to have."
+                 echo "*** shared version of the library, which I believe you do not have"
+                 echo "*** because a test_compile did reveal that the linker did not use it for"
+                 echo "*** its dynamic dependency list that programs get resolved with at runtime."
                fi
              else
                newdeplibs="$newdeplibs $i"
              fi
            done
          else
-           # Error occured in the first compile.  Let's try to salvage the situation:
-           # Compile a seperate program for each library.
+           # Error occured in the first compile.  Let's try to salvage
+           # the situation: Compile a separate program for each library.
            for i in $deplibs; do
              name="`expr $i : '-l\(.*\)'`"
             # If $name is empty we are operating on a -L argument.
@@ -2497,10 +2552,12 @@ EOF
                  else
                    droppeddeps=yes
                    echo
-                   echo "*** Warning: This library needs some functionality provided by $i."
+                   echo "*** Warning: dynamic linker does not accept needed library $i."
                    echo "*** I have the capability to make that library automatically link in when"
                    echo "*** you link to this library.  But I can only do this if you have a"
-                   echo "*** shared version of the library, which you do not appear to have."
+                   echo "*** shared version of the library, which you do not appear to have"
+                   echo "*** because a test_compile did reveal that the linker did not use this one"
+                   echo "*** as a dynamic dependency that programs can get resolved with at runtime."
                  fi
                else
                  droppeddeps=yes
@@ -2557,10 +2614,17 @@ EOF
              if test -n "$a_deplib" ; then
                droppeddeps=yes
                echo
-               echo "*** Warning: This library needs some functionality provided by $a_deplib."
+               echo "*** Warning: linker path does not have real file for library $a_deplib."
                echo "*** I have the capability to make that library automatically link in when"
                echo "*** you link to this library.  But I can only do this if you have a"
-               echo "*** shared version of the library, which you do not appear to have."
+               echo "*** shared version of the library, which you do not appear to have"
+               echo "*** because I did check the linker path looking for a file starting"
+               if test -z "$potlib" ; then
+                 echo "*** with $libname but no candidates were found. (...for file magic test)"
+               else
+                 echo "*** with $libname and none of the candidates passed a file format test"
+                 echo "*** using a file magic. Last file checked: $potlib"
+               fi
              fi
            else
              # Add a -L argument.
@@ -2579,6 +2643,7 @@ EOF
              for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
                potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
                for potent_lib in $potential_libs; do
+                 potlib="$potent_lib" # see symlink-check below in file_magic test
                  if eval echo \"$potent_lib\" 2>/dev/null \
                      | sed 10q \
                      | egrep "$match_pattern_regex" > /dev/null; then
@@ -2591,10 +2656,17 @@ EOF
              if test -n "$a_deplib" ; then
                droppeddeps=yes
                echo
-               echo "*** Warning: This library needs some functionality provided by $a_deplib."
+               echo "*** Warning: linker path does not have real file for library $a_deplib."
                echo "*** I have the capability to make that library automatically link in when"
                echo "*** you link to this library.  But I can only do this if you have a"
-               echo "*** shared version of the library, which you do not appear to have."
+               echo "*** shared version of the library, which you do not appear to have"
+               echo "*** because I did check the linker path looking for a file starting"
+               if test -z "$potlib" ; then
+                 echo "*** with $libname but no candidates were found. (...for regex pattern test)"
+               else
+                 echo "*** with $libname and none of the candidates passed a file format test"
+                 echo "*** using a regex pattern. Last file checked: $potlib"
+               fi
              fi
            else
              # Add a -L argument.
@@ -2684,7 +2756,7 @@ EOF
 
       # Test again, we may have decided not to build it any more
       if test "$build_libtool_libs" = yes; then
-       if test "$hardcode_into_libs" = yes; then
+       if test $hardcode_into_libs = yes; then
          # Hardcode the library paths
          hardcode_libdirs=
          dep_rpath=
@@ -2785,7 +2857,7 @@ EOF
            export_symbols="$output_objdir/$libname.exp"
            $run $rm $export_symbols
            eval cmds=\"$export_symbols_cmds\"
-           IFS="${IFS=         }"; save_ifs="$IFS"; IFS='~'
+           save_ifs="$IFS"; IFS='~'
            for cmd in $cmds; do
              IFS="$save_ifs"
              $show "$cmd"
@@ -2861,7 +2933,7 @@ EOF
        else
          eval cmds=\"$archive_cmds\"
        fi
-       IFS="${IFS=     }"; save_ifs="$IFS"; IFS='~'
+       save_ifs="$IFS"; IFS='~'
        for cmd in $cmds; do
          IFS="$save_ifs"
          $show "$cmd"
@@ -2989,7 +3061,7 @@ EOF
 
       output="$obj"
       eval cmds=\"$reload_cmds\"
-      IFS="${IFS=      }"; save_ifs="$IFS"; IFS='~'
+      save_ifs="$IFS"; IFS='~'
       for cmd in $cmds; do
        IFS="$save_ifs"
        $show "$cmd"
@@ -3025,7 +3097,7 @@ EOF
        reload_objs="$libobjs $reload_conv_objs"
        output="$libobj"
        eval cmds=\"$reload_cmds\"
-       IFS="${IFS=     }"; save_ifs="$IFS"; IFS='~'
+       save_ifs="$IFS"; IFS='~'
        for cmd in $cmds; do
          IFS="$save_ifs"
          $show "$cmd"
@@ -3288,27 +3360,25 @@ extern \"C\" {
 #undef lt_preloaded_symbols
 
 #if defined (__STDC__) && __STDC__
-# define lt_ptr_t void *
+# define lt_ptr void *
 #else
-# define lt_ptr_t char *
+# define lt_ptr char *
 # define const
 #endif
 
 /* The mapping between symbol names and symbols. */
 const struct {
   const char *name;
-  lt_ptr_t address;
+  lt_ptr address;
 }
 lt_preloaded_symbols[] =
 {\
 "
 
-           sed -n -e 's/^: \([^ ]*\) $/  {\"\1\", (lt_ptr_t) 0},/p' \
-               -e 's/^. \([^ ]*\) \([^ ]*\)$/  {"\2", (lt_ptr_t) \&\2},/p' \
-                 < "$nlist" >> "$output_objdir/$dlsyms"
+           eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms"
 
            $echo >> "$output_objdir/$dlsyms" "\
-  {0, (lt_ptr_t) 0}
+  {0, (lt_ptr) 0}
 };
 
 /* This works around a problem in FreeBSD linker */
@@ -3495,7 +3565,7 @@ static const void *lt_preloaded_setup() {
            relink_command="$var=\"$var_value\"; export $var; $relink_command"
          fi
        done
-       relink_command="cd `pwd`; $relink_command"
+       relink_command="(cd `pwd`; $relink_command)"
        relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
       fi
 
@@ -3619,8 +3689,9 @@ else
 
     # relink executable if necessary
     if test -n \"\$relink_command\"; then
-      if (eval \$relink_command); then :
+      if relink_command_output=\`eval \$relink_command 2>&1\`; then :
       else
+       $echo \"\$relink_command_output\" >&2
        $rm \"\$progdir/\$file\"
        exit 1
       fi
@@ -3791,7 +3862,7 @@ fi\
 
        eval cmds=\"$old_archive_cmds\"
       fi
-      IFS="${IFS=      }"; save_ifs="$IFS"; IFS='~'
+      save_ifs="$IFS"; IFS='~'
       for cmd in $cmds; do
        IFS="$save_ifs"
        $show "$cmd"
@@ -3824,7 +3895,7 @@ fi\
        fi
       done
       # Quote the link command for shipping.
-      relink_command="cd `pwd`; $SHELL $0 --mode=relink $libtool_args"
+      relink_command="(cd `pwd`; $SHELL $0 --mode=relink $libtool_args)"
       relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
 
       # Only create the output if not a dry run.
@@ -4166,7 +4237,7 @@ relink_command=\"$relink_command\""
          # Do each command in the postinstall commands.
          lib="$destdir/$realname"
          eval cmds=\"$postinstall_cmds\"
-         IFS="${IFS=   }"; save_ifs="$IFS"; IFS='~'
+         save_ifs="$IFS"; IFS='~'
          for cmd in $cmds; do
            IFS="$save_ifs"
            $show "$cmd"
@@ -4239,19 +4310,27 @@ relink_command=\"$relink_command\""
        fi
 
        # Do a test to see if this is really a libtool program.
-       if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+       case $host in
+       *cygwin*|*mingw*)
+           wrapper=`echo $file | sed -e 's,.exe$,,'`
+           ;;
+       *)
+           wrapper=$file
+           ;;
+       esac
+       if (sed -e '4q' $wrapper | egrep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then
          notinst_deplibs=
          relink_command=
 
          # If there is no directory component, then add one.
          case $file in
-         */* | *\\*) . $file ;;
-         *) . ./$file ;;
+         */* | *\\*) . $wrapper ;;
+         *) . ./$wrapper ;;
          esac
 
          # Check the variables that should have been set.
          if test -z "$notinst_deplibs"; then
-           $echo "$modename: invalid libtool wrapper script \`$file'" 1>&2
+           $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2
            exit 1
          fi
 
@@ -4276,8 +4355,8 @@ relink_command=\"$relink_command\""
          relink_command=
          # If there is no directory component, then add one.
          case $file in
-         */* | *\\*) . $file ;;
-         *) . ./$file ;;
+         */* | *\\*) . $wrapper ;;
+         *) . ./$wrapper ;;
          esac
 
          outputname=
@@ -4353,7 +4432,7 @@ relink_command=\"$relink_command\""
 
       # Do each command in the postinstall commands.
       eval cmds=\"$old_postinstall_cmds\"
-      IFS="${IFS=      }"; save_ifs="$IFS"; IFS='~'
+      save_ifs="$IFS"; IFS='~'
       for cmd in $cmds; do
        IFS="$save_ifs"
        $show "$cmd"
@@ -4369,11 +4448,10 @@ relink_command=\"$relink_command\""
     if test -n "$current_libdirs"; then
       # Maybe just do a dry run.
       test -n "$run" && current_libdirs=" -n$current_libdirs"
-      exec $SHELL $0 --finish$current_libdirs
-      exit 1
+      exec_cmd='$SHELL $0 --finish$current_libdirs'
+    else
+      exit 0
     fi
-
-    exit 0
     ;;
 
   # libtool finish mode
@@ -4392,7 +4470,7 @@ relink_command=\"$relink_command\""
        if test -n "$finish_cmds"; then
          # Do each command in the finish commands.
          eval cmds=\"$finish_cmds\"
-         IFS="${IFS=   }"; save_ifs="$IFS"; IFS='~'
+         save_ifs="$IFS"; IFS='~'
          for cmd in $cmds; do
            IFS="$save_ifs"
            $show "$cmd"
@@ -4576,11 +4654,8 @@ relink_command=\"$relink_command\""
        LANG="$save_LANG"; export LANG
       fi
 
-      # Now actually exec the command.
-      eval "exec \$cmd$args"
-
-      $echo "$modename: cannot exec \$cmd$args"
-      exit 1
+      # Now prepare to actually exec the command.
+      exec_cmd="\$cmd$args"
     else
       # Display what would be done.
       if test -n "$shlibpath_var"; then
@@ -4642,14 +4717,14 @@ relink_command=\"$relink_command\""
 
       # Don't error if the file doesn't exist and rm -f was used.
       if (test -L "$file") >/dev/null 2>&1 \
-        || (test -h "$file") >/dev/null 2>&1 \
+       || (test -h "$file") >/dev/null 2>&1 \
        || test -f "$file"; then
-        :
+       :
       elif test -d "$file"; then
-        exit_status=1
+       exit_status=1
        continue
       elif test "$rmforce" = yes; then
-        continue
+       continue
       fi
 
       rmfiles="$file"
@@ -4671,7 +4746,7 @@ relink_command=\"$relink_command\""
            if test -n "$library_names"; then
              # Do each command in the postuninstall commands.
              eval cmds=\"$postuninstall_cmds\"
-             IFS="${IFS=       }"; save_ifs="$IFS"; IFS='~'
+             save_ifs="$IFS"; IFS='~'
              for cmd in $cmds; do
                IFS="$save_ifs"
                $show "$cmd"
@@ -4686,7 +4761,7 @@ relink_command=\"$relink_command\""
            if test -n "$old_library"; then
              # Do each command in the old_postuninstall commands.
              eval cmds=\"$old_postuninstall_cmds\"
-             IFS="${IFS=       }"; save_ifs="$IFS"; IFS='~'
+             save_ifs="$IFS"; IFS='~'
              for cmd in $cmds; do
                IFS="$save_ifs"
                $show "$cmd"
@@ -4745,11 +4820,18 @@ relink_command=\"$relink_command\""
     ;;
   esac
 
-  $echo "$modename: invalid operation mode \`$mode'" 1>&2
-  $echo "$generic_help" 1>&2
-  exit 1
+  if test -z "$exec_cmd"; then
+    $echo "$modename: invalid operation mode \`$mode'" 1>&2
+    $echo "$generic_help" 1>&2
+    exit 1
+  fi
 fi # test -z "$show_help"
 
+if test -n "$exec_cmd"; then
+  eval exec $exec_cmd
+  exit 1
+fi
+
 # We need to display help for each of the modes.
 case $mode in
 "") $echo \
index 90d635c..f67bd0f 100644 (file)
@@ -569,15 +569,17 @@ gst_filesrc_open_file (GstFileSrc *src)
                       src->filename, strerror (errno), NULL);
     return FALSE;
   } else {
-               /* check if it is a regular file, otherwise bail out */
-               struct stat stat_results;
-               fstat(src->fd, &stat_results);
-               if (!S_ISREG(stat_results.st_mode)) {
-                       gst_element_error (GST_ELEMENT (src), "opening file \"%s\" failed. it isn't a regular file", 
-                                                                                                src->filename, NULL);
-                       close(src->fd);
-                       return FALSE;
-               }
+    /* check if it is a regular file, otherwise bail out */
+    struct stat stat_results;
+
+    fstat(src->fd, &stat_results);
+
+    if (!S_ISREG(stat_results.st_mode)) {
+      gst_element_error (GST_ELEMENT (src), "opening file \"%s\" failed. it isn't a regular file", 
+                                       src->filename, NULL);
+      close(src->fd);
+      return FALSE;
+    }
                
     /* find the file length */
     src->filelen = lseek (src->fd, 0, SEEK_END);
index f45baa0..482a21b 100644 (file)
@@ -3,7 +3,7 @@
 int main(int argc,char *argv[]) 
 {
   GstElement *bin, *element;
-  gint i=10000;
+  gint i=1000000;
 
   free (malloc(8)); /* -lefence */
 
@@ -15,13 +15,15 @@ int main(int argc,char *argv[])
 
   while (i--)
   {
+    GstPad *pad;
+
     fprintf (stderr, "+");
 
     element = gst_element_factory_make ("tee", "tee");
     if (!element) 
       break;
 
-    gst_element_request_pad_by_name (element, "src%d");
+    pad = gst_element_request_pad_by_name (element, "src%d");
 
     gst_bin_add (GST_BIN (bin), element);
     gst_bin_remove (GST_BIN (bin), element);
index fa3de4e..a89f9aa 100644 (file)
@@ -20,7 +20,6 @@ int main (int argc, char *argv[])
     fakesink1 = gst_element_factory_make("fakesink", "fakesink1");
     fakesink2 = gst_element_factory_make("fakesink", "fakesink2");
     pipe1 = gst_pipeline_new("pipe1");
-    pipe2 = gst_pipeline_new("pipe2");
     
     /* make the first pipeline */
     gst_bin_add (GST_BIN(pipe1), fakesrc);
@@ -37,8 +36,10 @@ int main (int argc, char *argv[])
     gst_object_ref(GST_OBJECT(fakesrc));
     gst_bin_remove(GST_BIN(pipe1), fakesrc);
     gst_bin_remove(GST_BIN(pipe1), fakesink1);
-    gst_object_unref(GST_OBJECT(pipe1));
+
+    gst_object_unref (GST_OBJECT (pipe1));
     
+    pipe2 = gst_pipeline_new("pipe2");
     /* make a new pipeline */
     gst_bin_add (GST_BIN(pipe2), fakesink2);
     
index f45baa0..482a21b 100644 (file)
@@ -3,7 +3,7 @@
 int main(int argc,char *argv[]) 
 {
   GstElement *bin, *element;
-  gint i=10000;
+  gint i=1000000;
 
   free (malloc(8)); /* -lefence */
 
@@ -15,13 +15,15 @@ int main(int argc,char *argv[])
 
   while (i--)
   {
+    GstPad *pad;
+
     fprintf (stderr, "+");
 
     element = gst_element_factory_make ("tee", "tee");
     if (!element) 
       break;
 
-    gst_element_request_pad_by_name (element, "src%d");
+    pad = gst_element_request_pad_by_name (element, "src%d");
 
     gst_bin_add (GST_BIN (bin), element);
     gst_bin_remove (GST_BIN (bin), element);
index 49fd163..cd196d0 100644 (file)
@@ -18,7 +18,7 @@ int main(int argc,char *argv[]) {
   doc = xmlNewDoc("1.0");
   doc->xmlRootNode = xmlNewDocNode(doc, NULL, "GST-CompletionRegistry", NULL);
 
-  plugins = (GList *) gst_plugin_get_list();
+  plugins = gst_registry_pool_plugin_list();
   while (plugins) {
     GstPlugin *plugin;
 
index 75080a6..bd8847f 100644 (file)
@@ -132,6 +132,107 @@ output_hierarchy (GType type, gint level, gint *maxlevel)
     g_print ("\n");
 }
 
+static void
+print_element_properties (GstElement *element) 
+{
+  GParamSpec **property_specs;
+  gint num_properties,i;
+
+  property_specs = g_object_class_list_properties 
+                    (G_OBJECT_GET_CLASS (element), &num_properties);
+  printf("\nElement Arguments:\n");
+
+  for (i = 0; i < num_properties; i++) {
+    GValue value = { 0, };
+    GParamSpec *param = property_specs[i];
+
+    if (param->flags & G_PARAM_READABLE) {
+      g_value_init (&value, param->value_type);
+      g_object_get_property (G_OBJECT (element), param->name, &value);
+    }
+
+    printf("  %-40.40s: %s\n", g_param_spec_get_name (param),
+                              g_param_spec_get_blurb (param));
+
+    switch (G_VALUE_TYPE (&value)) {
+      case G_TYPE_STRING: 
+       printf ("%-43.43s String (Default \"%s\")", "", g_value_get_string (&value));
+       break;
+      case G_TYPE_BOOLEAN: 
+       printf ("%-43.43s Boolean (Default %s)", "", (g_value_get_boolean (&value) ? "true" : "false"));
+       break;
+      case G_TYPE_ULONG: 
+      {
+       GParamSpecULong *pulong = G_PARAM_SPEC_ULONG (param);
+       printf("%-43.43s Unsigned Long. Range: %lu - %lu (Default %lu)", "", 
+                       pulong->minimum, pulong->maximum, g_value_get_long (&value));
+       break;
+      }
+      case G_TYPE_LONG: 
+      {
+       GParamSpecLong *plong = G_PARAM_SPEC_LONG (param);
+       printf("%-43.43s Long. Range: %ld - %ld (Default %ld)", "", 
+                       plong->minimum, plong->maximum, g_value_get_long (&value));
+       break;
+      }
+      case G_TYPE_UINT: 
+       printf("%-43.43s Unsigned Integer (Default %u)", "", g_value_get_uint (&value));
+       break;
+      {
+       GParamSpecUInt *puint = G_PARAM_SPEC_UINT (param);
+       printf("%-43.43s Unsigned Integer. Range: %u - %u (Default %u)", "", 
+                       puint->minimum, puint->maximum, g_value_get_uint (&value));
+       break;
+      }
+      case G_TYPE_INT: 
+      {
+       GParamSpecInt *pint = G_PARAM_SPEC_INT (param);
+       printf("%-43.43s Integer. Range: %d - %d (Default %d)", "", 
+                       pint->minimum, pint->maximum, g_value_get_int (&value));
+       break;
+      }
+      case G_TYPE_FLOAT: 
+      {
+       GParamSpecFloat *pfloat = G_PARAM_SPEC_FLOAT (param);
+       printf("%-43.43s Float. Range: %f - %f (Default %f)", "", 
+                       pfloat->minimum, pfloat->maximum, g_value_get_float (&value));
+       break;
+      }
+      case G_TYPE_DOUBLE: 
+      {
+       GParamSpecDouble *pdouble = G_PARAM_SPEC_DOUBLE (param);
+       printf("%-43.43s Double. Range: %f - %f (Default %f)", "", 
+                       pdouble->minimum, pdouble->maximum, g_value_get_double (&value));
+       break;
+      }
+      default:
+        if (param->value_type == GST_TYPE_FILENAME)
+          printf("Filename");
+        else if (G_IS_PARAM_SPEC_ENUM (param)) {
+          GEnumValue *values;
+         guint j = 0;
+
+          printf("%-43.43s Enum \"%s\" (default %d)", "", 
+                         g_type_name (G_VALUE_TYPE (&value)),
+                         g_value_get_enum (&value));
+         values = G_ENUM_CLASS (g_type_class_ref (param->value_type))->values;
+
+         while (values[j].value_name) {
+            printf("\n%-43.43s    (%d): \t%s", "", values[j].value, values[j].value_nick);
+           j++; 
+         }
+         /* g_type_class_unref (ec); */
+       }
+        else
+          printf("unknown %ld", param->value_type);
+        break;
+    }
+    printf("\n");
+  }
+  if (num_properties == 0) 
+    g_print ("  none\n");
+}
+
 static gint
 print_element_info (GstElementFactory *factory)
 {
@@ -143,8 +244,6 @@ print_element_info (GstElementFactory *factory)
   GstPad *pad;
   GstRealPad *realpad;
   GstPadTemplate *padtemplate;
-  gint num_properties,i;
-  GParamSpec **property_specs;
   GList *children;
   GstElement *child;
   gboolean have_flags;
@@ -354,84 +453,7 @@ print_element_info (GstElementFactory *factory)
   } else
     printf("  none\n");
 
-  property_specs = g_object_class_list_properties(G_OBJECT_GET_CLASS (element), &num_properties);
-  printf("\nElement Arguments:\n");
-
-  for (i=0;i<num_properties;i++) {
-    GValue value = { 0, };
-    GParamSpec *param = property_specs[i];
-
-    if (param->flags & G_PARAM_READABLE) {
-      g_value_init (&value, param->value_type);
-      g_object_get_property (G_OBJECT (element), param->name, &value);
-    }
-
-    printf("  %-40.40s: ",param->name);
-    switch (G_VALUE_TYPE (&value)) {
-      case G_TYPE_STRING: 
-        printf("String (Default \"%s\")", g_value_get_string (&value));
-        break;
-      case G_TYPE_POINTER: 
-        printf("Pointer (Default \"%p\")", g_value_get_pointer (&value));
-        break;
-      case G_TYPE_BOOLEAN: 
-        printf("Boolean (Default %s)", (g_value_get_boolean (&value)?"true":"false"));
-        break;
-      case G_TYPE_ULONG: 
-        printf("Unsigned Long (Default %lu, Range %lu -> %lu)", g_value_get_ulong (&value), 
-        ((GParamSpecULong*)param)->minimum, ((GParamSpecULong*)param)->maximum);
-        break;
-      case G_TYPE_LONG: 
-        printf("Long (Default %ld, Range %ld -> %ld)", g_value_get_long (&value), 
-        ((GParamSpecLong*)param)->minimum, ((GParamSpecLong*)param)->maximum);
-        break;
-      case G_TYPE_UINT: 
-        printf("Unsigned Integer (Default %u, Range %u -> %u)", g_value_get_uint (&value), 
-        ((GParamSpecUInt*)param)->minimum, ((GParamSpecUInt*)param)->maximum);
-        break;
-      case G_TYPE_INT: 
-        printf("Integer (Default %d, Range %d -> %d)", g_value_get_int (&value), 
-        ((GParamSpecInt*)param)->minimum, ((GParamSpecInt*)param)->maximum);
-        break;
-      case G_TYPE_INT64: 
-        printf("64 Bit Integer (Default %lld, Range %lld -> %lld)", g_value_get_int64 (&value), 
-        ((GParamSpecInt64*)param)->minimum, ((GParamSpecInt64*)param)->maximum);
-        break;
-      case G_TYPE_FLOAT: 
-        printf("Float (Default %f, Range %f -> %f)", g_value_get_float (&value), 
-        ((GParamSpecFloat*)param)->minimum, ((GParamSpecFloat*)param)->maximum);
-        break;
-      case G_TYPE_DOUBLE: 
-        printf("Double (Default %f, Range %f -> %f)", g_value_get_double (&value), 
-        ((GParamSpecDouble*)param)->minimum, ((GParamSpecDouble*)param)->maximum);
-        break;
-      default:
-        if (param->value_type == GST_TYPE_FILENAME)
-          printf("Filename");
-        else if (G_IS_PARAM_SPEC_ENUM (param)) {
-          GEnumValue *values;
-         guint j = 0;
-
-          printf("Enum \"%s\" (default %d)", g_type_name (G_VALUE_TYPE (&value)),
-                                 g_value_get_enum (&value));
-         values = G_ENUM_CLASS (g_type_class_ref (param->value_type))->values;
-
-         while (values[j].value_name) {
-            printf("\n    (%d): \t%s", values[j].value, values[j].value_nick);
-           j++; 
-         }
-         /* g_type_class_unref (ec); */
-       }
-        else
-          printf("unknown %ld", param->value_type);
-        break;
-    }
-    printf("\n");
-  }
-    /*
-  g_free (args);
-  */
-  if (num_properties == 0) g_print ("  none\n");
+  print_element_properties (element);
 
   /* Dynamic Parameters block */
   {
@@ -505,6 +527,8 @@ print_element_info (GstElementFactory *factory)
         printf ("    \t\t\t\t%s arg%d,\n", g_type_name (param_types[j]), j);
       }
       printf ("    \t\t\t\tgpointer user_data);\n");
+
+      g_free (query);
     }
     if (nsignals == 0) g_print ("  none\n");
   }
@@ -534,7 +558,7 @@ print_element_list (void)
 {
   GList *plugins;
 
-  plugins = (GList *) gst_plugin_get_list();
+  plugins = gst_registry_pool_plugin_list();
   while (plugins) {
     GList *features;
     GstPlugin *plugin;
@@ -552,13 +576,13 @@ print_element_list (void)
         GstElementFactory *factory;
 
         factory = GST_ELEMENT_FACTORY (feature);
-        printf("%s element:  %s: %s\n",plugin->name, GST_OBJECT_NAME (factory) ,factory->details->longname);
+        printf("%s:  %s: %s\n",plugin->name, GST_PLUGIN_FEATURE_NAME (factory) ,factory->details->longname);
       }
       else if (GST_IS_AUTOPLUG_FACTORY (feature)) {
         GstAutoplugFactory *factory;
 
         factory = GST_AUTOPLUG_FACTORY (feature);
-        printf("%s autoplug:  %s: %s\n", plugin->name, GST_OBJECT_NAME (factory), factory->longdesc);
+        printf("%s:  %s: %s\n", plugin->name, GST_PLUGIN_FEATURE_NAME (factory), factory->longdesc);
       }
       else if (GST_IS_TYPE_FACTORY (feature)) {
         GstTypeFactory *factory;
@@ -573,10 +597,10 @@ print_element_list (void)
         GstSchedulerFactory *factory;
 
         factory = GST_SCHEDULER_FACTORY (feature);
-        printf("%s scheduler:  %s: %s\n", plugin->name, GST_OBJECT_NAME (factory), factory->longdesc);
+        printf("%s:  %s: %s\n", plugin->name, GST_PLUGIN_FEATURE_NAME (factory), factory->longdesc);
       }
       else {
-        printf("%s:  %s (%s)\n", plugin->name, gst_object_get_name (GST_OBJECT (feature)), 
+        printf("%s:  %s (%s)\n", plugin->name, GST_PLUGIN_FEATURE_NAME (feature), 
                      g_type_name (G_OBJECT_TYPE (feature)));
       }
 
@@ -680,7 +704,7 @@ main (int argc, char *argv[])
     }
 
     /* otherwise assume it's a plugin */
-    plugin = gst_plugin_find (argv[1]);
+    plugin = gst_registry_pool_find_plugin (argv[1]);
 
     /* if there is such a plugin, print out info */
 
index 655d009..426eeae 100644 (file)
@@ -6,6 +6,7 @@ static guint64 iterations = 0;
 static guint64 sum = 0;
 static guint64 min = G_MAXINT;
 static guint64 max = 0;
+static GstClock *s_clock;
 
 gboolean
 idle_func (gpointer data)
@@ -14,6 +15,10 @@ idle_func (gpointer data)
   GTimeVal tfthen, tfnow;
   GstClockTimeDiff diff;
 
+  if (s_clock) {
+    //g_print ("%lld\n", gst_clock_get_time (s_clock));
+  }
+
   g_get_current_time (&tfthen);
   busy = gst_bin_iterate (GST_BIN (data));
   iterations++;
@@ -193,6 +198,8 @@ main(int argc, char *argv[])
       exit (-1);
     }
 
+    s_clock = gst_bin_get_clock (GST_BIN (pipeline));
+
     if (!GST_FLAG_IS_SET (GST_OBJECT (pipeline), GST_BIN_SELF_SCHEDULABLE)) {
         g_idle_add (idle_func, pipeline);
         gst_main ();
index 435b114..353ff37 100644 (file)
 #include <stdlib.h>
 #include <stdio.h>
 
-#include <sys/stat.h>
-#include <sys/types.h>
 #include <fcntl.h>
 #include <unistd.h>
-
 #include <string.h>
 #include <errno.h>
 
 #include "config.h"
 
-extern gboolean _gst_plugin_spew;
-extern gboolean _gst_warn_old_registry;
-extern gboolean _gst_init_registry_write; /* we ask post_init to be delayed */
-
-static void error_perm() {
-    g_print("\n(%s)\n"
-           "Do you have the appropriate permissions?\n"
-           "You may need to be root to run this command.\n\n",
-           strerror(errno));
-    exit(1);
-}
-
-static void usage(const char *progname) {
-    g_print("usage: %s\n", progname);
-    g_print("Builds the plugin registry for gstreamer.\n");
-    g_print("This command will usually require superuser privileges.\n\n");
-    exit(0);
-}
-
-static int is_file(const char * filename) {
-  struct stat statbuf;
-  if(stat(filename, &statbuf)) return 0;
-  return S_ISREG(statbuf.st_mode);
-}
-
-static int is_dir(const char * filename) {
-  struct stat statbuf;
-  if(stat(filename, &statbuf)) return 0;
-  return S_ISDIR(statbuf.st_mode);
-}
-
-static void set_filemode(const char * filename, mode_t mode) {
-    if(chmod(filename, mode)) {
-       g_print("Cannot set file permissions on `%s' to %o", filename, mode);
-       error_perm();
-    }
-}
-
-static int get_filemode(const char * filename, mode_t * mode) {
-    struct stat statbuf;
-    if(stat(filename, &statbuf)) return 0;
-    *mode = statbuf.st_mode & ~ S_IFMT;
-    return 1;
-}
-
-static void move_file(const char * nameold,
-                     const char * namenew,
-                     mode_t * newmode) {
-    if (!is_file(nameold)) {
-       g_print("Temporary `%s' is not a file", nameold);
-       error_perm();
-    }
-    if (is_dir(namenew)) {
-       g_print("Destination path `%s' for registry file is a directory\n", namenew);
-       g_print("Please remove, or reconfigure GStreamer\n\n");
-       exit(1);
-    }
-    if (rename(nameold, namenew)) {
-       g_print("Cannot move `%s' to `%s'", nameold, namenew);
-       error_perm();
-    }
-    /* set mode again, to make this public */
-    set_filemode(namenew, *newmode);
-}
-
-static void make_dir(const char * dirname) {
-    mode_t mode = REGISTRY_DIR_PERMS;
-    if(mkdir(dirname, mode)) {
-       g_print("Cannot create GStreamer registry directory `%s'", dirname);
-       error_perm();
-    }
+extern gboolean _gst_registry_auto_load;
+static gint num_features = 0;
+static gint num_plugins = 0;
 
-    if(chmod(dirname, mode)) {
-       g_print("Cannot set permissions on GStreamer registry directory `%s' to %o", dirname, mode);
-       error_perm();
-    }
+static void
+plugin_added_func (GstRegistry *registry, GstPlugin *plugin, gpointer user_data)
+{
+  g_print ("added plugin %s with %d features\n", plugin->name, plugin->numfeatures);
 
-    return;
+  num_features += plugin->numfeatures;
+  num_plugins++;
 }
 
-static void check_dir(const char * dirname) {
-    if (!is_dir(dirname)) {
-       make_dir(dirname);
-    }
-}
+int main(int argc,char *argv[]) 
+{
+  GList *registries;
 
-static void save_registry(const char *destfile,
-                         xmlDocPtr * doc) {
-    mode_t tmpmode = REGISTRY_TMPFILE_PERMS;
-#if 0
-    FILE *fp;
-    int fd;
-
-    fd = open(destfile, O_CREAT | O_TRUNC | O_WRONLY, tmpmode);
-    if (fd == -1) {
-       g_print("Cannot open `%s' to save new registry to.", destfile);
-       error_perm();
-    }
-    fp = fdopen (fd, "wb");
-    if (!fp) {
-       g_print("Cannot fopen `%s' to save new registry to.", destfile);
-       error_perm();
-    }
-    /* set mode to make this private */
-    set_filemode(destfile, tmpmode);
+    /* Init gst */
+  _gst_registry_auto_load = FALSE;
+  gst_init (&argc, &argv);
 
-    /*  FIXME: no way to check success of xmlDocDump, which is why
-       this piece of code is ifdefed out.
-       The version of libxml currently (Jan 2001) in their CVS tree fixes
-       this problem. */
+  registries = gst_registry_pool_list ();
+  registries = g_list_reverse (registries);
 
-    xmlDocDump(fp, *doc);
+  while (registries) {
+    GstRegistry *registry = GST_REGISTRY (registries->data);
 
-    if (!fclose(fp)) {
-       g_print("Cannot close `%s' having saved new registry.", destfile);
-       error_perm();
-    }
+    g_signal_connect (G_OBJECT (registry), "plugin_added", 
+                   G_CALLBACK (plugin_added_func), NULL);
 
-#else
-#ifdef HAVE_LIBXML2
-    /* indent the document */
-    if (xmlSaveFormatFile(destfile, *doc, 1) <= 0) {
-#else
-    if (xmlSaveFile(destfile, *doc) <= 0) {
-#endif
-       g_print("Cannot save new registry to `%s'", destfile);
-       error_perm();
+    if (registry->flags & GST_REGISTRY_WRITABLE) {
+      g_print ("rebuilding %s\n", registry->name);
+      gst_registry_rebuild (registry);
+      gst_registry_save (registry);
     }
-    set_filemode(destfile, tmpmode);
-#endif
-}
-
-int main(int argc,char *argv[]) 
-{
-    xmlDocPtr doc;
-    xmlNodePtr node;
-    GstRegistryWrite *gst_reg;
-
-    /* Mode of the file we're saving the repository to; */
-    mode_t newmode;
-
-    /* Get mode of old repository, or a default. */
-    if (!get_filemode(GLOBAL_REGISTRY_FILE, &newmode)) {
-       mode_t theumask = umask(0);
-       umask(theumask);
-       newmode = REGISTRY_FILE_PERMS & ~ theumask;
+    else {
+      g_print ("loading %s\n", registry->name);
+      gst_registry_load (registry);
     }
-
-    /* Init gst */
-    _gst_plugin_spew = TRUE;
-    _gst_warn_old_registry = FALSE;
-    gst_info_enable_category(GST_CAT_PLUGIN_LOADING);
-    _gst_init_registry_write = TRUE; /* signal that we're writing registry */
-    gst_init(&argc,&argv);
-
-    /* remove the old registry file first
-     * if a local is returned, then do that, else remove the global one
-     * If this fails, we simply ignore it since we'll overwrite it later
-     * anyway */
-    gst_reg = gst_registry_write_get ();
-    unlink (gst_reg->file);
-
-    GST_INFO (GST_CAT_PLUGIN_LOADING, " Writing to registry %s", gst_reg->file);
-
-    /* Check args */
-    if (argc != 1) usage(argv[0]);
-
-    /* Read the plugins */
-    doc = xmlNewDoc("1.0");
-    node = xmlNewDocNode(doc, NULL, "GST-PluginRegistry", NULL);
-    xmlDocSetRootElement (doc, node);
-    gst_plugin_save_thyself(doc->xmlRootNode);
-    
-    if (gst_reg->dir)
-      check_dir(gst_reg->dir);
     
-    /* Save the registry to a tmp file. */
-    save_registry(gst_reg->tmp_file, &doc);
+    registries = g_list_next (registries);
+  }
 
-    /* Make the tmp file live. */
-    move_file(gst_reg->tmp_file, gst_reg->file, &newmode);
-#ifdef THOMAS
-    }
-    else
-    {
-      gchar *homedir;
-      gchar *reg_dir, *reg_file_tmp, *reg_file;
-
-      homedir = (gchar *) g_get_home_dir ();
-      reg_dir      = g_strjoin ("/", homedir, LOCAL_REGISTRY_DIR,      NULL);
-      reg_file_tmp = g_strjoin ("/", homedir, LOCAL_REGISTRY_FILE_TMP, NULL);
-      reg_file     = g_strjoin ("/", homedir, LOCAL_REGISTRY_FILE,     NULL);
-
-      /* try to make the dir; we'll find out if it fails anyway */
-      mkdir(reg_dir, S_IRWXU);
-      g_free(reg_dir);
-
-      /* Save the registry to a tmp file. */
-      save_registry(reg_file_tmp, &doc);
-
-      /* Make the tmp file live. */
-      move_file(reg_file_tmp, reg_file, &newmode);
-      g_free(reg_file_tmp);
-      g_free(reg_file);
-    }
-#endif
-    g_free (gst_reg);
-    return(0);
+  g_print ("loaded %d plugins with %d features\n", num_plugins, num_features);
+
+  return(0);
 }