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 :-)
This commit is contained in:
Wim Taymans 2001-08-21 20:16:48 +00:00
parent 0732e92957
commit 12bbbd5c1e
66 changed files with 1938 additions and 949 deletions

View file

@ -841,6 +841,7 @@ GST_SUBSYSTEM_DISABLE(TYPEFIND,[typefind plugin],)
GST_SUBSYSTEM_DISABLE(AUTOPLUG,[autoplugger subsystem]) GST_SUBSYSTEM_DISABLE(AUTOPLUG,[autoplugger subsystem])
GST_SUBSYSTEM_DISABLE(PARSE,[command-line parser]) GST_SUBSYSTEM_DISABLE(PARSE,[command-line parser])
GST_SUBSYSTEM_DISABLE(TRACE,[tracing subsystem]) GST_SUBSYSTEM_DISABLE(TRACE,[tracing subsystem])
GST_SUBSYSTEM_DISABLE(REGISTRY,[plugin registry])
GST_DEFINE_CFLAGS="$GST_DEFINE_CFLAGS $GST_SUBSYSTEM_DISABLE_DEFINES" GST_DEFINE_CFLAGS="$GST_DEFINE_CFLAGS $GST_SUBSYSTEM_DISABLE_DEFINES"
@ -1224,6 +1225,7 @@ tests/muxing/Makefile
testsuite/Makefile testsuite/Makefile
testsuite/capsnego/Makefile testsuite/capsnego/Makefile
testsuite/refcounting/Makefile testsuite/refcounting/Makefile
testsuite/plugin/Makefile
tests/nego/Makefile tests/nego/Makefile
examples/Makefile examples/Makefile
examples/autoplug/Makefile examples/autoplug/Makefile

View file

@ -36,7 +36,7 @@ gst_editor_create_item(gdouble x,gdouble y)
factory = element_select_dialog(); factory = element_select_dialog();
if (factory) { if (factory) {
// g_print("got factory \"%s\"\n",factory->name); // 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 (element) {
if (GST_IS_BIN(element)) { if (GST_IS_BIN(element)) {
// g_print("factory is a bin\n"); // g_print("factory is a bin\n");

View file

@ -479,7 +479,7 @@ gst_editor_property_create (GstEditorProperty *property, GstEditorElement *eleme
gtk_widget_show(entry); gtk_widget_show(entry);
gtk_entry_set_editable(GTK_ENTRY(entry), FALSE); gtk_entry_set_editable(GTK_ENTRY(entry), FALSE);
gtk_entry_set_text(GTK_ENTRY(entry), 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), 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); gtk_table_attach(GTK_TABLE(table), entry, 1, 2, count, count+1, GTK_FILL|GTK_EXPAND, 0, 0, 0);
count++; count++;

View file

@ -33,8 +33,8 @@ struct element_select_details {
}; };
static gint compare_name(gconstpointer a,gconstpointer b) { static gint compare_name(gconstpointer a,gconstpointer b) {
return (strcmp(((GstElementFactory *)a)->name, return (strcmp(GST_OBJECT_NAME (a),
((GstElementFactory *)b)->name)); GST_OBJECT_NAME (b)));
} }
gint str_compare(gconstpointer a,gconstpointer b) { gint str_compare(gconstpointer a,gconstpointer b) {
@ -64,7 +64,7 @@ static void make_ctree(GtkCTree *tree,GtkCTreeNode *parent,
traverse = class->factories; traverse = class->factories;
while (traverse) { while (traverse) {
GstElementFactory *factory = (GstElementFactory *)(traverse->data); 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); data[1] = g_strdup(factory->details->description);
node = gtk_ctree_insert_node(tree,classnode,NULL,data,0, node = gtk_ctree_insert_node(tree,classnode,NULL,data,0,
NULL,NULL,NULL,NULL,TRUE,FALSE); NULL,NULL,NULL,NULL,TRUE,FALSE);
@ -200,7 +200,7 @@ GstElementFactory *element_select_dialog() {
elements = gst_elementfactory_get_list(); elements = gst_elementfactory_get_list();
while (elements) { while (elements) {
element = (GstElementFactory *)(elements->data); 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 */ /* split up the factory's class */
classes = g_strsplit(element->details->klass,"/",0); classes = g_strsplit(element->details->klass,"/",0);
class = classes; class = classes;

View file

@ -87,18 +87,15 @@ GST_PADTEMPLATE_FACTORY (src_factory,
/* A number of functon prototypes are given so we can refer to them later. */ /* 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_class_init (GstExampleClass *klass);
static void gst_example_init (GstExample *example); 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_set_property (GObject *object, guint prop_id,
static void gst_example_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); const GValue *value, GParamSpec *pspec);
static void gst_example_get_property (GObject *object, guint prop_id,
/* These hold the constructed pad templates, which are created during GValue *value, GParamSpec *pspec);
* plugin load, and used during element instantiation.
*/
static GstPadTemplate *src_template, *sink_template;
/* The parent class pointer needs to be kept around for some object /* The parent class pointer needs to be kept around for some object
* operations. * operations.
@ -189,10 +186,10 @@ static void
gst_example_init(GstExample *example) gst_example_init(GstExample *example)
{ {
/* First we create the sink pad, which is the input to the element. /* 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 * We will use the template constructed by the factory.
* (below) to quickly generate the pad we need.
*/ */
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 /* Setting the chain function allows us to supply the function that will
* actually be performing the work. Without this, the element would do * actually be performing the work. Without this, the element would do
* nothing, with undefined results (assertion failures and such). * 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, * pads don't have chain functions, because they can't accept buffers,
* they only produce them. * 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); gst_element_add_pad(GST_ELEMENT(example),example->srcpad);
/* Initialization of element's private variables. */ /* 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, /* The pad templates can be easily generated from the factories above,
* and then added to the list of padtemplates for the elementfactory. * 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, GST_PADTEMPLATE_GET (sink_factory));
gst_elementfactory_add_padtemplate (factory, sink_template); gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (src_factory));
src_template = src_factory ();
gst_elementfactory_add_padtemplate (factory, src_template);
/* The very last thing is to register the elementfactory with the plugin. */ /* 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. */ /* Now we can return successfully. */
return TRUE; return TRUE;

View file

@ -72,6 +72,7 @@ libgst_la_SOURCES = \
gstpad.c \ gstpad.c \
gstpipeline.c \ gstpipeline.c \
gstplugin.c \ gstplugin.c \
gstpluginfeature.c \
gstprops.c \ gstprops.c \
gstqueue.c \ gstqueue.c \
gstscheduler.c \ gstscheduler.c \
@ -171,6 +172,7 @@ libgstinclude_HEADERS = \
gstpad.h \ gstpad.h \
gstpipeline.h \ gstpipeline.h \
gstplugin.h \ gstplugin.h \
gstpluginfeature.h \
gstprops.h \ gstprops.h \
gstqueue.h \ gstqueue.h \
gstscheduler.h \ gstscheduler.h \

View file

@ -362,7 +362,7 @@ plugin_init (GModule *module, GstPlugin *plugin)
&gst_autoplugcache_details); &gst_autoplugcache_details);
g_return_val_if_fail (factory != NULL, FALSE); 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; return TRUE;
} }

View file

@ -594,7 +594,7 @@ plugin_init (GModule *module, GstPlugin *plugin)
&gst_autoplugger_details); &gst_autoplugger_details);
g_return_val_if_fail (factory != NULL, FALSE); 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; return TRUE;
} }

View file

@ -93,7 +93,7 @@ plugin_init (GModule *module, GstPlugin *plugin)
gst_static_autoplug_get_type ()); gst_static_autoplug_get_type ());
if (factory != NULL) { if (factory != NULL) {
gst_plugin_add_autoplugger (plugin, factory); gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
} }
return TRUE; return TRUE;
} }
@ -125,7 +125,8 @@ gst_autoplug_can_match (GstElementFactory *src, GstElementFactory *dest)
if (gst_caps_check_compatibility (gst_padtemplate_get_caps (srctemp), if (gst_caps_check_compatibility (gst_padtemplate_get_caps (srctemp),
gst_padtemplate_get_caps (desttemp))) { gst_padtemplate_get_caps (desttemp))) {
GST_DEBUG (GST_CAT_AUTOPLUG_ATTEMPT, 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; return TRUE;
} }
} }
@ -135,7 +136,8 @@ gst_autoplug_can_match (GstElementFactory *src, GstElementFactory *dest)
srctemps = g_list_next (srctemps); srctemps = g_list_next (srctemps);
} }
GST_DEBUG (GST_CAT_AUTOPLUG_ATTEMPT, 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; 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); gst_bin_add (GST_BIN(result), element);
if (srcelement != NULL) { if (srcelement != NULL) {
@ -415,8 +417,8 @@ differ:
factory = (GstElementFactory *)(factories[i]->data); factory = (GstElementFactory *)(factories[i]->data);
GST_DEBUG (0,"factory \"%s\"\n", factory->name); GST_DEBUG (0,"factory \"%s\"\n", GST_OBJECT_NAME (factory));
element = gst_elementfactory_create(factory, factory->name); element = gst_elementfactory_create(factory, GST_OBJECT_NAME (factory));
GST_DEBUG (0,"adding element %s\n", GST_ELEMENT_NAME (element)); GST_DEBUG (0,"adding element %s\n", GST_ELEMENT_NAME (element));
gst_bin_add(GST_BIN(thebin), 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; next = rgnNodes[find_factory(rgnNodes, current)].iPrev;
if (next) { if (next) {
factories = g_list_prepend (factories, current); 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; current = next;
} }

View file

@ -93,7 +93,7 @@ plugin_init (GModule *module, GstPlugin *plugin)
gst_static_autoplug_render_get_type ()); gst_static_autoplug_render_get_type ());
if (factory != NULL) { if (factory != NULL) {
gst_plugin_add_autoplugger (plugin, factory); gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
} }
return TRUE; 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 (desttemp->direction == GST_PAD_SINK && desttemp->presence != GST_PAD_REQUEST) {
if (gst_caps_check_compatibility (GST_PADTEMPLATE_CAPS (srctemp), GST_PADTEMPLATE_CAPS (desttemp))) { if (gst_caps_check_compatibility (GST_PADTEMPLATE_CAPS (srctemp), GST_PADTEMPLATE_CAPS (desttemp))) {
GST_DEBUG (GST_CAT_AUTOPLUG_ATTEMPT, 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; return TRUE;
} }
} }
@ -159,7 +160,8 @@ gst_autoplug_can_match (GstElementFactory *src, GstElementFactory *dest)
} }
} }
GST_DEBUG (GST_CAT_AUTOPLUG_ATTEMPT, 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; return FALSE;
} }
@ -283,7 +285,7 @@ gst_autoplug_caps_find_cost (gpointer src, gpointer dest, gpointer data)
else { else {
res = gst_autoplug_can_match ((GstElementFactory *)src, (GstElementFactory *)dest); res = gst_autoplug_can_match ((GstElementFactory *)src, (GstElementFactory *)dest);
GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"factory %s to factory %s %d", 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) 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); gst_bin_add (GST_BIN(result), element);
if (srcelement != NULL) { if (srcelement != NULL) {
@ -454,8 +456,8 @@ differ:
if (factories[i]) { if (factories[i]) {
factory = (GstElementFactory *)(factories[i]->data); factory = (GstElementFactory *)(factories[i]->data);
GST_DEBUG (0,"factory \"%s\"\n", factory->name); GST_DEBUG (0,"factory \"%s\"\n", GST_OBJECT_NAME (factory));
element = gst_elementfactory_create(factory, factory->name); element = gst_elementfactory_create(factory, GST_OBJECT_NAME (factory));
} }
else { else {
element = sinkelement; element = sinkelement;
@ -553,7 +555,7 @@ construct_path (gst_autoplug_node *rgnNodes, gpointer factory)
next = rgnNodes[find_factory(rgnNodes, current)].iPrev; next = rgnNodes[find_factory(rgnNodes, current)].iPrev;
if (next) { if (next) {
factories = g_list_prepend (factories, current); 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; current = next;
} }

View file

@ -82,7 +82,7 @@ plugin_init (GModule *module, GstPlugin *plugin)
(_elements[i].type) (), (_elements[i].type) (),
_elements[i].details); _elements[i].details);
if (factory != NULL) { if (factory != NULL) {
gst_plugin_add_factory (plugin, factory); gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
if (_elements[i].factoryinit) { if (_elements[i].factoryinit) {
_elements[i].factoryinit (factory); _elements[i].factoryinit (factory);
} }

View file

@ -32,6 +32,7 @@
#include "gstpipeline.h" #include "gstpipeline.h"
#include "gstthread.h" #include "gstthread.h"
#include "gstqueue.h" #include "gstqueue.h"
#include "gstautoplug.h"
#ifndef GST_DISABLE_TYPEFIND #ifndef GST_DISABLE_TYPEFIND
#include "gsttypefind.h" #include "gsttypefind.h"
#endif #endif
@ -88,8 +89,11 @@ gst_init (int *argc, char **argv[])
GST_INFO (GST_CAT_GST_INIT, "Initializing GStreamer Core Library"); 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_cpu_initialize ();
_gst_type_initialize ();
_gst_props_initialize (); _gst_props_initialize ();
_gst_caps_initialize (); _gst_caps_initialize ();
_gst_plugin_initialize (); _gst_plugin_initialize ();

View file

@ -24,9 +24,8 @@
#include "gst_private.h" #include "gst_private.h"
#include "gstautoplug.h" #include "gstautoplug.h"
#include "gstplugin.h"
GList* _gst_autoplugfactories; static GList* _gst_autoplugfactories;
enum { enum {
NEW_OBJECT, NEW_OBJECT,
@ -60,7 +59,7 @@ GType gst_autoplug_get_type(void)
4, 4,
(GInstanceInitFunc)gst_autoplug_init, (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; return autoplug_type;
} }
@ -81,18 +80,13 @@ gst_autoplug_class_init(GstAutoplugClass *klass)
G_STRUCT_OFFSET (GstAutoplugClass, new_object), NULL, NULL, G_STRUCT_OFFSET (GstAutoplugClass, new_object), NULL, NULL,
g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
GST_TYPE_OBJECT); GST_TYPE_OBJECT);
} }
static void gst_autoplug_init(GstAutoplug *autoplug) static void gst_autoplug_init(GstAutoplug *autoplug)
{ {
} }
void
_gst_autoplug_initialize (void)
{
_gst_autoplugfactories = NULL;
}
/** /**
* gst_autoplug_signal_new_object: * gst_autoplug_signal_new_object:
* @autoplug: The autoplugger to emit the signal * @autoplug: The autoplugger to emit the signal
@ -170,6 +164,63 @@ gst_autoplug_to_renderers (GstAutoplug *autoplug, GstCaps *srccaps, GstElement *
return element; 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: * gst_autoplugfactory_new:
@ -187,15 +238,17 @@ gst_autoplugfactory_new (const gchar *name, const gchar *longdesc, GType type)
GstAutoplugFactory *factory; GstAutoplugFactory *factory;
g_return_val_if_fail(name != NULL, NULL); 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); gst_object_set_name (GST_OBJECT (factory), name);
if (factory->longdesc)
factory->name = g_strdup(name); g_free (factory->longdesc);
factory->longdesc = g_strdup (longdesc); factory->longdesc = g_strdup (longdesc);
factory->type = type; factory->type = type;
_gst_autoplugfactories = g_list_prepend (_gst_autoplugfactories, factory);
return factory; return factory;
} }
@ -236,7 +289,7 @@ gst_autoplugfactory_find (const gchar *name)
walk = _gst_autoplugfactories; walk = _gst_autoplugfactories;
while (walk) { while (walk) {
factory = (GstAutoplugFactory *)(walk->data); factory = (GstAutoplugFactory *)(walk->data);
if (!strcmp (name, factory->name)) if (!strcmp (name, GST_OBJECT_NAME (factory)))
return factory; return factory;
walk = g_list_next (walk); walk = g_list_next (walk);
} }
@ -273,10 +326,8 @@ gst_autoplugfactory_create (GstAutoplugFactory *factory)
g_return_val_if_fail (factory != NULL, NULL); g_return_val_if_fail (factory != NULL, NULL);
if (factory->type == 0){ gst_plugin_feature_ensure_loaded (GST_PLUGIN_FEATURE (factory));
factory = gst_plugin_load_autoplugfactory (factory->name);
}
g_return_val_if_fail (factory != NULL, NULL);
g_return_val_if_fail (factory->type != 0, NULL); g_return_val_if_fail (factory->type != 0, NULL);
new = GST_AUTOPLUG (g_object_new(factory->type,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);; return gst_autoplugfactory_create (factory);;
} }
/** static xmlNodePtr
* gst_autoplugfactory_save_thyself: gst_autoplugfactory_save_thyself (GstObject *object, xmlNodePtr parent)
* @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)
{ {
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); xmlNewChild(parent,NULL,"longdesc", factory->longdesc);
return parent; return parent;
@ -336,23 +385,23 @@ gst_autoplugfactory_save_thyself (GstAutoplugFactory *factory, xmlNodePtr parent
* *
* Returns: A new factory based on the XML node. * Returns: A new factory based on the XML node.
*/ */
GstAutoplugFactory* static void
gst_autoplugfactory_load_thyself (xmlNodePtr parent) gst_autoplugfactory_restore_thyself (GstObject *object, xmlNodePtr parent)
{ {
GstAutoplugFactory *factory = g_new0(GstAutoplugFactory, 1); GstAutoplugFactory *factory = GST_AUTOPLUGFACTORY (object);
xmlNodePtr children = parent->xmlChildrenNode; 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) { while (children) {
if (!strcmp(children->name, "name")) { if (!strcmp(children->name, "name")) {
factory->name = xmlNodeGetContent(children); gst_object_set_name (GST_OBJECT (factory), xmlNodeGetContent(children));
} }
if (!strcmp(children->name, "longdesc")) { if (!strcmp(children->name, "longdesc")) {
factory->longdesc = xmlNodeGetContent(children); factory->longdesc = xmlNodeGetContent(children);
} }
children = children->next; children = children->next;
} }
_gst_autoplugfactories = g_list_prepend (_gst_autoplugfactories, factory);
return factory;
} }

View file

@ -69,13 +69,6 @@ struct _GstAutoplugClass {
GstElement* (*autoplug_to_renderers) (GstAutoplug *autoplug, GstCaps *srccaps, GstElement *target, va_list args); 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); GType gst_autoplug_get_type (void);
@ -90,6 +83,33 @@ GstElement* gst_autoplug_to_renderers (GstAutoplug *autoplug, GstCaps *srccaps
* creating autopluggers * 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); GstAutoplugFactory* gst_autoplugfactory_new (const gchar *name, const gchar *longdesc, GType type);
void gst_autoplugfactory_destroy (GstAutoplugFactory *factory); 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_create (GstAutoplugFactory *factory);
GstAutoplug* gst_autoplugfactory_make (const gchar *name); 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 #ifdef __cplusplus
} }
#endif /* __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_caps
#pragma GCC poison gst_autoplug_to_renderers #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_new
#pragma GCC poison gst_autoplugfactory_destroy #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_create
#pragma GCC poison gst_autoplugfactory_make #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_DISABLE_AUTOPLUG
#endif /* __GST_AUTOPLUG_H__ */ #endif /* __GST_AUTOPLUG_H__ */

View file

@ -47,13 +47,17 @@ get_type_for_mime (const gchar *mime)
typeid = gst_type_find_by_mime (mime); typeid = gst_type_find_by_mime (mime);
if (typeid == 0) { if (typeid == 0) {
GstTypeFactory factory; // = g_new0 (GstTypeFactory, 1); GstTypeDefinition definition;
GstTypeFactory *factory;
factory.mime = g_strdup (mime); definition.name = "capstype";
factory.exts = NULL; definition.mime = g_strdup (mime);
factory.typefindfunc = NULL; definition.exts = NULL;
definition.typefindfunc = NULL;
typeid = gst_type_register (&factory); factory = gst_typefactory_new (&definition);
typeid = gst_type_register (factory);
} }
return typeid; return typeid;
} }

View file

@ -51,8 +51,10 @@ static void gst_element_class_init (GstElementClass *klass);
static void gst_element_init (GstElement *element); static void gst_element_init (GstElement *element);
static void gst_element_base_class_init (GstElementClass *klass); 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_set_property (GObject *object, guint prop_id,
static void gst_element_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); 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_shutdown (GObject *object);
static void gst_element_real_destroy (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: * gst_element_set_name:
* @element: GstElement to set name of * @element: GstElement to set name of
@ -1004,9 +993,7 @@ gst_element_save_thyself (GstObject *object,
// GType type; // GType type;
GstElement *element; 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 (GST_IS_ELEMENT (object), parent);
g_return_val_if_fail (parent != NULL, parent);
element = GST_ELEMENT (object); element = GST_ELEMENT (object);
@ -1017,7 +1004,7 @@ gst_element_save_thyself (GstObject *object,
if (oclass->elementfactory != NULL) { if (oclass->elementfactory != NULL) {
GstElementFactory *factory = (GstElementFactory *)oclass->elementfactory; 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); 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) { switch (state) {
#ifdef GST_DEBUG_COLOR #ifdef GST_DEBUG_COLOR
case GST_STATE_VOID_PENDING: return "NONE_PENDING";break; case GST_STATE_VOID_PENDING: return "NONE_PENDING";break;

View file

@ -36,6 +36,7 @@
#include <gst/gstobject.h> #include <gst/gstobject.h>
#include <gst/gstpad.h> #include <gst/gstpad.h>
#include <gst/cothreads.h> #include <gst/cothreads.h>
#include <gst/gstpluginfeature.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -125,8 +126,8 @@ typedef enum {
//typedef struct _GstElement GstElement; //typedef struct _GstElement GstElement;
//typedef struct _GstElementClass GstElementClass; //typedef struct _GstElementClass GstElementClass;
typedef struct _GstElementDetails GstElementDetails;
typedef struct _GstElementFactory GstElementFactory; typedef struct _GstElementFactory GstElementFactory;
typedef struct _GstElementFactoryClass GstElementFactoryClass;
typedef void (*GstElementLoopFunction) (GstElement *element); typedef void (*GstElementLoopFunction) (GstElement *element);
@ -177,29 +178,9 @@ struct _GstElementClass {
GstPad* (*request_new_pad) (GstElement *element, GstPadTemplate *templ); 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); void gst_element_class_add_padtemplate (GstElementClass *element, GstPadTemplate *templ);
GType gst_element_get_type (void); GType gst_element_get_type (void);
GstElement* gst_element_new (void);
#define gst_element_destroy(element) gst_object_destroy (GST_OBJECT (element)) #define gst_element_destroy(element) gst_object_destroy (GST_OBJECT (element))
void gst_element_set_loop_function (GstElement *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 */ /* called by the app to set the state of the element */
gint gst_element_set_state (GstElement *element, GstElementState state); 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); void gst_element_error (GstElement *element, const gchar *error);
@ -250,12 +232,50 @@ GstElement* gst_element_restore_thyself (xmlNodePtr self, GstObject *parent);
* factories stuff * 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, GstElementFactory* gst_elementfactory_new (const gchar *name,GType type,
GstElementDetails *details); GstElementDetails *details);
void gst_elementfactory_destroy (GstElementFactory *elementfactory);
GstElementFactory* gst_elementfactory_find (const gchar *name); 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, void gst_elementfactory_add_padtemplate (GstElementFactory *elementfactory,
GstPadTemplate *templ); GstPadTemplate *templ);
@ -271,12 +291,6 @@ GstElement* gst_elementfactory_create (GstElementFactory *factory,
GstElement* gst_elementfactory_make (const gchar *factoryname, const gchar *name); 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 #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */

View file

@ -24,32 +24,72 @@
#include "gst_private.h" #include "gst_private.h"
#include "gstelement.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 */ /* global list of registered elementfactories */
GList* _gst_elementfactories; static GList* _gst_elementfactories;
void static GstPluginFeatureClass *parent_class = NULL;
_gst_elementfactory_initialize (void) //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_elementfactories = NULL;
} }
/** static void
* gst_elementfactory_destroy: gst_elementfactory_init (GstElementFactory *factory)
* @elementfactory: factory to destroy
*
* Removes the elementfactory from the global list.
*/
void
gst_elementfactory_destroy (GstElementFactory *elementfactory)
{ {
g_return_if_fail (elementfactory != NULL); factory->padtemplates = NULL;
factory->numpadtemplates = 0;
_gst_elementfactories = g_list_remove (_gst_elementfactories, elementfactory); _gst_elementfactories = g_list_prepend (_gst_elementfactories, factory);
// we don't free the struct bacause someone might have a handle to it..
} }
/** /**
@ -71,13 +111,13 @@ gst_elementfactory_find (const gchar *name)
walk = _gst_elementfactories; walk = _gst_elementfactories;
while (walk) { while (walk) {
factory = (GstElementFactory *)(walk->data); factory = (GstElementFactory *)(walk->data);
if (!strcmp(name,factory->name)) if (!strcmp(name, GST_OBJECT_NAME (factory)))
return factory; return factory;
walk = g_list_next(walk); walk = g_list_next(walk);
} }
// this should be an ERROR // 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; return NULL;
} }
@ -88,7 +128,7 @@ gst_elementfactory_find (const gchar *name)
* *
* Returns: GList of type #GstElementFactory * Returns: GList of type #GstElementFactory
*/ */
GList* const GList*
gst_elementfactory_get_list (void) gst_elementfactory_get_list (void)
{ {
return _gst_elementfactories; return _gst_elementfactories;
@ -113,16 +153,18 @@ gst_elementfactory_new (const gchar *name, GType type,
GstElementFactory *factory; GstElementFactory *factory;
g_return_val_if_fail(name != NULL, NULL); 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; factory->type = type;
if (factory->details)
g_free (factory->details);
factory->details = details; factory->details = details;
factory->padtemplates = NULL;
factory->numpadtemplates = 0;
_gst_elementfactories = g_list_prepend (_gst_elementfactories, factory);
return factory; return factory;
} }
@ -149,13 +191,10 @@ gst_elementfactory_create (GstElementFactory *factory,
g_return_val_if_fail(name != NULL, NULL); g_return_val_if_fail(name != NULL, NULL);
GST_DEBUG (GST_CAT_ELEMENTFACTORY,"creating element from factory \"%s\" with name \"%s\"\n", 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); g_return_val_if_fail(factory->type != 0, NULL);
// create an instance of the element // create an instance of the element
@ -165,7 +204,7 @@ gst_elementfactory_create (GstElementFactory *factory,
// attempt to set the elemenfactory class pointer if necessary // attempt to set the elemenfactory class pointer if necessary
oclass = GST_ELEMENT_CLASS(G_OBJECT_GET_CLASS(element)); oclass = GST_ELEMENT_CLASS(G_OBJECT_GET_CLASS(element));
if (oclass->elementfactory == NULL) { 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; oclass->elementfactory = factory;
} }
@ -195,10 +234,10 @@ gst_elementfactory_make (const gchar *factoryname, const gchar *name)
GstElementFactory *factory; GstElementFactory *factory;
GstElement *element; GstElement *element;
g_return_val_if_fail(factoryname != NULL, NULL); g_return_val_if_fail (factoryname != NULL, NULL);
g_return_val_if_fail(name != 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); //gst_plugin_load_elementfactory(factoryname);
factory = gst_elementfactory_find(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); GST_INFO (GST_CAT_ELEMENTFACTORY,"couldn't create instance of elementfactory \"%s\"!",factoryname);
return NULL; return NULL;
} }
return element; return element;
} }
@ -225,9 +265,24 @@ void
gst_elementfactory_add_padtemplate (GstElementFactory *factory, gst_elementfactory_add_padtemplate (GstElementFactory *factory,
GstPadTemplate *templ) GstPadTemplate *templ)
{ {
GList *padtemplates;
g_return_if_fail(factory != NULL); g_return_if_fail(factory != NULL);
g_return_if_fail(templ != 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->padtemplates = g_list_append (factory->padtemplates, templ);
factory->numpadtemplates++; factory->numpadtemplates++;
} }
@ -298,24 +353,31 @@ gst_elementfactory_can_sink_caps (GstElementFactory *factory,
return FALSE; return FALSE;
} }
/** static void
* gst_elementfactory_save_thyself: gst_elementfactory_unload_thyself (GstPluginFeature *feature)
* @factory: factory to save {
* @parent: the parent xmlNodePtr GstElementFactory *factory;
*
* Saves the factory into an XML tree. factory = GST_ELEMENTFACTORY (feature);
*
* Returns: the new xmlNodePtr factory->type = 0;
*/ }
xmlNodePtr
gst_elementfactory_save_thyself (GstElementFactory *factory, static xmlNodePtr
gst_elementfactory_save_thyself (GstObject *object,
xmlNodePtr parent) xmlNodePtr parent)
{ {
GList *pads; 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); g_return_val_if_fail(factory != NULL, NULL);
xmlNewChild(parent,NULL,"name",factory->name);
xmlNewChild(parent,NULL,"longname", factory->details->longname); xmlNewChild(parent,NULL,"longname", factory->details->longname);
xmlNewChild(parent,NULL,"class", factory->details->klass); xmlNewChild(parent,NULL,"class", factory->details->klass);
xmlNewChild(parent,NULL,"description", factory->details->description); xmlNewChild(parent,NULL,"description", factory->details->description);
@ -338,26 +400,19 @@ gst_elementfactory_save_thyself (GstElementFactory *factory,
return parent; return parent;
} }
/** static void
* gst_elementfactory_load_thyself: gst_elementfactory_restore_thyself (GstObject *object, xmlNodePtr parent)
* @parent: the parent xmlNodePtr
*
* Creates a new factory from an xmlNodePtr.
*
* Returns: the new factory
*/
GstElementFactory *
gst_elementfactory_load_thyself (xmlNodePtr parent)
{ {
GstElementFactory *factory = g_new0(GstElementFactory, 1); GstElementFactory *factory = GST_ELEMENTFACTORY (object);
xmlNodePtr children = parent->xmlChildrenNode; xmlNodePtr children = parent->xmlChildrenNode;
factory->details = g_new0(GstElementDetails, 1); factory->details = g_new0(GstElementDetails, 1);
factory->padtemplates = NULL; factory->padtemplates = NULL;
if (GST_OBJECT_CLASS (parent_class)->restore_thyself) {
GST_OBJECT_CLASS (parent_class)->restore_thyself (object, parent);
}
while (children) { while (children) {
if (!strcmp(children->name, "name")) {
factory->name = xmlNodeGetContent(children);
}
if (!strcmp(children->name, "longname")) { if (!strcmp(children->name, "longname")) {
factory->details->longname = xmlNodeGetContent(children); factory->details->longname = xmlNodeGetContent(children);
} }
@ -386,8 +441,4 @@ gst_elementfactory_load_thyself (xmlNodePtr parent)
children = children->next; children = children->next;
} }
_gst_elementfactories = g_list_prepend (_gst_elementfactories, factory);
return factory;
} }

View file

@ -125,19 +125,6 @@ gst_object_init (GstObject *object)
GST_FLAG_SET (object, GST_FLOATING); 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: * gst_object_ref:
* @object: GstObject to reference * @object: GstObject to reference
@ -454,13 +441,15 @@ gst_object_unref (GstObject *object)
gboolean gboolean
gst_object_check_uniqueness (GList *list, const gchar *name) gst_object_check_uniqueness (GList *list, const gchar *name)
{ {
GstObject *child; g_return_val_if_fail (name != NULL, FALSE);
while (list) { while (list) {
child = GST_OBJECT (list->data); GstObject *child = GST_OBJECT (list->data);
list = g_list_next(list); 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; return TRUE;
@ -468,7 +457,6 @@ gst_object_check_uniqueness (GList *list, const gchar *name)
#ifndef GST_DISABLE_LOADSAVE #ifndef GST_DISABLE_LOADSAVE
/** /**
* gst_object_save_thyself: * gst_object_save_thyself:
* @object: GstObject to save * @object: GstObject to save
@ -488,17 +476,36 @@ gst_object_save_thyself (GstObject *object, xmlNodePtr parent)
g_return_val_if_fail (parent != NULL, parent); g_return_val_if_fail (parent != NULL, parent);
oclass = (GstObjectClass *)G_OBJECT_GET_CLASS(object); oclass = (GstObjectClass *)G_OBJECT_GET_CLASS(object);
if (oclass->save_thyself) if (oclass->save_thyself)
oclass->save_thyself (object, parent); oclass->save_thyself (object, parent);
#ifndef GST_DISABLE_LOADSAVE
g_signal_emit (G_OBJECT (object), gst_object_signals[OBJECT_SAVED], 0, parent); g_signal_emit (G_OBJECT (object), gst_object_signals[OBJECT_SAVED], 0, parent);
#endif
return parent; 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 #endif // GST_DISABLE_LOADSAVE
/** /**

View file

@ -103,17 +103,13 @@ struct _GstObjectClass {
/* signals */ /* signals */
void (*parent_set) (GstObject *object, GstObject *parent); void (*parent_set) (GstObject *object, GstObject *parent);
#ifndef GST_DISABLE_LOADSAVE
void (*object_saved) (GstObject *object, xmlNodePtr parent); void (*object_saved) (GstObject *object, xmlNodePtr parent);
#endif
/* functions go here */ /* functions go here */
void (*destroy) (GstObject *object); void (*destroy) (GstObject *object);
#ifndef GST_DISABLE_LOADSAVE
xmlNodePtr (*save_thyself) (GstObject *object, xmlNodePtr parent); xmlNodePtr (*save_thyself) (GstObject *object, xmlNodePtr parent);
void (*restore_thyself) (GstObject *object, xmlNodePtr self); void (*restore_thyself) (GstObject *object, xmlNodePtr self);
#endif
}; };
#define GST_FLAGS(obj) (GST_OBJECT (obj)->flags) #define GST_FLAGS(obj) (GST_OBJECT (obj)->flags)
@ -136,7 +132,6 @@ struct _GstObjectClass {
/* normal GObject stuff */ /* normal GObject stuff */
GType gst_object_get_type (void); GType gst_object_get_type (void);
GstObject* gst_object_new (void);
/* name routines */ /* name routines */
void gst_object_set_name (GstObject *object, const gchar *name); 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 #ifndef GST_DISABLE_LOADSAVE
xmlNodePtr gst_object_save_thyself (GstObject *object, xmlNodePtr parent); xmlNodePtr gst_object_save_thyself (GstObject *object, xmlNodePtr parent);
void gst_object_restore_thyself (GstObject *object, xmlNodePtr parent);
#else #else
#pragma GCC poison gst_object_save_thyself #pragma GCC poison gst_object_save_thyself
#endif #endif
@ -159,7 +155,6 @@ xmlNodePtr gst_object_save_thyself (GstObject *object, xmlNodePtr parent);
GstObject * gst_object_ref (GstObject *object); GstObject * gst_object_ref (GstObject *object);
void gst_object_unref (GstObject *object); void gst_object_unref (GstObject *object);
void gst_object_sink (GstObject *object); void gst_object_sink (GstObject *object);
/* destroying an object */ /* destroying an object */
void gst_object_destroy (GstObject *object); void gst_object_destroy (GstObject *object);

View file

@ -25,27 +25,23 @@
#include <dirent.h> #include <dirent.h>
#include <unistd.h> #include <unistd.h>
#undef RTLD_GLOBAL
#include "gst_private.h" #include "gst_private.h"
#include "gstplugin.h" #include "gstplugin.h"
#include "gstversion.h" #include "gstversion.h"
#include "config.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 */ /* global list of plugins and its sequence number */
GList *_gst_plugins; GList *_gst_plugins = NULL;
gint _gst_plugins_seqno; gint _gst_plugins_seqno = 0;
gint _gst_plugin_elementfactories = 0;
gint _gst_plugin_types = 0;
/* list of paths to check for plugins */ /* list of paths to check for plugins */
GList *_gst_plugin_paths; GList *_gst_plugin_paths = NULL;
GList *_gst_libraries; GList *_gst_libraries = NULL;
gint _gst_libraries_seqno; gint _gst_libraries_seqno = 0;
/* whether or not to spew library load issues */ /* whether or not to spew library load issues */
gboolean _gst_plugin_spew = FALSE; gboolean _gst_plugin_spew = FALSE;
@ -54,8 +50,13 @@ gboolean _gst_plugin_spew = FALSE;
* this to false.) */ * this to false.) */
gboolean _gst_warn_old_registry = TRUE; gboolean _gst_warn_old_registry = TRUE;
static gboolean plugin_times_older_than(time_t regtime); #ifndef GST_DISABLE_REGISTRY
static time_t get_time(const char * path); 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 void
_gst_plugin_initialize (void) _gst_plugin_initialize (void)
@ -64,13 +65,8 @@ _gst_plugin_initialize (void)
xmlDocPtr doc; xmlDocPtr doc;
#endif #endif
_gst_modules = NULL; main_module = g_module_open (NULL, G_MODULE_BIND_LAZY);
_gst_modules_seqno = 0; gst_plugin_register_statics (main_module);
_gst_plugins = NULL;
_gst_plugins_seqno = 0;
_gst_plugin_paths = NULL;
_gst_libraries = NULL;
_gst_libraries_seqno = 0;
/* add the main (installed) library path */ /* add the main (installed) library path */
_gst_plugin_paths = g_list_prepend (_gst_plugin_paths, PLUGINS_DIR); _gst_plugin_paths = g_list_prepend (_gst_plugin_paths, PLUGINS_DIR);
@ -103,6 +99,7 @@ _gst_plugin_initialize (void)
if (_gst_warn_old_registry) if (_gst_warn_old_registry)
g_warning ("gstplugin: registry needs rebuild: run gstreamer-register\n"); g_warning ("gstplugin: registry needs rebuild: run gstreamer-register\n");
gst_plugin_load_all (); gst_plugin_load_all ();
//gst_plugin_unload_all ();
return; return;
} }
gst_plugin_load_thyself (doc->xmlRootNode); gst_plugin_load_thyself (doc->xmlRootNode);
@ -111,6 +108,36 @@ _gst_plugin_initialize (void)
#endif // GST_DISABLE_REGISTRY #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: * gst_plugin_add_path:
* @path: the directory to add to the search 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)); _gst_plugin_paths = g_list_prepend (_gst_plugin_paths,g_strdup(path));
} }
#ifndef GST_DISABLE_REGISTRY
static time_t static time_t
get_time(const char * path) get_time(const char * path)
{ {
@ -184,6 +212,7 @@ plugin_times_older_than(time_t regtime)
} }
return TRUE; return TRUE;
} }
#endif
static gboolean static gboolean
gst_plugin_load_recurse (gchar *directory, gchar *name) 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. * Load all plugins in the path.
*/ */
void void
gst_plugin_load_all(void) gst_plugin_load_all (void)
{ {
GList *path; GList *path;
@ -242,8 +271,39 @@ gst_plugin_load_all(void)
gst_plugin_load_recurse(path->data,NULL); gst_plugin_load_recurse(path->data,NULL);
path = g_list_next(path); path = g_list_next(path);
} }
GST_INFO (GST_CAT_PLUGIN_LOADING,"loaded %d plugins with %d elements and %d types", GST_INFO (GST_CAT_PLUGIN_LOADING,"loaded %d plugins", _gst_plugins_seqno);
_gst_plugins_seqno,_gst_plugin_elementfactories,_gst_plugin_types); }
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; 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: * gst_plugin_load:
* @name: name of plugin to load * @name: name of plugin to load
@ -307,14 +351,15 @@ gst_plugin_load (const gchar *name)
{ {
GList *path; GList *path;
gchar *libspath; gchar *libspath;
GstPlugin *plugin;
gchar *pluginname; gchar *pluginname;
GstPlugin *plugin;
//g_print("attempting to load plugin '%s'\n",name);
g_return_val_if_fail (name != NULL, FALSE);
plugin = gst_plugin_find (name); plugin = gst_plugin_find (name);
if (plugin && plugin->loaded) return TRUE; if (plugin && plugin->module)
return TRUE;
path = _gst_plugin_paths; path = _gst_plugin_paths;
while (path != NULL) { while (path != NULL) {
@ -345,6 +390,79 @@ gst_plugin_load (const gchar *name)
return FALSE; return FALSE;
} }
/**
* gst_plugin_load:
* @name: name of plugin to load
*
* Load the named plugin. Name should be given as
* &quot;libplugin.so&quot;.
*
* Returns: whether the plugin was loaded or not
*/
gboolean
gst_plugin_load_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: * gst_plugin_load_absolute:
* @name: name of plugin to load * @name: name of plugin to load
@ -352,105 +470,60 @@ gst_plugin_load (const gchar *name)
* Returns: whether or not the plugin loaded * Returns: whether or not the plugin loaded
*/ */
gboolean gboolean
gst_plugin_load_absolute (const gchar *name) gst_plugin_load_plugin (GstPlugin *plugin)
{ {
GModule *module; GModule *module;
GstPluginDesc *desc; GstPluginDesc *desc;
GstPlugin *plugin;
struct stat file_status; 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"); g_warning("gstplugin: wow, you built this on a platform without dynamic loading???\n");
return FALSE; return FALSE;
} }
if (stat(name,&file_status)) { if (stat (filename, &file_status)) {
//g_print("problem opening file %s\n",name); //g_print("problem opening file %s\n",filename);
return FALSE; return FALSE;
} }
module = g_module_open(name,G_MODULE_BIND_LAZY); module = g_module_open (filename, G_MODULE_BIND_LAZY);
if (module != NULL) { if (module != NULL) {
if (g_module_symbol(module,"plugin_desc",(gpointer *)&desc)) { if (g_module_symbol (module, "plugin_desc", (gpointer *)&desc)) {
GST_INFO (GST_CAT_PLUGIN_LOADING,"loading plugin \"%s\"...", name); GST_INFO (GST_CAT_PLUGIN_LOADING,"loading plugin \"%s\"...", filename);
plugin = gst_plugin_new(desc->name, desc->major_version, desc->minor_version);
if (plugin != NULL) { plugin->filename = g_strdup (filename);
plugin->filename = g_strdup(name); plugin = gst_plugin_register_func (desc, plugin, module);
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 (plugin != NULL) { if (plugin != NULL) {
GST_INFO (GST_CAT_PLUGIN_LOADING,"plugin \"%s\" loaded: %d elements, %d types", GST_INFO (GST_CAT_PLUGIN_LOADING,"plugin \"%s\" loaded",
plugin->name,plugin->numelements,plugin->numtypes); plugin->filename);
plugin->loaded = TRUE; plugin->module = module;
_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;
return TRUE; return TRUE;
} }
} }
return TRUE; return TRUE;
} else if (_gst_plugin_spew) { } else if (_gst_plugin_spew) {
// FIXME this should be some standard gst mechanism!!! // 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 { 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; 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: * gst_plugin_get_name:
@ -549,7 +622,7 @@ gst_plugin_is_loaded (GstPlugin *plugin)
{ {
g_return_val_if_fail (plugin != NULL, FALSE); 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; GList *plugins = _gst_plugins;
g_return_val_if_fail(name != NULL, NULL); g_return_val_if_fail (name != NULL, NULL);
while (plugins) { while (plugins) {
GstPlugin *plugin = (GstPlugin *)plugins->data; GstPlugin *plugin = (GstPlugin *)plugins->data;
// g_print("plugin name is '%s'\n",plugin->name);
if (plugin->name) { if (plugin->name) {
if (!strcmp(plugin->name,name)) { if (!strcmp (plugin->name, name)) {
return plugin; return plugin;
} }
} }
plugins = g_list_next(plugins); plugins = g_list_next (plugins);
} }
return NULL; return NULL;
} }
static GstElementFactory* static GstPluginFeature*
gst_plugin_find_elementfactory (const gchar *name) gst_plugin_find_feature_func (GstPlugin *plugin, const gchar *name, GType type)
{ {
GList *plugins, *factories; GList *features = plugin->features;
GstElementFactory *factory;
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; plugins = _gst_plugins;
while (plugins) { while (plugins) {
factories = ((GstPlugin *)(plugins->data))->elements; GstPlugin *plugin = (GstPlugin *)plugins->data;
while (factories) { GstPluginFeature *feature;
factory = (GstElementFactory*)(factories->data);
if (!strcmp(factory->name, name)) feature = gst_plugin_find_feature_func (plugin, name, type);
return (GstElementFactory*)(factory); if (feature)
factories = g_list_next(factories); return feature;
}
plugins = g_list_next(plugins); plugins = g_list_next(plugins);
} }
@ -605,234 +695,30 @@ gst_plugin_find_elementfactory (const gchar *name)
} }
/** /**
* gst_plugin_load_elementfactory: * gst_plugin_add_feature:
* @name: name of elementfactory to load * @plugin: plugin to add feature to
* @feature: feature to add
* *
* Load a registered elementfactory by name. * Add feature to the list of those provided by the plugin.
*
* 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.
*/ */
void void
gst_plugin_load_typefactory (const gchar *mime) gst_plugin_add_feature (GstPlugin *plugin, GstPluginFeature *feature)
{ {
GList *plugins, *factories; GstPluginFeature *oldfeature;
GstTypeFactory *factory;
GstPlugin *plugin;
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 (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"); oldfeature = gst_plugin_find_feature_func (plugin, GST_OBJECT_NAME (feature), G_OBJECT_TYPE (feature));
plugin->elements = g_list_prepend (plugin->elements, factory);
plugin->numelements++; 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: * gst_plugin_get_list:
* *
@ -859,49 +745,35 @@ xmlNodePtr
gst_plugin_save_thyself (xmlNodePtr parent) gst_plugin_save_thyself (xmlNodePtr parent)
{ {
xmlNodePtr tree, subtree; 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) { while (plugins) {
GstPlugin *plugin = (GstPlugin *)plugins->data; GstPlugin *plugin = (GstPlugin *)plugins->data;
GList *features;
plugins = g_list_next (plugins);
if (!plugin->name)
continue;
tree = xmlNewChild (parent, NULL, "plugin", NULL); tree = xmlNewChild (parent, NULL, "plugin", NULL);
xmlNewChild (tree, NULL, "name", plugin->name); xmlNewChild (tree, NULL, "name", plugin->name);
xmlNewChild (tree, NULL, "longname", plugin->longname); xmlNewChild (tree, NULL, "longname", plugin->longname);
xmlNewChild (tree, NULL, "filename", plugin->filename); xmlNewChild (tree, NULL, "filename", plugin->filename);
types = plugin->types; features = plugin->features;
while (types) { while (features) {
GstTypeFactory *factory = (GstTypeFactory *)types->data; GstPluginFeature *feature = GST_PLUGIN_FEATURE (features->data);
subtree = xmlNewChild(tree, NULL, "typefactory", NULL);
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; return parent;
} }
@ -915,9 +787,7 @@ void
gst_plugin_load_thyself (xmlNodePtr parent) gst_plugin_load_thyself (xmlNodePtr parent)
{ {
xmlNodePtr kinderen; xmlNodePtr kinderen;
gint elementcount = 0; gint featurecount = 0;
gint autoplugcount = 0;
gint typecount = 0;
gchar *pluginname; gchar *pluginname;
kinderen = parent->xmlChildrenNode; // Dutch invasion :-) kinderen = parent->xmlChildrenNode; // Dutch invasion :-)
@ -926,9 +796,9 @@ gst_plugin_load_thyself (xmlNodePtr parent)
xmlNodePtr field = kinderen->xmlChildrenNode; xmlNodePtr field = kinderen->xmlChildrenNode;
GstPlugin *plugin = g_new0 (GstPlugin, 1); GstPlugin *plugin = g_new0 (GstPlugin, 1);
plugin->elements = NULL; plugin->numfeatures = 0;
plugin->types = NULL; plugin->features = NULL;
plugin->loaded = FALSE; plugin->module = NULL;
while (field) { while (field) {
if (!strcmp (field->name, "name")) { if (!strcmp (field->name, "name")) {
@ -948,23 +818,18 @@ gst_plugin_load_thyself (xmlNodePtr parent)
else if (!strcmp (field->name, "filename")) { else if (!strcmp (field->name, "filename")) {
plugin->filename = xmlNodeGetContent (field); plugin->filename = xmlNodeGetContent (field);
} }
else if (!strcmp (field->name, "elementfactory")) { else if (!strcmp (field->name, "feature")) {
GstElementFactory *factory = gst_elementfactory_load_thyself (field); GstPluginFeature *feature;
gst_plugin_add_factory (plugin, factory); gchar *prop;
elementcount++;
} prop = xmlGetProp (field, "typename");
#ifndef GST_DISABLE_AUTOPLUG feature = GST_PLUGIN_FEATURE (g_object_new (g_type_from_name (prop), NULL));
else if (!strcmp (field->name, "autoplugfactory")) {
GstAutoplugFactory *factory = gst_autoplugfactory_load_thyself (field); if (feature) {
gst_plugin_add_autoplugger (plugin, factory); gst_object_restore_thyself (GST_OBJECT (feature), field);
autoplugcount++; gst_plugin_add_feature (plugin, feature);
} featurecount++;
#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++;
} }
field = field->next; field = field->next;
@ -972,63 +837,29 @@ gst_plugin_load_thyself (xmlNodePtr parent)
if (plugin) { if (plugin) {
_gst_plugins = g_list_prepend (_gst_plugins, plugin); _gst_plugins = g_list_prepend (_gst_plugins, plugin);
_gst_plugins_seqno++;
} }
} }
kinderen = kinderen->next; kinderen = kinderen->next;
} }
GST_INFO (GST_CAT_PLUGIN_LOADING, "added %d registered factories, %d autopluggers and %d types", GST_INFO (GST_CAT_PLUGIN_LOADING, "added %d features ", featurecount);
elementcount, autoplugcount, typecount);
} }
#endif // GST_DISABLE_REGISTRY #endif // GST_DISABLE_REGISTRY
/** /**
* gst_plugin_get_factory_list: * gst_plugin_get_feature_list:
* @plugin: the plugin to get the factories from * @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* GList*
gst_plugin_get_factory_list (GstPlugin *plugin) gst_plugin_get_feature_list (GstPlugin *plugin)
{ {
g_return_val_if_fail (plugin != NULL, NULL); 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

View file

@ -34,10 +34,7 @@
#define xmlRootNode root #define xmlRootNode root
#endif #endif
#include <gst/gsttype.h> #include <gst/gstpluginfeature.h>
#include <gst/gstelement.h>
#include <gst/gstautoplug.h>
typedef struct _GstPlugin GstPlugin; typedef struct _GstPlugin GstPlugin;
typedef struct _GstPluginDesc GstPluginDesc; typedef struct _GstPluginDesc GstPluginDesc;
@ -47,16 +44,10 @@ struct _GstPlugin {
gchar *longname; /* long name of plugin */ gchar *longname; /* long name of plugin */
gchar *filename; /* filename it came from */ gchar *filename; /* filename it came from */
GList *types; /* list of types provided */ GList *features; /* list of features provided */
gint numtypes; gint numfeatures;
GList *elements; /* list of elements provided */
gint numelements;
#ifndef GST_DISABLE_AUTOPLUG
GList *autopluggers; /* list of autopluggers provided */
gint numautopluggers;
#endif // GST_DISABLE_AUTOPLUG
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 */ /* Initialiser function: returns TRUE if plugin initialised successfully */
@ -69,7 +60,36 @@ struct _GstPluginDesc {
GstPluginInitFunc plugin_init; /* pointer to plugin_init function */ 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_initialize (void);
void _gst_plugin_register_static (GstPluginDesc *desc);
GstPlugin* gst_plugin_new (const gchar *name, gint major, gint minor); 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); const gchar* gst_plugin_get_filename (GstPlugin *plugin);
gboolean gst_plugin_is_loaded (GstPlugin *plugin); gboolean gst_plugin_is_loaded (GstPlugin *plugin);
GList* gst_plugin_get_type_list (GstPlugin *plugin); GList* gst_plugin_get_feature_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
void gst_plugin_load_all (void); void gst_plugin_load_all (void);
void gst_plugin_unload_all (void);
gboolean gst_plugin_load (const gchar *name); gboolean gst_plugin_load (const gchar *name);
gboolean gst_plugin_load_absolute (const gchar *name); gboolean gst_plugin_load_absolute (const gchar *name);
gboolean gst_library_load (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_feature (GstPlugin *plugin, GstPluginFeature *feature);
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
GstPlugin* gst_plugin_find (const gchar *name); GstPlugin* gst_plugin_find (const gchar *name);
GList* gst_plugin_get_list (void); 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); xmlNodePtr gst_plugin_save_thyself (xmlNodePtr parent);
void gst_plugin_load_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__ */ #endif /* __GST_PLUGIN_H__ */

133
gst/gstpluginfeature.c Normal file
View file

@ -0,0 +1,133 @@
/* GStreamer
* Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
* 2000 Wim Taymans <wtay@chello.be>
*
* 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);
}

72
gst/gstpluginfeature.h Normal file
View file

@ -0,0 +1,72 @@
/* GStreamer
* Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
* 2000 Wim Taymans <wtay@chello.be>
*
* 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 <gst/gstobject.h>
#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__ */

View file

@ -67,30 +67,33 @@ enum {
}; };
static void gst_queue_class_init (GstQueueClass *klass); static void gst_queue_class_init (GstQueueClass *klass);
static void gst_queue_init (GstQueue *queue); 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_set_property (GObject *object, guint prop_id,
static void gst_queue_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); 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 GstPadNegotiateReturn gst_queue_handle_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data);
static void gst_queue_chain (GstPad *pad, GstBuffer *buf); static void gst_queue_chain (GstPad *pad, GstBuffer *buf);
static GstBuffer * gst_queue_get (GstPad *pad); static GstBuffer * gst_queue_get (GstPad *pad);
static GstBufferPool* gst_queue_get_bufferpool (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 static GType
queue_leaky_get_type(void) { queue_leaky_get_type(void) {
static GType queue_leaky_type = 0; static GType queue_leaky_type = 0;
static GEnumValue queue_leaky[] = { static GEnumValue queue_leaky[] = {
{ GST_QUEUE_NO_LEAK, "0", "Not Leaky" }, { GST_QUEUE_NO_LEAK, "0", "Not Leaky" },
{ GST_QUEUE_LEAK_UPSTREAM, "1", "Leaky on Upstream" }, { GST_QUEUE_LEAK_UPSTREAM, "1", "Leaky on Upstream" },
{ GST_QUEUE_LEAK_DOWNSTREAM, "2", "Leaky on Downstream" }, { GST_QUEUE_LEAK_DOWNSTREAM, "2", "Leaky on Downstream" },
{ 0, NULL, NULL }, { 0, NULL, NULL },
}; };
if (!queue_leaky_type) { if (!queue_leaky_type) {
@ -98,14 +101,13 @@ queue_leaky_get_type(void) {
} }
return queue_leaky_type; return queue_leaky_type;
} }
#define GST_TYPE_QUEUE_LEAKY (queue_leaky_get_type())
static GstElementClass *parent_class = NULL; static GstElementClass *parent_class = NULL;
//static guint gst_queue_signals[LAST_SIGNAL] = { 0 }; //static guint gst_queue_signals[LAST_SIGNAL] = { 0 };
GType GType
gst_queue_get_type(void) { gst_queue_get_type(void)
{
static GType queue_type = 0; static GType queue_type = 0;
if (!queue_type) { if (!queue_type) {

View file

@ -30,26 +30,101 @@
#include "gst_private.h" #include "gst_private.h"
#include "gsttype.h" #include "gsttype.h"
#include "gstplugin.h"
/* global list of registered types */ /* global list of registered types */
GList *_gst_types; static GList *_gst_types;
guint16 _gst_maxtype; static guint16 _gst_maxtype;
struct _GstTypeFindInfo { static GList *_gst_typefactories;
GstTypeFindFunc typefindfunc; /* typefind function */
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); static GstCaps* gst_type_typefind_dummy (GstBuffer *buffer, gpointer priv);
void static xmlNodePtr gst_typefactory_save_thyself (GstObject *object, xmlNodePtr parent);
_gst_type_initialize (void) 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_types = NULL;
_gst_maxtype = 1; /* type 0 is undefined */ _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->id = _gst_maxtype++;
type->mime = factory->mime; type->mime = factory->mime;
type->exts = factory->exts; type->exts = factory->exts;
type->factories = NULL;
_gst_types = g_list_prepend (_gst_types, type); _gst_types = g_list_prepend (_gst_types, type);
id = type->id; id = type->id;
GST_DEBUG (GST_CAT_TYPES,"gsttype: new mime type '%s', id %d\n", type->mime, type->id);
} else { } else {
type = gst_type_find_by_id (id); 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 there is no existing typefind function, try to use new one */
} }
if (factory->typefindfunc) { GST_DEBUG (GST_CAT_TYPES,"gsttype: %s(%p) gave new mime type '%s', id %d\n",
type->typefindfuncs = g_slist_prepend (type->typefindfuncs, factory->typefindfunc); GST_OBJECT_NAME (factory), factory, type->mime, type->id);
} type->factories = g_slist_prepend (type->factories, factory);
return id; return id;
} }
static static guint16
guint16 gst_type_find_by_mime_func (const gchar *mime) gst_type_find_by_mime_func (const gchar *mime)
{ {
GList *walk; GList *walk;
GstType *type; GstType *type;
@ -202,18 +277,56 @@ gst_type_get_list (void)
return _gst_types; return _gst_types;
} }
/** /**
* gst_typefactory_save_thyself: * gst_typefactory_find:
* @factory: the type factory to save * @name: the name of the typefactory to find
* @parent: the parent node to save into
* *
* 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 GstTypeFactory*
gst_typefactory_save_thyself (GstTypeFactory *factory, xmlNodePtr parent) 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); xmlNewChild (parent, NULL, "mime", factory->mime);
if (factory->exts) { if (factory->exts) {
xmlNewChild (parent, NULL, "extensions", factory->exts); xmlNewChild (parent, NULL, "extensions", factory->exts);
@ -225,52 +338,43 @@ gst_typefactory_save_thyself (GstTypeFactory *factory, xmlNodePtr parent)
return parent; return parent;
} }
static GstCaps * static GstCaps*
gst_type_typefind_dummy (GstBuffer *buffer, gpointer priv) gst_type_typefind_dummy (GstBuffer *buffer, gpointer priv)
{ {
GstType *type = (GstType *)priv; GstTypeFactory *factory = (GstTypeFactory *)priv;
guint16 typeid;
GSList *funcs;
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_feature_ensure_loaded (GST_PLUGIN_FEATURE (factory));
gst_plugin_load_typefactory (type->mime);
typeid = gst_type_find_by_mime (type->mime);
type = gst_type_find_by_id (typeid);
funcs = type->typefindfuncs; if (factory->typefindfunc) {
GstCaps *res = factory->typefindfunc (buffer, factory);
while (funcs) { if (res)
GstTypeFindFunc func = (GstTypeFindFunc) funcs->data; return res;
if (func) {
GstCaps *res = func (buffer, type);
if (res) return res;
}
funcs = g_slist_next (funcs);
} }
return FALSE; return NULL;
} }
/** /**
* gst_typefactory_load_thyself: * gst_typefactory_restore_thyself:
* @parent: the parent node to load from * @parent: the parent node to load from
* *
* Load a typefactory from an XML representation. * Load a typefactory from an XML representation.
* *
* Returns: the new typefactory * Returns: the new typefactory
*/ */
GstTypeFactory* static void
gst_typefactory_load_thyself (xmlNodePtr parent) gst_typefactory_restore_thyself (GstObject *object, xmlNodePtr parent)
{ {
GstTypeFactory *factory = GST_TYPEFACTORY (object);
GstTypeFactory *factory = g_new0 (GstTypeFactory, 1);
xmlNodePtr field = parent->xmlChildrenNode; xmlNodePtr field = parent->xmlChildrenNode;
factory->typefindfunc = NULL; factory->typefindfunc = NULL;
if (GST_OBJECT_CLASS (parent_class)->restore_thyself) {
GST_OBJECT_CLASS (parent_class)->restore_thyself (object, parent);
}
while (field) { while (field) {
if (!strcmp (field->name, "mime")) { if (!strcmp (field->name, "mime")) {
factory->mime = xmlNodeGetContent (field); factory->mime = xmlNodeGetContent (field);
@ -284,6 +388,6 @@ gst_typefactory_load_thyself (xmlNodePtr parent)
field = field->next; field = field->next;
} }
return factory; gst_type_register (factory);
} }

View file

@ -26,13 +26,16 @@
#include <gst/gstbuffer.h> #include <gst/gstbuffer.h>
#include <gst/gstcaps.h> #include <gst/gstcaps.h>
#include <gst/gstpluginfeature.h>
/* type of function used to check a stream for equality with type */ /* 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 _GstType GstType;
typedef struct _GstTypeDefinition GstTypeDefinition;
typedef struct _GstTypeFactory GstTypeFactory; typedef struct _GstTypeFactory GstTypeFactory;
typedef struct _GstTypeFactoryClass GstTypeFactoryClass;
struct _GstType { struct _GstType {
guint16 id; /* type id (assigned) */ guint16 id; /* type id (assigned) */
@ -40,34 +43,58 @@ struct _GstType {
gchar *mime; /* MIME type */ gchar *mime; /* MIME type */
gchar *exts; /* space-delimited list of extensions */ 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 *mime;
gchar *exts; gchar *exts;
GstTypeFindFunc typefindfunc; 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 */ struct _GstTypeFactory {
void _gst_type_initialize (void); 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 */ /* 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 */ /* look up a type by mime or extension */
guint16 gst_type_find_by_mime (const gchar *mime); guint16 gst_type_find_by_mime (const gchar *mime);
guint16 gst_type_find_by_ext (const gchar *ext); guint16 gst_type_find_by_ext (const gchar *ext);
/* get GstType by id */ /* 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!) */ /* get the list of registered types (returns list of GstType!) */
GList* gst_type_get_list (void); GList* gst_type_get_list (void);
xmlNodePtr gst_typefactory_save_thyself (GstTypeFactory *factory, xmlNodePtr parent);
GstTypeFactory* gst_typefactory_load_thyself (xmlNodePtr parent);
#endif /* __GST_TYPE_H__ */ #endif /* __GST_TYPE_H__ */

View file

@ -52,13 +52,15 @@ enum {
}; };
static void gst_typefind_class_init (GstTypeFindClass *klass); static void gst_typefind_class_init (GstTypeFindClass *klass);
static void gst_typefind_init (GstTypeFind *typefind); 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_set_property (GObject *object, guint prop_id,
static void gst_typefind_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); 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 GstElementClass *parent_class = NULL;
static guint gst_typefind_signals[LAST_SIGNAL] = { 0 }; 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_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1,
G_TYPE_POINTER); G_TYPE_POINTER);
gobject_class->set_property = gst_typefind_set_property; gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_typefind_set_property);
gobject_class->get_property = gst_typefind_get_property; gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_typefind_get_property);
} }
static void static void
@ -168,17 +170,18 @@ gst_typefind_chain (GstPad *pad, GstBuffer *buf)
type_list = gst_type_get_list (); type_list = gst_type_get_list ();
while (type_list) { while (type_list) {
GSList *funcs; GSList *factories;
type = (GstType *)type_list->data; type = (GstType *)type_list->data;
funcs = type->typefindfuncs; factories = type->factories;
while (funcs) { while (factories) {
GstTypeFindFunc typefindfunc = (GstTypeFindFunc)funcs->data; GstTypeFactory *factory = GST_TYPEFACTORY (factories->data);
GstTypeFindFunc typefindfunc = (GstTypeFindFunc)factory->typefindfunc;
GstCaps *caps; GstCaps *caps;
GST_DEBUG (0,"try type :%d \"%s\"\n", type->id, type->mime); 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_DEBUG (0,"found type :%d \"%s\" \"%s\"\n", caps->id, type->mime,
gst_caps_get_name (caps)); gst_caps_get_name (caps));
typefind->caps = caps; typefind->caps = caps;
@ -200,7 +203,7 @@ gst_typefind_chain (GstPad *pad, GstBuffer *buf)
goto end; goto end;
} }
funcs = g_slist_next (funcs); factories = g_slist_next (factories);
} }
type_list = g_list_next (type_list); type_list = g_list_next (type_list);

View file

@ -21,10 +21,10 @@
#include <gst/gst.h> #include <gst/gst.h>
#include <string.h> #include <string.h>
GstTypeFactory _factories[] = { GstTypeDefinition _definitions[] = {
{ "audio/raw", ".raw", NULL }, { "gsttypes_audio/raw", "audio/raw", ".raw", NULL },
{ "video/raw image/raw", ".raw", NULL }, { "gsttypes_video/raw", "video/raw", ".raw", NULL },
{ NULL, NULL, NULL }, { NULL, NULL, NULL, NULL },
}; };
@ -33,10 +33,12 @@ plugin_init (GModule *module, GstPlugin *plugin)
{ {
gint i = 0; gint i = 0;
while (_factories[i].mime) { while (_definitions[i].name) {
gst_type_register (&_factories[i]); GstTypeFactory *factory;
gst_plugin_add_type (plugin, &_factories[i]);
GST_DEBUG(0, "added factory #%d '%s'\n",i,_factories[i].mime); 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++; i++;
} }

View file

@ -82,7 +82,7 @@ plugin_init (GModule *module, GstPlugin *plugin)
(_elements[i].type) (), (_elements[i].type) (),
_elements[i].details); _elements[i].details);
if (factory != NULL) { if (factory != NULL) {
gst_plugin_add_factory (plugin, factory); gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
if (_elements[i].factoryinit) { if (_elements[i].factoryinit) {
_elements[i].factoryinit (factory); _elements[i].factoryinit (factory);
} }

View file

@ -67,30 +67,33 @@ enum {
}; };
static void gst_queue_class_init (GstQueueClass *klass); static void gst_queue_class_init (GstQueueClass *klass);
static void gst_queue_init (GstQueue *queue); 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_set_property (GObject *object, guint prop_id,
static void gst_queue_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); 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 GstPadNegotiateReturn gst_queue_handle_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data);
static void gst_queue_chain (GstPad *pad, GstBuffer *buf); static void gst_queue_chain (GstPad *pad, GstBuffer *buf);
static GstBuffer * gst_queue_get (GstPad *pad); static GstBuffer * gst_queue_get (GstPad *pad);
static GstBufferPool* gst_queue_get_bufferpool (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 static GType
queue_leaky_get_type(void) { queue_leaky_get_type(void) {
static GType queue_leaky_type = 0; static GType queue_leaky_type = 0;
static GEnumValue queue_leaky[] = { static GEnumValue queue_leaky[] = {
{ GST_QUEUE_NO_LEAK, "0", "Not Leaky" }, { GST_QUEUE_NO_LEAK, "0", "Not Leaky" },
{ GST_QUEUE_LEAK_UPSTREAM, "1", "Leaky on Upstream" }, { GST_QUEUE_LEAK_UPSTREAM, "1", "Leaky on Upstream" },
{ GST_QUEUE_LEAK_DOWNSTREAM, "2", "Leaky on Downstream" }, { GST_QUEUE_LEAK_DOWNSTREAM, "2", "Leaky on Downstream" },
{ 0, NULL, NULL }, { 0, NULL, NULL },
}; };
if (!queue_leaky_type) { if (!queue_leaky_type) {
@ -98,14 +101,13 @@ queue_leaky_get_type(void) {
} }
return queue_leaky_type; return queue_leaky_type;
} }
#define GST_TYPE_QUEUE_LEAKY (queue_leaky_get_type())
static GstElementClass *parent_class = NULL; static GstElementClass *parent_class = NULL;
//static guint gst_queue_signals[LAST_SIGNAL] = { 0 }; //static guint gst_queue_signals[LAST_SIGNAL] = { 0 };
GType GType
gst_queue_get_type(void) { gst_queue_get_type(void)
{
static GType queue_type = 0; static GType queue_type = 0;
if (!queue_type) { if (!queue_type) {

View file

@ -19,7 +19,7 @@ struct _GstRegistryElement {
int main(int argc,char *argv[]) { int main(int argc,char *argv[]) {
xmlDocPtr doc; xmlDocPtr doc;
xmlNodePtr tree, subtree; xmlNodePtr tree, subtree;
GList *plugins = NULL, *elements = NULL; GList *plugins = NULL, *features = NULL;
gst_init(&argc,&argv); gst_init(&argc,&argv);
gst_plugin_load_all(); 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,"name",plugin->name);
subtree = xmlNewChild(tree,NULL,"longname",plugin->longname); subtree = xmlNewChild(tree,NULL,"longname",plugin->longname);
subtree = xmlNewChild(tree,NULL,"filename",plugin->filename); subtree = xmlNewChild(tree,NULL,"filename",plugin->filename);
elements = plugin->elements; features = plugin->features;
while (elements) { while (features) {
GstElementFactory *element = (GstElementFactory *)elements->data; GstPluginFeature *feature = GST_PLUGIN_FEATURE (features->data);
tree = xmlNewChild(doc->root,NULL,"element",NULL);
subtree = xmlNewChild(tree,NULL,"plugin",plugin->name); if (GST_IS_ELEMENTFACTORY (feature)) {
subtree = xmlNewChild(tree,NULL,"name",element->name); GstElementFactory *element = GST_ELEMENTFACTORY (feature);
subtree = xmlNewChild(tree,NULL,"longname",
element->details->longname); tree = xmlNewChild(doc->root,NULL, "element", NULL);
subtree = xmlNewChild(tree,NULL,"class", subtree = xmlNewChild (tree, NULL, "plugin", plugin->name);
element->details->klass); subtree = xmlNewChild (tree, NULL, "name", gst_object_get_name (GST_OBJECT (element)));
subtree = xmlNewChild(tree,NULL,"description", subtree = xmlNewChild (tree, NULL, "longname",
element->details->description); element->details->longname);
subtree = xmlNewChild(tree,NULL,"version", subtree = xmlNewChild (tree, NULL, "class",
element->details->version); element->details->klass);
subtree = xmlNewChild(tree,NULL,"author", subtree = xmlNewChild (tree, NULL, "description",
element->details->author); element->details->description);
subtree = xmlNewChild(tree,NULL,"copyright", subtree = xmlNewChild (tree, NULL, "version",
element->details->copyright); element->details->version);
elements = g_list_next(elements); 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); plugins = g_list_next(plugins);
} }

View file

@ -123,7 +123,7 @@ main (int argc, char *argv[])
doc->xmlRootNode = xmlNewDocNode (doc, NULL, "Capabilities", NULL); doc->xmlRootNode = xmlNewDocNode (doc, NULL, "Capabilities", NULL);
g_thread_init (NULL); g_thread_init (NULL);
_gst_type_initialize (); gst_typefactory_get_type ();
_gst_props_initialize (); _gst_props_initialize ();
_gst_caps_initialize (); _gst_caps_initialize ();

View file

@ -87,18 +87,15 @@ GST_PADTEMPLATE_FACTORY (src_factory,
/* A number of functon prototypes are given so we can refer to them later. */ /* 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_class_init (GstExampleClass *klass);
static void gst_example_init (GstExample *example); 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_set_property (GObject *object, guint prop_id,
static void gst_example_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); const GValue *value, GParamSpec *pspec);
static void gst_example_get_property (GObject *object, guint prop_id,
/* These hold the constructed pad templates, which are created during GValue *value, GParamSpec *pspec);
* plugin load, and used during element instantiation.
*/
static GstPadTemplate *src_template, *sink_template;
/* The parent class pointer needs to be kept around for some object /* The parent class pointer needs to be kept around for some object
* operations. * operations.
@ -189,10 +186,10 @@ static void
gst_example_init(GstExample *example) gst_example_init(GstExample *example)
{ {
/* First we create the sink pad, which is the input to the element. /* 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 * We will use the template constructed by the factory.
* (below) to quickly generate the pad we need.
*/ */
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 /* Setting the chain function allows us to supply the function that will
* actually be performing the work. Without this, the element would do * actually be performing the work. Without this, the element would do
* nothing, with undefined results (assertion failures and such). * 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, * pads don't have chain functions, because they can't accept buffers,
* they only produce them. * 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); gst_element_add_pad(GST_ELEMENT(example),example->srcpad);
/* Initialization of element's private variables. */ /* 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, /* The pad templates can be easily generated from the factories above,
* and then added to the list of padtemplates for the elementfactory. * 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, GST_PADTEMPLATE_GET (sink_factory));
gst_elementfactory_add_padtemplate (factory, sink_template); gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (src_factory));
src_template = src_factory ();
gst_elementfactory_add_padtemplate (factory, src_template);
/* The very last thing is to register the elementfactory with the plugin. */ /* 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. */ /* Now we can return successfully. */
return TRUE; return TRUE;

View file

@ -1,4 +1,4 @@
SUBDIRS = refcounting capsnego SUBDIRS = refcounting capsnego plugin
testprogs = test_gst_init testprogs = test_gst_init

13
tests/old/testsuite/plugin/.gitignore vendored Normal file
View file

@ -0,0 +1,13 @@
Makefile
Makefile.in
*.o
*.lo
*.la
.deps
.libs
dynamic
linked
loading
registry
static
static2

View file

@ -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)

View file

@ -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)

View file

@ -0,0 +1,23 @@
#include <gst/gst.h>
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;
}

View file

@ -0,0 +1,22 @@
#include <gst/gst.h>
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;
}

View file

@ -0,0 +1,54 @@
#include <gst/gst.h>
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;
}

View file

@ -0,0 +1,17 @@
#include <gst/gst.h>
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;
}

View file

@ -0,0 +1,23 @@
#include <gst/gst.h>
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;
}

View file

@ -0,0 +1,50 @@
#define GST_PLUGIN_STATIC
#include <gst/gst.h>
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;
}

View file

@ -0,0 +1,15 @@
#include <gst/gst.h>
static gboolean
plugin_init (GModule *module, GstPlugin *plugin)
{
return TRUE;
}
GST_PLUGIN_DESC (
GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"testplugin",
plugin_init
);

View file

@ -0,0 +1,15 @@
#include <gst/gst.h>
static gboolean
plugin_init (GModule *module, GstPlugin *plugin)
{
return TRUE;
}
GST_PLUGIN_DESC (
GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"testplugin2",
plugin_init
);

View file

@ -0,0 +1,3 @@
#define GST_PLUGIN_STATIC
#include "testplugin2.c"

View file

@ -0,0 +1,3 @@
#define GST_PLUGIN_STATIC
#include "testplugin.c"

View file

@ -9,7 +9,7 @@ dump_plugins (void)
while (plugins) { while (plugins) {
GstPlugin *plugin = (GstPlugin *)plugins->data; 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); plugins = g_list_next (plugins);
} }
@ -24,7 +24,7 @@ dump_factories (void)
while (factories) { while (factories) {
GstElementFactory *factory = (GstElementFactory *)factories->data; 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); factories = g_list_next (factories);
} }

View file

@ -1,4 +1,4 @@
SUBDIRS = refcounting capsnego SUBDIRS = refcounting capsnego plugin
testprogs = test_gst_init testprogs = test_gst_init

13
testsuite/plugin/.gitignore vendored Normal file
View file

@ -0,0 +1,13 @@
Makefile
Makefile.in
*.o
*.lo
*.la
.deps
.libs
dynamic
linked
loading
registry
static
static2

View file

@ -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)

59
testsuite/plugin/README Normal file
View file

@ -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)

View file

@ -0,0 +1,23 @@
#include <gst/gst.h>
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;
}

22
testsuite/plugin/linked.c Normal file
View file

@ -0,0 +1,22 @@
#include <gst/gst.h>
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;
}

View file

@ -0,0 +1,54 @@
#include <gst/gst.h>
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;
}

View file

@ -0,0 +1,17 @@
#include <gst/gst.h>
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;
}

23
testsuite/plugin/static.c Normal file
View file

@ -0,0 +1,23 @@
#include <gst/gst.h>
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;
}

View file

@ -0,0 +1,50 @@
#define GST_PLUGIN_STATIC
#include <gst/gst.h>
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;
}

View file

@ -0,0 +1,15 @@
#include <gst/gst.h>
static gboolean
plugin_init (GModule *module, GstPlugin *plugin)
{
return TRUE;
}
GST_PLUGIN_DESC (
GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"testplugin",
plugin_init
);

View file

@ -0,0 +1,15 @@
#include <gst/gst.h>
static gboolean
plugin_init (GModule *module, GstPlugin *plugin)
{
return TRUE;
}
GST_PLUGIN_DESC (
GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"testplugin2",
plugin_init
);

View file

@ -0,0 +1,3 @@
#define GST_PLUGIN_STATIC
#include "testplugin2.c"

View file

@ -0,0 +1,3 @@
#define GST_PLUGIN_STATIC
#include "testplugin.c"

View file

@ -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 \ man_MANS = gstreamer-launch.1 gstreamer-register.1 gstreamer-inspect.1 \
gstreamer-complete.1 gstreamer-compprep.1 gstreamer-complete.1 gstreamer-compprep.1

View file

@ -4,9 +4,7 @@
int main(int argc,char *argv[]) { int main(int argc,char *argv[]) {
xmlDocPtr doc; xmlDocPtr doc;
xmlNodePtr factorynode, padnode, argnode, optionnode; xmlNodePtr factorynode, padnode, argnode, optionnode;
GList *plugins, *factories, *padtemplates, *pads; GList *plugins, *features, *padtemplates, *pads;
GstPlugin *plugin;
GstElementFactory *factory;
GstElement *element; GstElement *element;
GstPad *pad; GstPad *pad;
GstPadTemplate *padtemplate; GstPadTemplate *padtemplate;
@ -22,20 +20,31 @@ int main(int argc,char *argv[]) {
plugins = gst_plugin_get_list(); plugins = gst_plugin_get_list();
while (plugins) { while (plugins) {
GstPlugin *plugin;
plugin = (GstPlugin *)(plugins->data); plugin = (GstPlugin *)(plugins->data);
plugins = g_list_next (plugins); plugins = g_list_next (plugins);
factories = gst_plugin_get_factory_list(plugin); features = gst_plugin_get_feature_list(plugin);
while (factories) { while (features) {
factory = (GstElementFactory *)(factories->data); GstPluginFeature *feature;
factories = g_list_next (factories); 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); 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"); element = gst_elementfactory_create(factory,"element");
if (element == NULL) { 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; return 1;
} }

View file

@ -4,7 +4,9 @@
// this must be built within the gstreamer dir, else this will fail // this must be built within the gstreamer dir, else this will fail
#include <gst/gstpropsprivate.h> #include <gst/gstpropsprivate.h>
void print_prop(GstPropsEntry *prop,gboolean showname,gchar *pfx) { static void
print_prop (GstPropsEntry *prop, gboolean showname, gchar *pfx)
{
GList *list; GList *list;
GstPropsEntry *listentry; GstPropsEntry *listentry;
gchar *longprefix; 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; GList *props;
GstPropsEntry *prop; GstPropsEntry *prop;
@ -94,7 +98,7 @@ output_hierarchy (GType type, gint level, gint *maxlevel)
g_print ("\n"); g_print ("\n");
} }
gint static gint
print_element_info (GstElementFactory *factory) print_element_info (GstElementFactory *factory)
{ {
GstElement *element; GstElement *element;
@ -394,88 +398,110 @@ print_element_info (GstElementFactory *factory)
return 0; return 0;
} }
void print_element_list() { static void
GList *plugins, *factories; print_element_list (void)
GstPlugin *plugin; {
GstElementFactory *factory; GList *plugins;
plugins = gst_plugin_get_list(); plugins = gst_plugin_get_list();
while (plugins) { while (plugins) {
GList *features;
GstPlugin *plugin;
plugin = (GstPlugin*)(plugins->data); plugin = (GstPlugin*)(plugins->data);
plugins = g_list_next (plugins); 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); feature = GST_PLUGIN_FEATURE (features->data);
while (factories) {
factory = (GstElementFactory*)(factories->data);
factories = g_list_next (factories);
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) print_plugin_info (GstPlugin *plugin)
{ {
GList *features;
printf("Plugin Details:\n"); printf("Plugin Details:\n");
printf(" Name:\t\t%s\n",plugin->name); printf(" Name:\t\t%s\n",plugin->name);
printf(" Long Name:\t%s\n",plugin->longname); printf(" Long Name:\t%s\n",plugin->longname);
printf(" Filename:\t%s\n",plugin->filename); printf(" Filename:\t%s\n",plugin->filename);
printf("\n"); printf("\n");
if (plugin->numelements) { features = gst_plugin_get_feature_list (plugin);
GList *factories;
GstElementFactory *factory;
printf("Element Factories:\n"); while (features) {
GstPluginFeature *feature;
factories = gst_plugin_get_factory_list(plugin); feature = GST_PLUGIN_FEATURE (features->data);
while (factories) {
factory = (GstElementFactory*)(factories->data);
factories = g_list_next(factories);
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);
} }
} else if (GST_IS_AUTOPLUGFACTORY (feature)) {
if (plugin->numautopluggers) { GstAutoplugFactory *factory;
GList *factories;
GstAutoplugFactory *factory;
printf("Autpluggers:\n"); factory = GST_AUTOPLUGFACTORY (feature);
printf(" %s: %s\n", GST_OBJECT_NAME (factory), factory->longdesc);
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);
} }
} else if (GST_IS_TYPEFACTORY (feature)) {
if (plugin->numtypes) { GstTypeFactory *factory;
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);
factory = GST_TYPEFACTORY (feature);
printf(" %s: %s\n", factory->mime, factory->exts); printf(" %s: %s\n", factory->mime, factory->exts);
if (factory->typefindfunc) if (factory->typefindfunc)
printf(" Has typefind function: %s\n",GST_DEBUG_FUNCPTR_NAME(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"); printf("\n");
} }
int main(int argc,char *argv[]) { int
main (int argc, char *argv[])
{
GstElementFactory *factory; GstElementFactory *factory;
GstPlugin *plugin; GstPlugin *plugin;
gchar *so; gchar *so;