From 7ccc2cf90b33f6a84cebc2e3f6ca1585abe12d1b Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 28 Aug 2000 20:20:55 +0000 Subject: [PATCH] Externalized the plugin information in /etc/gstreamer/reg.xml Original commit message from CVS: Externalized the plugin information in /etc/gstreamer/reg.xml - no need to do a plugin_load_all() - plugins are loaded when needed - typedetect functions are loaded when needed (still buggy) - no need to check for the existance of the plugin in the codecs - added gstreamer-register to create the reg.xml file - renamed launch to gstreamer-launch - plugins need to register the typefactory they provide modified the plugins to meet the new design modified the plugins to correctly set their pad types autoplugging can be done without loading the plugins now --- examples/helloworld2/helloworld2.c | 5 +- gst/gst.c | 8 +- gst/gstelement.h | 3 + gst/gstelementfactory.c | 91 +++++++ gst/gstplugin.c | 240 ++++++++++++++++++- gst/gstplugin.h | 12 +- gst/gsttype.c | 126 +++++++++- gst/gsttype.h | 9 +- gst/types/gsttypes.c | 2 +- gstplay/gstplay.c | 8 +- tests/old/examples/helloworld2/helloworld2.c | 5 +- tools/.gitignore | 3 +- tools/Makefile.am | 4 +- tools/{launch.c => gstreamer-launch.c} | 14 +- tools/gstreamer-register.c | 18 ++ 15 files changed, 502 insertions(+), 46 deletions(-) rename tools/{launch.c => gstreamer-launch.c} (92%) create mode 100644 tools/gstreamer-register.c diff --git a/examples/helloworld2/helloworld2.c b/examples/helloworld2/helloworld2.c index e2a0ab7ef1..42a194a673 100644 --- a/examples/helloworld2/helloworld2.c +++ b/examples/helloworld2/helloworld2.c @@ -21,20 +21,21 @@ int main(int argc,char *argv[]) } gst_init(&argc,&argv); - gst_plugin_load_all(); - g_print("\n"); /* create a new bin to hold the elements */ pipeline = gst_pipeline_new("pipeline"); + g_assert(pipeline != NULL); /* create a disk reader */ disksrc = gst_elementfactory_make("disksrc", "disk_source"); + g_assert(disksrc != NULL); gtk_object_set(GTK_OBJECT(disksrc),"location", argv[1],NULL); gtk_signal_connect(GTK_OBJECT(disksrc),"eos", GTK_SIGNAL_FUNC(eos),NULL); /* and an audio sink */ audiosink = gst_elementfactory_make("audiosink", "play_audio"); + g_assert(audiosink != NULL); /* add objects to the main pipeline */ gst_bin_add(GST_BIN(pipeline), disksrc); diff --git a/gst/gst.c b/gst/gst.c index 7c2da8a0c7..606134db92 100644 --- a/gst/gst.c +++ b/gst/gst.c @@ -32,10 +32,10 @@ extern gint _gst_trace_on; void gst_init(int *argc,char **argv[]) { GstTrace *gst_trace; - gtk_init(argc,argv); - if (!g_thread_supported()) g_thread_init (NULL); + gtk_init(argc,argv); + _gst_type_initialize(); _gst_plugin_initialize(); _gst_buffer_initialize(); @@ -48,8 +48,8 @@ void gst_init(int *argc,char **argv[]) { gst_elementfactory_register(gst_elementfactory_new( "thread",gst_thread_get_type(),&gst_thread_details)); - gst_plugin_load("libgsttypes.so"); - gst_plugin_load("libgstelements.so"); + //gst_plugin_load_elementfactory("gsttypes"); + //gst_plugin_load("libgstelements.so"); _gst_trace_on = 0; if (_gst_trace_on) { diff --git a/gst/gstelement.h b/gst/gstelement.h index ffdee7fc7c..4024cd0335 100644 --- a/gst/gstelement.h +++ b/gst/gstelement.h @@ -199,6 +199,9 @@ GstElement *gst_elementfactory_create(GstElementFactory *factory, // FIXME this name is wrong, probably so is the one above it GstElement *gst_elementfactory_make(gchar *factoryname,gchar *name); +xmlNodePtr gst_elementfactory_save_thyself(GstElementFactory *factory, xmlNodePtr parent); +GstElementFactory *gst_elementfactory_load_thyself(xmlNodePtr parent); + int gst_element_loopfunc_wrapper(int argc,char **argv); #ifdef __cplusplus diff --git a/gst/gstelementfactory.c b/gst/gstelementfactory.c index 699fada6fd..50d53df2cc 100644 --- a/gst/gstelementfactory.c +++ b/gst/gstelementfactory.c @@ -18,6 +18,7 @@ */ #include +#include /* global list of registered elementfactories */ @@ -113,6 +114,9 @@ GstElement *gst_elementfactory_create(GstElementFactory *factory, GstElementClass *oclass; g_return_val_if_fail(factory != NULL, NULL); + + factory = gst_plugin_load_elementfactory(factory->name); + g_return_val_if_fail(factory->type != 0, NULL); // create an instance of the element @@ -133,6 +137,7 @@ GstElement *gst_elementfactory_make(gchar *factoryname,gchar *name) { GstElementFactory *factory; GstElement *element; + gst_plugin_load_elementfactory(factoryname); factory = gst_elementfactory_find(factoryname); if (factory == NULL) return NULL; element = gst_elementfactory_create(factory,name); @@ -151,3 +156,89 @@ void gst_elementfactory_add_sink(GstElementFactory *elementfactory, guint16 id) elementfactory->sink_types = g_list_prepend(elementfactory->sink_types, GUINT_TO_POINTER(type)); } +xmlNodePtr gst_elementfactory_save_thyself(GstElementFactory *factory, xmlNodePtr parent) { + GList *types; + xmlNodePtr subtree; + + xmlNewChild(parent,NULL,"name",factory->name); + xmlNewChild(parent,NULL,"longname", factory->details->longname); + xmlNewChild(parent,NULL,"class", factory->details->class); + 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); + + types = factory->src_types; + if (types) { + subtree = xmlNewChild(parent,NULL,"sources",NULL); + while (types) { + guint16 typeid = GPOINTER_TO_UINT(types->data); + GstType *type = gst_type_find_by_id(typeid); + + gst_type_save_thyself(type, subtree); + + types = g_list_next(types); + } + } + types = factory->sink_types; + if (types) { + subtree = xmlNewChild(parent,NULL,"sinks",NULL); + while (types) { + guint16 typeid = GPOINTER_TO_UINT(types->data); + GstType *type = gst_type_find_by_id(typeid); + + gst_type_save_thyself(type, subtree); + + types = g_list_next(types); + } + } + + return parent; +} + +GstElementFactory *gst_elementfactory_load_thyself(xmlNodePtr parent) { + GstElementFactory *factory = g_new0(GstElementFactory, 1); + xmlNodePtr children = parent->childs; + factory->details = g_new0(GstElementDetails, 1); + factory->sink_types = NULL; + factory->src_types = NULL; + + while (children) { + if (!strcmp(children->name, "name")) { + factory->name = g_strdup(xmlNodeGetContent(children)); + } + if (!strcmp(children->name, "longname")) { + factory->details->longname = g_strdup(xmlNodeGetContent(children)); + } + if (!strcmp(children->name, "class")) { + factory->details->class = g_strdup(xmlNodeGetContent(children)); + } + if (!strcmp(children->name, "description")) { + factory->details->description = g_strdup(xmlNodeGetContent(children)); + } + if (!strcmp(children->name, "version")) { + factory->details->version = g_strdup(xmlNodeGetContent(children)); + } + if (!strcmp(children->name, "author")) { + factory->details->author = g_strdup(xmlNodeGetContent(children)); + } + if (!strcmp(children->name, "copyright")) { + factory->details->copyright = g_strdup(xmlNodeGetContent(children)); + } + if (!strcmp(children->name, "sources")) { + guint16 typeid = gst_type_load_thyself(children); + + gst_type_add_src(typeid, factory); + } + if (!strcmp(children->name, "sinks")) { + guint16 typeid = gst_type_load_thyself(children); + + gst_type_add_sink(typeid, factory); + } + + children = children->next; + } + + return factory; +} + diff --git a/gst/gstplugin.c b/gst/gstplugin.c index d455ce190b..bcb2f9a774 100644 --- a/gst/gstplugin.c +++ b/gst/gstplugin.c @@ -28,6 +28,8 @@ #include "config.h" +#undef PLUGINS_USE_SRCDIR + /* list of loaded modules and its sequence number */ GList *_gst_modules; gint _gst_modules_seqno; @@ -37,34 +39,49 @@ gint _gst_plugins_seqno; /* list of paths to check for plugins */ GList *_gst_plugin_paths; +GList *_gst_libraries; +gint _gst_libraries_seqno; + /* whether or not to spew library load issues */ gboolean _gst_plugin_spew = FALSE; void _gst_plugin_initialize() { + xmlDocPtr doc; _gst_modules = NULL; _gst_modules_seqno = 0; _gst_plugins = NULL; _gst_plugins_seqno = 0; _gst_plugin_paths = NULL; + _gst_libraries = NULL; + _gst_libraries_seqno = 0; /* add the main (installed) library path */ - _gst_plugin_paths = g_list_prepend(_gst_plugin_paths,PLUGINS_DIR); + _gst_plugin_paths = g_list_append(_gst_plugin_paths,PLUGINS_DIR); /* if this is set, we add build-directory paths to the list */ #ifdef PLUGINS_USE_SRCDIR /* the catch-all plugins directory */ - _gst_plugin_paths = g_list_prepend(_gst_plugin_paths, + _gst_plugin_paths = g_list_append(_gst_plugin_paths, PLUGINS_SRCDIR "/plugins"); /* the libreary directory */ - _gst_plugin_paths = g_list_prepend(_gst_plugin_paths, + _gst_plugin_paths = g_list_append(_gst_plugin_paths, PLUGINS_SRCDIR "/libs"); /* location libgstelements.so */ - _gst_plugin_paths = g_list_prepend(_gst_plugin_paths, + _gst_plugin_paths = g_list_append(_gst_plugin_paths, PLUGINS_SRCDIR "/gst/elements"); - _gst_plugin_paths = g_list_prepend(_gst_plugin_paths, + _gst_plugin_paths = g_list_append(_gst_plugin_paths, PLUGINS_SRCDIR "/gst/types"); #endif /* PLUGINS_USE_SRCDIR */ + + doc = xmlParseFile("/etc/gstreamer/reg.xml"); + + if (!doc || strcmp(doc->root->name, "GST-PluginRegistry")) { + g_print("gstplugin: registry needs rebuild\n"); + gst_plugin_load_all(); + return; + } + gst_plugin_load_thyself(doc->root); } static gboolean gst_plugin_load_recurse(gchar *directory,gchar *name) { @@ -128,8 +145,23 @@ void gst_plugin_load_all() { * Returns: whether the library was loaded or not */ gboolean gst_library_load(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 - return gst_plugin_load(name); + res = gst_plugin_load(name); + + if (res) { + _gst_libraries = g_list_prepend(_gst_libraries, name); + } + + return res; } /** @@ -145,7 +177,7 @@ gboolean gst_plugin_load(gchar *name) { GList *path; gchar *libspath; -// g_print("attempting to load plugin '%s'\n",name); + //g_print("attempting to load plugin '%s'\n",name); path = _gst_plugin_paths; while (path != NULL) { @@ -177,20 +209,35 @@ gboolean gst_plugin_load_absolute(gchar *name) { GModule *module; GstPluginInitFunc initfunc; GstPlugin *plugin; + GList *plugins; - //g_print("trying to absolute load '%s\n",name); if (g_module_supported() == FALSE) { - g_print("wow, you built this on a platform without dynamic loading???\n"); + g_print("gstplugin: wow, you built this on a platform without dynamic loading???\n"); return FALSE; } + plugins = _gst_plugins; + + while (plugins) { + plugin = (GstPlugin *)plugins->data; + + if (!strcmp(plugin->filename, name) && plugin->loaded) { + _gst_plugins = g_list_append(_gst_plugins,plugin); + return TRUE; + } + plugins = g_list_next(plugins); + } + //g_print("trying to absolute load '%s\n",name); + module = g_module_open(name,G_MODULE_BIND_LAZY); if (module != NULL) { if (g_module_symbol(module,"plugin_init",(gpointer *)&initfunc)) { if ((plugin = (initfunc)(module))) { GList *factories; + g_print("gstplugin: plugin %s loaded\n", plugin->name); plugin->filename = g_strdup(name); + plugin->loaded = TRUE; _gst_modules = g_list_append(_gst_modules,module); _gst_modules_seqno++; _gst_plugins = g_list_append(_gst_plugins,plugin); @@ -203,7 +250,7 @@ gboolean gst_plugin_load_absolute(gchar *name) { return TRUE; } } - return TRUE; + return TRUE; } else if (_gst_plugin_spew) { // if (strstr(g_module_error(),"No such") == NULL) gst_info("error loading plugin: %s\n",g_module_error()); @@ -227,6 +274,7 @@ GstPlugin *gst_plugin_new(gchar *name) { plugin->longname = NULL; plugin->types = NULL; plugin->elements = NULL; + plugin->loaded = FALSE; return plugin; } @@ -253,7 +301,7 @@ void gst_plugin_set_longname(GstPlugin *plugin,gchar *longname) { * * Returns: pointer to the #GstPlugin if found, NULL otherwise */ -GstPlugin *gst_plugin_find(gchar *name) { +GstPlugin *gst_plugin_find(const gchar *name) { GList *plugins = _gst_plugins; g_return_val_if_fail(name != NULL, NULL); @@ -262,8 +310,9 @@ GstPlugin *gst_plugin_find(gchar *name) { GstPlugin *plugin = (GstPlugin *)plugins->data; // g_print("plugin name is '%s'\n",plugin->name); if (plugin->name) { - if (!strcmp(plugin->name,name)) + if (!strcmp(plugin->name,name)) { return plugin; + } } plugins = g_list_next(plugins); } @@ -289,7 +338,7 @@ GstElementFactory *gst_plugin_find_elementfactory(gchar *name) { factories = ((GstPlugin *)(plugins->data))->elements; while (factories) { factory = (GstElementFactory*)(factories->data); - if (!strcmp(gst_element_get_name(GST_ELEMENT(factory)),name)) + if (!strcmp(factory->name,name)) return (GstElementFactory*)(factory); factories = g_list_next(factories); } @@ -299,6 +348,69 @@ GstElementFactory *gst_plugin_find_elementfactory(gchar *name) { return NULL; } +GstElementFactory *gst_plugin_load_elementfactory(gchar *name) { + GList *plugins, *factories; + GstElementFactory *factory = NULL; + GstPlugin *plugin; + + g_return_val_if_fail(name != NULL, NULL); + + plugins = _gst_plugins; + while (plugins) { + plugin = (GstPlugin *)plugins->data; + factories = plugin->elements; + while (factories) { + factory = (GstElementFactory*)(factories->data); + if (!strcmp(factory->name,name)) { + if (!plugin->loaded) { + g_print("gstplugin: loading element factory %s from plugin %s\n", name, plugin->name); + _gst_plugins = g_list_remove(_gst_plugins, plugin); + if (!gst_plugin_load_absolute(plugin->filename)) { + g_print("gstplugin: error loading element factory %s from plugin %s\n", name, plugin->name); + } + factory = gst_plugin_find_elementfactory(factory->name); + } + return factory; + } + factories = g_list_next(factories); + } + plugins = g_list_next(plugins); + } + + return factory; +} + +void gst_plugin_load_typefactory(gchar *mime) { + GList *plugins, *factories; + GstTypeFactory *factory; + GstPlugin *plugin; + + g_return_if_fail(mime != NULL); + + plugins = _gst_plugins; + while (plugins) { + plugin = (GstPlugin *)plugins->data; + factories = plugin->types; + while (factories) { + factory = (GstTypeFactory*)(factories->data); + if (!strcmp(factory->mime,mime)) { + if (!plugin->loaded) { + g_print("gstplugin: loading type factory for \"%s\" from plugin %s\n", mime, plugin->name); + _gst_plugins = g_list_remove(_gst_plugins, plugin); + if (!gst_plugin_load_absolute(plugin->filename)) { + g_print("gstplugin: error loading type factory \"%s\" from plugin %s\n", mime, plugin->name); + } + } + return; + } + factories = g_list_next(factories); + } + plugins = g_list_next(plugins); + } + + return; +} + /** * gst_plugin_add_factory: * @plugin: plugin to add factory to @@ -314,6 +426,14 @@ void gst_plugin_add_factory(GstPlugin *plugin,GstElementFactory *factory) { plugin->elements = g_list_append(plugin->elements,factory); } +void gst_plugin_add_type(GstPlugin *plugin,GstTypeFactory *factory) { + g_return_if_fail(plugin != NULL); + g_return_if_fail(factory != NULL); + +// g_print("adding factory to plugin\n"); + plugin->types = g_list_append(plugin->types,factory); +} + /** * gst_plugin_get_list: * @@ -324,3 +444,97 @@ void gst_plugin_add_factory(GstPlugin *plugin,GstElementFactory *factory) { GList *gst_plugin_get_list() { return _gst_plugins; } + +xmlNodePtr gst_plugin_save_thyself(xmlNodePtr parent) { + xmlNodePtr tree, subtree; + GList *plugins = NULL, *elements = NULL, *types = NULL; + + plugins = gst_plugin_get_list(); + while (plugins) { + GstPlugin *plugin = (GstPlugin *)plugins->data; + tree = xmlNewChild(parent,NULL,"plugin",NULL); + xmlNewChild(tree,NULL,"name",plugin->name); + xmlNewChild(tree,NULL,"longname",plugin->longname); + xmlNewChild(tree,NULL,"filename",plugin->filename); + types = plugin->types; + while (types) { + GstTypeFactory *factory = (GstTypeFactory *)types->data; + subtree = xmlNewChild(tree,NULL,"type",NULL); + + gst_typefactory_save_thyself(factory, subtree); + + types = g_list_next(types); + } + elements = plugin->elements; + while (elements) { + GstElementFactory *factory = (GstElementFactory *)elements->data; + subtree = xmlNewChild(tree,NULL,"element",NULL); + + gst_elementfactory_save_thyself(factory, subtree); + + elements = g_list_next(elements); + } + plugins = g_list_next(plugins); + } + return parent; +} + +void gst_plugin_load_thyself(xmlNodePtr parent) { + xmlNodePtr kinderen; + gint elementcount = 0; + gint typecount = 0; + + kinderen = parent->childs; // Dutch invasion :-) + while (kinderen) { + if (!strcmp(kinderen->name, "plugin")) { + xmlNodePtr field = kinderen->childs; + GstPlugin *plugin = (GstPlugin *)g_malloc(sizeof(GstPlugin)); + plugin->elements = NULL; + plugin->types = NULL; + plugin->loaded = FALSE; + + while (field) { + if (!strcmp(field->name, "name")) { + if (gst_plugin_find(xmlNodeGetContent(field))) { + g_free(plugin); + plugin = NULL; + break; + } + else { + plugin->name = g_strdup(xmlNodeGetContent(field)); + } + } + else if (!strcmp(field->name, "longname")) { + plugin->longname = g_strdup(xmlNodeGetContent(field)); + } + else if (!strcmp(field->name, "filename")) { + plugin->filename = g_strdup(xmlNodeGetContent(field)); + } + else if (!strcmp(field->name, "element")) { + GstElementFactory *factory = gst_elementfactory_load_thyself(field); + plugin->elements = g_list_prepend(plugin->elements, factory); + elementcount++; + } + else if (!strcmp(field->name, "type")) { + GstTypeFactory *factory = gst_typefactory_load_thyself(field); + guint16 typeid = gst_type_find_by_mime(factory->mime); + if (!typeid) { + typeid = gst_type_register(factory); + } + plugin->types = g_list_prepend(plugin->types, factory); + typecount++; + } + + field = field->next; + } + + if (plugin) { + _gst_plugins = g_list_prepend(_gst_plugins, plugin); + } + } + + kinderen = kinderen->next; + } + g_print("gstplugin: added %d registered factories and %d types\n", elementcount, typecount); +} + diff --git a/gst/gstplugin.h b/gst/gstplugin.h index 337b8927d2..8d5bc78758 100644 --- a/gst/gstplugin.h +++ b/gst/gstplugin.h @@ -37,7 +37,8 @@ struct _GstPlugin { GList *types; /* list of types provided */ GList *elements; /* list of elements provided */ - GList *identifiers; /* list of identifiers */ + + gboolean loaded; /* if the plugin is in memory */ }; @@ -53,9 +54,16 @@ gboolean gst_library_load(gchar *name); gboolean gst_plugin_load_absolute(gchar *name); void gst_plugin_add_factory(GstPlugin *plugin,GstElementFactory *factory); +void gst_plugin_add_type(GstPlugin *plugin,GstTypeFactory *factory); -GstPlugin *gst_plugin_find(gchar *name); +GstPlugin *gst_plugin_find(const gchar *name); GList *gst_plugin_get_list(); GstElementFactory *gst_plugin_find_elementfactory(gchar *name); +GstElementFactory *gst_plugin_load_elementfactory(gchar *name); +void gst_plugin_load_typefactory(gchar *mime); + +xmlNodePtr gst_plugin_save_thyself(xmlNodePtr parent); +void gst_plugin_load_thyself(xmlNodePtr parent); + #endif /* __GST_PLUGIN_H__ */ diff --git a/gst/gsttype.c b/gst/gsttype.c index 29c1dbf782..d12ab42f57 100644 --- a/gst/gsttype.c +++ b/gst/gsttype.c @@ -43,6 +43,8 @@ struct _gst_type_node }; typedef struct _gst_type_node gst_type_node; +static gboolean gst_type_typefind_dummy(GstBuffer *buffer, gpointer priv); + /* we keep a (spase) matrix in the hashtable like: * * type_id list of factories hashed by src type_id @@ -58,6 +60,7 @@ typedef struct _gst_type_node gst_type_node; **/ void _gst_type_initialize() { + _gst_types = NULL; _gst_maxtype = 1; /* type 0 is undefined */ @@ -70,10 +73,9 @@ guint16 gst_type_register(GstTypeFactory *factory) { g_return_val_if_fail(factory != NULL, 0); -// id = gst_type_find_by_mime(factory->mime); - id = 0; + id = gst_type_find_by_mime(factory->mime); if (!id) { - type = (GstType *)g_malloc(sizeof(GstType)); + type = g_new0(GstType, 1); type->id = _gst_maxtype++; type->mime = factory->mime; @@ -85,6 +87,7 @@ guint16 gst_type_register(GstTypeFactory *factory) { _gst_types = g_list_prepend(_gst_types,type); id = type->id; + } else { type = gst_type_find_by_id(id); /* now we want to try to merge the types and return the original */ @@ -92,19 +95,22 @@ guint16 gst_type_register(GstTypeFactory *factory) { /* FIXME: do extension merging here, not that easy */ /* if there is no existing typefind function, try to use new one */ - if (!type->typefindfunc && factory->typefindfunc) + if ((type->typefindfunc == gst_type_typefind_dummy || + type->typefindfunc == NULL) && factory->typefindfunc) type->typefindfunc = factory->typefindfunc; } return id; } -guint16 gst_type_find_by_mime(gchar *mime) { - GList *walk = _gst_types; +static guint16 gst_type_find_by_mime_func(gchar *mime) { + GList *walk; GstType *type; gint typelen,mimelen; gchar *search, *found; + + walk = _gst_types; // DEBUG("searching for '%s'\n",mime); mimelen = strlen(mime); while (walk) { @@ -132,6 +138,18 @@ guint16 gst_type_find_by_mime(gchar *mime) { return 0; } +guint16 gst_type_find_by_mime(gchar *mime) { + guint16 typeid; + + typeid = gst_type_find_by_mime_func(mime); + + if (!typeid) { + gst_plugin_load_typefactory(mime); + } + + return gst_type_find_by_mime_func(mime); +} + GstType *gst_type_find_by_id(guint16 id) { GList *walk = _gst_types; GstType *type; @@ -150,7 +168,7 @@ static void gst_type_dump_converter(gpointer key, gpointer value, gpointer data) GList *walk = (GList *)value; GstElementFactory *factory; - g_print("%u, (", GPOINTER_TO_UINT(key)); + g_print("gsttype: %u, (", GPOINTER_TO_UINT(key)); while (walk) { factory = (GstElementFactory *) walk->data; @@ -304,6 +322,7 @@ static GList *construct_path (gst_type_node *rgnNodes, gint chNode) GstType *type; GList *converters; + g_print("gsttype: constructed pad "); while (current != MAX_COST) { type = gst_type_find_by_id(current); @@ -323,6 +342,7 @@ static guint gst_type_find_cost(gint src, gint dest) { GList *converters = (GList *)g_hash_table_lookup(type->converters, GUINT_TO_POINTER(dest)); + // FIXME do something very clever here... if (converters) return 1; return MAX_COST; } @@ -374,3 +394,95 @@ GList *gst_type_get_sink_to_src(guint16 sinkid, guint16 srcid) { GList *gst_type_get_list() { return _gst_types; } + +xmlNodePtr gst_type_save_thyself(GstType *type, xmlNodePtr parent) { + xmlNodePtr tree; + + tree = xmlNewChild(parent, NULL, "type", NULL); + + xmlNewChild(tree, NULL, "mime", type->mime); + + return tree; +} + +guint16 gst_type_load_thyself(xmlNodePtr parent) { + xmlNodePtr children = parent->childs; + guint16 typeid = 0; + + while (children) { + if (!strcmp(children->name, "type")) { + xmlNodePtr field = children->childs; + while (field) { + if (!strcmp(field->name, "mime")) { + typeid = gst_type_find_by_mime(xmlNodeGetContent(field)); + if (!typeid) { + GstTypeFactory *factory = g_new0(GstTypeFactory, 1); + + factory->mime = g_strdup(xmlNodeGetContent(field)); + typeid = gst_type_register(factory); + } + return typeid; + } + field = field->next; + } + } + children = children->next; + } + + return typeid; +} + + +xmlNodePtr gst_typefactory_save_thyself(GstTypeFactory *factory, xmlNodePtr 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; +} + +static gboolean gst_type_typefind_dummy(GstBuffer *buffer, gpointer priv) +{ + GstType *type = (GstType *)priv; + guint16 typeid; + g_print("gsttype: need to load typefind function\n"); + + type->typefindfunc = NULL; + gst_plugin_load_typefactory(type->mime); + typeid = gst_type_find_by_mime(type->mime); + type = gst_type_find_by_id(typeid); + + if (type->typefindfunc) { + return type->typefindfunc(buffer, type); + } + + return FALSE; +} + +GstTypeFactory *gst_typefactory_load_thyself(xmlNodePtr parent) { + + GstTypeFactory *factory = g_new0(GstTypeFactory, 1); + xmlNodePtr field = parent->childs; + factory->typefindfunc = NULL; + + while (field) { + if (!strcmp(field->name, "mime")) { + factory->mime = g_strdup(xmlNodeGetContent(field)); + } + else if (!strcmp(field->name, "extensions")) { + factory->exts = g_strdup(xmlNodeGetContent(field)); + } + else if (!strcmp(field->name, "typefind")) { + factory->typefindfunc = gst_type_typefind_dummy; + } + field = field->next; + } + + return factory; +} + diff --git a/gst/gsttype.h b/gst/gsttype.h index e8cdb593f4..2a89a21719 100644 --- a/gst/gsttype.h +++ b/gst/gsttype.h @@ -27,7 +27,7 @@ /* type of function used to check a stream for equality with type */ -typedef gboolean (*GstTypeFindFunc) (GstBuffer *buf,gpointer *priv); +typedef gboolean (*GstTypeFindFunc) (GstBuffer *buf,gpointer priv); typedef struct _GstType GstType; typedef struct _GstTypeFactory GstTypeFactory; @@ -81,4 +81,11 @@ GList *gst_type_get_sink_to_src(guint16 sinkid, guint16 srcid); GList *gst_type_get_list(); void gst_type_dump(); + +xmlNodePtr gst_type_save_thyself(GstType *type, xmlNodePtr parent); +guint16 gst_type_load_thyself(xmlNodePtr parent); + +xmlNodePtr gst_typefactory_save_thyself(GstTypeFactory *factory, xmlNodePtr parent); +GstTypeFactory *gst_typefactory_load_thyself(xmlNodePtr parent); + #endif /* __GST_TYPE_H__ */ diff --git a/gst/types/gsttypes.c b/gst/types/gsttypes.c index ee377c7ad4..1755c121e7 100644 --- a/gst/types/gsttypes.c +++ b/gst/types/gsttypes.c @@ -24,7 +24,6 @@ GstTypeFactory _factories[] = { { "audio/raw", ".raw", NULL }, - { "audio/ac3", ".ac3", NULL }, { "video/raw image/raw", ".raw", NULL }, { NULL, NULL, NULL }, }; @@ -42,6 +41,7 @@ GstPlugin *plugin_init(GModule *module) { while (_factories[i].mime) { gst_type_register(&_factories[i]); + gst_plugin_add_type(plugin, &_factories[i]); // DEBUG("added factory #%d '%s'\n",i,_factories[i].mime); i++; } diff --git a/gstplay/gstplay.c b/gstplay/gstplay.c index 834d0160a0..3d3ba93f75 100644 --- a/gstplay/gstplay.c +++ b/gstplay/gstplay.c @@ -315,6 +315,7 @@ main (int argc, char *argv[]) glade_init(); glade_gnome_init(); gst_init(&argc,&argv); + //gst_plugin_load_all(); g_print("using %s\n", DATADIR"gstplay.glade"); /* load the interface */ @@ -367,13 +368,6 @@ main (int argc, char *argv[]) glade_xml_signal_autoconnect(xml); - gst_plugin_load("mpeg1parse"); - gst_plugin_load("mpeg2parse"); - gst_plugin_load("mp1videoparse"); - gst_plugin_load("mp3parse"); - gst_plugin_load("parsewav"); - gst_plugin_load("parseavi"); - video_render_queue = gst_elementfactory_make("queue","video_render_queue"); gtk_object_set(GTK_OBJECT(video_render_queue),"max_level",BUFFER,NULL); gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(video_render_queue)); diff --git a/tests/old/examples/helloworld2/helloworld2.c b/tests/old/examples/helloworld2/helloworld2.c index e2a0ab7ef1..42a194a673 100644 --- a/tests/old/examples/helloworld2/helloworld2.c +++ b/tests/old/examples/helloworld2/helloworld2.c @@ -21,20 +21,21 @@ int main(int argc,char *argv[]) } gst_init(&argc,&argv); - gst_plugin_load_all(); - g_print("\n"); /* create a new bin to hold the elements */ pipeline = gst_pipeline_new("pipeline"); + g_assert(pipeline != NULL); /* create a disk reader */ disksrc = gst_elementfactory_make("disksrc", "disk_source"); + g_assert(disksrc != NULL); gtk_object_set(GTK_OBJECT(disksrc),"location", argv[1],NULL); gtk_signal_connect(GTK_OBJECT(disksrc),"eos", GTK_SIGNAL_FUNC(eos),NULL); /* and an audio sink */ audiosink = gst_elementfactory_make("audiosink", "play_audio"); + g_assert(audiosink != NULL); /* add objects to the main pipeline */ gst_bin_add(GST_BIN(pipeline), disksrc); diff --git a/tools/.gitignore b/tools/.gitignore index 99f8e62c92..b5ae73baf9 100644 --- a/tools/.gitignore +++ b/tools/.gitignore @@ -6,5 +6,6 @@ Makefile.in .deps .libs -launch +gstreamer-launch +gstreamer-register *.xml diff --git a/tools/Makefile.am b/tools/Makefile.am index d79c8bf84a..0701fa5897 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -1,4 +1,6 @@ -bin_PROGRAMS = launch +bin_PROGRAMS = gstreamer-launch gstreamer-register + +CFLAGS = -Wall -O2 LDADD = $(GLIB_LIBS) $(GTK_LIBS) $(top_builddir)/gst/libgst.la INCLUDES = $(GLIB_CFLAGS) $(GTK_CFLAGS) -I$(top_srcdir) diff --git a/tools/launch.c b/tools/gstreamer-launch.c similarity index 92% rename from tools/launch.c rename to tools/gstreamer-launch.c index cbec8e30dd..fb5e8c4931 100644 --- a/tools/launch.c +++ b/tools/gstreamer-launch.c @@ -1,5 +1,7 @@ #include #include +#include +#include typedef struct _launch_delayed_pad launch_delayed_pad; struct _launch_delayed_pad { @@ -17,11 +19,11 @@ void launch_newpad(GstElement *element,GstPad *pad,launch_delayed_pad *peer) { } } -gint parse(int argc,char *argv[],GstElement *parent,gint offset,gchar endchar) { +void parse(int argc,char *argv[],GstElement *parent,gint offset,gchar endchar) { gint i = offset; gchar *plugin; - GstElement *element, *prevelement; - GstPad *prevpad,*nextpad; + GstElement *element = NULL, *prevelement; + GstPad *prevpad = NULL,*nextpad; gchar *prevpadname = NULL,*nextpadname = NULL; gchar *ptr; gint len; @@ -64,7 +66,7 @@ gint parse(int argc,char *argv[],GstElement *parent,gint offset,gchar endchar) { // snag the length in advance; len = strlen(argv[i]); // if it's just a connection, pick the 'src' pad and move on - if (ptr = strchr(argv[i],'|')) { + if ((ptr = strchr(argv[i],'|')) != 0) { // if there's a previous pad name if (ptr != argv[i]) { ptr[0] = '\0'; @@ -98,7 +100,7 @@ int main(int argc,char *argv[]) { gst_info("\n\n"); pipeline = gst_elementfactory_make("thread","launch"); - if (t = atoi(argv[1])) + if ((t = atoi(argv[1]))) parse(argc,argv,pipeline,2,0); else parse(argc,argv,pipeline,1,0); @@ -112,4 +114,6 @@ int main(int argc,char *argv[]) { sleep(t); else sleep(5); + + return 1; } diff --git a/tools/gstreamer-register.c b/tools/gstreamer-register.c new file mode 100644 index 0000000000..4dfd703f26 --- /dev/null +++ b/tools/gstreamer-register.c @@ -0,0 +1,18 @@ +#include + +int main(int argc,char *argv[]) +{ + xmlDocPtr doc; + + unlink("/etc/gstreamer/reg.xml"); + + gst_init(&argc,&argv); + gst_plugin_load_all(); + + doc = xmlNewDoc("1.0"); + doc->root = xmlNewDocNode(doc, NULL, "GST-PluginRegistry", NULL); + gst_plugin_save_thyself(doc->root); + xmlSaveFile("/etc/gstreamer/reg.xml", doc); + exit(0); +} +