diff --git a/configure.ac b/configure.ac index 95d581aa07..af35907e65 100644 --- a/configure.ac +++ b/configure.ac @@ -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 diff --git a/gst/Makefile.am b/gst/Makefile.am index 3ddcf3cdad..fc1acbe464 100644 --- a/gst/Makefile.am +++ b/gst/Makefile.am @@ -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 diff --git a/gst/autoplug/gstautoplugcache.c b/gst/autoplug/gstautoplugcache.c index 783f9a1f71..7601e02a7c 100644 --- a/gst/autoplug/gstautoplugcache.c +++ b/gst/autoplug/gstautoplugcache.c @@ -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)); } diff --git a/gst/autoplug/gstspider.c b/gst/autoplug/gstspider.c index a8f90fe280..954661750e 100644 --- a/gst/autoplug/gstspider.c +++ b/gst/autoplug/gstspider.c @@ -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; } diff --git a/gst/autoplug/gststaticautoplug.c b/gst/autoplug/gststaticautoplug.c index d4d8f1ba74..9fb3d3c87f 100644 --- a/gst/autoplug/gststaticautoplug.c +++ b/gst/autoplug/gststaticautoplug.c @@ -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 { diff --git a/gst/autoplug/gststaticautoplugrender.c b/gst/autoplug/gststaticautoplugrender.c index fee73cc99a..ec60b5617b 100644 --- a/gst/autoplug/gststaticautoplugrender.c +++ b/gst/autoplug/gststaticautoplugrender.c @@ -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 { diff --git a/gst/elements/gstfilesrc.c b/gst/elements/gstfilesrc.c index 90d635ceb2..f67bd0f431 100644 --- a/gst/elements/gstfilesrc.c +++ b/gst/elements/gstfilesrc.c @@ -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); diff --git a/gst/gst.c b/gst/gst.c index 2e6914779b..4fd4b04be7 100644 --- a/gst/gst.c +++ b/gst/gst.c @@ -30,15 +30,18 @@ #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); diff --git a/gst/gst.h b/gst/gst.h index 00935dcda6..473e4018a5 100644 --- 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 } diff --git a/gst/gstautoplug.c b/gst/gstautoplug.c index f2ef2c2148..e0439b2ad8 100644 --- a/gst/gstautoplug.c +++ b/gst/gstautoplug.c @@ -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,37 +272,19 @@ 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 */ diff --git a/gst/gstautoplug.h b/gst/gstautoplug.h index 3b50b2bb86..c8a750bfa0 100644 --- a/gst/gstautoplug.h +++ b/gst/gstautoplug.h @@ -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); diff --git a/gst/gstclock.c b/gst/gstclock.c index 41f3cac16b..fa72ac2335 100644 --- a/gst/gstclock.c +++ b/gst/gstclock.c @@ -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; diff --git a/gst/gstelement.h b/gst/gstelement.h index ed1dc12a4f..7b0229194c 100644 --- a/gst/gstelement.h +++ b/gst/gstelement.h @@ -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 } diff --git a/gst/gstelementfactory.c b/gst/gstelementfactory.c index 00b8ddaf37..8505d048fa 100644 --- a/gst/gstelementfactory.c +++ b/gst/gstelementfactory.c @@ -24,20 +24,13 @@ #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 */ diff --git a/gst/gstevent.c b/gst/gstevent.c index 3dbec8ebaf..880dd6890b 100644 --- a/gst/gstevent.c +++ b/gst/gstevent.c @@ -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; -} - diff --git a/gst/gstevent.h b/gst/gstevent.h index 4c3d72d2e6..46166ffd12 100644 --- a/gst/gstevent.h +++ b/gst/gstevent.h @@ -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 */ diff --git a/gst/gstpad.c b/gst/gstpad.c index 836f46590a..361cafa438 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -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 diff --git a/gst/gstpad.h b/gst/gstpad.h index edc6693956..5bab8ac8d8 100644 --- a/gst/gstpad.h +++ b/gst/gstpad.h @@ -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); diff --git a/gst/gstplugin.c b/gst/gstplugin.c index 6746f66c75..c6bd2bb386 100644 --- a/gst/gstplugin.c +++ b/gst/gstplugin.c @@ -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 - * "liblibrary.so". - * - * 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 - * "libplugin.so". - * - * 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 - * "/path/to/plugin/libplugin.so". - * - * 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()); } @@ -574,6 +169,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; @@ -770,146 +343,6 @@ gst_plugin_add_feature (GstPlugin *plugin, GstPluginFeature *feature) } } -/** - * gst_plugin_get_list: - * - * get the currently loaded plugins - * - * Returns; a GList of GstPlugin elements - */ -const GList* -gst_plugin_get_list (void) -{ - return _gst_plugins; -} - -#ifndef GST_DISABLE_REGISTRY -/** - * gst_plugin_save_thyself: - * @parent: the parent node to save the plugin to - * - * saves the plugin into an XML representation - * - * Returns: the new XML node - */ -xmlNodePtr -gst_plugin_save_thyself (xmlNodePtr parent) -{ - 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); - - 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; -} - -/** - * 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); -} -#endif /* GST_DISABLE_REGISTRY */ - - /** * gst_plugin_get_feature_list: * @plugin: the plugin to get the features from @@ -925,3 +358,44 @@ gst_plugin_get_feature_list (GstPlugin *plugin) return plugin->features; } + +/** + * gst_plugin_load: + * @name: name of plugin to load + * + * Load the named plugin. + * + * Returns: whether the plugin was loaded or not + */ +gboolean +gst_plugin_load (const gchar *name) +{ + GstPlugin *plugin; + + plugin = gst_registry_pool_find_plugin (name); + if (plugin) + return gst_plugin_load_plugin (plugin); + + return FALSE; +} + +/** + * gst_library_load: + * @name: name of library to load + * + * Load the named library. Name should be given as + * "liblibrary.so". + * + * Returns: whether the library was loaded or not + */ +gboolean +gst_library_load (const gchar *name) +{ + gboolean res; + + /* for now this is the same */ + res = gst_plugin_load(name); + + return res; +} + diff --git a/gst/gstplugin.h b/gst/gstplugin.h index fba15df38b..80dbd9ee2e 100644 --- a/gst/gstplugin.h +++ b/gst/gstplugin.h @@ -30,18 +30,22 @@ #include +#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__ */ diff --git a/gst/gstpluginfeature.c b/gst/gstpluginfeature.c index 7baa9836cc..ae29f0d7eb 100644 --- a/gst/gstpluginfeature.c +++ b/gst/gstpluginfeature.c @@ -23,15 +23,11 @@ #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; } diff --git a/gst/gstpluginfeature.h b/gst/gstpluginfeature.h index 8e3b8b92b3..e369a0977e 100644 --- a/gst/gstpluginfeature.h +++ b/gst/gstpluginfeature.h @@ -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); }; diff --git a/gst/gstregistry.c b/gst/gstregistry.c index 5dbd907d71..a4cabaf059 100644 --- a/gst/gstregistry.c +++ b/gst/gstregistry.c @@ -31,6 +31,624 @@ #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", + ®istry_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 */ diff --git a/gst/gstregistry.h b/gst/gstregistry.h index fc876d6438..ec768a8dd2 100644 --- a/gst/gstregistry.h +++ b/gst/gstregistry.h @@ -24,6 +24,8 @@ #ifndef __GST_REGISTRY_H__ #define __GST_REGISTRY_H__ +#include + #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__ */ diff --git a/gst/gstscheduler.c b/gst/gstscheduler.c index 225c46a8e1..0963b7d9e6 100644 --- a/gst/gstscheduler.c +++ b/gst/gstscheduler.c @@ -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,37 +705,19 @@ 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 @@ -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 */ diff --git a/gst/gstscheduler.h b/gst/gstscheduler.h index 49a09863fd..ba61ffe2f5 100644 --- a/gst/gstscheduler.h +++ b/gst/gstscheduler.h @@ -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); diff --git a/gst/gsttype.c b/gst/gsttype.c index 0b986ccb3f..7c6893b212 100644 --- a/gst/gsttype.c +++ b/gst/gsttype.c @@ -30,24 +30,18 @@ #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; @@ -290,19 +278,6 @@ gst_type_get_list (void) return _gst_types; } -/** - * 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 */ diff --git a/gst/gsttype.h b/gst/gsttype.h index ca7b73d287..3080c03db7 100644 --- a/gst/gsttype.h +++ b/gst/gsttype.h @@ -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 */ diff --git a/gst/gsttypefind.c b/gst/gsttypefind.c index b2c311edb3..cd2101a8e9 100644 --- a/gst/gsttypefind.c +++ b/gst/gsttypefind.c @@ -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 index 0000000000..9fb1d0d39b --- /dev/null +++ b/gst/registries/Makefile.am @@ -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 index 0000000000..96bcdfc71b --- /dev/null +++ b/gst/registries/gstxmlregistry.c @@ -0,0 +1,1074 @@ +/* GStreamer + * Copyright (C) 1999,2000 Erik Walthinsen + * 2000 Wim Taymans + * + * 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 +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#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\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, "\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, "\n", name, min, max); + break; + } + case GST_PROPS_FLOAT_TYPE: + { + gfloat value; + gst_props_entry_get_float (entry, &value); + CLASS (xmlregistry)->save_func (xmlregistry, "\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, "\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, "\n", (gchar *)&fourcc); + CLASS (xmlregistry)->save_func (xmlregistry, "\n", name, fourcc); + break; + } + case GST_PROPS_BOOL_TYPE: + { + gboolean value; + gst_props_entry_get_boolean (entry, &value); + CLASS (xmlregistry)->save_func (xmlregistry, "\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, "\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, "\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, "\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, "\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, "\n"); + gst_xml_registry_save_props (xmlregistry, caps->properties); + CLASS (xmlregistry)->save_func (xmlregistry, "\n"); + } + CLASS (xmlregistry)->save_func (xmlregistry, "\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, "%s\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, "%s\n", presence); + + if (GST_PAD_TEMPLATE_CAPS (template)) { + CLASS (xmlregistry)->save_func (xmlregistry, "\n"); + gst_xml_registry_save_caps (xmlregistry, GST_PAD_TEMPLATE_CAPS (template)); + CLASS (xmlregistry)->save_func (xmlregistry, "\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, "\n"); + gst_xml_registry_save_pad_template (xmlregistry, template); + CLASS (xmlregistry)->save_func (xmlregistry, "\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, "\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, "\n", g_type_name (G_OBJECT_TYPE (feature))); + gst_xml_registry_save_feature (xmlregistry, feature); + CLASS (xmlregistry)->save_func (xmlregistry, "\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, "\n"); + CLASS (xmlregistry)->save_func (xmlregistry, "\n"); + + while (walk) { + GstPlugin *plugin = GST_PLUGIN (walk->data); + + CLASS (xmlregistry)->save_func (xmlregistry, "\n"); + gst_xml_registry_save_plugin (xmlregistry, plugin); + CLASS (xmlregistry)->save_func (xmlregistry, "\n"); + + walk = g_list_previous (walk); + } + CLASS (xmlregistry)->save_func (xmlregistry, "\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 index 0000000000..14894ceaba --- /dev/null +++ b/gst/registries/gstxmlregistry.h @@ -0,0 +1,126 @@ +/* GStreamer + * Copyright (C) 1999,2000 Erik Walthinsen + * 2000 Wim Taymans + * + * 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 + +#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 index 0000000000..5da6ecb2cd --- /dev/null +++ b/gst/registries/registrytest.c @@ -0,0 +1,19 @@ +#include + +#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; + +} diff --git a/gst/schedulers/gstbasicscheduler.c b/gst/schedulers/gstbasicscheduler.c index 4aac1d9145..0df5c83a3b 100644 --- a/gst/schedulers/gstbasicscheduler.c +++ b/gst/schedulers/gstbasicscheduler.c @@ -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; diff --git a/libs/gst/bytestream/bytestream.c b/libs/gst/bytestream/bytestream.c index eb1887cacf..4660329868 100644 --- a/libs/gst/bytestream/bytestream.c +++ b/libs/gst/bytestream/bytestream.c @@ -26,7 +26,7 @@ #include #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; diff --git a/ltmain.sh b/ltmain.sh index 6aa99d1325..a92647710f 100644 --- 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 \ diff --git a/plugins/elements/gstfilesrc.c b/plugins/elements/gstfilesrc.c index 90d635ceb2..f67bd0f431 100644 --- a/plugins/elements/gstfilesrc.c +++ b/plugins/elements/gstfilesrc.c @@ -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); diff --git a/tests/old/testsuite/cleanup/cleanup5.c b/tests/old/testsuite/cleanup/cleanup5.c index f45baa092e..482a21b0d4 100644 --- a/tests/old/testsuite/cleanup/cleanup5.c +++ b/tests/old/testsuite/cleanup/cleanup5.c @@ -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); diff --git a/tests/sched/dynamic-pipeline.c b/tests/sched/dynamic-pipeline.c index fa3de4ed06..a89f9aa359 100644 --- a/tests/sched/dynamic-pipeline.c +++ b/tests/sched/dynamic-pipeline.c @@ -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); diff --git a/testsuite/cleanup/cleanup5.c b/testsuite/cleanup/cleanup5.c index f45baa092e..482a21b0d4 100644 --- a/testsuite/cleanup/cleanup5.c +++ b/testsuite/cleanup/cleanup5.c @@ -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); diff --git a/tools/gst-compprep.c b/tools/gst-compprep.c index 49fd163350..cd196d0cae 100644 --- a/tools/gst-compprep.c +++ b/tools/gst-compprep.c @@ -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; diff --git a/tools/gst-inspect.c b/tools/gst-inspect.c index 75080a69af..bd8847feaf 100644 --- a/tools/gst-inspect.c +++ b/tools/gst-inspect.c @@ -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;iflags & 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 */ diff --git a/tools/gst-launch.c b/tools/gst-launch.c index 655d0095eb..426eeae24b 100644 --- a/tools/gst-launch.c +++ b/tools/gst-launch.c @@ -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 (); diff --git a/tools/gst-register.c b/tools/gst-register.c index 435b1149b1..353ff370c1 100644 --- a/tools/gst-register.c +++ b/tools/gst-register.c @@ -25,223 +25,58 @@ #include #include -#include -#include #include #include - #include #include #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 */ +extern gboolean _gst_registry_auto_load; +static gint num_features = 0; +static gint num_plugins = 0; -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 +plugin_added_func (GstRegistry *registry, GstPlugin *plugin, gpointer user_data) +{ + g_print ("added plugin %s with %d features\n", plugin->name, plugin->numfeatures); -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(); - } - - if(chmod(dirname, mode)) { - g_print("Cannot set permissions on GStreamer registry directory `%s' to %o", dirname, mode); - error_perm(); - } - - return; -} - -static void check_dir(const char * dirname) { - if (!is_dir(dirname)) { - make_dir(dirname); - } -} - -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); - - /* 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. */ - - xmlDocDump(fp, *doc); - - if (!fclose(fp)) { - g_print("Cannot close `%s' having saved new registry.", destfile); - error_perm(); - } - -#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(); - } - set_filemode(destfile, tmpmode); -#endif + num_features += plugin->numfeatures; + num_plugins++; } 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; - } + GList *registries; /* 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); + _gst_registry_auto_load = FALSE; + 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); + registries = gst_registry_pool_list (); + registries = g_list_reverse (registries); - GST_INFO (GST_CAT_PLUGIN_LOADING, " Writing to registry %s", gst_reg->file); + while (registries) { + GstRegistry *registry = GST_REGISTRY (registries->data); - /* Check args */ - if (argc != 1) usage(argv[0]); + g_signal_connect (G_OBJECT (registry), "plugin_added", + G_CALLBACK (plugin_added_func), NULL); - /* 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); - - /* Make the tmp file live. */ - move_file(gst_reg->tmp_file, gst_reg->file, &newmode); -#ifdef THOMAS + if (registry->flags & GST_REGISTRY_WRITABLE) { + g_print ("rebuilding %s\n", registry->name); + gst_registry_rebuild (registry); + gst_registry_save (registry); } - 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); + else { + g_print ("loading %s\n", registry->name); + gst_registry_load (registry); } -#endif - g_free (gst_reg); - return(0); + + registries = g_list_next (registries); + } + + g_print ("loaded %d plugins with %d features\n", num_plugins, num_features); + + return(0); }