From 12bbbd5c1e5461be6f747c9811322a70247748a5 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 21 Aug 2001 20:16:48 +0000 Subject: [PATCH] Lots of modifications to the plugin system. Original commit message from CVS: Lots of modifications to the plugin system. - Added a GstPluginfeature object that serves as a base class for all plugin contents. - changed the plugin API, everyhting is now added with gst_plugin_add_feature - typefactories are named now so that they can be located easily and filled in at plugin load. - mime types like "video/raw image/raw" are gone for now. - lots of plugin updates (style and API changes) - tested with an without registry. - updates to various tools. - added a little testsuite to test/show how you can load plugins (4 modes) Test this one, Almost everything has changed :-) --- configure.base | 2 + editor/gsteditorcreate.c | 2 +- editor/gsteditorproperty.c | 2 +- editor/gstelementselect.c | 8 +- examples/plugins/example.c | 37 +- gst/Makefile.am | 2 + gst/autoplug/gstautoplugcache.c | 2 +- gst/autoplug/gstautoplugger.c | 2 +- gst/autoplug/gststaticautoplug.c | 18 +- gst/autoplug/gststaticautoplugrender.c | 20 +- gst/elements/gstelements.c | 2 +- gst/gst.c | 6 +- gst/gstautoplug.c | 129 ++-- gst/gstautoplug.h | 41 +- gst/gstcaps.c | 14 +- gst/gstelement.c | 25 +- gst/gstelement.h | 72 +- gst/gstelementfactory.c | 181 ++++-- gst/gstobject.c | 47 +- gst/gstobject.h | 7 +- gst/gstplugin.c | 723 ++++++++------------- gst/gstplugin.h | 77 ++- gst/gstpluginfeature.c | 133 ++++ gst/gstpluginfeature.h | 72 ++ gst/gstqueue.c | 34 +- gst/gsttype.c | 202 ++++-- gst/gsttype.h | 53 +- gst/gsttypefind.c | 29 +- gst/types/gsttypes.c | 18 +- plugins/elements/gstelements.c | 2 +- plugins/elements/gstqueue.c | 34 +- test/xml/createreg.c | 45 +- tests/caps.c | 2 +- tests/old/examples/plugins/example.c | 37 +- tests/old/testsuite/Makefile.am | 2 +- tests/old/testsuite/plugin/.gitignore | 13 + tests/old/testsuite/plugin/Makefile.am | 20 + tests/old/testsuite/plugin/README | 59 ++ tests/old/testsuite/plugin/dynamic.c | 23 + tests/old/testsuite/plugin/linked.c | 22 + tests/old/testsuite/plugin/loading.c | 54 ++ tests/old/testsuite/plugin/registry.c | 17 + tests/old/testsuite/plugin/static.c | 23 + tests/old/testsuite/plugin/static2.c | 50 ++ tests/old/testsuite/plugin/testplugin.c | 15 + tests/old/testsuite/plugin/testplugin2.c | 15 + tests/old/testsuite/plugin/testplugin2_s.c | 3 + tests/old/testsuite/plugin/testplugin_s.c | 3 + tests/registry.c | 4 +- testsuite/Makefile.am | 2 +- testsuite/plugin/.gitignore | 13 + testsuite/plugin/Makefile.am | 20 + testsuite/plugin/README | 59 ++ testsuite/plugin/dynamic.c | 23 + testsuite/plugin/linked.c | 22 + testsuite/plugin/loading.c | 54 ++ testsuite/plugin/registry.c | 17 + testsuite/plugin/static.c | 23 + testsuite/plugin/static2.c | 50 ++ testsuite/plugin/testplugin.c | 15 + testsuite/plugin/testplugin2.c | 15 + testsuite/plugin/testplugin2_s.c | 3 + testsuite/plugin/testplugin_s.c | 3 + tools/Makefile.am | 14 +- tools/gstreamer-compprep.c | 27 +- tools/gstreamer-inspect.c | 124 ++-- 66 files changed, 1938 insertions(+), 949 deletions(-) create mode 100644 gst/gstpluginfeature.c create mode 100644 gst/gstpluginfeature.h create mode 100644 tests/old/testsuite/plugin/.gitignore create mode 100644 tests/old/testsuite/plugin/Makefile.am create mode 100644 tests/old/testsuite/plugin/README create mode 100644 tests/old/testsuite/plugin/dynamic.c create mode 100644 tests/old/testsuite/plugin/linked.c create mode 100644 tests/old/testsuite/plugin/loading.c create mode 100644 tests/old/testsuite/plugin/registry.c create mode 100644 tests/old/testsuite/plugin/static.c create mode 100644 tests/old/testsuite/plugin/static2.c create mode 100644 tests/old/testsuite/plugin/testplugin.c create mode 100644 tests/old/testsuite/plugin/testplugin2.c create mode 100644 tests/old/testsuite/plugin/testplugin2_s.c create mode 100644 tests/old/testsuite/plugin/testplugin_s.c create mode 100644 testsuite/plugin/.gitignore create mode 100644 testsuite/plugin/Makefile.am create mode 100644 testsuite/plugin/README create mode 100644 testsuite/plugin/dynamic.c create mode 100644 testsuite/plugin/linked.c create mode 100644 testsuite/plugin/loading.c create mode 100644 testsuite/plugin/registry.c create mode 100644 testsuite/plugin/static.c create mode 100644 testsuite/plugin/static2.c create mode 100644 testsuite/plugin/testplugin.c create mode 100644 testsuite/plugin/testplugin2.c create mode 100644 testsuite/plugin/testplugin2_s.c create mode 100644 testsuite/plugin/testplugin_s.c diff --git a/configure.base b/configure.base index dda0f899f1..f3897b8636 100644 --- a/configure.base +++ b/configure.base @@ -841,6 +841,7 @@ GST_SUBSYSTEM_DISABLE(TYPEFIND,[typefind plugin],) GST_SUBSYSTEM_DISABLE(AUTOPLUG,[autoplugger subsystem]) GST_SUBSYSTEM_DISABLE(PARSE,[command-line parser]) GST_SUBSYSTEM_DISABLE(TRACE,[tracing subsystem]) +GST_SUBSYSTEM_DISABLE(REGISTRY,[plugin registry]) GST_DEFINE_CFLAGS="$GST_DEFINE_CFLAGS $GST_SUBSYSTEM_DISABLE_DEFINES" @@ -1224,6 +1225,7 @@ tests/muxing/Makefile testsuite/Makefile testsuite/capsnego/Makefile testsuite/refcounting/Makefile +testsuite/plugin/Makefile tests/nego/Makefile examples/Makefile examples/autoplug/Makefile diff --git a/editor/gsteditorcreate.c b/editor/gsteditorcreate.c index 8d8b29b384..9c6950ee37 100644 --- a/editor/gsteditorcreate.c +++ b/editor/gsteditorcreate.c @@ -36,7 +36,7 @@ gst_editor_create_item(gdouble x,gdouble y) factory = element_select_dialog(); if (factory) { // g_print("got factory \"%s\"\n",factory->name); - element = gst_elementfactory_create(factory,factory->name); + element = gst_elementfactory_create(factory, GST_OBJECT_NAME (factory)); if (element) { if (GST_IS_BIN(element)) { // g_print("factory is a bin\n"); diff --git a/editor/gsteditorproperty.c b/editor/gsteditorproperty.c index 64c070f73f..5ccb5a685f 100644 --- a/editor/gsteditorproperty.c +++ b/editor/gsteditorproperty.c @@ -479,7 +479,7 @@ gst_editor_property_create (GstEditorProperty *property, GstEditorElement *eleme gtk_widget_show(entry); gtk_entry_set_editable(GTK_ENTRY(entry), FALSE); gtk_entry_set_text(GTK_ENTRY(entry), - gst_element_get_factory(element->element)->name); + gst_object_get_name (GST_OBJECT (gst_element_get_factory(element->element)))); gtk_table_attach(GTK_TABLE(table), label, 0, 1, count, count+1, GTK_FILL, 0, 0, 0); gtk_table_attach(GTK_TABLE(table), entry, 1, 2, count, count+1, GTK_FILL|GTK_EXPAND, 0, 0, 0); count++; diff --git a/editor/gstelementselect.c b/editor/gstelementselect.c index a137f5a39b..74edcecf63 100644 --- a/editor/gstelementselect.c +++ b/editor/gstelementselect.c @@ -33,8 +33,8 @@ struct element_select_details { }; static gint compare_name(gconstpointer a,gconstpointer b) { - return (strcmp(((GstElementFactory *)a)->name, - ((GstElementFactory *)b)->name)); + return (strcmp(GST_OBJECT_NAME (a), + GST_OBJECT_NAME (b))); } gint str_compare(gconstpointer a,gconstpointer b) { @@ -64,7 +64,7 @@ static void make_ctree(GtkCTree *tree,GtkCTreeNode *parent, traverse = class->factories; while (traverse) { GstElementFactory *factory = (GstElementFactory *)(traverse->data); - data[0] = g_strdup(factory->name); + data[0] = g_strdup(GST_OBJECT_NAME (factory)); data[1] = g_strdup(factory->details->description); node = gtk_ctree_insert_node(tree,classnode,NULL,data,0, NULL,NULL,NULL,NULL,TRUE,FALSE); @@ -200,7 +200,7 @@ GstElementFactory *element_select_dialog() { elements = gst_elementfactory_get_list(); while (elements) { element = (GstElementFactory *)(elements->data); - printf("%s %s\n", element->name, element->details->klass); + printf("%s %s\n", GST_OBJECT_NAME (element), element->details->klass); /* split up the factory's class */ classes = g_strsplit(element->details->klass,"/",0); class = classes; diff --git a/examples/plugins/example.c b/examples/plugins/example.c index 351f9fcfc2..1783a82eba 100644 --- a/examples/plugins/example.c +++ b/examples/plugins/example.c @@ -87,18 +87,15 @@ GST_PADTEMPLATE_FACTORY (src_factory, /* A number of functon prototypes are given so we can refer to them later. */ -static void gst_example_class_init (GstExampleClass *klass); -static void gst_example_init (GstExample *example); +static void gst_example_class_init (GstExampleClass *klass); +static void gst_example_init (GstExample *example); -static void gst_example_chain (GstPad *pad, GstBuffer *buf); +static void gst_example_chain (GstPad *pad, GstBuffer *buf); -static void gst_example_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); -static void gst_example_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); - -/* These hold the constructed pad templates, which are created during - * plugin load, and used during element instantiation. - */ -static GstPadTemplate *src_template, *sink_template; +static void gst_example_set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec); +static void gst_example_get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec); /* The parent class pointer needs to be kept around for some object * operations. @@ -189,10 +186,10 @@ static void gst_example_init(GstExample *example) { /* First we create the sink pad, which is the input to the element. - * We will use the sink_template constructed in the plugin_init function - * (below) to quickly generate the pad we need. + * We will use the template constructed by the factory. */ - example->sinkpad = gst_pad_new_from_template (sink_template, "sink"); + example->sinkpad = gst_pad_new_from_template ( + GST_PADTEMPLATE_GET (sink_factory), "sink"); /* Setting the chain function allows us to supply the function that will * actually be performing the work. Without this, the element would do * nothing, with undefined results (assertion failures and such). @@ -208,7 +205,8 @@ gst_example_init(GstExample *example) * pads don't have chain functions, because they can't accept buffers, * they only produce them. */ - example->srcpad = gst_pad_new_from_template (src_template, "src"); + example->srcpad = gst_pad_new_from_template ( + GST_PADTEMPLATE_GET (src_factory), "src"); gst_element_add_pad(GST_ELEMENT(example),example->srcpad); /* Initialization of element's private variables. */ @@ -344,17 +342,12 @@ plugin_init (GModule *module, GstPlugin *plugin) /* The pad templates can be easily generated from the factories above, * and then added to the list of padtemplates for the elementfactory. - * Note that the generated padtemplates are stored in static global - * variables, for the gst_example_init function to use later on. */ - sink_template = sink_factory (); - gst_elementfactory_add_padtemplate (factory, sink_template); - - src_template = src_factory (); - gst_elementfactory_add_padtemplate (factory, src_template); + gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (sink_factory)); + gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (src_factory)); /* The very last thing is to register the elementfactory with the plugin. */ - gst_plugin_add_factory (plugin, factory); + gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory)); /* Now we can return successfully. */ return TRUE; diff --git a/gst/Makefile.am b/gst/Makefile.am index 8d3e73debb..2989579513 100644 --- a/gst/Makefile.am +++ b/gst/Makefile.am @@ -72,6 +72,7 @@ libgst_la_SOURCES = \ gstpad.c \ gstpipeline.c \ gstplugin.c \ + gstpluginfeature.c \ gstprops.c \ gstqueue.c \ gstscheduler.c \ @@ -171,6 +172,7 @@ libgstinclude_HEADERS = \ gstpad.h \ gstpipeline.h \ gstplugin.h \ + gstpluginfeature.h \ gstprops.h \ gstqueue.h \ gstscheduler.h \ diff --git a/gst/autoplug/gstautoplugcache.c b/gst/autoplug/gstautoplugcache.c index f1993d3fe1..9f7549ad63 100644 --- a/gst/autoplug/gstautoplugcache.c +++ b/gst/autoplug/gstautoplugcache.c @@ -362,7 +362,7 @@ plugin_init (GModule *module, GstPlugin *plugin) &gst_autoplugcache_details); g_return_val_if_fail (factory != NULL, FALSE); - gst_plugin_add_factory (plugin, factory); + gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory)); return TRUE; } diff --git a/gst/autoplug/gstautoplugger.c b/gst/autoplug/gstautoplugger.c index 2ba800b5bc..68ed930915 100644 --- a/gst/autoplug/gstautoplugger.c +++ b/gst/autoplug/gstautoplugger.c @@ -594,7 +594,7 @@ plugin_init (GModule *module, GstPlugin *plugin) &gst_autoplugger_details); g_return_val_if_fail (factory != NULL, FALSE); - gst_plugin_add_factory (plugin, factory); + gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory)); return TRUE; } diff --git a/gst/autoplug/gststaticautoplug.c b/gst/autoplug/gststaticautoplug.c index 9c92081977..53ac01a278 100644 --- a/gst/autoplug/gststaticautoplug.c +++ b/gst/autoplug/gststaticautoplug.c @@ -93,7 +93,7 @@ plugin_init (GModule *module, GstPlugin *plugin) gst_static_autoplug_get_type ()); if (factory != NULL) { - gst_plugin_add_autoplugger (plugin, factory); + gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory)); } return TRUE; } @@ -125,7 +125,8 @@ gst_autoplug_can_match (GstElementFactory *src, GstElementFactory *dest) if (gst_caps_check_compatibility (gst_padtemplate_get_caps (srctemp), gst_padtemplate_get_caps (desttemp))) { GST_DEBUG (GST_CAT_AUTOPLUG_ATTEMPT, - "factory \"%s\" can connect with factory \"%s\"\n", src->name, dest->name); + "factory \"%s\" can connect with factory \"%s\"\n", GST_OBJECT_NAME (src), + GST_OBJECT_NAME (dest)); return TRUE; } } @@ -135,7 +136,8 @@ gst_autoplug_can_match (GstElementFactory *src, GstElementFactory *dest) srctemps = g_list_next (srctemps); } GST_DEBUG (GST_CAT_AUTOPLUG_ATTEMPT, - "factory \"%s\" cannot connect with factory \"%s\"\n", src->name, dest->name); + "factory \"%s\" cannot connect with factory \"%s\"\n", GST_OBJECT_NAME (src), + GST_OBJECT_NAME (dest)); return FALSE; } @@ -363,9 +365,9 @@ gst_static_autoplug_to_caps (GstAutoplug *autoplug, GstCaps *srccaps, GstCaps *s } } - GST_DEBUG (0,"common factory \"%s\"\n", factory->name); + GST_DEBUG (0,"common factory \"%s\"\n", GST_OBJECT_NAME (factory)); - element = gst_elementfactory_create (factory, factory->name); + element = gst_elementfactory_create (factory, GST_OBJECT_NAME (factory)); gst_bin_add (GST_BIN(result), element); if (srcelement != NULL) { @@ -415,8 +417,8 @@ differ: factory = (GstElementFactory *)(factories[i]->data); - GST_DEBUG (0,"factory \"%s\"\n", factory->name); - element = gst_elementfactory_create(factory, factory->name); + GST_DEBUG (0,"factory \"%s\"\n", GST_OBJECT_NAME (factory)); + element = gst_elementfactory_create(factory, GST_OBJECT_NAME (factory)); GST_DEBUG (0,"adding element %s\n", GST_ELEMENT_NAME (element)); gst_bin_add(GST_BIN(thebin), element); @@ -513,7 +515,7 @@ construct_path (gst_autoplug_node *rgnNodes, gpointer factory) next = rgnNodes[find_factory(rgnNodes, current)].iPrev; if (next) { factories = g_list_prepend (factories, current); - GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"factory: \"%s\"", current->name); + GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"factory: \"%s\"", GST_OBJECT_NAME (current)); } current = next; } diff --git a/gst/autoplug/gststaticautoplugrender.c b/gst/autoplug/gststaticautoplugrender.c index b38cfe7988..94b5295ffd 100644 --- a/gst/autoplug/gststaticautoplugrender.c +++ b/gst/autoplug/gststaticautoplugrender.c @@ -93,7 +93,7 @@ plugin_init (GModule *module, GstPlugin *plugin) gst_static_autoplug_render_get_type ()); if (factory != NULL) { - gst_plugin_add_autoplugger (plugin, factory); + gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory)); } return TRUE; } @@ -151,7 +151,8 @@ 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_PADTEMPLATE_CAPS (srctemp), GST_PADTEMPLATE_CAPS (desttemp))) { GST_DEBUG (GST_CAT_AUTOPLUG_ATTEMPT, - "factory \"%s\" can connect with factory \"%s\"\n", src->name, dest->name); + "factory \"%s\" can connect with factory \"%s\"\n", + GST_OBJECT_NAME (src), GST_OBJECT_NAME (dest)); return TRUE; } } @@ -159,7 +160,8 @@ gst_autoplug_can_match (GstElementFactory *src, GstElementFactory *dest) } } GST_DEBUG (GST_CAT_AUTOPLUG_ATTEMPT, - "factory \"%s\" cannot connect with factory \"%s\"\n", src->name, dest->name); + "factory \"%s\" cannot connect with factory \"%s\"\n", + GST_OBJECT_NAME (src), GST_OBJECT_NAME (dest)); return FALSE; } @@ -283,7 +285,7 @@ gst_autoplug_caps_find_cost (gpointer src, gpointer dest, gpointer data) else { res = gst_autoplug_can_match ((GstElementFactory *)src, (GstElementFactory *)dest); GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"factory %s to factory %s %d", - ((GstElementFactory *)src)->name, ((GstElementFactory *)dest)->name, res); + GST_OBJECT_NAME (src), GST_OBJECT_NAME (dest), res); } if (res) @@ -394,9 +396,9 @@ next: } } - GST_DEBUG (0,"common factory \"%s\"\n", factory->name); + GST_DEBUG (0,"common factory \"%s\"\n", GST_OBJECT_NAME (factory)); - element = gst_elementfactory_create (factory, factory->name); + element = gst_elementfactory_create (factory, GST_OBJECT_NAME (factory)); gst_bin_add (GST_BIN(result), element); if (srcelement != NULL) { @@ -454,8 +456,8 @@ differ: if (factories[i]) { factory = (GstElementFactory *)(factories[i]->data); - GST_DEBUG (0,"factory \"%s\"\n", factory->name); - element = gst_elementfactory_create(factory, factory->name); + GST_DEBUG (0,"factory \"%s\"\n", GST_OBJECT_NAME (factory)); + element = gst_elementfactory_create(factory, GST_OBJECT_NAME (factory)); } else { element = sinkelement; @@ -553,7 +555,7 @@ construct_path (gst_autoplug_node *rgnNodes, gpointer factory) next = rgnNodes[find_factory(rgnNodes, current)].iPrev; if (next) { factories = g_list_prepend (factories, current); - GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"factory: \"%s\"", current->name); + GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"factory: \"%s\"", GST_OBJECT_NAME (current)); } current = next; } diff --git a/gst/elements/gstelements.c b/gst/elements/gstelements.c index a41efd6ac8..482c7bd5b7 100644 --- a/gst/elements/gstelements.c +++ b/gst/elements/gstelements.c @@ -82,7 +82,7 @@ plugin_init (GModule *module, GstPlugin *plugin) (_elements[i].type) (), _elements[i].details); if (factory != NULL) { - gst_plugin_add_factory (plugin, factory); + gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory)); if (_elements[i].factoryinit) { _elements[i].factoryinit (factory); } diff --git a/gst/gst.c b/gst/gst.c index 3c8afc90d9..f3e8121575 100644 --- a/gst/gst.c +++ b/gst/gst.c @@ -32,6 +32,7 @@ #include "gstpipeline.h" #include "gstthread.h" #include "gstqueue.h" +#include "gstautoplug.h" #ifndef GST_DISABLE_TYPEFIND #include "gsttypefind.h" #endif @@ -88,8 +89,11 @@ gst_init (int *argc, char **argv[]) GST_INFO (GST_CAT_GST_INIT, "Initializing GStreamer Core Library"); + gst_elementfactory_get_type (); + gst_typefactory_get_type (); + gst_autoplugfactory_get_type (); + _gst_cpu_initialize (); - _gst_type_initialize (); _gst_props_initialize (); _gst_caps_initialize (); _gst_plugin_initialize (); diff --git a/gst/gstautoplug.c b/gst/gstautoplug.c index a054127526..3904845f58 100644 --- a/gst/gstautoplug.c +++ b/gst/gstautoplug.c @@ -24,9 +24,8 @@ #include "gst_private.h" #include "gstautoplug.h" -#include "gstplugin.h" -GList* _gst_autoplugfactories; +static GList* _gst_autoplugfactories; enum { NEW_OBJECT, @@ -60,7 +59,7 @@ GType gst_autoplug_get_type(void) 4, (GInstanceInitFunc)gst_autoplug_init, }; - autoplug_type = g_type_register_static (GST_TYPE_OBJECT, "GstAutoplug", &autoplug_info, 0); + autoplug_type = g_type_register_static (GST_TYPE_OBJECT, "GstAutoplug", &autoplug_info, G_TYPE_FLAG_ABSTRACT); } return autoplug_type; } @@ -81,18 +80,13 @@ gst_autoplug_class_init(GstAutoplugClass *klass) G_STRUCT_OFFSET (GstAutoplugClass, new_object), NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_OBJECT); + } static void gst_autoplug_init(GstAutoplug *autoplug) { } -void -_gst_autoplug_initialize (void) -{ - _gst_autoplugfactories = NULL; -} - /** * gst_autoplug_signal_new_object: * @autoplug: The autoplugger to emit the signal @@ -170,6 +164,63 @@ gst_autoplug_to_renderers (GstAutoplug *autoplug, GstCaps *srccaps, GstElement * return element; } +static void gst_autoplugfactory_class_init (GstAutoplugFactoryClass *klass); +static void gst_autoplugfactory_init (GstAutoplugFactory *factory); + +static xmlNodePtr gst_autoplugfactory_save_thyself (GstObject *object, xmlNodePtr parent); +static void gst_autoplugfactory_restore_thyself (GstObject *object, xmlNodePtr parent); + +static GstPluginFeatureClass *factory_parent_class = NULL; +//static guint gst_autoplugfactory_signals[LAST_SIGNAL] = { 0 }; + +GType +gst_autoplugfactory_get_type (void) +{ + static GType autoplugfactory_type = 0; + + if (!autoplugfactory_type) { + static const GTypeInfo autoplugfactory_info = { + sizeof (GstAutoplugFactoryClass), + NULL, + NULL, + (GClassInitFunc) gst_autoplugfactory_class_init, + NULL, + NULL, + sizeof(GstAutoplugFactory), + 0, + (GInstanceInitFunc) gst_autoplugfactory_init, + }; + autoplugfactory_type = g_type_register_static (GST_TYPE_PLUGIN_FEATURE, + "GstAutoplugFactory", &autoplugfactory_info, 0); + } + return autoplugfactory_type; +} + +static void +gst_autoplugfactory_class_init (GstAutoplugFactoryClass *klass) +{ + GObjectClass *gobject_class; + GstObjectClass *gstobject_class; + GstPluginFeatureClass *gstpluginfeature_class; + + gobject_class = (GObjectClass*)klass; + gstobject_class = (GstObjectClass*)klass; + gstpluginfeature_class = (GstPluginFeatureClass*) klass; + + factory_parent_class = g_type_class_ref (GST_TYPE_PLUGIN_FEATURE); + + gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_autoplugfactory_save_thyself); + gstobject_class->restore_thyself = GST_DEBUG_FUNCPTR (gst_autoplugfactory_restore_thyself); + + _gst_autoplugfactories = NULL; +} + +static void +gst_autoplugfactory_init (GstAutoplugFactory *factory) +{ + _gst_autoplugfactories = g_list_prepend (_gst_autoplugfactories, factory); +} + /** * gst_autoplugfactory_new: @@ -187,15 +238,17 @@ gst_autoplugfactory_new (const gchar *name, const gchar *longdesc, GType type) GstAutoplugFactory *factory; g_return_val_if_fail(name != NULL, NULL); + factory = gst_autoplugfactory_find (name); + if (!factory) { + factory = GST_AUTOPLUGFACTORY (g_object_new (GST_TYPE_AUTOPLUGFACTORY, NULL)); + } - factory = g_new0(GstAutoplugFactory, 1); - - factory->name = g_strdup(name); + gst_object_set_name (GST_OBJECT (factory), name); + if (factory->longdesc) + g_free (factory->longdesc); factory->longdesc = g_strdup (longdesc); factory->type = type; - _gst_autoplugfactories = g_list_prepend (_gst_autoplugfactories, factory); - return factory; } @@ -236,7 +289,7 @@ gst_autoplugfactory_find (const gchar *name) walk = _gst_autoplugfactories; while (walk) { factory = (GstAutoplugFactory *)(walk->data); - if (!strcmp (name, factory->name)) + if (!strcmp (name, GST_OBJECT_NAME (factory))) return factory; walk = g_list_next (walk); } @@ -273,10 +326,8 @@ gst_autoplugfactory_create (GstAutoplugFactory *factory) g_return_val_if_fail (factory != NULL, NULL); - if (factory->type == 0){ - factory = gst_plugin_load_autoplugfactory (factory->name); - } - g_return_val_if_fail (factory != NULL, NULL); + gst_plugin_feature_ensure_loaded (GST_PLUGIN_FEATURE (factory)); + g_return_val_if_fail (factory->type != 0, NULL); new = GST_AUTOPLUG (g_object_new(factory->type,NULL)); @@ -308,21 +359,19 @@ gst_autoplugfactory_make (const gchar *name) return gst_autoplugfactory_create (factory);; } -/** - * gst_autoplugfactory_save_thyself: - * @factory: The facory to save - * @parent: the parent XML node pointer - * - * Save the autoplugfactory into an XML representation - * - * Returns: The new XML parent. - */ -xmlNodePtr -gst_autoplugfactory_save_thyself (GstAutoplugFactory *factory, xmlNodePtr parent) +static xmlNodePtr +gst_autoplugfactory_save_thyself (GstObject *object, xmlNodePtr parent) { - g_return_val_if_fail(factory != NULL, NULL); + GstAutoplugFactory *factory; + + g_return_val_if_fail(GST_IS_AUTOPLUGFACTORY (object), parent); + + factory = GST_AUTOPLUGFACTORY (object); + + if (GST_OBJECT_CLASS (factory_parent_class)->save_thyself) { + GST_OBJECT_CLASS (factory_parent_class)->save_thyself (object, parent); + } - xmlNewChild(parent,NULL,"name",factory->name); xmlNewChild(parent,NULL,"longdesc", factory->longdesc); return parent; @@ -336,23 +385,23 @@ gst_autoplugfactory_save_thyself (GstAutoplugFactory *factory, xmlNodePtr parent * * Returns: A new factory based on the XML node. */ -GstAutoplugFactory* -gst_autoplugfactory_load_thyself (xmlNodePtr parent) +static void +gst_autoplugfactory_restore_thyself (GstObject *object, xmlNodePtr parent) { - GstAutoplugFactory *factory = g_new0(GstAutoplugFactory, 1); + GstAutoplugFactory *factory = GST_AUTOPLUGFACTORY (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")) { - factory->name = xmlNodeGetContent(children); + gst_object_set_name (GST_OBJECT (factory), xmlNodeGetContent(children)); } if (!strcmp(children->name, "longdesc")) { factory->longdesc = xmlNodeGetContent(children); } children = children->next; } - - _gst_autoplugfactories = g_list_prepend (_gst_autoplugfactories, factory); - - return factory; } diff --git a/gst/gstautoplug.h b/gst/gstautoplug.h index 8df20935af..6432cd3130 100644 --- a/gst/gstautoplug.h +++ b/gst/gstautoplug.h @@ -69,13 +69,6 @@ struct _GstAutoplugClass { GstElement* (*autoplug_to_renderers) (GstAutoplug *autoplug, GstCaps *srccaps, GstElement *target, va_list args); }; -typedef struct _GstAutoplugFactory GstAutoplugFactory; - -struct _GstAutoplugFactory { - gchar *name; /* name of autoplugger */ - gchar *longdesc; /* long description of the autoplugger (well, don't overdo it..) */ - GType type; /* unique GType of the autoplugger */ -}; GType gst_autoplug_get_type (void); @@ -90,6 +83,33 @@ GstElement* gst_autoplug_to_renderers (GstAutoplug *autoplug, GstCaps *srccaps * creating autopluggers * */ +#define GST_TYPE_AUTOPLUGFACTORY \ + (gst_autoplugfactory_get_type()) +#define GST_AUTOPLUGFACTORY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AUTOPLUGFACTORY,GstAutoplugFactory)) +#define GST_AUTOPLUGFACTORY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AUTOPLUGFACTORY,GstAutoplugFactoryClass)) +#define GST_IS_AUTOPLUGFACTORY(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AUTOPLUGFACTORY)) +#define GST_IS_AUTOPLUGFACTORY_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AUTOPLUGFACTORY)) + +typedef struct _GstAutoplugFactory GstAutoplugFactory; +typedef struct _GstAutoplugFactoryClass GstAutoplugFactoryClass; + +struct _GstAutoplugFactory { + GstPluginFeature feature; + + gchar *longdesc; /* long description of the autoplugger (well, don't overdo it..) */ + GType type; /* unique GType of the autoplugger */ +}; + +struct _GstAutoplugFactoryClass { + GstPluginFeatureClass parent; +}; + +GType gst_autoplugfactory_get_type (void); + GstAutoplugFactory* gst_autoplugfactory_new (const gchar *name, const gchar *longdesc, GType type); void gst_autoplugfactory_destroy (GstAutoplugFactory *factory); @@ -99,9 +119,6 @@ GList* gst_autoplugfactory_get_list (void); GstAutoplug* gst_autoplugfactory_create (GstAutoplugFactory *factory); GstAutoplug* gst_autoplugfactory_make (const gchar *name); -xmlNodePtr gst_autoplugfactory_save_thyself (GstAutoplugFactory *factory, xmlNodePtr parent); -GstAutoplugFactory* gst_autoplugfactory_load_thyself (xmlNodePtr parent); - #ifdef __cplusplus } #endif /* __cplusplus */ @@ -113,6 +130,7 @@ GstAutoplugFactory* gst_autoplugfactory_load_thyself (xmlNodePtr parent); #pragma GCC poison gst_autoplug_to_caps #pragma GCC poison gst_autoplug_to_renderers +#pragma GCC poison gst_autoplugfactory_get_type #pragma GCC poison gst_autoplugfactory_new #pragma GCC poison gst_autoplugfactory_destroy @@ -122,9 +140,6 @@ GstAutoplugFactory* gst_autoplugfactory_load_thyself (xmlNodePtr parent); #pragma GCC poison gst_autoplugfactory_create #pragma GCC poison gst_autoplugfactory_make -#pragma GCC poison gst_autoplugfactory_save_thyself -#pragma GCC poison gst_autoplugfactory_load_thyself - #endif // GST_DISABLE_AUTOPLUG #endif /* __GST_AUTOPLUG_H__ */ diff --git a/gst/gstcaps.c b/gst/gstcaps.c index fb4c868e41..7e935c1863 100644 --- a/gst/gstcaps.c +++ b/gst/gstcaps.c @@ -47,13 +47,17 @@ get_type_for_mime (const gchar *mime) typeid = gst_type_find_by_mime (mime); if (typeid == 0) { - GstTypeFactory factory; // = g_new0 (GstTypeFactory, 1); + GstTypeDefinition definition; + GstTypeFactory *factory; - factory.mime = g_strdup (mime); - factory.exts = NULL; - factory.typefindfunc = NULL; + definition.name = "capstype"; + definition.mime = g_strdup (mime); + definition.exts = NULL; + definition.typefindfunc = NULL; - typeid = gst_type_register (&factory); + factory = gst_typefactory_new (&definition); + + typeid = gst_type_register (factory); } return typeid; } diff --git a/gst/gstelement.c b/gst/gstelement.c index c77d7cb247..38c43d1006 100644 --- a/gst/gstelement.c +++ b/gst/gstelement.c @@ -51,8 +51,10 @@ static void gst_element_class_init (GstElementClass *klass); static void gst_element_init (GstElement *element); static void gst_element_base_class_init (GstElementClass *klass); -static void gst_element_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); -static void gst_element_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); +static void gst_element_set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec); +static void gst_element_get_property (GObject *object, guint prop_id, GValue *value, + GParamSpec *pspec); static void gst_element_shutdown (GObject *object); static void gst_element_real_destroy (GObject *object); @@ -206,19 +208,6 @@ gst_element_get_property (GObject *object, guint prop_id, GValue *value, GParamS } -/** - * gst_element_new: - * - * Create a new element. Should never be used, as it does no good. - * - * Returns: new element - */ -GstElement* -gst_element_new(void) -{ - return GST_ELEMENT (g_object_new(GST_TYPE_ELEMENT,NULL)); -} - /** * gst_element_set_name: * @element: GstElement to set name of @@ -1004,9 +993,7 @@ gst_element_save_thyself (GstObject *object, // GType type; GstElement *element; - g_return_val_if_fail (object != NULL, parent); g_return_val_if_fail (GST_IS_ELEMENT (object), parent); - g_return_val_if_fail (parent != NULL, parent); element = GST_ELEMENT (object); @@ -1017,7 +1004,7 @@ gst_element_save_thyself (GstObject *object, if (oclass->elementfactory != NULL) { GstElementFactory *factory = (GstElementFactory *)oclass->elementfactory; - xmlNewChild (parent, NULL, "type", factory->name); + xmlNewChild (parent, NULL, "type", GST_OBJECT_NAME (factory)); xmlNewChild (parent, NULL, "version", factory->details->version); } @@ -1261,7 +1248,7 @@ gst_element_signal_eos (GstElement *element) } -const gchar *gst_element_statename(int state) { +const gchar *gst_element_statename(GstElementState state) { switch (state) { #ifdef GST_DEBUG_COLOR case GST_STATE_VOID_PENDING: return "NONE_PENDING";break; diff --git a/gst/gstelement.h b/gst/gstelement.h index b4bf680350..945ab35b35 100644 --- a/gst/gstelement.h +++ b/gst/gstelement.h @@ -36,6 +36,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -125,8 +126,8 @@ typedef enum { //typedef struct _GstElement GstElement; //typedef struct _GstElementClass GstElementClass; -typedef struct _GstElementDetails GstElementDetails; typedef struct _GstElementFactory GstElementFactory; +typedef struct _GstElementFactoryClass GstElementFactoryClass; typedef void (*GstElementLoopFunction) (GstElement *element); @@ -177,29 +178,9 @@ struct _GstElementClass { GstPad* (*request_new_pad) (GstElement *element, GstPadTemplate *templ); }; -struct _GstElementDetails { - gchar *longname; /* long, english name */ - gchar *klass; /* type of element, as hierarchy */ - gchar *description; /* insights of one form or another */ - gchar *version; /* version of the element */ - gchar *author; /* who wrote this thing? */ - gchar *copyright; /* copyright details (year, etc.) */ -}; - -struct _GstElementFactory { - gchar *name; /* name of element */ - GType type; /* unique GType of element */ - - GstElementDetails *details; /* pointer to details struct */ - - GList *padtemplates; - guint16 numpadtemplates; -}; - void gst_element_class_add_padtemplate (GstElementClass *element, GstPadTemplate *templ); GType gst_element_get_type (void); -GstElement* gst_element_new (void); #define gst_element_destroy(element) gst_object_destroy (GST_OBJECT (element)) void gst_element_set_loop_function (GstElement *element, @@ -236,6 +217,7 @@ void gst_element_signal_eos (GstElement *element); /* called by the app to set the state of the element */ gint gst_element_set_state (GstElement *element, GstElementState state); +const gchar * gst_element_statename (GstElementState state); void gst_element_error (GstElement *element, const gchar *error); @@ -250,12 +232,50 @@ GstElement* gst_element_restore_thyself (xmlNodePtr self, GstObject *parent); * factories stuff * **/ +typedef struct _GstElementDetails GstElementDetails; + +struct _GstElementDetails { + gchar *longname; /* long, english name */ + gchar *klass; /* type of element, as hierarchy */ + gchar *description; /* insights of one form or another */ + gchar *version; /* version of the element */ + gchar *author; /* who wrote this thing? */ + gchar *copyright; /* copyright details (year, etc.) */ +}; + +#define GST_TYPE_ELEMENTFACTORY \ + (gst_elementfactory_get_type()) +#define GST_ELEMENTFACTORY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ELEMENTFACTORY,GstElementFactory)) +#define GST_ELEMENTFACTORY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ELEMENTFACTORY,GstElementFactoryClass)) +#define GST_IS_ELEMENTFACTORY(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ELEMENTFACTORY)) +#define GST_IS_ELEMENTFACTORY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ELEMENTFACTORY)) + +struct _GstElementFactory { + GstPluginFeature feature; + + GType type; /* unique GType of element */ + + GstElementDetails *details; /* pointer to details struct */ + + GList *padtemplates; + guint16 numpadtemplates; +}; + +struct _GstElementFactoryClass { + GstPluginFeatureClass parent_class; +}; + +GType gst_elementfactory_get_type (void); + GstElementFactory* gst_elementfactory_new (const gchar *name,GType type, GstElementDetails *details); -void gst_elementfactory_destroy (GstElementFactory *elementfactory); GstElementFactory* gst_elementfactory_find (const gchar *name); -GList* gst_elementfactory_get_list (void); +const GList* gst_elementfactory_get_list (void); void gst_elementfactory_add_padtemplate (GstElementFactory *elementfactory, GstPadTemplate *templ); @@ -271,12 +291,6 @@ GstElement* gst_elementfactory_create (GstElementFactory *factory, GstElement* gst_elementfactory_make (const gchar *factoryname, const gchar *name); -xmlNodePtr gst_elementfactory_save_thyself (GstElementFactory *factory, xmlNodePtr parent); -GstElementFactory* gst_elementfactory_load_thyself (xmlNodePtr parent); - - -const gchar * gst_element_statename (int state); - #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/gst/gstelementfactory.c b/gst/gstelementfactory.c index 86788f1725..5a5b4c9e8d 100644 --- a/gst/gstelementfactory.c +++ b/gst/gstelementfactory.c @@ -24,32 +24,72 @@ #include "gst_private.h" #include "gstelement.h" -#include "gstplugin.h" +static void gst_elementfactory_class_init (GstElementFactoryClass *klass); +static void gst_elementfactory_init (GstElementFactory *factory); + +static void gst_elementfactory_restore_thyself (GstObject *object, xmlNodePtr parent); +static xmlNodePtr gst_elementfactory_save_thyself (GstObject *object, xmlNodePtr parent); + +static void gst_elementfactory_unload_thyself (GstPluginFeature *feature); /* global list of registered elementfactories */ -GList* _gst_elementfactories; +static GList* _gst_elementfactories; -void -_gst_elementfactory_initialize (void) +static GstPluginFeatureClass *parent_class = NULL; +//static guint gst_elementfactory_signals[LAST_SIGNAL] = { 0 }; + +GType +gst_elementfactory_get_type (void) { + static GType elementfactory_type = 0; + + if (!elementfactory_type) { + static const GTypeInfo elementfactory_info = { + sizeof (GstElementFactoryClass), + NULL, + NULL, + (GClassInitFunc) gst_elementfactory_class_init, + NULL, + NULL, + sizeof(GstElementFactory), + 0, + (GInstanceInitFunc) gst_elementfactory_init, + }; + elementfactory_type = g_type_register_static (GST_TYPE_PLUGIN_FEATURE, + "GstElementFactory", &elementfactory_info, 0); + } + return elementfactory_type; +} + +static void +gst_elementfactory_class_init (GstElementFactoryClass *klass) +{ + GObjectClass *gobject_class; + GstObjectClass *gstobject_class; + GstPluginFeatureClass *gstpluginfeature_class; + + gobject_class = (GObjectClass*)klass; + gstobject_class = (GstObjectClass*)klass; + gstpluginfeature_class = (GstPluginFeatureClass*) klass; + + parent_class = g_type_class_ref (GST_TYPE_PLUGIN_FEATURE); + + gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_elementfactory_save_thyself); + gstobject_class->restore_thyself = GST_DEBUG_FUNCPTR (gst_elementfactory_restore_thyself); + + gstpluginfeature_class->unload_thyself = GST_DEBUG_FUNCPTR (gst_elementfactory_unload_thyself); + _gst_elementfactories = NULL; } -/** - * gst_elementfactory_destroy: - * @elementfactory: factory to destroy - * - * Removes the elementfactory from the global list. - */ -void -gst_elementfactory_destroy (GstElementFactory *elementfactory) +static void +gst_elementfactory_init (GstElementFactory *factory) { - g_return_if_fail (elementfactory != NULL); + factory->padtemplates = NULL; + factory->numpadtemplates = 0; - _gst_elementfactories = g_list_remove (_gst_elementfactories, elementfactory); - - // we don't free the struct bacause someone might have a handle to it.. + _gst_elementfactories = g_list_prepend (_gst_elementfactories, factory); } /** @@ -71,13 +111,13 @@ gst_elementfactory_find (const gchar *name) walk = _gst_elementfactories; while (walk) { factory = (GstElementFactory *)(walk->data); - if (!strcmp(name,factory->name)) + if (!strcmp(name, GST_OBJECT_NAME (factory))) return factory; walk = g_list_next(walk); } // this should be an ERROR - GST_DEBUG (GST_CAT_ELEMENTFACTORY,"no such elementfactoryfactory \"%s\"\n", name); + GST_DEBUG (GST_CAT_ELEMENTFACTORY,"no such elementfactory \"%s\"\n", name); return NULL; } @@ -88,7 +128,7 @@ gst_elementfactory_find (const gchar *name) * * Returns: GList of type #GstElementFactory */ -GList* +const GList* gst_elementfactory_get_list (void) { return _gst_elementfactories; @@ -113,16 +153,18 @@ gst_elementfactory_new (const gchar *name, GType type, GstElementFactory *factory; g_return_val_if_fail(name != NULL, NULL); + g_return_val_if_fail(type != 0, NULL); - factory = g_new0(GstElementFactory, 1); + factory = gst_elementfactory_find (name); + if (!factory) { + factory = GST_ELEMENTFACTORY (g_object_new (GST_TYPE_ELEMENTFACTORY, NULL)); + } - factory->name = g_strdup(name); + gst_object_set_name (GST_OBJECT (factory), name); factory->type = type; + if (factory->details) + g_free (factory->details); factory->details = details; - factory->padtemplates = NULL; - factory->numpadtemplates = 0; - - _gst_elementfactories = g_list_prepend (_gst_elementfactories, factory); return factory; } @@ -149,13 +191,10 @@ gst_elementfactory_create (GstElementFactory *factory, g_return_val_if_fail(name != NULL, NULL); GST_DEBUG (GST_CAT_ELEMENTFACTORY,"creating element from factory \"%s\" with name \"%s\"\n", - factory->name, name); + GST_OBJECT_NAME (factory), name); + + gst_plugin_feature_ensure_loaded (GST_PLUGIN_FEATURE (factory)); - // it's not loaded, try to load the plugin - if (factory->type == 0) { - factory = gst_plugin_load_elementfactory(factory->name); - } - g_return_val_if_fail(factory != NULL, NULL); g_return_val_if_fail(factory->type != 0, NULL); // create an instance of the element @@ -165,7 +204,7 @@ gst_elementfactory_create (GstElementFactory *factory, // attempt to set the elemenfactory class pointer if necessary oclass = GST_ELEMENT_CLASS(G_OBJECT_GET_CLASS(element)); if (oclass->elementfactory == NULL) { - GST_DEBUG (GST_CAT_ELEMENTFACTORY,"class %s\n", factory->name); + GST_DEBUG (GST_CAT_ELEMENTFACTORY,"class %s\n", GST_OBJECT_NAME (factory)); oclass->elementfactory = factory; } @@ -195,10 +234,10 @@ gst_elementfactory_make (const gchar *factoryname, const gchar *name) GstElementFactory *factory; GstElement *element; - g_return_val_if_fail(factoryname != NULL, NULL); - g_return_val_if_fail(name != NULL, NULL); + g_return_val_if_fail (factoryname != NULL, NULL); + g_return_val_if_fail (name != NULL, NULL); -// GST_DEBUG (GST_CAT_ELEMENTFACTORY,"gstelementfactory: make \"%s\" \"%s\"\n", factoryname, name); + GST_DEBUG (GST_CAT_ELEMENTFACTORY, "gstelementfactory: make \"%s\" \"%s\"\n", factoryname, name); //gst_plugin_load_elementfactory(factoryname); factory = gst_elementfactory_find(factoryname); @@ -211,6 +250,7 @@ gst_elementfactory_make (const gchar *factoryname, const gchar *name) GST_INFO (GST_CAT_ELEMENTFACTORY,"couldn't create instance of elementfactory \"%s\"!",factoryname); return NULL; } + return element; } @@ -225,9 +265,24 @@ void gst_elementfactory_add_padtemplate (GstElementFactory *factory, GstPadTemplate *templ) { + GList *padtemplates; + g_return_if_fail(factory != NULL); g_return_if_fail(templ != NULL); + padtemplates = factory->padtemplates; + + while (padtemplates) { + GstPadTemplate *oldtempl = GST_PADTEMPLATE (padtemplates->data); + + if (!strcmp (oldtempl->name_template, templ->name_template)) { + gst_object_unref (GST_OBJECT (oldtempl)); + padtemplates->data = templ; + return; + } + + padtemplates = g_list_next (padtemplates); + } factory->padtemplates = g_list_append (factory->padtemplates, templ); factory->numpadtemplates++; } @@ -298,24 +353,31 @@ gst_elementfactory_can_sink_caps (GstElementFactory *factory, return FALSE; } -/** - * gst_elementfactory_save_thyself: - * @factory: factory to save - * @parent: the parent xmlNodePtr - * - * Saves the factory into an XML tree. - * - * Returns: the new xmlNodePtr - */ -xmlNodePtr -gst_elementfactory_save_thyself (GstElementFactory *factory, +static void +gst_elementfactory_unload_thyself (GstPluginFeature *feature) +{ + GstElementFactory *factory; + + factory = GST_ELEMENTFACTORY (feature); + + factory->type = 0; +} + +static xmlNodePtr +gst_elementfactory_save_thyself (GstObject *object, xmlNodePtr parent) { GList *pads; + GstElementFactory *factory; + + factory = GST_ELEMENTFACTORY (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); - xmlNewChild(parent,NULL,"name",factory->name); xmlNewChild(parent,NULL,"longname", factory->details->longname); xmlNewChild(parent,NULL,"class", factory->details->klass); xmlNewChild(parent,NULL,"description", factory->details->description); @@ -338,26 +400,19 @@ gst_elementfactory_save_thyself (GstElementFactory *factory, return parent; } -/** - * gst_elementfactory_load_thyself: - * @parent: the parent xmlNodePtr - * - * Creates a new factory from an xmlNodePtr. - * - * Returns: the new factory - */ -GstElementFactory * -gst_elementfactory_load_thyself (xmlNodePtr parent) +static void +gst_elementfactory_restore_thyself (GstObject *object, xmlNodePtr parent) { - GstElementFactory *factory = g_new0(GstElementFactory, 1); + GstElementFactory *factory = GST_ELEMENTFACTORY (object); xmlNodePtr children = parent->xmlChildrenNode; 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, "name")) { - factory->name = xmlNodeGetContent(children); - } if (!strcmp(children->name, "longname")) { factory->details->longname = xmlNodeGetContent(children); } @@ -386,8 +441,4 @@ gst_elementfactory_load_thyself (xmlNodePtr parent) children = children->next; } - - _gst_elementfactories = g_list_prepend (_gst_elementfactories, factory); - - return factory; } diff --git a/gst/gstobject.c b/gst/gstobject.c index 77b603e512..b7df0fc0cc 100644 --- a/gst/gstobject.c +++ b/gst/gstobject.c @@ -125,19 +125,6 @@ gst_object_init (GstObject *object) GST_FLAG_SET (object, GST_FLOATING); } -/** - * gst_object_new: - * - * Create a new, empty object. Not very useful, should never be used. - * - * Returns: new object - */ -GstObject* -gst_object_new (void) -{ - return GST_OBJECT (g_object_new (gst_object_get_type (), NULL)); -} - /** * gst_object_ref: * @object: GstObject to reference @@ -454,13 +441,15 @@ gst_object_unref (GstObject *object) gboolean gst_object_check_uniqueness (GList *list, const gchar *name) { - GstObject *child; + g_return_val_if_fail (name != NULL, FALSE); while (list) { - child = GST_OBJECT (list->data); + GstObject *child = GST_OBJECT (list->data); + list = g_list_next(list); - if (strcmp(GST_OBJECT_NAME(child), name) == 0) return FALSE; + if (strcmp(GST_OBJECT_NAME(child), name) == 0) + return FALSE; } return TRUE; @@ -468,7 +457,6 @@ gst_object_check_uniqueness (GList *list, const gchar *name) #ifndef GST_DISABLE_LOADSAVE - /** * gst_object_save_thyself: * @object: GstObject to save @@ -488,17 +476,36 @@ gst_object_save_thyself (GstObject *object, xmlNodePtr parent) g_return_val_if_fail (parent != NULL, parent); oclass = (GstObjectClass *)G_OBJECT_GET_CLASS(object); - if (oclass->save_thyself) oclass->save_thyself (object, parent); -#ifndef GST_DISABLE_LOADSAVE g_signal_emit (G_OBJECT (object), gst_object_signals[OBJECT_SAVED], 0, parent); -#endif return parent; } +/** + * gst_object_load_thyself: + * @object: GstObject to load into + * @parent: The parent XML node to save the object into + * + * Saves the given object into the parent XML node. + * + * Returns: the new xmlNodePtr with the saved object + */ +void +gst_object_restore_thyself (GstObject *object, xmlNodePtr parent) +{ + GstObjectClass *oclass; + + g_return_if_fail (object != NULL); + g_return_if_fail (GST_IS_OBJECT (object)); + g_return_if_fail (parent != NULL); + + oclass = (GstObjectClass *)G_OBJECT_GET_CLASS(object); + if (oclass->restore_thyself) + oclass->restore_thyself (object, parent); +} #endif // GST_DISABLE_LOADSAVE /** diff --git a/gst/gstobject.h b/gst/gstobject.h index 2d26739024..d8140c7ac6 100644 --- a/gst/gstobject.h +++ b/gst/gstobject.h @@ -103,17 +103,13 @@ struct _GstObjectClass { /* signals */ void (*parent_set) (GstObject *object, GstObject *parent); -#ifndef GST_DISABLE_LOADSAVE void (*object_saved) (GstObject *object, xmlNodePtr parent); -#endif /* functions go here */ void (*destroy) (GstObject *object); -#ifndef GST_DISABLE_LOADSAVE xmlNodePtr (*save_thyself) (GstObject *object, xmlNodePtr parent); void (*restore_thyself) (GstObject *object, xmlNodePtr self); -#endif }; #define GST_FLAGS(obj) (GST_OBJECT (obj)->flags) @@ -136,7 +132,6 @@ struct _GstObjectClass { /* normal GObject stuff */ GType gst_object_get_type (void); -GstObject* gst_object_new (void); /* name routines */ void gst_object_set_name (GstObject *object, const gchar *name); @@ -151,6 +146,7 @@ gboolean gst_object_check_uniqueness (GList *list, const gchar *name); #ifndef GST_DISABLE_LOADSAVE xmlNodePtr gst_object_save_thyself (GstObject *object, xmlNodePtr parent); +void gst_object_restore_thyself (GstObject *object, xmlNodePtr parent); #else #pragma GCC poison gst_object_save_thyself #endif @@ -159,7 +155,6 @@ xmlNodePtr gst_object_save_thyself (GstObject *object, xmlNodePtr parent); GstObject * gst_object_ref (GstObject *object); void gst_object_unref (GstObject *object); void gst_object_sink (GstObject *object); - /* destroying an object */ void gst_object_destroy (GstObject *object); diff --git a/gst/gstplugin.c b/gst/gstplugin.c index 3347079b96..128ae2aa04 100644 --- a/gst/gstplugin.c +++ b/gst/gstplugin.c @@ -25,27 +25,23 @@ #include #include -#undef RTLD_GLOBAL - #include "gst_private.h" #include "gstplugin.h" #include "gstversion.h" #include "config.h" +static GModule *main_module; + +GList *_gst_plugin_static = NULL; -/* list of loaded modules and its sequence number */ -GList *_gst_modules; -gint _gst_modules_seqno; /* global list of plugins and its sequence number */ -GList *_gst_plugins; -gint _gst_plugins_seqno; -gint _gst_plugin_elementfactories = 0; -gint _gst_plugin_types = 0; +GList *_gst_plugins = NULL; +gint _gst_plugins_seqno = 0; /* list of paths to check for plugins */ -GList *_gst_plugin_paths; +GList *_gst_plugin_paths = NULL; -GList *_gst_libraries; -gint _gst_libraries_seqno; +GList *_gst_libraries = NULL; +gint _gst_libraries_seqno = 0; /* whether or not to spew library load issues */ gboolean _gst_plugin_spew = FALSE; @@ -54,8 +50,13 @@ gboolean _gst_plugin_spew = FALSE; * this to false.) */ gboolean _gst_warn_old_registry = TRUE; -static gboolean plugin_times_older_than(time_t regtime); -static time_t get_time(const char * path); +#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) @@ -64,13 +65,8 @@ _gst_plugin_initialize (void) xmlDocPtr doc; #endif - _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; + main_module = g_module_open (NULL, G_MODULE_BIND_LAZY); + gst_plugin_register_statics (main_module); /* add the main (installed) library path */ _gst_plugin_paths = g_list_prepend (_gst_plugin_paths, PLUGINS_DIR); @@ -103,6 +99,7 @@ _gst_plugin_initialize (void) if (_gst_warn_old_registry) g_warning ("gstplugin: registry needs rebuild: run gstreamer-register\n"); gst_plugin_load_all (); + //gst_plugin_unload_all (); return; } gst_plugin_load_thyself (doc->xmlRootNode); @@ -111,6 +108,36 @@ _gst_plugin_initialize (void) #endif // GST_DISABLE_REGISTRY } +void +_gst_plugin_register_static (GstPluginDesc *desc) +{ + _gst_plugin_static = g_list_prepend (_gst_plugin_static, desc); +} + +static void +gst_plugin_register_statics (GModule *module) +{ + GList *walk = _gst_plugin_static; + + while (walk) { + GstPluginDesc *desc = (GstPluginDesc *) walk->data; + GstPlugin *plugin; + + plugin = g_new0 (GstPlugin, 1); + plugin->filename = NULL; + plugin->module = NULL; + plugin = gst_plugin_register_func (desc, plugin, module); + + if (plugin) { + _gst_plugins = g_list_prepend (_gst_plugins, plugin); + _gst_plugins_seqno++; + plugin->module = module; + } + + walk = g_list_next (walk); + } +} + /** * gst_plugin_add_path: * @path: the directory to add to the search path @@ -123,6 +150,7 @@ 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) { @@ -184,6 +212,7 @@ plugin_times_older_than(time_t regtime) } return TRUE; } +#endif static gboolean gst_plugin_load_recurse (gchar *directory, gchar *name) @@ -232,7 +261,7 @@ gst_plugin_load_recurse (gchar *directory, gchar *name) * Load all plugins in the path. */ void -gst_plugin_load_all(void) +gst_plugin_load_all (void) { GList *path; @@ -242,8 +271,39 @@ gst_plugin_load_all(void) gst_plugin_load_recurse(path->data,NULL); path = g_list_next(path); } - GST_INFO (GST_CAT_PLUGIN_LOADING,"loaded %d plugins with %d elements and %d types", - _gst_plugins_seqno,_gst_plugin_elementfactories,_gst_plugin_types); + GST_INFO (GST_CAT_PLUGIN_LOADING,"loaded %d plugins", _gst_plugins_seqno); +} + +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); + } } /** @@ -277,22 +337,6 @@ gst_library_load (const gchar *name) return res; } -static void -gst_plugin_remove (GstPlugin *plugin) -{ - GList *factories; - - factories = plugin->elements; - while (factories) { - gst_elementfactory_destroy ((GstElementFactory*)(factories->data)); - factories = g_list_next(factories); - } - - _gst_plugins = g_list_remove(_gst_plugins, plugin); - - // don't free the stuct because someone can have a handle to it -} - /** * gst_plugin_load: * @name: name of plugin to load @@ -307,14 +351,15 @@ gst_plugin_load (const gchar *name) { GList *path; gchar *libspath; - GstPlugin *plugin; gchar *pluginname; - - //g_print("attempting to load plugin '%s'\n",name); + GstPlugin *plugin; + + g_return_val_if_fail (name != NULL, FALSE); plugin = gst_plugin_find (name); - - if (plugin && plugin->loaded) return TRUE; + + if (plugin && plugin->module) + return TRUE; path = _gst_plugin_paths; while (path != NULL) { @@ -345,6 +390,79 @@ gst_plugin_load (const gchar *name) return FALSE; } +/** + * 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_absolute (const gchar *filename) +{ + GstPlugin *plugin = NULL; + GList *plugins = _gst_plugins; + + g_return_val_if_fail (filename != NULL, FALSE); + + GST_INFO (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) +{ + // return NULL if the major and minor version numbers are not compatible + // with ours. + if (major != GST_VERSION_MAJOR || minor != GST_VERSION_MINOR) + return FALSE; + + return TRUE; +} + +static GstPlugin* +gst_plugin_register_func (GstPluginDesc *desc, GstPlugin *plugin, GModule *module) +{ + 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; + } + + 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; +} + /** * gst_plugin_load_absolute: * @name: name of plugin to load @@ -352,105 +470,60 @@ gst_plugin_load (const gchar *name) * Returns: whether or not the plugin loaded */ gboolean -gst_plugin_load_absolute (const gchar *name) +gst_plugin_load_plugin (GstPlugin *plugin) { GModule *module; GstPluginDesc *desc; - GstPlugin *plugin; struct stat file_status; + gchar *filename; - GST_INFO (GST_CAT_PLUGIN_LOADING,"plugin \"%s\" loading", name); + g_return_val_if_fail (plugin != NULL, FALSE); - if (g_module_supported() == FALSE) { + if (plugin->module) + return TRUE; + + filename = plugin->filename; + + GST_INFO (GST_CAT_PLUGIN_LOADING, "plugin \"%s\" loading", filename); + + if (g_module_supported () == FALSE) { g_warning("gstplugin: wow, you built this on a platform without dynamic loading???\n"); return FALSE; } - if (stat(name,&file_status)) { - //g_print("problem opening file %s\n",name); + if (stat (filename, &file_status)) { + //g_print("problem opening file %s\n",filename); return FALSE; } - module = g_module_open(name,G_MODULE_BIND_LAZY); + module = g_module_open (filename, G_MODULE_BIND_LAZY); + if (module != NULL) { - if (g_module_symbol(module,"plugin_desc",(gpointer *)&desc)) { - GST_INFO (GST_CAT_PLUGIN_LOADING,"loading plugin \"%s\"...", name); - plugin = gst_plugin_new(desc->name, desc->major_version, desc->minor_version); - if (plugin != NULL) { - plugin->filename = g_strdup(name); - if (!((desc->plugin_init)(module, plugin))) { - GST_INFO (GST_CAT_PLUGIN_LOADING,"plugin \"%s\" failed to initialise", - plugin->name); - g_free(plugin); - plugin = NULL; - } - } + if (g_module_symbol (module, "plugin_desc", (gpointer *)&desc)) { + GST_INFO (GST_CAT_PLUGIN_LOADING,"loading plugin \"%s\"...", 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: %d elements, %d types", - plugin->name,plugin->numelements,plugin->numtypes); - plugin->loaded = TRUE; - _gst_modules = g_list_prepend(_gst_modules,module); - _gst_modules_seqno++; - _gst_plugins = g_list_prepend(_gst_plugins,plugin); - _gst_plugins_seqno++; - _gst_plugin_elementfactories += plugin->numelements; - _gst_plugin_types += plugin->numtypes; + 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", name, g_module_error()); + g_printerr ("error loading plugin %s, reason: %s\n", filename, g_module_error()); } else { - GST_INFO (GST_CAT_PLUGIN_LOADING, "error loading plugin %s, reason: %s\n", name, g_module_error()); + GST_INFO (GST_CAT_PLUGIN_LOADING, "error loading plugin %s, reason: %s\n", filename, g_module_error()); } return FALSE; } -/** - * gst_plugin_new: - * @name: name of new plugin - * @major: major version number of core that plugin is compatible with - * @minor: minor version number of core that plugin is compatible with - * - * Create a new plugin with given name. - * - * Returns: new plugin, or NULL if plugin couldn't be created, due to - * incompatible version number, or name already being allocated) - */ -GstPlugin* -gst_plugin_new (const gchar *name, gint major, gint minor) -{ - GstPlugin *plugin; - - // return NULL if the major and minor version numbers are not compatible - // with ours. - if (major != GST_VERSION_MAJOR || minor != GST_VERSION_MINOR) return NULL; - - // return NULL if the plugin is allready loaded - plugin = gst_plugin_find (name); - if (plugin) return NULL; - - plugin = (GstPlugin *)g_malloc(sizeof(GstPlugin)); - - plugin->name = g_strdup(name); - plugin->longname = NULL; - plugin->elements = NULL; - plugin->numelements = 0; - plugin->types = NULL; - plugin->numtypes = 0; -#ifndef GST_DISABLE_AUTOPLUG - plugin->autopluggers = NULL; - plugin->numautopluggers = 0; -#endif // GST_DISABLE_AUTOPLUG - plugin->loaded = TRUE; - - return plugin; -} /** * gst_plugin_get_name: @@ -549,7 +622,7 @@ gst_plugin_is_loaded (GstPlugin *plugin) { g_return_val_if_fail (plugin != NULL, FALSE); - return plugin->loaded; + return (plugin->module != NULL); } @@ -566,38 +639,55 @@ gst_plugin_find (const gchar *name) { GList *plugins = _gst_plugins; - g_return_val_if_fail(name != NULL, NULL); + g_return_val_if_fail (name != NULL, NULL); while (plugins) { 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); + plugins = g_list_next (plugins); } return NULL; } -static GstElementFactory* -gst_plugin_find_elementfactory (const gchar *name) +static GstPluginFeature* +gst_plugin_find_feature_func (GstPlugin *plugin, const gchar *name, GType type) { - GList *plugins, *factories; - GstElementFactory *factory; + GList *features = plugin->features; - g_return_val_if_fail(name != NULL, NULL); + g_return_val_if_fail (name != NULL, NULL); + + 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); + + features = g_list_next (features); + } + + return NULL; +} + +GstPluginFeature* +gst_plugin_find_feature (const gchar *name, GType type) +{ + GList *plugins; plugins = _gst_plugins; while (plugins) { - factories = ((GstPlugin *)(plugins->data))->elements; - while (factories) { - factory = (GstElementFactory*)(factories->data); - if (!strcmp(factory->name, name)) - return (GstElementFactory*)(factory); - factories = g_list_next(factories); - } + 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); } @@ -605,234 +695,30 @@ gst_plugin_find_elementfactory (const gchar *name) } /** - * gst_plugin_load_elementfactory: - * @name: name of elementfactory to load + * gst_plugin_add_feature: + * @plugin: plugin to add feature to + * @feature: feature to add * - * Load a registered elementfactory by name. - * - * Returns: @GstElementFactory if loaded, NULL if not - */ -GstElementFactory* -gst_plugin_load_elementfactory (const 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) { - gchar *filename = g_strdup (plugin->filename); - gchar *pluginname = g_strdup (plugin->name); - - GST_INFO (GST_CAT_PLUGIN_LOADING,"loaded elementfactory %s from plugin %s",name,plugin->name); - gst_plugin_remove(plugin); - if (!gst_plugin_load_absolute(filename)) { - GST_DEBUG (0,"gstplugin: error loading element factory %s from plugin %s\n", name, pluginname); - } - g_free (pluginname); - g_free (filename); - } - factory = gst_plugin_find_elementfactory(name); - return factory; - } - factories = g_list_next(factories); - } - plugins = g_list_next(plugins); - } - - return factory; -} - -#ifndef GST_DISABLE_AUTOPLUG -static GstAutoplugFactory* -gst_plugin_find_autoplugfactory (const gchar *name) -{ - GList *plugins, *factories; - GstAutoplugFactory *factory; - - g_return_val_if_fail(name != NULL, NULL); - - plugins = _gst_plugins; - while (plugins) { - factories = ((GstPlugin *)(plugins->data))->autopluggers; - while (factories) { - factory = (GstAutoplugFactory*)(factories->data); - if (!strcmp(factory->name, name)) - return (GstAutoplugFactory*)(factory); - factories = g_list_next(factories); - } - plugins = g_list_next(plugins); - } - - return NULL; -} -/** - * gst_plugin_load_autoplugfactory: - * @name: name of autoplugfactory to load - * - * Load a registered autoplugfactory by name. - * - * Returns: @GstAutoplugFactory if loaded, NULL if not - */ -GstAutoplugFactory* -gst_plugin_load_autoplugfactory (const gchar *name) -{ - GList *plugins, *factories; - GstAutoplugFactory *factory = NULL; - GstPlugin *plugin; - - g_return_val_if_fail(name != NULL, NULL); - - plugins = _gst_plugins; - while (plugins) { - plugin = (GstPlugin *)plugins->data; - factories = plugin->autopluggers; - - while (factories) { - factory = (GstAutoplugFactory*)(factories->data); - - if (!strcmp(factory->name,name)) { - if (!plugin->loaded) { - gchar *filename = g_strdup (plugin->filename); - gchar *pluginname = g_strdup (plugin->name); - - GST_INFO (GST_CAT_PLUGIN_LOADING,"loaded autoplugfactory %s from plugin %s",name,plugin->name); - gst_plugin_remove(plugin); - if (!gst_plugin_load_absolute(filename)) { - GST_DEBUG (0,"gstplugin: error loading autoplug factory %s from plugin %s\n", name, pluginname); - } - g_free (pluginname); - g_free (filename); - } - factory = gst_plugin_find_autoplugfactory(name); - return factory; - } - factories = g_list_next(factories); - } - plugins = g_list_next(plugins); - } - - return factory; -} -#endif // GST_DISABLE_AUTOPLUG - -/** - * gst_plugin_load_typefactory: - * @mime: name of typefactory to load - * - * Load a registered typefactory by mime type. + * Add feature to the list of those provided by the plugin. */ void -gst_plugin_load_typefactory (const gchar *mime) +gst_plugin_add_feature (GstPlugin *plugin, GstPluginFeature *feature) { - GList *plugins, *factories; - GstTypeFactory *factory; - GstPlugin *plugin; + GstPluginFeature *oldfeature; - g_return_if_fail (mime != NULL); - - plugins = g_list_copy (_gst_plugins); - while (plugins) { - plugin = (GstPlugin *)plugins->data; - factories = g_list_copy (plugin->types); - - while (factories) { - factory = (GstTypeFactory*)(factories->data); - - if (!strcmp(factory->mime,mime)) { - if (!plugin->loaded) { - gchar *filename = g_strdup (plugin->filename); - gchar *pluginname = g_strdup (plugin->name); - - GST_INFO (GST_CAT_PLUGIN_LOADING,"loading type factory for \"%s\" from plugin %s",mime,plugin->name); - plugin->loaded = TRUE; - gst_plugin_remove(plugin); - if (!gst_plugin_load_absolute(filename)) { - GST_DEBUG (0,"gstplugin: error loading type factory \"%s\" from plugin %s\n", mime, pluginname); - } - g_free (filename); - g_free (pluginname); - } - //return; - } - factories = g_list_next(factories); - } - - g_list_free (factories); - plugins = g_list_next(plugins); - } - g_list_free (plugins); - - return; -} - -/** - * gst_plugin_add_factory: - * @plugin: plugin to add factory to - * @factory: factory to add - * - * Add factory to the list of those provided by the plugin. - */ -void -gst_plugin_add_factory (GstPlugin *plugin, GstElementFactory *factory) -{ g_return_if_fail (plugin != NULL); - g_return_if_fail (factory != NULL); + g_return_if_fail (GST_IS_PLUGIN_FEATURE (feature)); + g_return_if_fail (feature != NULL); -// g_print("adding factory to plugin\n"); - plugin->elements = g_list_prepend (plugin->elements, factory); - plugin->numelements++; + oldfeature = gst_plugin_find_feature_func (plugin, GST_OBJECT_NAME (feature), G_OBJECT_TYPE (feature)); + + if (!oldfeature) { + feature->manager = plugin; + plugin->features = g_list_prepend (plugin->features, feature); + plugin->numfeatures++; + } } -/** - * gst_plugin_add_type: - * @plugin: plugin to add type to - * @factory: the typefactory to add - * - * Add a typefactory to the list of those provided by the plugin. - */ -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_prepend (plugin->types, factory); - plugin->numtypes++; - gst_type_register (factory); -} - -/** - * gst_plugin_add_autoplugger: - * @plugin: plugin to add the autoplugger to - * @factory: the autoplugfactory to add - * - * Add an autoplugfactory to the list of those provided by the plugin. - */ -#ifndef GST_DISABLE_AUTOPLUG -void -gst_plugin_add_autoplugger (GstPlugin *plugin, GstAutoplugFactory *factory) -{ - g_return_if_fail (plugin != NULL); - g_return_if_fail (factory != NULL); - -// g_print("adding factory to plugin\n"); - plugin->autopluggers = g_list_prepend (plugin->autopluggers, factory); - plugin->numautopluggers++; -} -#endif // GST_DISABLE_AUTOPLUG - /** * gst_plugin_get_list: * @@ -859,49 +745,35 @@ xmlNodePtr gst_plugin_save_thyself (xmlNodePtr parent) { xmlNodePtr tree, subtree; - GList *plugins = NULL, *elements = NULL, *types = NULL, *autopluggers = NULL; + GList *plugins = NULL; - plugins = g_list_copy (_gst_plugins); + 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); - types = plugin->types; - while (types) { - GstTypeFactory *factory = (GstTypeFactory *)types->data; - subtree = xmlNewChild(tree, NULL, "typefactory", NULL); + features = plugin->features; + while (features) { + GstPluginFeature *feature = GST_PLUGIN_FEATURE (features->data); - gst_typefactory_save_thyself (factory, subtree); + subtree = xmlNewChild(tree, NULL, "feature", NULL); + xmlNewProp (subtree, "typename", g_type_name (G_OBJECT_TYPE (feature))); - types = g_list_next (types); + gst_object_save_thyself (GST_OBJECT (feature), subtree); + + features = g_list_next (features); } - elements = plugin->elements; - while (elements) { - GstElementFactory *factory = (GstElementFactory *)elements->data; - subtree = xmlNewChild (tree, NULL, "elementfactory", NULL); - - gst_elementfactory_save_thyself (factory, subtree); - - elements = g_list_next (elements); - } -#ifndef GST_DISABLE_AUTOPLUG - autopluggers = plugin->autopluggers; - while (autopluggers) { - GstAutoplugFactory *factory = (GstAutoplugFactory *)autopluggers->data; - subtree = xmlNewChild (tree, NULL, "autoplugfactory", NULL); - - gst_autoplugfactory_save_thyself (factory, subtree); - - autopluggers = g_list_next (autopluggers); - } -#endif // GST_DISABLE_AUTOPLUG - plugins = g_list_next (plugins); } - g_list_free (plugins); return parent; } @@ -915,9 +787,7 @@ void gst_plugin_load_thyself (xmlNodePtr parent) { xmlNodePtr kinderen; - gint elementcount = 0; - gint autoplugcount = 0; - gint typecount = 0; + gint featurecount = 0; gchar *pluginname; kinderen = parent->xmlChildrenNode; // Dutch invasion :-) @@ -926,9 +796,9 @@ gst_plugin_load_thyself (xmlNodePtr parent) xmlNodePtr field = kinderen->xmlChildrenNode; GstPlugin *plugin = g_new0 (GstPlugin, 1); - plugin->elements = NULL; - plugin->types = NULL; - plugin->loaded = FALSE; + plugin->numfeatures = 0; + plugin->features = NULL; + plugin->module = NULL; while (field) { if (!strcmp (field->name, "name")) { @@ -948,23 +818,18 @@ gst_plugin_load_thyself (xmlNodePtr parent) else if (!strcmp (field->name, "filename")) { plugin->filename = xmlNodeGetContent (field); } - else if (!strcmp (field->name, "elementfactory")) { - GstElementFactory *factory = gst_elementfactory_load_thyself (field); - gst_plugin_add_factory (plugin, factory); - elementcount++; - } -#ifndef GST_DISABLE_AUTOPLUG - else if (!strcmp (field->name, "autoplugfactory")) { - GstAutoplugFactory *factory = gst_autoplugfactory_load_thyself (field); - gst_plugin_add_autoplugger (plugin, factory); - autoplugcount++; - } -#endif // GST_DISABLE_AUTOPLUG - else if (!strcmp (field->name, "typefactory")) { - GstTypeFactory *factory = gst_typefactory_load_thyself (field); - gst_plugin_add_type (plugin, factory); - elementcount++; - typecount++; + 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; @@ -972,63 +837,29 @@ gst_plugin_load_thyself (xmlNodePtr parent) if (plugin) { _gst_plugins = g_list_prepend (_gst_plugins, plugin); + _gst_plugins_seqno++; } } kinderen = kinderen->next; } - GST_INFO (GST_CAT_PLUGIN_LOADING, "added %d registered factories, %d autopluggers and %d types", - elementcount, autoplugcount, typecount); + GST_INFO (GST_CAT_PLUGIN_LOADING, "added %d features ", featurecount); } #endif // GST_DISABLE_REGISTRY /** - * gst_plugin_get_factory_list: - * @plugin: the plugin to get the factories from + * gst_plugin_get_feature_list: + * @plugin: the plugin to get the features from * - * get a list of all the factories that this plugin provides + * get a list of all the features that this plugin provides * - * Returns: a GList of factories + * Returns: a GList of features */ GList* -gst_plugin_get_factory_list (GstPlugin *plugin) +gst_plugin_get_feature_list (GstPlugin *plugin) { g_return_val_if_fail (plugin != NULL, NULL); - return plugin->elements; + return plugin->features; } - -/** - * gst_plugin_get_type_list: - * @plugin: the plugin to get the typefactories from - * - * get a list of all the typefactories that this plugin provides - * - * Returns: a GList of factories - */ -GList* -gst_plugin_get_type_list (GstPlugin *plugin) -{ - g_return_val_if_fail (plugin != NULL, NULL); - - return plugin->types; -} - -/** - * gst_plugin_get_autoplug_list: - * @plugin: the plugin to get the autoplugfactories from - * - * get a list of all the autoplugfactories that this plugin provides - * - * Returns: a GList of factories - */ -#ifndef GST_DISABLE_AUTOPLUG -GList* -gst_plugin_get_autoplug_list (GstPlugin *plugin) -{ - g_return_val_if_fail (plugin != NULL, NULL); - - return plugin->autopluggers; -} -#endif // GST_DISABLE_AUTOPLUG diff --git a/gst/gstplugin.h b/gst/gstplugin.h index 3d2641ada4..e678f58a3b 100644 --- a/gst/gstplugin.h +++ b/gst/gstplugin.h @@ -34,10 +34,7 @@ #define xmlRootNode root #endif -#include -#include -#include - +#include typedef struct _GstPlugin GstPlugin; typedef struct _GstPluginDesc GstPluginDesc; @@ -47,16 +44,10 @@ struct _GstPlugin { gchar *longname; /* long name of plugin */ gchar *filename; /* filename it came from */ - GList *types; /* list of types provided */ - gint numtypes; - GList *elements; /* list of elements provided */ - gint numelements; -#ifndef GST_DISABLE_AUTOPLUG - GList *autopluggers; /* list of autopluggers provided */ - gint numautopluggers; -#endif // GST_DISABLE_AUTOPLUG + GList *features; /* list of features provided */ + gint numfeatures; - gboolean loaded; /* if the plugin is in memory */ + GModule *module; /* contains the module if the plugin is loaded */ }; /* Initialiser function: returns TRUE if plugin initialised successfully */ @@ -69,7 +60,36 @@ struct _GstPluginDesc { GstPluginInitFunc plugin_init; /* pointer to plugin_init function */ }; +#ifndef GST_PLUGIN_STATIC +#define GST_PLUGIN_DESC_DYNAMIC(major,minor,name,init) \ +GstPluginDesc plugin_desc = { \ + major, \ + minor, \ + name, \ + init \ +}; +#else +#define GST_PLUGIN_DESC_DYNAMIC(major,minor,name,init) +#endif +#define GST_PLUGIN_DESC_STATIC(major,minor,name,init) \ +static void __attribute__ ((constructor)) \ +_gst_plugin_static_init__ ##init (void) \ +{ \ + static GstPluginDesc plugin_desc_ = { \ + major, \ + minor, \ + name, \ + init \ + }; \ + _gst_plugin_register_static (&plugin_desc_); \ +} + +#define GST_PLUGIN_DESC(major,minor,name,init) \ + GST_PLUGIN_DESC_DYNAMIC (major,minor,name,init) \ + GST_PLUGIN_DESC_STATIC (major,minor,name,init) + void _gst_plugin_initialize (void); +void _gst_plugin_register_static (GstPluginDesc *desc); GstPlugin* gst_plugin_new (const gchar *name, gint major, gint minor); @@ -83,39 +103,28 @@ 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_type_list (GstPlugin *plugin); -GList* gst_plugin_get_factory_list (GstPlugin *plugin); -#ifndef GST_DISABLE_AUTOPLUG -GList* gst_plugin_get_autoplug_list (GstPlugin *plugin); -#else -#pragma GCC poison gst_plugin_get_autoplug_list -#endif // GST_DISABLE_AUTOPLUG +GList* gst_plugin_get_feature_list (GstPlugin *plugin); 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); -void gst_plugin_add_factory (GstPlugin *plugin, GstElementFactory *factory); -void gst_plugin_add_type (GstPlugin *plugin, GstTypeFactory *factory); -#ifndef GST_DISABLE_AUTOPLUG -void gst_plugin_add_autoplugger (GstPlugin *plugin, GstAutoplugFactory *factory); -#else -#pragma GCC poison gst_plugin_add_autoplugger -#endif // GST_DISABLE_AUTOPLUG +void gst_plugin_add_feature (GstPlugin *plugin, GstPluginFeature *feature); GstPlugin* gst_plugin_find (const gchar *name); GList* gst_plugin_get_list (void); -GstElementFactory* gst_plugin_load_elementfactory (const gchar *name); -void gst_plugin_load_typefactory (const gchar *mime); -#ifndef GST_DISABLE_AUTOPLUG -GstAutoplugFactory* gst_plugin_load_autoplugfactory (const gchar *name); -#else -#pragma GCC poison gst_plugin_add_autoplugger -#endif // GST_DISABLE_AUTOPLUG +#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 new file mode 100644 index 0000000000..f33ee9e45b --- /dev/null +++ b/gst/gstpluginfeature.c @@ -0,0 +1,133 @@ +/* GStreamer + * Copyright (C) 1999,2000 Erik Walthinsen + * 2000 Wim Taymans + * + * gstpluginfeature.c: Abstract base class for all plugin features + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "gst_private.h" +#include "gstpluginfeature.h" +#include "gstplugin.h" + +static void gst_plugin_feature_class_init (GstPluginFeatureClass *klass); +static void gst_plugin_feature_init (GstPluginFeature *feature); + +static xmlNodePtr gst_plugin_feature_save_thyself (GstObject *object, xmlNodePtr parent); +static void gst_plugin_feature_restore_thyself (GstObject *object, xmlNodePtr parent); + +static GstObjectClass *parent_class = NULL; +//static guint gst_plugin_feature_signals[LAST_SIGNAL] = { 0 }; + +GType +gst_plugin_feature_get_type (void) +{ + static GType plugin_feature_type = 0; + + if (!plugin_feature_type) { + static const GTypeInfo plugin_feature_info = { + sizeof (GstObjectClass), + NULL, + NULL, + (GClassInitFunc) gst_plugin_feature_class_init, + NULL, + NULL, + sizeof (GstObject), + 32, + (GInstanceInitFunc) gst_plugin_feature_init, + }; + plugin_feature_type = g_type_register_static (GST_TYPE_OBJECT, "GstPluginFeature", + &plugin_feature_info, G_TYPE_FLAG_ABSTRACT); + } + return plugin_feature_type; +} + +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); + + gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_plugin_feature_save_thyself); + gstobject_class->restore_thyself = GST_DEBUG_FUNCPTR (gst_plugin_feature_restore_thyself); +} + +static void +gst_plugin_feature_init (GstPluginFeature *feature) +{ + feature->manager = NULL; +} + +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; + } +} + +void +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\n", plugin->name); + + gst_plugin_load_plugin (plugin); + } +} + +void +gst_plugin_feature_unload_thyself (GstPluginFeature *feature) +{ + GstPluginFeatureClass *oclass; + + g_return_if_fail (feature != NULL); + g_return_if_fail (GST_IS_PLUGIN_FEATURE (feature)); + + oclass = (GstPluginFeatureClass *)G_OBJECT_GET_CLASS (feature); + + if (oclass->unload_thyself) + oclass->unload_thyself (feature); +} + + + diff --git a/gst/gstpluginfeature.h b/gst/gstpluginfeature.h new file mode 100644 index 0000000000..6fd92f1e08 --- /dev/null +++ b/gst/gstpluginfeature.h @@ -0,0 +1,72 @@ +/* GStreamer + * Copyright (C) 1999,2000 Erik Walthinsen + * 2000 Wim Taymans + * + * gstpluginfeature.h: Header for base GstPluginFeature + * + * 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_PLUGIN_FEATURE_H__ +#define __GST_PLUGIN_FEATURE_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include + +#define GST_TYPE_PLUGIN_FEATURE \ + (gst_plugin_feature_get_type()) +#define GST_PLUGIN_FEATURE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_PLUGIN_FEATURE,GstPluginFeature)) +#define GST_PLUGIN_FEATURE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_PLUGIN_FEATURE,GstPluginFeatureClass)) +#define GST_IS_PLUGIN_FEATURE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_PLUGIN_FEATURE)) +#define GST_IS_PLUGIN_FEATURE_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_PLUGIN_FEATURE)) + +typedef struct _GstPluginFeature GstPluginFeature; +typedef struct _GstPluginFeatureClass GstPluginFeatureClass; + +struct _GstPluginFeature { + GstObject object; + + gpointer manager; +}; + +struct _GstPluginFeatureClass { + GstObjectClass parent_class; + + void (*unload_thyself) (GstPluginFeature *feature); +}; + + +/* normal GObject stuff */ +GType gst_plugin_feature_get_type (void); + +void gst_plugin_feature_ensure_loaded (GstPluginFeature *feature); +void gst_plugin_feature_unload_thyself (GstPluginFeature *feature); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* __GST_PLUGIN_FEATURE_H__ */ + diff --git a/gst/gstqueue.c b/gst/gstqueue.c index 2722e96cf9..fdf8bfec54 100644 --- a/gst/gstqueue.c +++ b/gst/gstqueue.c @@ -67,30 +67,33 @@ enum { }; -static void gst_queue_class_init (GstQueueClass *klass); -static void gst_queue_init (GstQueue *queue); +static void gst_queue_class_init (GstQueueClass *klass); +static void gst_queue_init (GstQueue *queue); -static void gst_queue_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); -static void gst_queue_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); +static void gst_queue_set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec); +static void gst_queue_get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec); -static GstPadNegotiateReturn gst_queue_handle_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data); +static GstPadNegotiateReturn gst_queue_handle_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data); static GstPadNegotiateReturn gst_queue_handle_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data); -static void gst_queue_chain (GstPad *pad, GstBuffer *buf); -static GstBuffer * gst_queue_get (GstPad *pad); -static GstBufferPool* gst_queue_get_bufferpool (GstPad *pad); +static void gst_queue_chain (GstPad *pad, GstBuffer *buf); +static GstBuffer * gst_queue_get (GstPad *pad); +static GstBufferPool* gst_queue_get_bufferpool (GstPad *pad); -static void gst_queue_flush (GstQueue *queue); +static void gst_queue_flush (GstQueue *queue); -static GstElementStateReturn gst_queue_change_state (GstElement *element); +static GstElementStateReturn gst_queue_change_state (GstElement *element); +#define GST_TYPE_QUEUE_LEAKY (queue_leaky_get_type()) static GType queue_leaky_get_type(void) { static GType queue_leaky_type = 0; static GEnumValue queue_leaky[] = { - { GST_QUEUE_NO_LEAK, "0", "Not Leaky" }, - { GST_QUEUE_LEAK_UPSTREAM, "1", "Leaky on Upstream" }, - { GST_QUEUE_LEAK_DOWNSTREAM, "2", "Leaky on Downstream" }, + { GST_QUEUE_NO_LEAK, "0", "Not Leaky" }, + { GST_QUEUE_LEAK_UPSTREAM, "1", "Leaky on Upstream" }, + { GST_QUEUE_LEAK_DOWNSTREAM, "2", "Leaky on Downstream" }, { 0, NULL, NULL }, }; if (!queue_leaky_type) { @@ -98,14 +101,13 @@ queue_leaky_get_type(void) { } return queue_leaky_type; } -#define GST_TYPE_QUEUE_LEAKY (queue_leaky_get_type()) - static GstElementClass *parent_class = NULL; //static guint gst_queue_signals[LAST_SIGNAL] = { 0 }; GType -gst_queue_get_type(void) { +gst_queue_get_type(void) +{ static GType queue_type = 0; if (!queue_type) { diff --git a/gst/gsttype.c b/gst/gsttype.c index 744089885e..39d3237c4b 100644 --- a/gst/gsttype.c +++ b/gst/gsttype.c @@ -30,26 +30,101 @@ #include "gst_private.h" #include "gsttype.h" -#include "gstplugin.h" /* global list of registered types */ -GList *_gst_types; -guint16 _gst_maxtype; +static GList *_gst_types; +static guint16 _gst_maxtype; -struct _GstTypeFindInfo { - GstTypeFindFunc typefindfunc; /* typefind function */ +static GList *_gst_typefactories; - GstPlugin *plugin; /* the plugin with this typefind function */ -}; +static void gst_typefactory_class_init (GstTypeFactoryClass *klass); +static void gst_typefactory_init (GstTypeFactory *factory); static GstCaps* gst_type_typefind_dummy (GstBuffer *buffer, gpointer priv); -void -_gst_type_initialize (void) +static xmlNodePtr gst_typefactory_save_thyself (GstObject *object, xmlNodePtr parent); +static void gst_typefactory_restore_thyself (GstObject *object, xmlNodePtr parent); + +static void gst_typefactory_unload_thyself (GstPluginFeature *feature); + +static GstPluginFeatureClass *parent_class = NULL; +//static guint gst_typefactory_signals[LAST_SIGNAL] = { 0 }; + +GType +gst_typefactory_get_type (void) { + static GType typefactory_type = 0; + + if (!typefactory_type) { + static const GTypeInfo typefactory_info = { + sizeof (GstTypeFactoryClass), + NULL, + NULL, + (GClassInitFunc) gst_typefactory_class_init, + NULL, + NULL, + sizeof(GstTypeFactory), + 0, + (GInstanceInitFunc) gst_typefactory_init, + }; + typefactory_type = g_type_register_static (GST_TYPE_PLUGIN_FEATURE, + "GstTypeFactory", &typefactory_info, 0); + } + return typefactory_type; +} + +static void +gst_typefactory_class_init (GstTypeFactoryClass *klass) +{ + GObjectClass *gobject_class; + GstObjectClass *gstobject_class; + GstPluginFeatureClass *gstpluginfeature_class; + + gobject_class = (GObjectClass*)klass; + gstobject_class = (GstObjectClass*)klass; + gstpluginfeature_class = (GstPluginFeatureClass*) klass; + + parent_class = g_type_class_ref (GST_TYPE_PLUGIN_FEATURE); + + gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_typefactory_save_thyself); + gstobject_class->restore_thyself = GST_DEBUG_FUNCPTR (gst_typefactory_restore_thyself); + + gstpluginfeature_class->unload_thyself = GST_DEBUG_FUNCPTR (gst_typefactory_unload_thyself); + _gst_types = NULL; _gst_maxtype = 1; /* type 0 is undefined */ + + _gst_typefactories = NULL; +} + +static void +gst_typefactory_init (GstTypeFactory *factory) +{ + _gst_typefactories = g_list_prepend (_gst_typefactories, factory); +} + +GstTypeFactory* +gst_typefactory_new (GstTypeDefinition *definition) +{ + GstTypeFactory *factory; + + g_return_val_if_fail (definition != NULL, NULL); + g_return_val_if_fail (definition->name != NULL, NULL); + g_return_val_if_fail (definition->mime != NULL, NULL); + + factory = gst_typefactory_find (definition->name); + + if (!factory) { + factory = GST_TYPEFACTORY (g_object_new (GST_TYPE_TYPEFACTORY, NULL)); + } + + gst_object_set_name (GST_OBJECT (factory), definition->name); + factory->mime = g_strdup (definition->mime); + factory->exts = g_strdup (definition->exts); + factory->typefindfunc = definition->typefindfunc; + + return factory; } /** @@ -77,10 +152,10 @@ gst_type_register (GstTypeFactory *factory) type->id = _gst_maxtype++; type->mime = factory->mime; type->exts = factory->exts; + type->factories = NULL; _gst_types = g_list_prepend (_gst_types, type); id = type->id; - GST_DEBUG (GST_CAT_TYPES,"gsttype: new mime type '%s', id %d\n", type->mime, type->id); } else { type = gst_type_find_by_id (id); @@ -90,15 +165,15 @@ gst_type_register (GstTypeFactory *factory) /* if there is no existing typefind function, try to use new one */ } - if (factory->typefindfunc) { - type->typefindfuncs = g_slist_prepend (type->typefindfuncs, factory->typefindfunc); - } + GST_DEBUG (GST_CAT_TYPES,"gsttype: %s(%p) gave new mime type '%s', id %d\n", + GST_OBJECT_NAME (factory), factory, type->mime, type->id); + type->factories = g_slist_prepend (type->factories, factory); return id; } -static -guint16 gst_type_find_by_mime_func (const gchar *mime) +static guint16 +gst_type_find_by_mime_func (const gchar *mime) { GList *walk; GstType *type; @@ -202,18 +277,56 @@ gst_type_get_list (void) return _gst_types; } + /** - * gst_typefactory_save_thyself: - * @factory: the type factory to save - * @parent: the parent node to save into + * gst_typefactory_find: + * @name: the name of the typefactory to find * - * Save a typefactory into an XML representation. + * Return the TypeFactory with the given name. * - * Returns: the new xmlNodePtr + * Returns: a GstTypeFactory with the given name; */ -xmlNodePtr -gst_typefactory_save_thyself (GstTypeFactory *factory, xmlNodePtr parent) +GstTypeFactory* +gst_typefactory_find (const gchar *name) { + GList *walk = _gst_typefactories; + GstTypeFactory *factory; + + while (walk) { + factory = GST_TYPEFACTORY (walk->data); + if (!strcmp (GST_OBJECT_NAME (factory), name)) + return factory; + walk = g_list_next (walk); + } + return NULL; +} + +static void +gst_typefactory_unload_thyself (GstPluginFeature *feature) +{ + GstTypeFactory *factory; + + g_return_if_fail (GST_IS_TYPEFACTORY (feature)); + + factory = GST_TYPEFACTORY (feature); + + if (factory->typefindfunc) + factory->typefindfunc = gst_type_typefind_dummy; +} + +static xmlNodePtr +gst_typefactory_save_thyself (GstObject *object, xmlNodePtr parent) +{ + GstTypeFactory *factory; + + g_return_val_if_fail (GST_IS_TYPEFACTORY (object), parent); + + factory = GST_TYPEFACTORY (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); @@ -225,52 +338,43 @@ gst_typefactory_save_thyself (GstTypeFactory *factory, xmlNodePtr parent) return parent; } -static GstCaps * +static GstCaps* gst_type_typefind_dummy (GstBuffer *buffer, gpointer priv) { - GstType *type = (GstType *)priv; - guint16 typeid; - GSList *funcs; + GstTypeFactory *factory = (GstTypeFactory *)priv; - GST_DEBUG (GST_CAT_TYPES,"gsttype: need to load typefind function for %s\n", type->mime); + GST_DEBUG (GST_CAT_TYPES,"gsttype: need to load typefind function for %s\n", factory->mime); - type->typefindfuncs = NULL; - gst_plugin_load_typefactory (type->mime); - typeid = gst_type_find_by_mime (type->mime); - type = gst_type_find_by_id (typeid); + gst_plugin_feature_ensure_loaded (GST_PLUGIN_FEATURE (factory)); - funcs = type->typefindfuncs; - - while (funcs) { - GstTypeFindFunc func = (GstTypeFindFunc) funcs->data; - - if (func) { - GstCaps *res = func (buffer, type); - if (res) return res; - } - - funcs = g_slist_next (funcs); + if (factory->typefindfunc) { + GstCaps *res = factory->typefindfunc (buffer, factory); + if (res) + return res; } - return FALSE; + return NULL; } /** - * gst_typefactory_load_thyself: + * gst_typefactory_restore_thyself: * @parent: the parent node to load from * * Load a typefactory from an XML representation. * * Returns: the new typefactory */ -GstTypeFactory* -gst_typefactory_load_thyself (xmlNodePtr parent) +static void +gst_typefactory_restore_thyself (GstObject *object, xmlNodePtr parent) { - - GstTypeFactory *factory = g_new0 (GstTypeFactory, 1); + GstTypeFactory *factory = GST_TYPEFACTORY (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); @@ -284,6 +388,6 @@ gst_typefactory_load_thyself (xmlNodePtr parent) field = field->next; } - return factory; + gst_type_register (factory); } diff --git a/gst/gsttype.h b/gst/gsttype.h index 68ab8ce686..9c7606c27d 100644 --- a/gst/gsttype.h +++ b/gst/gsttype.h @@ -26,13 +26,16 @@ #include #include +#include /* type of function used to check a stream for equality with type */ -typedef GstCaps *(*GstTypeFindFunc) (GstBuffer *buf,gpointer priv); +typedef GstCaps *(*GstTypeFindFunc) (GstBuffer *buf, gpointer priv); typedef struct _GstType GstType; +typedef struct _GstTypeDefinition GstTypeDefinition; typedef struct _GstTypeFactory GstTypeFactory; +typedef struct _GstTypeFactoryClass GstTypeFactoryClass; struct _GstType { guint16 id; /* type id (assigned) */ @@ -40,34 +43,58 @@ struct _GstType { gchar *mime; /* MIME type */ gchar *exts; /* space-delimited list of extensions */ - GSList *typefindfuncs; /* typefind functions */ + GSList *factories; /* factories providing this type */ }; -struct _GstTypeFactory { +struct _GstTypeDefinition { + gchar *name; gchar *mime; gchar *exts; GstTypeFindFunc typefindfunc; }; +#define GST_TYPE_TYPEFACTORY \ + (gst_typefactory_get_type()) +#define GST_TYPEFACTORY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_TYPEFACTORY,GstTypeFactory)) +#define GST_TYPEFACTORY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_TYPEFACTORY,GstTypeFactoryClass)) +#define GST_IS_TYPEFACTORY(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_TYPEFACTORY)) +#define GST_IS_TYPEFACTORY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_TYPEFACTORY)) -/* initialize the subsystem */ -void _gst_type_initialize (void); +struct _GstTypeFactory { + GstPluginFeature feature; + + gchar *mime; + gchar *exts; + GstTypeFindFunc typefindfunc; +}; + +struct _GstTypeFactoryClass { + GstPluginFeatureClass parent; +}; + + +GType gst_typefactory_get_type (void); + +GstTypeFactory* gst_typefactory_new (GstTypeDefinition *definition); + +GstTypeFactory* gst_typefactory_find (const gchar *name); /* create a new type, or find/merge an existing one */ -guint16 gst_type_register (GstTypeFactory *factory); +guint16 gst_type_register (GstTypeFactory *factory); /* look up a type by mime or extension */ -guint16 gst_type_find_by_mime (const gchar *mime); -guint16 gst_type_find_by_ext (const gchar *ext); +guint16 gst_type_find_by_mime (const gchar *mime); +guint16 gst_type_find_by_ext (const gchar *ext); /* get GstType by id */ -GstType* gst_type_find_by_id (guint16 id); +GstType* gst_type_find_by_id (guint16 id); /* get the list of registered types (returns list of GstType!) */ -GList* gst_type_get_list (void); - -xmlNodePtr gst_typefactory_save_thyself (GstTypeFactory *factory, xmlNodePtr parent); -GstTypeFactory* gst_typefactory_load_thyself (xmlNodePtr parent); +GList* gst_type_get_list (void); #endif /* __GST_TYPE_H__ */ diff --git a/gst/gsttypefind.c b/gst/gsttypefind.c index 8ab953e400..09894e0de1 100644 --- a/gst/gsttypefind.c +++ b/gst/gsttypefind.c @@ -52,13 +52,15 @@ enum { }; -static void gst_typefind_class_init (GstTypeFindClass *klass); -static void gst_typefind_init (GstTypeFind *typefind); +static void gst_typefind_class_init (GstTypeFindClass *klass); +static void gst_typefind_init (GstTypeFind *typefind); -static void gst_typefind_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); -static void gst_typefind_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); +static void gst_typefind_set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec); +static void gst_typefind_get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec); -static void gst_typefind_chain (GstPad *pad, GstBuffer *buf); +static void gst_typefind_chain (GstPad *pad, GstBuffer *buf); static GstElementClass *parent_class = NULL; static guint gst_typefind_signals[LAST_SIGNAL] = { 0 }; @@ -103,8 +105,8 @@ gst_typefind_class_init (GstTypeFindClass *klass) g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); - gobject_class->set_property = gst_typefind_set_property; - gobject_class->get_property = gst_typefind_get_property; + gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_typefind_set_property); + gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_typefind_get_property); } static void @@ -168,17 +170,18 @@ gst_typefind_chain (GstPad *pad, GstBuffer *buf) type_list = gst_type_get_list (); while (type_list) { - GSList *funcs; + GSList *factories; type = (GstType *)type_list->data; - funcs = type->typefindfuncs; + factories = type->factories; - while (funcs) { - GstTypeFindFunc typefindfunc = (GstTypeFindFunc)funcs->data; + while (factories) { + GstTypeFactory *factory = GST_TYPEFACTORY (factories->data); + GstTypeFindFunc typefindfunc = (GstTypeFindFunc)factory->typefindfunc; GstCaps *caps; GST_DEBUG (0,"try type :%d \"%s\"\n", type->id, type->mime); - if (typefindfunc && (caps = typefindfunc (buf, type))) { + if (typefindfunc && (caps = typefindfunc (buf, factory))) { GST_DEBUG (0,"found type :%d \"%s\" \"%s\"\n", caps->id, type->mime, gst_caps_get_name (caps)); typefind->caps = caps; @@ -200,7 +203,7 @@ gst_typefind_chain (GstPad *pad, GstBuffer *buf) goto end; } - funcs = g_slist_next (funcs); + factories = g_slist_next (factories); } type_list = g_list_next (type_list); diff --git a/gst/types/gsttypes.c b/gst/types/gsttypes.c index 0723f3db00..dedd45a62f 100644 --- a/gst/types/gsttypes.c +++ b/gst/types/gsttypes.c @@ -21,10 +21,10 @@ #include #include -GstTypeFactory _factories[] = { - { "audio/raw", ".raw", NULL }, - { "video/raw image/raw", ".raw", NULL }, - { NULL, NULL, NULL }, +GstTypeDefinition _definitions[] = { + { "gsttypes_audio/raw", "audio/raw", ".raw", NULL }, + { "gsttypes_video/raw", "video/raw", ".raw", NULL }, + { NULL, NULL, NULL, NULL }, }; @@ -33,10 +33,12 @@ plugin_init (GModule *module, GstPlugin *plugin) { gint i = 0; - while (_factories[i].mime) { - gst_type_register (&_factories[i]); - gst_plugin_add_type (plugin, &_factories[i]); - GST_DEBUG(0, "added factory #%d '%s'\n",i,_factories[i].mime); + while (_definitions[i].name) { + GstTypeFactory *factory; + + factory = gst_typefactory_new (&_definitions[i]); + gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory)); + GST_DEBUG(0, "added factory #%d '%s'\n", i, _definitions[i].name); i++; } diff --git a/plugins/elements/gstelements.c b/plugins/elements/gstelements.c index a41efd6ac8..482c7bd5b7 100644 --- a/plugins/elements/gstelements.c +++ b/plugins/elements/gstelements.c @@ -82,7 +82,7 @@ plugin_init (GModule *module, GstPlugin *plugin) (_elements[i].type) (), _elements[i].details); if (factory != NULL) { - gst_plugin_add_factory (plugin, factory); + gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory)); if (_elements[i].factoryinit) { _elements[i].factoryinit (factory); } diff --git a/plugins/elements/gstqueue.c b/plugins/elements/gstqueue.c index 2722e96cf9..fdf8bfec54 100644 --- a/plugins/elements/gstqueue.c +++ b/plugins/elements/gstqueue.c @@ -67,30 +67,33 @@ enum { }; -static void gst_queue_class_init (GstQueueClass *klass); -static void gst_queue_init (GstQueue *queue); +static void gst_queue_class_init (GstQueueClass *klass); +static void gst_queue_init (GstQueue *queue); -static void gst_queue_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); -static void gst_queue_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); +static void gst_queue_set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec); +static void gst_queue_get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec); -static GstPadNegotiateReturn gst_queue_handle_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data); +static GstPadNegotiateReturn gst_queue_handle_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data); static GstPadNegotiateReturn gst_queue_handle_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data); -static void gst_queue_chain (GstPad *pad, GstBuffer *buf); -static GstBuffer * gst_queue_get (GstPad *pad); -static GstBufferPool* gst_queue_get_bufferpool (GstPad *pad); +static void gst_queue_chain (GstPad *pad, GstBuffer *buf); +static GstBuffer * gst_queue_get (GstPad *pad); +static GstBufferPool* gst_queue_get_bufferpool (GstPad *pad); -static void gst_queue_flush (GstQueue *queue); +static void gst_queue_flush (GstQueue *queue); -static GstElementStateReturn gst_queue_change_state (GstElement *element); +static GstElementStateReturn gst_queue_change_state (GstElement *element); +#define GST_TYPE_QUEUE_LEAKY (queue_leaky_get_type()) static GType queue_leaky_get_type(void) { static GType queue_leaky_type = 0; static GEnumValue queue_leaky[] = { - { GST_QUEUE_NO_LEAK, "0", "Not Leaky" }, - { GST_QUEUE_LEAK_UPSTREAM, "1", "Leaky on Upstream" }, - { GST_QUEUE_LEAK_DOWNSTREAM, "2", "Leaky on Downstream" }, + { GST_QUEUE_NO_LEAK, "0", "Not Leaky" }, + { GST_QUEUE_LEAK_UPSTREAM, "1", "Leaky on Upstream" }, + { GST_QUEUE_LEAK_DOWNSTREAM, "2", "Leaky on Downstream" }, { 0, NULL, NULL }, }; if (!queue_leaky_type) { @@ -98,14 +101,13 @@ queue_leaky_get_type(void) { } return queue_leaky_type; } -#define GST_TYPE_QUEUE_LEAKY (queue_leaky_get_type()) - static GstElementClass *parent_class = NULL; //static guint gst_queue_signals[LAST_SIGNAL] = { 0 }; GType -gst_queue_get_type(void) { +gst_queue_get_type(void) +{ static GType queue_type = 0; if (!queue_type) { diff --git a/test/xml/createreg.c b/test/xml/createreg.c index 7ca35148ee..c94e7b10ef 100644 --- a/test/xml/createreg.c +++ b/test/xml/createreg.c @@ -19,7 +19,7 @@ struct _GstRegistryElement { int main(int argc,char *argv[]) { xmlDocPtr doc; xmlNodePtr tree, subtree; - GList *plugins = NULL, *elements = NULL; + GList *plugins = NULL, *features = NULL; gst_init(&argc,&argv); gst_plugin_load_all(); @@ -33,25 +33,30 @@ int main(int argc,char *argv[]) { subtree = xmlNewChild(tree,NULL,"name",plugin->name); subtree = xmlNewChild(tree,NULL,"longname",plugin->longname); subtree = xmlNewChild(tree,NULL,"filename",plugin->filename); - elements = plugin->elements; - while (elements) { - GstElementFactory *element = (GstElementFactory *)elements->data; - tree = xmlNewChild(doc->root,NULL,"element",NULL); - subtree = xmlNewChild(tree,NULL,"plugin",plugin->name); - subtree = xmlNewChild(tree,NULL,"name",element->name); - subtree = xmlNewChild(tree,NULL,"longname", - element->details->longname); - subtree = xmlNewChild(tree,NULL,"class", - element->details->klass); - subtree = xmlNewChild(tree,NULL,"description", - element->details->description); - subtree = xmlNewChild(tree,NULL,"version", - element->details->version); - subtree = xmlNewChild(tree,NULL,"author", - element->details->author); - subtree = xmlNewChild(tree,NULL,"copyright", - element->details->copyright); - elements = g_list_next(elements); + features = plugin->features; + while (features) { + GstPluginFeature *feature = GST_PLUGIN_FEATURE (features->data); + + if (GST_IS_ELEMENTFACTORY (feature)) { + GstElementFactory *element = GST_ELEMENTFACTORY (feature); + + tree = xmlNewChild(doc->root,NULL, "element", NULL); + subtree = xmlNewChild (tree, NULL, "plugin", plugin->name); + subtree = xmlNewChild (tree, NULL, "name", gst_object_get_name (GST_OBJECT (element))); + subtree = xmlNewChild (tree, NULL, "longname", + element->details->longname); + subtree = xmlNewChild (tree, NULL, "class", + element->details->klass); + subtree = xmlNewChild (tree, NULL, "description", + element->details->description); + subtree = xmlNewChild (tree, NULL, "version", + element->details->version); + subtree = xmlNewChild (tree, NULL, "author", + element->details->author); + subtree = xmlNewChild (tree, NULL, "copyright", + element->details->copyright); + } + features = g_list_next (features); } plugins = g_list_next(plugins); } diff --git a/tests/caps.c b/tests/caps.c index 97dc963817..214aa131d3 100644 --- a/tests/caps.c +++ b/tests/caps.c @@ -123,7 +123,7 @@ main (int argc, char *argv[]) doc->xmlRootNode = xmlNewDocNode (doc, NULL, "Capabilities", NULL); g_thread_init (NULL); - _gst_type_initialize (); + gst_typefactory_get_type (); _gst_props_initialize (); _gst_caps_initialize (); diff --git a/tests/old/examples/plugins/example.c b/tests/old/examples/plugins/example.c index 351f9fcfc2..1783a82eba 100644 --- a/tests/old/examples/plugins/example.c +++ b/tests/old/examples/plugins/example.c @@ -87,18 +87,15 @@ GST_PADTEMPLATE_FACTORY (src_factory, /* A number of functon prototypes are given so we can refer to them later. */ -static void gst_example_class_init (GstExampleClass *klass); -static void gst_example_init (GstExample *example); +static void gst_example_class_init (GstExampleClass *klass); +static void gst_example_init (GstExample *example); -static void gst_example_chain (GstPad *pad, GstBuffer *buf); +static void gst_example_chain (GstPad *pad, GstBuffer *buf); -static void gst_example_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); -static void gst_example_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); - -/* These hold the constructed pad templates, which are created during - * plugin load, and used during element instantiation. - */ -static GstPadTemplate *src_template, *sink_template; +static void gst_example_set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec); +static void gst_example_get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec); /* The parent class pointer needs to be kept around for some object * operations. @@ -189,10 +186,10 @@ static void gst_example_init(GstExample *example) { /* First we create the sink pad, which is the input to the element. - * We will use the sink_template constructed in the plugin_init function - * (below) to quickly generate the pad we need. + * We will use the template constructed by the factory. */ - example->sinkpad = gst_pad_new_from_template (sink_template, "sink"); + example->sinkpad = gst_pad_new_from_template ( + GST_PADTEMPLATE_GET (sink_factory), "sink"); /* Setting the chain function allows us to supply the function that will * actually be performing the work. Without this, the element would do * nothing, with undefined results (assertion failures and such). @@ -208,7 +205,8 @@ gst_example_init(GstExample *example) * pads don't have chain functions, because they can't accept buffers, * they only produce them. */ - example->srcpad = gst_pad_new_from_template (src_template, "src"); + example->srcpad = gst_pad_new_from_template ( + GST_PADTEMPLATE_GET (src_factory), "src"); gst_element_add_pad(GST_ELEMENT(example),example->srcpad); /* Initialization of element's private variables. */ @@ -344,17 +342,12 @@ plugin_init (GModule *module, GstPlugin *plugin) /* The pad templates can be easily generated from the factories above, * and then added to the list of padtemplates for the elementfactory. - * Note that the generated padtemplates are stored in static global - * variables, for the gst_example_init function to use later on. */ - sink_template = sink_factory (); - gst_elementfactory_add_padtemplate (factory, sink_template); - - src_template = src_factory (); - gst_elementfactory_add_padtemplate (factory, src_template); + gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (sink_factory)); + gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (src_factory)); /* The very last thing is to register the elementfactory with the plugin. */ - gst_plugin_add_factory (plugin, factory); + gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory)); /* Now we can return successfully. */ return TRUE; diff --git a/tests/old/testsuite/Makefile.am b/tests/old/testsuite/Makefile.am index 1d95a82218..ccab2e5c73 100644 --- a/tests/old/testsuite/Makefile.am +++ b/tests/old/testsuite/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = refcounting capsnego +SUBDIRS = refcounting capsnego plugin testprogs = test_gst_init diff --git a/tests/old/testsuite/plugin/.gitignore b/tests/old/testsuite/plugin/.gitignore new file mode 100644 index 0000000000..2532427aec --- /dev/null +++ b/tests/old/testsuite/plugin/.gitignore @@ -0,0 +1,13 @@ +Makefile +Makefile.in +*.o +*.lo +*.la +.deps +.libs +dynamic +linked +loading +registry +static +static2 diff --git a/tests/old/testsuite/plugin/Makefile.am b/tests/old/testsuite/plugin/Makefile.am new file mode 100644 index 0000000000..9acef8767d --- /dev/null +++ b/tests/old/testsuite/plugin/Makefile.am @@ -0,0 +1,20 @@ +testprogs = loading dynamic linked static registry static2 + +filterdir = $(libdir)/gst + +filter_LTLIBRARIES = libtestplugin.la libtestplugin2.la + +libtestplugin_la_SOURCES = testplugin.c +libtestplugin2_la_SOURCES = testplugin2.c + +linked_LDFLAGS = -L. -ltestplugin -ltestplugin2 + +static_SOURCES = static.c testplugin_s.c testplugin2_s.c + +TESTS = $(testprogs) + +check_PROGRAMS = $(testprogs) + +# we have nothing but apps here, we can do this safely +LIBS += $(GST_LIBS) +CFLAGS += $(GST_CFLAGS) diff --git a/tests/old/testsuite/plugin/README b/tests/old/testsuite/plugin/README new file mode 100644 index 0000000000..f8898c59d0 --- /dev/null +++ b/tests/old/testsuite/plugin/README @@ -0,0 +1,59 @@ +The following plugin modes are supported: + +1) registry based +----------------- + +All known plugins are listed in the registry file. + + gst_plugin_find ("pluginname"); + +Works right after gst_init (), along with the elements in it. +dynamic loading of the plugin is performed when a feature inside +it is requested. + +example: registry.c. (You might want to run gstreamer-register with +the --gst-plugin-path=. to added the test dir to the plugin path so +that the testplugins can be found) + + +2) non registry based, dynmic loading +------------------------------------- + +Plugins are know after a gst_plugin_load ("pluginname"). This +function will scan de plugin paths, so you might want to perform +a gst_plugin_add_path ("path"). + +After the gst_plugin_load(), the features are available without any +further actions. + +example: dynamic.c + + +3) non registry based, shared linking +------------------------------------- + +You can add the plugin .so (or equivalent) file to the LDFLAGS at +compile time. The plugin will be known after the gst_init() without +any further actions. + +example: linked.c + + +4) non registry based, static linking +------------------------------------- + +Plugin compiled with the GST_PLUGIN_STATIC defined can be statically +linked to the executable. The plugin is available after gst_init () +without any further actions. + +example: static.c (plugins are statically linked from another file) + static2.c (plugins are included in the main file) + + +Any combination of the above is possible too, for example, you can use +a registry, have some plugins load dynamically and have another few +linked in as a shared lib. + +You cannot statically link multiple plugins that are compiled without the +GST_PLUGIN_STATIC symbol defined (this will cause multiple defined at link +time for obvious reasons) diff --git a/tests/old/testsuite/plugin/dynamic.c b/tests/old/testsuite/plugin/dynamic.c new file mode 100644 index 0000000000..1e3c4d3255 --- /dev/null +++ b/tests/old/testsuite/plugin/dynamic.c @@ -0,0 +1,23 @@ + +#include + +int +main (int argc, char *argv[]) +{ + GstPlugin *plugin; + gboolean loaded; + + gst_init (&argc, &argv); + + gst_plugin_add_path ("."); + + loaded = gst_plugin_load ("testplugin"); + g_assert (loaded == TRUE); + + plugin = gst_plugin_find ("testplugin"); + g_assert (plugin != NULL); + + g_print ("testplugin: %d, %s\n", loaded, plugin->name); + + return 0; +} diff --git a/tests/old/testsuite/plugin/linked.c b/tests/old/testsuite/plugin/linked.c new file mode 100644 index 0000000000..48215ee5bb --- /dev/null +++ b/tests/old/testsuite/plugin/linked.c @@ -0,0 +1,22 @@ + +#include + +int +main (int argc, char *argv[]) +{ + GstPlugin *plugin; + + gst_init (&argc, &argv); + + plugin = gst_plugin_find ("testplugin"); + g_assert (plugin != NULL); + + g_print ("testplugin: %p %s\n", plugin, plugin->name); + + plugin = gst_plugin_find ("testplugin2"); + g_assert (plugin != NULL); + + g_print ("testplugin2: %p %s\n", plugin, plugin->name); + + return 0; +} diff --git a/tests/old/testsuite/plugin/loading.c b/tests/old/testsuite/plugin/loading.c new file mode 100644 index 0000000000..479630fe73 --- /dev/null +++ b/tests/old/testsuite/plugin/loading.c @@ -0,0 +1,54 @@ + +#include + +int +main (int argc, char *argv[]) +{ + GstPlugin *plugin; + gboolean loaded = FALSE; + gint numplugins; + + gst_init (&argc, &argv); + + numplugins = g_list_length (gst_plugin_get_list ()); + g_print ("%d plugins loaded\n", numplugins); + g_mem_chunk_info (); + + plugin = gst_plugin_find ("ossaudio"); + g_assert (plugin != NULL); + + g_print ("%d features in plugin\n", g_list_length (gst_plugin_get_feature_list (plugin))); + + + g_print ("ossaudio: %p %d\n", plugin, gst_plugin_is_loaded (plugin)); + + loaded = gst_plugin_load_plugin (plugin); + g_assert (loaded == TRUE); + + numplugins = g_list_length (gst_plugin_get_list ()); + g_print ("%d plugins loaded\n", numplugins); + + g_mem_chunk_info (); + + plugin = gst_plugin_find ("ossaudio"); + g_assert (plugin != NULL); + g_print ("ossaudio: %p %d\n", plugin, gst_plugin_is_loaded (plugin)); + + g_print ("%d features in plugin\n", g_list_length (gst_plugin_get_feature_list (plugin))); + + loaded = gst_plugin_load_plugin (plugin); + g_assert (loaded == TRUE); + + numplugins = g_list_length (gst_plugin_get_list ()); + g_print ("%d plugins loaded\n", numplugins); + + g_print ("%d features in plugin\n", g_list_length (gst_plugin_get_feature_list (plugin))); + + g_mem_chunk_info (); + + plugin = gst_plugin_find ("ossaudio"); + g_assert (plugin != NULL); + g_print ("osssink: %p %d\n", plugin, gst_plugin_is_loaded (plugin)); + + return 0; +} diff --git a/tests/old/testsuite/plugin/registry.c b/tests/old/testsuite/plugin/registry.c new file mode 100644 index 0000000000..e7ec555dc8 --- /dev/null +++ b/tests/old/testsuite/plugin/registry.c @@ -0,0 +1,17 @@ + +#include + +int +main (int argc, char *argv[]) +{ + GstPlugin *plugin; + + gst_init (&argc, &argv); + + plugin = gst_plugin_find ("testplugin"); + g_assert (plugin != NULL); + + g_print ("testplugin: %s\n", plugin->name); + + return 0; +} diff --git a/tests/old/testsuite/plugin/static.c b/tests/old/testsuite/plugin/static.c new file mode 100644 index 0000000000..6b7d5373a8 --- /dev/null +++ b/tests/old/testsuite/plugin/static.c @@ -0,0 +1,23 @@ + +#include + +int +main (int argc, char *argv[]) +{ + GstPlugin *plugin; + + gst_init (&argc, &argv); + + plugin = gst_plugin_find ("testplugin"); + g_assert (plugin != NULL); + + g_print ("testplugin: %p %s\n", plugin, plugin->name); + + plugin = gst_plugin_find ("testplugin2"); + g_assert (plugin != NULL); + + g_print ("testplugin2: %p %s\n", plugin, plugin->name); + + return 0; +} + diff --git a/tests/old/testsuite/plugin/static2.c b/tests/old/testsuite/plugin/static2.c new file mode 100644 index 0000000000..4d16ab9864 --- /dev/null +++ b/tests/old/testsuite/plugin/static2.c @@ -0,0 +1,50 @@ + +#define GST_PLUGIN_STATIC + +#include + +static gboolean +plugin_init (GModule *module, GstPlugin *plugin) +{ + return TRUE; +} + +GST_PLUGIN_DESC ( + GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "testplugin", + plugin_init +); + +static gboolean +plugin2_init (GModule *module, GstPlugin *plugin) +{ + return TRUE; +} + +GST_PLUGIN_DESC ( + GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "testplugin2", + plugin2_init +); + +int +main (int argc, char *argv[]) +{ + GstPlugin *plugin; + + gst_init (&argc, &argv); + + plugin = gst_plugin_find ("testplugin"); + g_assert (plugin != NULL); + + g_print ("testplugin: %p %s\n", plugin, plugin->name); + + plugin = gst_plugin_find ("testplugin2"); + g_assert (plugin != NULL); + + g_print ("testplugin2: %p %s\n", plugin, plugin->name); + + return 0; +} diff --git a/tests/old/testsuite/plugin/testplugin.c b/tests/old/testsuite/plugin/testplugin.c new file mode 100644 index 0000000000..57c55220af --- /dev/null +++ b/tests/old/testsuite/plugin/testplugin.c @@ -0,0 +1,15 @@ + +#include + +static gboolean +plugin_init (GModule *module, GstPlugin *plugin) +{ + return TRUE; +} + +GST_PLUGIN_DESC ( + GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "testplugin", + plugin_init +); diff --git a/tests/old/testsuite/plugin/testplugin2.c b/tests/old/testsuite/plugin/testplugin2.c new file mode 100644 index 0000000000..08a14b7247 --- /dev/null +++ b/tests/old/testsuite/plugin/testplugin2.c @@ -0,0 +1,15 @@ + +#include + +static gboolean +plugin_init (GModule *module, GstPlugin *plugin) +{ + return TRUE; +} + +GST_PLUGIN_DESC ( + GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "testplugin2", + plugin_init +); diff --git a/tests/old/testsuite/plugin/testplugin2_s.c b/tests/old/testsuite/plugin/testplugin2_s.c new file mode 100644 index 0000000000..a743a0cbf0 --- /dev/null +++ b/tests/old/testsuite/plugin/testplugin2_s.c @@ -0,0 +1,3 @@ +#define GST_PLUGIN_STATIC + +#include "testplugin2.c" diff --git a/tests/old/testsuite/plugin/testplugin_s.c b/tests/old/testsuite/plugin/testplugin_s.c new file mode 100644 index 0000000000..7ecea6c093 --- /dev/null +++ b/tests/old/testsuite/plugin/testplugin_s.c @@ -0,0 +1,3 @@ +#define GST_PLUGIN_STATIC + +#include "testplugin.c" diff --git a/tests/registry.c b/tests/registry.c index a7ac4c5006..03e3d6a19d 100644 --- a/tests/registry.c +++ b/tests/registry.c @@ -9,7 +9,7 @@ dump_plugins (void) while (plugins) { GstPlugin *plugin = (GstPlugin *)plugins->data; - g_print ("plugin: %s, loaded %d\n", plugin->name, plugin->loaded); + g_print ("plugin: %s, loaded %d\n", plugin->name, gst_plugin_is_loaded (plugin)); plugins = g_list_next (plugins); } @@ -24,7 +24,7 @@ dump_factories (void) while (factories) { GstElementFactory *factory = (GstElementFactory *)factories->data; - g_print ("factory: %s %d\n", factory->name, factory->type); + g_print ("factory: %s %d\n", gst_object_get_name (GST_OBJECT (factory)), factory->type); factories = g_list_next (factories); } diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am index 1d95a82218..ccab2e5c73 100644 --- a/testsuite/Makefile.am +++ b/testsuite/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = refcounting capsnego +SUBDIRS = refcounting capsnego plugin testprogs = test_gst_init diff --git a/testsuite/plugin/.gitignore b/testsuite/plugin/.gitignore new file mode 100644 index 0000000000..2532427aec --- /dev/null +++ b/testsuite/plugin/.gitignore @@ -0,0 +1,13 @@ +Makefile +Makefile.in +*.o +*.lo +*.la +.deps +.libs +dynamic +linked +loading +registry +static +static2 diff --git a/testsuite/plugin/Makefile.am b/testsuite/plugin/Makefile.am new file mode 100644 index 0000000000..9acef8767d --- /dev/null +++ b/testsuite/plugin/Makefile.am @@ -0,0 +1,20 @@ +testprogs = loading dynamic linked static registry static2 + +filterdir = $(libdir)/gst + +filter_LTLIBRARIES = libtestplugin.la libtestplugin2.la + +libtestplugin_la_SOURCES = testplugin.c +libtestplugin2_la_SOURCES = testplugin2.c + +linked_LDFLAGS = -L. -ltestplugin -ltestplugin2 + +static_SOURCES = static.c testplugin_s.c testplugin2_s.c + +TESTS = $(testprogs) + +check_PROGRAMS = $(testprogs) + +# we have nothing but apps here, we can do this safely +LIBS += $(GST_LIBS) +CFLAGS += $(GST_CFLAGS) diff --git a/testsuite/plugin/README b/testsuite/plugin/README new file mode 100644 index 0000000000..f8898c59d0 --- /dev/null +++ b/testsuite/plugin/README @@ -0,0 +1,59 @@ +The following plugin modes are supported: + +1) registry based +----------------- + +All known plugins are listed in the registry file. + + gst_plugin_find ("pluginname"); + +Works right after gst_init (), along with the elements in it. +dynamic loading of the plugin is performed when a feature inside +it is requested. + +example: registry.c. (You might want to run gstreamer-register with +the --gst-plugin-path=. to added the test dir to the plugin path so +that the testplugins can be found) + + +2) non registry based, dynmic loading +------------------------------------- + +Plugins are know after a gst_plugin_load ("pluginname"). This +function will scan de plugin paths, so you might want to perform +a gst_plugin_add_path ("path"). + +After the gst_plugin_load(), the features are available without any +further actions. + +example: dynamic.c + + +3) non registry based, shared linking +------------------------------------- + +You can add the plugin .so (or equivalent) file to the LDFLAGS at +compile time. The plugin will be known after the gst_init() without +any further actions. + +example: linked.c + + +4) non registry based, static linking +------------------------------------- + +Plugin compiled with the GST_PLUGIN_STATIC defined can be statically +linked to the executable. The plugin is available after gst_init () +without any further actions. + +example: static.c (plugins are statically linked from another file) + static2.c (plugins are included in the main file) + + +Any combination of the above is possible too, for example, you can use +a registry, have some plugins load dynamically and have another few +linked in as a shared lib. + +You cannot statically link multiple plugins that are compiled without the +GST_PLUGIN_STATIC symbol defined (this will cause multiple defined at link +time for obvious reasons) diff --git a/testsuite/plugin/dynamic.c b/testsuite/plugin/dynamic.c new file mode 100644 index 0000000000..1e3c4d3255 --- /dev/null +++ b/testsuite/plugin/dynamic.c @@ -0,0 +1,23 @@ + +#include + +int +main (int argc, char *argv[]) +{ + GstPlugin *plugin; + gboolean loaded; + + gst_init (&argc, &argv); + + gst_plugin_add_path ("."); + + loaded = gst_plugin_load ("testplugin"); + g_assert (loaded == TRUE); + + plugin = gst_plugin_find ("testplugin"); + g_assert (plugin != NULL); + + g_print ("testplugin: %d, %s\n", loaded, plugin->name); + + return 0; +} diff --git a/testsuite/plugin/linked.c b/testsuite/plugin/linked.c new file mode 100644 index 0000000000..48215ee5bb --- /dev/null +++ b/testsuite/plugin/linked.c @@ -0,0 +1,22 @@ + +#include + +int +main (int argc, char *argv[]) +{ + GstPlugin *plugin; + + gst_init (&argc, &argv); + + plugin = gst_plugin_find ("testplugin"); + g_assert (plugin != NULL); + + g_print ("testplugin: %p %s\n", plugin, plugin->name); + + plugin = gst_plugin_find ("testplugin2"); + g_assert (plugin != NULL); + + g_print ("testplugin2: %p %s\n", plugin, plugin->name); + + return 0; +} diff --git a/testsuite/plugin/loading.c b/testsuite/plugin/loading.c new file mode 100644 index 0000000000..479630fe73 --- /dev/null +++ b/testsuite/plugin/loading.c @@ -0,0 +1,54 @@ + +#include + +int +main (int argc, char *argv[]) +{ + GstPlugin *plugin; + gboolean loaded = FALSE; + gint numplugins; + + gst_init (&argc, &argv); + + numplugins = g_list_length (gst_plugin_get_list ()); + g_print ("%d plugins loaded\n", numplugins); + g_mem_chunk_info (); + + plugin = gst_plugin_find ("ossaudio"); + g_assert (plugin != NULL); + + g_print ("%d features in plugin\n", g_list_length (gst_plugin_get_feature_list (plugin))); + + + g_print ("ossaudio: %p %d\n", plugin, gst_plugin_is_loaded (plugin)); + + loaded = gst_plugin_load_plugin (plugin); + g_assert (loaded == TRUE); + + numplugins = g_list_length (gst_plugin_get_list ()); + g_print ("%d plugins loaded\n", numplugins); + + g_mem_chunk_info (); + + plugin = gst_plugin_find ("ossaudio"); + g_assert (plugin != NULL); + g_print ("ossaudio: %p %d\n", plugin, gst_plugin_is_loaded (plugin)); + + g_print ("%d features in plugin\n", g_list_length (gst_plugin_get_feature_list (plugin))); + + loaded = gst_plugin_load_plugin (plugin); + g_assert (loaded == TRUE); + + numplugins = g_list_length (gst_plugin_get_list ()); + g_print ("%d plugins loaded\n", numplugins); + + g_print ("%d features in plugin\n", g_list_length (gst_plugin_get_feature_list (plugin))); + + g_mem_chunk_info (); + + plugin = gst_plugin_find ("ossaudio"); + g_assert (plugin != NULL); + g_print ("osssink: %p %d\n", plugin, gst_plugin_is_loaded (plugin)); + + return 0; +} diff --git a/testsuite/plugin/registry.c b/testsuite/plugin/registry.c new file mode 100644 index 0000000000..e7ec555dc8 --- /dev/null +++ b/testsuite/plugin/registry.c @@ -0,0 +1,17 @@ + +#include + +int +main (int argc, char *argv[]) +{ + GstPlugin *plugin; + + gst_init (&argc, &argv); + + plugin = gst_plugin_find ("testplugin"); + g_assert (plugin != NULL); + + g_print ("testplugin: %s\n", plugin->name); + + return 0; +} diff --git a/testsuite/plugin/static.c b/testsuite/plugin/static.c new file mode 100644 index 0000000000..6b7d5373a8 --- /dev/null +++ b/testsuite/plugin/static.c @@ -0,0 +1,23 @@ + +#include + +int +main (int argc, char *argv[]) +{ + GstPlugin *plugin; + + gst_init (&argc, &argv); + + plugin = gst_plugin_find ("testplugin"); + g_assert (plugin != NULL); + + g_print ("testplugin: %p %s\n", plugin, plugin->name); + + plugin = gst_plugin_find ("testplugin2"); + g_assert (plugin != NULL); + + g_print ("testplugin2: %p %s\n", plugin, plugin->name); + + return 0; +} + diff --git a/testsuite/plugin/static2.c b/testsuite/plugin/static2.c new file mode 100644 index 0000000000..4d16ab9864 --- /dev/null +++ b/testsuite/plugin/static2.c @@ -0,0 +1,50 @@ + +#define GST_PLUGIN_STATIC + +#include + +static gboolean +plugin_init (GModule *module, GstPlugin *plugin) +{ + return TRUE; +} + +GST_PLUGIN_DESC ( + GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "testplugin", + plugin_init +); + +static gboolean +plugin2_init (GModule *module, GstPlugin *plugin) +{ + return TRUE; +} + +GST_PLUGIN_DESC ( + GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "testplugin2", + plugin2_init +); + +int +main (int argc, char *argv[]) +{ + GstPlugin *plugin; + + gst_init (&argc, &argv); + + plugin = gst_plugin_find ("testplugin"); + g_assert (plugin != NULL); + + g_print ("testplugin: %p %s\n", plugin, plugin->name); + + plugin = gst_plugin_find ("testplugin2"); + g_assert (plugin != NULL); + + g_print ("testplugin2: %p %s\n", plugin, plugin->name); + + return 0; +} diff --git a/testsuite/plugin/testplugin.c b/testsuite/plugin/testplugin.c new file mode 100644 index 0000000000..57c55220af --- /dev/null +++ b/testsuite/plugin/testplugin.c @@ -0,0 +1,15 @@ + +#include + +static gboolean +plugin_init (GModule *module, GstPlugin *plugin) +{ + return TRUE; +} + +GST_PLUGIN_DESC ( + GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "testplugin", + plugin_init +); diff --git a/testsuite/plugin/testplugin2.c b/testsuite/plugin/testplugin2.c new file mode 100644 index 0000000000..08a14b7247 --- /dev/null +++ b/testsuite/plugin/testplugin2.c @@ -0,0 +1,15 @@ + +#include + +static gboolean +plugin_init (GModule *module, GstPlugin *plugin) +{ + return TRUE; +} + +GST_PLUGIN_DESC ( + GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "testplugin2", + plugin_init +); diff --git a/testsuite/plugin/testplugin2_s.c b/testsuite/plugin/testplugin2_s.c new file mode 100644 index 0000000000..a743a0cbf0 --- /dev/null +++ b/testsuite/plugin/testplugin2_s.c @@ -0,0 +1,3 @@ +#define GST_PLUGIN_STATIC + +#include "testplugin2.c" diff --git a/testsuite/plugin/testplugin_s.c b/testsuite/plugin/testplugin_s.c new file mode 100644 index 0000000000..7ecea6c093 --- /dev/null +++ b/testsuite/plugin/testplugin_s.c @@ -0,0 +1,3 @@ +#define GST_PLUGIN_STATIC + +#include "testplugin.c" diff --git a/tools/Makefile.am b/tools/Makefile.am index 45351f2a8c..332aa836b4 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -1,5 +1,15 @@ -bin_PROGRAMS = gstreamer-launch gstreamer-register gstreamer-inspect \ - gstreamer-compprep gstreamer-complete + +if GST_DISABLE_REGISTRY +GST_REGISTRY_SRC = +else +GST_REGISTRY_SRC = gstreamer-register +endif + +bin_PROGRAMS = gstreamer-launch \ + $(GST_REGISTRY_SRC) \ + gstreamer-inspect \ + gstreamer-compprep \ + gstreamer-complete man_MANS = gstreamer-launch.1 gstreamer-register.1 gstreamer-inspect.1 \ gstreamer-complete.1 gstreamer-compprep.1 diff --git a/tools/gstreamer-compprep.c b/tools/gstreamer-compprep.c index 40492ad169..215887ca01 100644 --- a/tools/gstreamer-compprep.c +++ b/tools/gstreamer-compprep.c @@ -4,9 +4,7 @@ int main(int argc,char *argv[]) { xmlDocPtr doc; xmlNodePtr factorynode, padnode, argnode, optionnode; - GList *plugins, *factories, *padtemplates, *pads; - GstPlugin *plugin; - GstElementFactory *factory; + GList *plugins, *features, *padtemplates, *pads; GstElement *element; GstPad *pad; GstPadTemplate *padtemplate; @@ -22,20 +20,31 @@ int main(int argc,char *argv[]) { plugins = gst_plugin_get_list(); while (plugins) { + GstPlugin *plugin; + plugin = (GstPlugin *)(plugins->data); plugins = g_list_next (plugins); - factories = gst_plugin_get_factory_list(plugin); - while (factories) { - factory = (GstElementFactory *)(factories->data); - factories = g_list_next (factories); + features = gst_plugin_get_feature_list(plugin); + while (features) { + GstPluginFeature *feature; + GstElementFactory *factory; + + feature = GST_PLUGIN_FEATURE (features->data); + features = g_list_next (features); + + if (!GST_IS_ELEMENTFACTORY (feature)) + continue; + + factory = GST_ELEMENTFACTORY (feature); factorynode = xmlNewChild (doc->xmlRootNode, NULL, "element", NULL); - xmlNewChild (factorynode, NULL, "name", factory->name); + xmlNewChild (factorynode, NULL, "name", gst_object_get_name (GST_OBJECT (factory))); element = gst_elementfactory_create(factory,"element"); if (element == NULL) { - fprintf(stderr,"couldn't construct element from factory %s\n",factory->name); + fprintf(stderr,"couldn't construct element from factory %s\n", + gst_object_get_name (GST_OBJECT (factory))); return 1; } diff --git a/tools/gstreamer-inspect.c b/tools/gstreamer-inspect.c index 2b9e2779a2..2ec45ac589 100644 --- a/tools/gstreamer-inspect.c +++ b/tools/gstreamer-inspect.c @@ -4,7 +4,9 @@ // this must be built within the gstreamer dir, else this will fail #include -void print_prop(GstPropsEntry *prop,gboolean showname,gchar *pfx) { +static void +print_prop (GstPropsEntry *prop, gboolean showname, gchar *pfx) +{ GList *list; GstPropsEntry *listentry; gchar *longprefix; @@ -56,7 +58,9 @@ void print_prop(GstPropsEntry *prop,gboolean showname,gchar *pfx) { } } -void print_props(GstProps *properties,gchar *pfx) { +static void +print_props (GstProps *properties, gchar *pfx) +{ GList *props; GstPropsEntry *prop; @@ -94,7 +98,7 @@ output_hierarchy (GType type, gint level, gint *maxlevel) g_print ("\n"); } -gint +static gint print_element_info (GstElementFactory *factory) { GstElement *element; @@ -394,88 +398,110 @@ print_element_info (GstElementFactory *factory) return 0; } -void print_element_list() { - GList *plugins, *factories; - GstPlugin *plugin; - GstElementFactory *factory; +static void +print_element_list (void) +{ + GList *plugins; plugins = gst_plugin_get_list(); while (plugins) { + GList *features; + GstPlugin *plugin; + plugin = (GstPlugin*)(plugins->data); plugins = g_list_next (plugins); -// printf("%s:\n",plugin->name); + features = gst_plugin_get_feature_list (plugin); + while (features) { + GstPluginFeature *feature; - factories = gst_plugin_get_factory_list(plugin); - while (factories) { - factory = (GstElementFactory*)(factories->data); - factories = g_list_next (factories); + feature = GST_PLUGIN_FEATURE (features->data); - printf("%s: %s: %s\n",plugin->name,factory->name,factory->details->longname); + if (GST_IS_ELEMENTFACTORY (feature)) { + GstElementFactory *factory; + + factory = GST_ELEMENTFACTORY (feature); + printf("%s: %s: %s\n",plugin->name, GST_OBJECT_NAME (factory) ,factory->details->longname); + } + else if (GST_IS_AUTOPLUGFACTORY (feature)) { + GstAutoplugFactory *factory; + + factory = GST_AUTOPLUGFACTORY (feature); + printf("%s: %s: %s\n", plugin->name, GST_OBJECT_NAME (factory), factory->longdesc); + } + else if (GST_IS_TYPEFACTORY (feature)) { + GstTypeFactory *factory; + + factory = GST_TYPEFACTORY (feature); + printf("%s: %s: %s\n", plugin->name, factory->mime, factory->exts); + + if (factory->typefindfunc) + printf(" Has typefind function: %s\n",GST_DEBUG_FUNCPTR_NAME(factory->typefindfunc)); + } + else { + printf("%s: %s (%s)\n", plugin->name, gst_object_get_name (GST_OBJECT (feature)), + g_type_name (G_OBJECT_TYPE (feature))); + } + + features = g_list_next (features); } - -// printf("\n"); } } -void +static void print_plugin_info (GstPlugin *plugin) { + GList *features; + printf("Plugin Details:\n"); printf(" Name:\t\t%s\n",plugin->name); printf(" Long Name:\t%s\n",plugin->longname); printf(" Filename:\t%s\n",plugin->filename); printf("\n"); - if (plugin->numelements) { - GList *factories; - GstElementFactory *factory; + features = gst_plugin_get_feature_list (plugin); - printf("Element Factories:\n"); + while (features) { + GstPluginFeature *feature; - factories = gst_plugin_get_factory_list(plugin); - while (factories) { - factory = (GstElementFactory*)(factories->data); - factories = g_list_next(factories); + feature = GST_PLUGIN_FEATURE (features->data); - printf(" %s: %s\n",factory->name,factory->details->longname); + if (GST_IS_ELEMENTFACTORY (feature)) { + GstElementFactory *factory; + + factory = GST_ELEMENTFACTORY (feature); + printf(" %s: %s\n", GST_OBJECT_NAME (factory) ,factory->details->longname); } - } - if (plugin->numautopluggers) { - GList *factories; - GstAutoplugFactory *factory; + else if (GST_IS_AUTOPLUGFACTORY (feature)) { + GstAutoplugFactory *factory; - printf("Autpluggers:\n"); - - factories = gst_plugin_get_autoplug_list(plugin); - while (factories) { - factory = (GstAutoplugFactory*)(factories->data); - factories = g_list_next(factories); - - printf(" %s: %s\n", factory->name, factory->longdesc); + factory = GST_AUTOPLUGFACTORY (feature); + printf(" %s: %s\n", GST_OBJECT_NAME (factory), factory->longdesc); } - } - if (plugin->numtypes) { - GList *factories; - GstTypeFactory *factory; - - printf("Types:\n"); - - factories = gst_plugin_get_type_list(plugin); - while (factories) { - factory = (GstTypeFactory*)(factories->data); - factories = g_list_next(factories); + else if (GST_IS_TYPEFACTORY (feature)) { + GstTypeFactory *factory; + factory = GST_TYPEFACTORY (feature); printf(" %s: %s\n", factory->mime, factory->exts); + if (factory->typefindfunc) printf(" Has typefind function: %s\n",GST_DEBUG_FUNCPTR_NAME(factory->typefindfunc)); } + else { + printf(" %s (%s)\n", gst_object_get_name (GST_OBJECT (feature)), + g_type_name (G_OBJECT_TYPE (feature))); + } + + + features = g_list_next (features); } printf("\n"); } -int main(int argc,char *argv[]) { +int +main (int argc, char *argv[]) +{ GstElementFactory *factory; GstPlugin *plugin; gchar *so;