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(PARSE,[command-line parser])
GST_SUBSYSTEM_DISABLE(TRACE,[tracing subsystem])
GST_SUBSYSTEM_DISABLE(REGISTRY,[plugin registry])
GST_DEFINE_CFLAGS="$GST_DEFINE_CFLAGS $GST_SUBSYSTEM_DISABLE_DEFINES"
@ -1224,6 +1225,7 @@ tests/muxing/Makefile
testsuite/Makefile
testsuite/capsnego/Makefile
testsuite/refcounting/Makefile
testsuite/plugin/Makefile
tests/nego/Makefile
examples/Makefile
examples/autoplug/Makefile

View file

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

View file

@ -479,7 +479,7 @@ gst_editor_property_create (GstEditorProperty *property, GstEditorElement *eleme
gtk_widget_show(entry);
gtk_entry_set_editable(GTK_ENTRY(entry), FALSE);
gtk_entry_set_text(GTK_ENTRY(entry),
gst_element_get_factory(element->element)->name);
gst_object_get_name (GST_OBJECT (gst_element_get_factory(element->element))));
gtk_table_attach(GTK_TABLE(table), label, 0, 1, count, count+1, GTK_FILL, 0, 0, 0);
gtk_table_attach(GTK_TABLE(table), entry, 1, 2, count, count+1, GTK_FILL|GTK_EXPAND, 0, 0, 0);
count++;

View file

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

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. */
static void gst_example_class_init (GstExampleClass *klass);
static void gst_example_init (GstExample *example);
static void gst_example_class_init (GstExampleClass *klass);
static void gst_example_init (GstExample *example);
static void gst_example_chain (GstPad *pad, GstBuffer *buf);
static void gst_example_chain (GstPad *pad, GstBuffer *buf);
static void gst_example_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
static void gst_example_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
/* These hold the constructed pad templates, which are created during
* plugin load, and used during element instantiation.
*/
static GstPadTemplate *src_template, *sink_template;
static void gst_example_set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec);
static void gst_example_get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec);
/* The parent class pointer needs to be kept around for some object
* operations.
@ -189,10 +186,10 @@ static void
gst_example_init(GstExample *example)
{
/* First we create the sink pad, which is the input to the element.
* We will use the sink_template constructed in the plugin_init function
* (below) to quickly generate the pad we need.
* We will use the template constructed by the factory.
*/
example->sinkpad = gst_pad_new_from_template (sink_template, "sink");
example->sinkpad = gst_pad_new_from_template (
GST_PADTEMPLATE_GET (sink_factory), "sink");
/* Setting the chain function allows us to supply the function that will
* actually be performing the work. Without this, the element would do
* nothing, with undefined results (assertion failures and such).
@ -208,7 +205,8 @@ gst_example_init(GstExample *example)
* pads don't have chain functions, because they can't accept buffers,
* they only produce them.
*/
example->srcpad = gst_pad_new_from_template (src_template, "src");
example->srcpad = gst_pad_new_from_template (
GST_PADTEMPLATE_GET (src_factory), "src");
gst_element_add_pad(GST_ELEMENT(example),example->srcpad);
/* Initialization of element's private variables. */
@ -344,17 +342,12 @@ plugin_init (GModule *module, GstPlugin *plugin)
/* The pad templates can be easily generated from the factories above,
* and then added to the list of padtemplates for the elementfactory.
* Note that the generated padtemplates are stored in static global
* variables, for the gst_example_init function to use later on.
*/
sink_template = sink_factory ();
gst_elementfactory_add_padtemplate (factory, sink_template);
src_template = src_factory ();
gst_elementfactory_add_padtemplate (factory, src_template);
gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (sink_factory));
gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (src_factory));
/* The very last thing is to register the elementfactory with the plugin. */
gst_plugin_add_factory (plugin, factory);
gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
/* Now we can return successfully. */
return TRUE;

View file

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

View file

@ -362,7 +362,7 @@ plugin_init (GModule *module, GstPlugin *plugin)
&gst_autoplugcache_details);
g_return_val_if_fail (factory != NULL, FALSE);
gst_plugin_add_factory (plugin, factory);
gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
return TRUE;
}

View file

@ -594,7 +594,7 @@ plugin_init (GModule *module, GstPlugin *plugin)
&gst_autoplugger_details);
g_return_val_if_fail (factory != NULL, FALSE);
gst_plugin_add_factory (plugin, factory);
gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
return TRUE;
}

View file

@ -93,7 +93,7 @@ plugin_init (GModule *module, GstPlugin *plugin)
gst_static_autoplug_get_type ());
if (factory != NULL) {
gst_plugin_add_autoplugger (plugin, factory);
gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
}
return TRUE;
}
@ -125,7 +125,8 @@ gst_autoplug_can_match (GstElementFactory *src, GstElementFactory *dest)
if (gst_caps_check_compatibility (gst_padtemplate_get_caps (srctemp),
gst_padtemplate_get_caps (desttemp))) {
GST_DEBUG (GST_CAT_AUTOPLUG_ATTEMPT,
"factory \"%s\" can connect with factory \"%s\"\n", src->name, dest->name);
"factory \"%s\" can connect with factory \"%s\"\n", GST_OBJECT_NAME (src),
GST_OBJECT_NAME (dest));
return TRUE;
}
}
@ -135,7 +136,8 @@ gst_autoplug_can_match (GstElementFactory *src, GstElementFactory *dest)
srctemps = g_list_next (srctemps);
}
GST_DEBUG (GST_CAT_AUTOPLUG_ATTEMPT,
"factory \"%s\" cannot connect with factory \"%s\"\n", src->name, dest->name);
"factory \"%s\" cannot connect with factory \"%s\"\n", GST_OBJECT_NAME (src),
GST_OBJECT_NAME (dest));
return FALSE;
}
@ -363,9 +365,9 @@ gst_static_autoplug_to_caps (GstAutoplug *autoplug, GstCaps *srccaps, GstCaps *s
}
}
GST_DEBUG (0,"common factory \"%s\"\n", factory->name);
GST_DEBUG (0,"common factory \"%s\"\n", GST_OBJECT_NAME (factory));
element = gst_elementfactory_create (factory, factory->name);
element = gst_elementfactory_create (factory, GST_OBJECT_NAME (factory));
gst_bin_add (GST_BIN(result), element);
if (srcelement != NULL) {
@ -415,8 +417,8 @@ differ:
factory = (GstElementFactory *)(factories[i]->data);
GST_DEBUG (0,"factory \"%s\"\n", factory->name);
element = gst_elementfactory_create(factory, factory->name);
GST_DEBUG (0,"factory \"%s\"\n", GST_OBJECT_NAME (factory));
element = gst_elementfactory_create(factory, GST_OBJECT_NAME (factory));
GST_DEBUG (0,"adding element %s\n", GST_ELEMENT_NAME (element));
gst_bin_add(GST_BIN(thebin), element);
@ -513,7 +515,7 @@ construct_path (gst_autoplug_node *rgnNodes, gpointer factory)
next = rgnNodes[find_factory(rgnNodes, current)].iPrev;
if (next) {
factories = g_list_prepend (factories, current);
GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"factory: \"%s\"", current->name);
GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"factory: \"%s\"", GST_OBJECT_NAME (current));
}
current = next;
}

View file

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

View file

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

View file

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

View file

@ -24,9 +24,8 @@
#include "gst_private.h"
#include "gstautoplug.h"
#include "gstplugin.h"
GList* _gst_autoplugfactories;
static GList* _gst_autoplugfactories;
enum {
NEW_OBJECT,
@ -60,7 +59,7 @@ GType gst_autoplug_get_type(void)
4,
(GInstanceInitFunc)gst_autoplug_init,
};
autoplug_type = g_type_register_static (GST_TYPE_OBJECT, "GstAutoplug", &autoplug_info, 0);
autoplug_type = g_type_register_static (GST_TYPE_OBJECT, "GstAutoplug", &autoplug_info, G_TYPE_FLAG_ABSTRACT);
}
return autoplug_type;
}
@ -81,18 +80,13 @@ gst_autoplug_class_init(GstAutoplugClass *klass)
G_STRUCT_OFFSET (GstAutoplugClass, new_object), NULL, NULL,
g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
GST_TYPE_OBJECT);
}
static void gst_autoplug_init(GstAutoplug *autoplug)
{
}
void
_gst_autoplug_initialize (void)
{
_gst_autoplugfactories = NULL;
}
/**
* gst_autoplug_signal_new_object:
* @autoplug: The autoplugger to emit the signal
@ -170,6 +164,63 @@ gst_autoplug_to_renderers (GstAutoplug *autoplug, GstCaps *srccaps, GstElement *
return element;
}
static void gst_autoplugfactory_class_init (GstAutoplugFactoryClass *klass);
static void gst_autoplugfactory_init (GstAutoplugFactory *factory);
static xmlNodePtr gst_autoplugfactory_save_thyself (GstObject *object, xmlNodePtr parent);
static void gst_autoplugfactory_restore_thyself (GstObject *object, xmlNodePtr parent);
static GstPluginFeatureClass *factory_parent_class = NULL;
//static guint gst_autoplugfactory_signals[LAST_SIGNAL] = { 0 };
GType
gst_autoplugfactory_get_type (void)
{
static GType autoplugfactory_type = 0;
if (!autoplugfactory_type) {
static const GTypeInfo autoplugfactory_info = {
sizeof (GstAutoplugFactoryClass),
NULL,
NULL,
(GClassInitFunc) gst_autoplugfactory_class_init,
NULL,
NULL,
sizeof(GstAutoplugFactory),
0,
(GInstanceInitFunc) gst_autoplugfactory_init,
};
autoplugfactory_type = g_type_register_static (GST_TYPE_PLUGIN_FEATURE,
"GstAutoplugFactory", &autoplugfactory_info, 0);
}
return autoplugfactory_type;
}
static void
gst_autoplugfactory_class_init (GstAutoplugFactoryClass *klass)
{
GObjectClass *gobject_class;
GstObjectClass *gstobject_class;
GstPluginFeatureClass *gstpluginfeature_class;
gobject_class = (GObjectClass*)klass;
gstobject_class = (GstObjectClass*)klass;
gstpluginfeature_class = (GstPluginFeatureClass*) klass;
factory_parent_class = g_type_class_ref (GST_TYPE_PLUGIN_FEATURE);
gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_autoplugfactory_save_thyself);
gstobject_class->restore_thyself = GST_DEBUG_FUNCPTR (gst_autoplugfactory_restore_thyself);
_gst_autoplugfactories = NULL;
}
static void
gst_autoplugfactory_init (GstAutoplugFactory *factory)
{
_gst_autoplugfactories = g_list_prepend (_gst_autoplugfactories, factory);
}
/**
* gst_autoplugfactory_new:
@ -187,15 +238,17 @@ gst_autoplugfactory_new (const gchar *name, const gchar *longdesc, GType type)
GstAutoplugFactory *factory;
g_return_val_if_fail(name != NULL, NULL);
factory = gst_autoplugfactory_find (name);
if (!factory) {
factory = GST_AUTOPLUGFACTORY (g_object_new (GST_TYPE_AUTOPLUGFACTORY, NULL));
}
factory = g_new0(GstAutoplugFactory, 1);
factory->name = g_strdup(name);
gst_object_set_name (GST_OBJECT (factory), name);
if (factory->longdesc)
g_free (factory->longdesc);
factory->longdesc = g_strdup (longdesc);
factory->type = type;
_gst_autoplugfactories = g_list_prepend (_gst_autoplugfactories, factory);
return factory;
}
@ -236,7 +289,7 @@ gst_autoplugfactory_find (const gchar *name)
walk = _gst_autoplugfactories;
while (walk) {
factory = (GstAutoplugFactory *)(walk->data);
if (!strcmp (name, factory->name))
if (!strcmp (name, GST_OBJECT_NAME (factory)))
return factory;
walk = g_list_next (walk);
}
@ -273,10 +326,8 @@ gst_autoplugfactory_create (GstAutoplugFactory *factory)
g_return_val_if_fail (factory != NULL, NULL);
if (factory->type == 0){
factory = gst_plugin_load_autoplugfactory (factory->name);
}
g_return_val_if_fail (factory != NULL, NULL);
gst_plugin_feature_ensure_loaded (GST_PLUGIN_FEATURE (factory));
g_return_val_if_fail (factory->type != 0, NULL);
new = GST_AUTOPLUG (g_object_new(factory->type,NULL));
@ -308,21 +359,19 @@ gst_autoplugfactory_make (const gchar *name)
return gst_autoplugfactory_create (factory);;
}
/**
* gst_autoplugfactory_save_thyself:
* @factory: The facory to save
* @parent: the parent XML node pointer
*
* Save the autoplugfactory into an XML representation
*
* Returns: The new XML parent.
*/
xmlNodePtr
gst_autoplugfactory_save_thyself (GstAutoplugFactory *factory, xmlNodePtr parent)
static xmlNodePtr
gst_autoplugfactory_save_thyself (GstObject *object, xmlNodePtr parent)
{
g_return_val_if_fail(factory != NULL, NULL);
GstAutoplugFactory *factory;
g_return_val_if_fail(GST_IS_AUTOPLUGFACTORY (object), parent);
factory = GST_AUTOPLUGFACTORY (object);
if (GST_OBJECT_CLASS (factory_parent_class)->save_thyself) {
GST_OBJECT_CLASS (factory_parent_class)->save_thyself (object, parent);
}
xmlNewChild(parent,NULL,"name",factory->name);
xmlNewChild(parent,NULL,"longdesc", factory->longdesc);
return parent;
@ -336,23 +385,23 @@ gst_autoplugfactory_save_thyself (GstAutoplugFactory *factory, xmlNodePtr parent
*
* Returns: A new factory based on the XML node.
*/
GstAutoplugFactory*
gst_autoplugfactory_load_thyself (xmlNodePtr parent)
static void
gst_autoplugfactory_restore_thyself (GstObject *object, xmlNodePtr parent)
{
GstAutoplugFactory *factory = g_new0(GstAutoplugFactory, 1);
GstAutoplugFactory *factory = GST_AUTOPLUGFACTORY (object);
xmlNodePtr children = parent->xmlChildrenNode;
if (GST_OBJECT_CLASS (factory_parent_class)->restore_thyself) {
GST_OBJECT_CLASS (factory_parent_class)->restore_thyself (object, parent);
}
while (children) {
if (!strcmp(children->name, "name")) {
factory->name = xmlNodeGetContent(children);
gst_object_set_name (GST_OBJECT (factory), xmlNodeGetContent(children));
}
if (!strcmp(children->name, "longdesc")) {
factory->longdesc = xmlNodeGetContent(children);
}
children = children->next;
}
_gst_autoplugfactories = g_list_prepend (_gst_autoplugfactories, factory);
return factory;
}

View file

@ -69,13 +69,6 @@ struct _GstAutoplugClass {
GstElement* (*autoplug_to_renderers) (GstAutoplug *autoplug, GstCaps *srccaps, GstElement *target, va_list args);
};
typedef struct _GstAutoplugFactory GstAutoplugFactory;
struct _GstAutoplugFactory {
gchar *name; /* name of autoplugger */
gchar *longdesc; /* long description of the autoplugger (well, don't overdo it..) */
GType type; /* unique GType of the autoplugger */
};
GType gst_autoplug_get_type (void);
@ -90,6 +83,33 @@ GstElement* gst_autoplug_to_renderers (GstAutoplug *autoplug, GstCaps *srccaps
* creating autopluggers
*
*/
#define GST_TYPE_AUTOPLUGFACTORY \
(gst_autoplugfactory_get_type())
#define GST_AUTOPLUGFACTORY(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AUTOPLUGFACTORY,GstAutoplugFactory))
#define GST_AUTOPLUGFACTORY_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AUTOPLUGFACTORY,GstAutoplugFactoryClass))
#define GST_IS_AUTOPLUGFACTORY(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AUTOPLUGFACTORY))
#define GST_IS_AUTOPLUGFACTORY_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AUTOPLUGFACTORY))
typedef struct _GstAutoplugFactory GstAutoplugFactory;
typedef struct _GstAutoplugFactoryClass GstAutoplugFactoryClass;
struct _GstAutoplugFactory {
GstPluginFeature feature;
gchar *longdesc; /* long description of the autoplugger (well, don't overdo it..) */
GType type; /* unique GType of the autoplugger */
};
struct _GstAutoplugFactoryClass {
GstPluginFeatureClass parent;
};
GType gst_autoplugfactory_get_type (void);
GstAutoplugFactory* gst_autoplugfactory_new (const gchar *name, const gchar *longdesc, GType type);
void gst_autoplugfactory_destroy (GstAutoplugFactory *factory);
@ -99,9 +119,6 @@ GList* gst_autoplugfactory_get_list (void);
GstAutoplug* gst_autoplugfactory_create (GstAutoplugFactory *factory);
GstAutoplug* gst_autoplugfactory_make (const gchar *name);
xmlNodePtr gst_autoplugfactory_save_thyself (GstAutoplugFactory *factory, xmlNodePtr parent);
GstAutoplugFactory* gst_autoplugfactory_load_thyself (xmlNodePtr parent);
#ifdef __cplusplus
}
#endif /* __cplusplus */
@ -113,6 +130,7 @@ GstAutoplugFactory* gst_autoplugfactory_load_thyself (xmlNodePtr parent);
#pragma GCC poison gst_autoplug_to_caps
#pragma GCC poison gst_autoplug_to_renderers
#pragma GCC poison gst_autoplugfactory_get_type
#pragma GCC poison gst_autoplugfactory_new
#pragma GCC poison gst_autoplugfactory_destroy
@ -122,9 +140,6 @@ GstAutoplugFactory* gst_autoplugfactory_load_thyself (xmlNodePtr parent);
#pragma GCC poison gst_autoplugfactory_create
#pragma GCC poison gst_autoplugfactory_make
#pragma GCC poison gst_autoplugfactory_save_thyself
#pragma GCC poison gst_autoplugfactory_load_thyself
#endif // GST_DISABLE_AUTOPLUG
#endif /* __GST_AUTOPLUG_H__ */

View file

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

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_base_class_init (GstElementClass *klass);
static void gst_element_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
static void gst_element_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
static void gst_element_set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec);
static void gst_element_get_property (GObject *object, guint prop_id, GValue *value,
GParamSpec *pspec);
static void gst_element_shutdown (GObject *object);
static void gst_element_real_destroy (GObject *object);
@ -206,19 +208,6 @@ gst_element_get_property (GObject *object, guint prop_id, GValue *value, GParamS
}
/**
* gst_element_new:
*
* Create a new element. Should never be used, as it does no good.
*
* Returns: new element
*/
GstElement*
gst_element_new(void)
{
return GST_ELEMENT (g_object_new(GST_TYPE_ELEMENT,NULL));
}
/**
* gst_element_set_name:
* @element: GstElement to set name of
@ -1004,9 +993,7 @@ gst_element_save_thyself (GstObject *object,
// GType type;
GstElement *element;
g_return_val_if_fail (object != NULL, parent);
g_return_val_if_fail (GST_IS_ELEMENT (object), parent);
g_return_val_if_fail (parent != NULL, parent);
element = GST_ELEMENT (object);
@ -1017,7 +1004,7 @@ gst_element_save_thyself (GstObject *object,
if (oclass->elementfactory != NULL) {
GstElementFactory *factory = (GstElementFactory *)oclass->elementfactory;
xmlNewChild (parent, NULL, "type", factory->name);
xmlNewChild (parent, NULL, "type", GST_OBJECT_NAME (factory));
xmlNewChild (parent, NULL, "version", factory->details->version);
}
@ -1261,7 +1248,7 @@ gst_element_signal_eos (GstElement *element)
}
const gchar *gst_element_statename(int state) {
const gchar *gst_element_statename(GstElementState state) {
switch (state) {
#ifdef GST_DEBUG_COLOR
case GST_STATE_VOID_PENDING: return "NONE_PENDING";break;

View file

@ -36,6 +36,7 @@
#include <gst/gstobject.h>
#include <gst/gstpad.h>
#include <gst/cothreads.h>
#include <gst/gstpluginfeature.h>
#ifdef __cplusplus
extern "C" {
@ -125,8 +126,8 @@ typedef enum {
//typedef struct _GstElement GstElement;
//typedef struct _GstElementClass GstElementClass;
typedef struct _GstElementDetails GstElementDetails;
typedef struct _GstElementFactory GstElementFactory;
typedef struct _GstElementFactoryClass GstElementFactoryClass;
typedef void (*GstElementLoopFunction) (GstElement *element);
@ -177,29 +178,9 @@ struct _GstElementClass {
GstPad* (*request_new_pad) (GstElement *element, GstPadTemplate *templ);
};
struct _GstElementDetails {
gchar *longname; /* long, english name */
gchar *klass; /* type of element, as hierarchy */
gchar *description; /* insights of one form or another */
gchar *version; /* version of the element */
gchar *author; /* who wrote this thing? */
gchar *copyright; /* copyright details (year, etc.) */
};
struct _GstElementFactory {
gchar *name; /* name of element */
GType type; /* unique GType of element */
GstElementDetails *details; /* pointer to details struct */
GList *padtemplates;
guint16 numpadtemplates;
};
void gst_element_class_add_padtemplate (GstElementClass *element, GstPadTemplate *templ);
GType gst_element_get_type (void);
GstElement* gst_element_new (void);
#define gst_element_destroy(element) gst_object_destroy (GST_OBJECT (element))
void gst_element_set_loop_function (GstElement *element,
@ -236,6 +217,7 @@ void gst_element_signal_eos (GstElement *element);
/* called by the app to set the state of the element */
gint gst_element_set_state (GstElement *element, GstElementState state);
const gchar * gst_element_statename (GstElementState state);
void gst_element_error (GstElement *element, const gchar *error);
@ -250,12 +232,50 @@ GstElement* gst_element_restore_thyself (xmlNodePtr self, GstObject *parent);
* factories stuff
*
**/
typedef struct _GstElementDetails GstElementDetails;
struct _GstElementDetails {
gchar *longname; /* long, english name */
gchar *klass; /* type of element, as hierarchy */
gchar *description; /* insights of one form or another */
gchar *version; /* version of the element */
gchar *author; /* who wrote this thing? */
gchar *copyright; /* copyright details (year, etc.) */
};
#define GST_TYPE_ELEMENTFACTORY \
(gst_elementfactory_get_type())
#define GST_ELEMENTFACTORY(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ELEMENTFACTORY,GstElementFactory))
#define GST_ELEMENTFACTORY_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ELEMENTFACTORY,GstElementFactoryClass))
#define GST_IS_ELEMENTFACTORY(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ELEMENTFACTORY))
#define GST_IS_ELEMENTFACTORY_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ELEMENTFACTORY))
struct _GstElementFactory {
GstPluginFeature feature;
GType type; /* unique GType of element */
GstElementDetails *details; /* pointer to details struct */
GList *padtemplates;
guint16 numpadtemplates;
};
struct _GstElementFactoryClass {
GstPluginFeatureClass parent_class;
};
GType gst_elementfactory_get_type (void);
GstElementFactory* gst_elementfactory_new (const gchar *name,GType type,
GstElementDetails *details);
void gst_elementfactory_destroy (GstElementFactory *elementfactory);
GstElementFactory* gst_elementfactory_find (const gchar *name);
GList* gst_elementfactory_get_list (void);
const GList* gst_elementfactory_get_list (void);
void gst_elementfactory_add_padtemplate (GstElementFactory *elementfactory,
GstPadTemplate *templ);
@ -271,12 +291,6 @@ GstElement* gst_elementfactory_create (GstElementFactory *factory,
GstElement* gst_elementfactory_make (const gchar *factoryname, const gchar *name);
xmlNodePtr gst_elementfactory_save_thyself (GstElementFactory *factory, xmlNodePtr parent);
GstElementFactory* gst_elementfactory_load_thyself (xmlNodePtr parent);
const gchar * gst_element_statename (int state);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View file

@ -24,32 +24,72 @@
#include "gst_private.h"
#include "gstelement.h"
#include "gstplugin.h"
static void gst_elementfactory_class_init (GstElementFactoryClass *klass);
static void gst_elementfactory_init (GstElementFactory *factory);
static void gst_elementfactory_restore_thyself (GstObject *object, xmlNodePtr parent);
static xmlNodePtr gst_elementfactory_save_thyself (GstObject *object, xmlNodePtr parent);
static void gst_elementfactory_unload_thyself (GstPluginFeature *feature);
/* global list of registered elementfactories */
GList* _gst_elementfactories;
static GList* _gst_elementfactories;
void
_gst_elementfactory_initialize (void)
static GstPluginFeatureClass *parent_class = NULL;
//static guint gst_elementfactory_signals[LAST_SIGNAL] = { 0 };
GType
gst_elementfactory_get_type (void)
{
static GType elementfactory_type = 0;
if (!elementfactory_type) {
static const GTypeInfo elementfactory_info = {
sizeof (GstElementFactoryClass),
NULL,
NULL,
(GClassInitFunc) gst_elementfactory_class_init,
NULL,
NULL,
sizeof(GstElementFactory),
0,
(GInstanceInitFunc) gst_elementfactory_init,
};
elementfactory_type = g_type_register_static (GST_TYPE_PLUGIN_FEATURE,
"GstElementFactory", &elementfactory_info, 0);
}
return elementfactory_type;
}
static void
gst_elementfactory_class_init (GstElementFactoryClass *klass)
{
GObjectClass *gobject_class;
GstObjectClass *gstobject_class;
GstPluginFeatureClass *gstpluginfeature_class;
gobject_class = (GObjectClass*)klass;
gstobject_class = (GstObjectClass*)klass;
gstpluginfeature_class = (GstPluginFeatureClass*) klass;
parent_class = g_type_class_ref (GST_TYPE_PLUGIN_FEATURE);
gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_elementfactory_save_thyself);
gstobject_class->restore_thyself = GST_DEBUG_FUNCPTR (gst_elementfactory_restore_thyself);
gstpluginfeature_class->unload_thyself = GST_DEBUG_FUNCPTR (gst_elementfactory_unload_thyself);
_gst_elementfactories = NULL;
}
/**
* gst_elementfactory_destroy:
* @elementfactory: factory to destroy
*
* Removes the elementfactory from the global list.
*/
void
gst_elementfactory_destroy (GstElementFactory *elementfactory)
static void
gst_elementfactory_init (GstElementFactory *factory)
{
g_return_if_fail (elementfactory != NULL);
factory->padtemplates = NULL;
factory->numpadtemplates = 0;
_gst_elementfactories = g_list_remove (_gst_elementfactories, elementfactory);
// we don't free the struct bacause someone might have a handle to it..
_gst_elementfactories = g_list_prepend (_gst_elementfactories, factory);
}
/**
@ -71,13 +111,13 @@ gst_elementfactory_find (const gchar *name)
walk = _gst_elementfactories;
while (walk) {
factory = (GstElementFactory *)(walk->data);
if (!strcmp(name,factory->name))
if (!strcmp(name, GST_OBJECT_NAME (factory)))
return factory;
walk = g_list_next(walk);
}
// this should be an ERROR
GST_DEBUG (GST_CAT_ELEMENTFACTORY,"no such elementfactoryfactory \"%s\"\n", name);
GST_DEBUG (GST_CAT_ELEMENTFACTORY,"no such elementfactory \"%s\"\n", name);
return NULL;
}
@ -88,7 +128,7 @@ gst_elementfactory_find (const gchar *name)
*
* Returns: GList of type #GstElementFactory
*/
GList*
const GList*
gst_elementfactory_get_list (void)
{
return _gst_elementfactories;
@ -113,16 +153,18 @@ gst_elementfactory_new (const gchar *name, GType type,
GstElementFactory *factory;
g_return_val_if_fail(name != NULL, NULL);
g_return_val_if_fail(type != 0, NULL);
factory = g_new0(GstElementFactory, 1);
factory = gst_elementfactory_find (name);
if (!factory) {
factory = GST_ELEMENTFACTORY (g_object_new (GST_TYPE_ELEMENTFACTORY, NULL));
}
factory->name = g_strdup(name);
gst_object_set_name (GST_OBJECT (factory), name);
factory->type = type;
if (factory->details)
g_free (factory->details);
factory->details = details;
factory->padtemplates = NULL;
factory->numpadtemplates = 0;
_gst_elementfactories = g_list_prepend (_gst_elementfactories, factory);
return factory;
}
@ -149,13 +191,10 @@ gst_elementfactory_create (GstElementFactory *factory,
g_return_val_if_fail(name != NULL, NULL);
GST_DEBUG (GST_CAT_ELEMENTFACTORY,"creating element from factory \"%s\" with name \"%s\"\n",
factory->name, name);
GST_OBJECT_NAME (factory), name);
gst_plugin_feature_ensure_loaded (GST_PLUGIN_FEATURE (factory));
// it's not loaded, try to load the plugin
if (factory->type == 0) {
factory = gst_plugin_load_elementfactory(factory->name);
}
g_return_val_if_fail(factory != NULL, NULL);
g_return_val_if_fail(factory->type != 0, NULL);
// create an instance of the element
@ -165,7 +204,7 @@ gst_elementfactory_create (GstElementFactory *factory,
// attempt to set the elemenfactory class pointer if necessary
oclass = GST_ELEMENT_CLASS(G_OBJECT_GET_CLASS(element));
if (oclass->elementfactory == NULL) {
GST_DEBUG (GST_CAT_ELEMENTFACTORY,"class %s\n", factory->name);
GST_DEBUG (GST_CAT_ELEMENTFACTORY,"class %s\n", GST_OBJECT_NAME (factory));
oclass->elementfactory = factory;
}
@ -195,10 +234,10 @@ gst_elementfactory_make (const gchar *factoryname, const gchar *name)
GstElementFactory *factory;
GstElement *element;
g_return_val_if_fail(factoryname != NULL, NULL);
g_return_val_if_fail(name != NULL, NULL);
g_return_val_if_fail (factoryname != NULL, NULL);
g_return_val_if_fail (name != NULL, NULL);
// GST_DEBUG (GST_CAT_ELEMENTFACTORY,"gstelementfactory: make \"%s\" \"%s\"\n", factoryname, name);
GST_DEBUG (GST_CAT_ELEMENTFACTORY, "gstelementfactory: make \"%s\" \"%s\"\n", factoryname, name);
//gst_plugin_load_elementfactory(factoryname);
factory = gst_elementfactory_find(factoryname);
@ -211,6 +250,7 @@ gst_elementfactory_make (const gchar *factoryname, const gchar *name)
GST_INFO (GST_CAT_ELEMENTFACTORY,"couldn't create instance of elementfactory \"%s\"!",factoryname);
return NULL;
}
return element;
}
@ -225,9 +265,24 @@ void
gst_elementfactory_add_padtemplate (GstElementFactory *factory,
GstPadTemplate *templ)
{
GList *padtemplates;
g_return_if_fail(factory != NULL);
g_return_if_fail(templ != NULL);
padtemplates = factory->padtemplates;
while (padtemplates) {
GstPadTemplate *oldtempl = GST_PADTEMPLATE (padtemplates->data);
if (!strcmp (oldtempl->name_template, templ->name_template)) {
gst_object_unref (GST_OBJECT (oldtempl));
padtemplates->data = templ;
return;
}
padtemplates = g_list_next (padtemplates);
}
factory->padtemplates = g_list_append (factory->padtemplates, templ);
factory->numpadtemplates++;
}
@ -298,24 +353,31 @@ gst_elementfactory_can_sink_caps (GstElementFactory *factory,
return FALSE;
}
/**
* gst_elementfactory_save_thyself:
* @factory: factory to save
* @parent: the parent xmlNodePtr
*
* Saves the factory into an XML tree.
*
* Returns: the new xmlNodePtr
*/
xmlNodePtr
gst_elementfactory_save_thyself (GstElementFactory *factory,
static void
gst_elementfactory_unload_thyself (GstPluginFeature *feature)
{
GstElementFactory *factory;
factory = GST_ELEMENTFACTORY (feature);
factory->type = 0;
}
static xmlNodePtr
gst_elementfactory_save_thyself (GstObject *object,
xmlNodePtr parent)
{
GList *pads;
GstElementFactory *factory;
factory = GST_ELEMENTFACTORY (object);
if (GST_OBJECT_CLASS (parent_class)->save_thyself) {
GST_OBJECT_CLASS (parent_class)->save_thyself (object, parent);
}
g_return_val_if_fail(factory != NULL, NULL);
xmlNewChild(parent,NULL,"name",factory->name);
xmlNewChild(parent,NULL,"longname", factory->details->longname);
xmlNewChild(parent,NULL,"class", factory->details->klass);
xmlNewChild(parent,NULL,"description", factory->details->description);
@ -338,26 +400,19 @@ gst_elementfactory_save_thyself (GstElementFactory *factory,
return parent;
}
/**
* gst_elementfactory_load_thyself:
* @parent: the parent xmlNodePtr
*
* Creates a new factory from an xmlNodePtr.
*
* Returns: the new factory
*/
GstElementFactory *
gst_elementfactory_load_thyself (xmlNodePtr parent)
static void
gst_elementfactory_restore_thyself (GstObject *object, xmlNodePtr parent)
{
GstElementFactory *factory = g_new0(GstElementFactory, 1);
GstElementFactory *factory = GST_ELEMENTFACTORY (object);
xmlNodePtr children = parent->xmlChildrenNode;
factory->details = g_new0(GstElementDetails, 1);
factory->padtemplates = NULL;
if (GST_OBJECT_CLASS (parent_class)->restore_thyself) {
GST_OBJECT_CLASS (parent_class)->restore_thyself (object, parent);
}
while (children) {
if (!strcmp(children->name, "name")) {
factory->name = xmlNodeGetContent(children);
}
if (!strcmp(children->name, "longname")) {
factory->details->longname = xmlNodeGetContent(children);
}
@ -386,8 +441,4 @@ gst_elementfactory_load_thyself (xmlNodePtr parent)
children = children->next;
}
_gst_elementfactories = g_list_prepend (_gst_elementfactories, factory);
return factory;
}

View file

@ -125,19 +125,6 @@ gst_object_init (GstObject *object)
GST_FLAG_SET (object, GST_FLOATING);
}
/**
* gst_object_new:
*
* Create a new, empty object. Not very useful, should never be used.
*
* Returns: new object
*/
GstObject*
gst_object_new (void)
{
return GST_OBJECT (g_object_new (gst_object_get_type (), NULL));
}
/**
* gst_object_ref:
* @object: GstObject to reference
@ -454,13 +441,15 @@ gst_object_unref (GstObject *object)
gboolean
gst_object_check_uniqueness (GList *list, const gchar *name)
{
GstObject *child;
g_return_val_if_fail (name != NULL, FALSE);
while (list) {
child = GST_OBJECT (list->data);
GstObject *child = GST_OBJECT (list->data);
list = g_list_next(list);
if (strcmp(GST_OBJECT_NAME(child), name) == 0) return FALSE;
if (strcmp(GST_OBJECT_NAME(child), name) == 0)
return FALSE;
}
return TRUE;
@ -468,7 +457,6 @@ gst_object_check_uniqueness (GList *list, const gchar *name)
#ifndef GST_DISABLE_LOADSAVE
/**
* gst_object_save_thyself:
* @object: GstObject to save
@ -488,17 +476,36 @@ gst_object_save_thyself (GstObject *object, xmlNodePtr parent)
g_return_val_if_fail (parent != NULL, parent);
oclass = (GstObjectClass *)G_OBJECT_GET_CLASS(object);
if (oclass->save_thyself)
oclass->save_thyself (object, parent);
#ifndef GST_DISABLE_LOADSAVE
g_signal_emit (G_OBJECT (object), gst_object_signals[OBJECT_SAVED], 0, parent);
#endif
return parent;
}
/**
* gst_object_load_thyself:
* @object: GstObject to load into
* @parent: The parent XML node to save the object into
*
* Saves the given object into the parent XML node.
*
* Returns: the new xmlNodePtr with the saved object
*/
void
gst_object_restore_thyself (GstObject *object, xmlNodePtr parent)
{
GstObjectClass *oclass;
g_return_if_fail (object != NULL);
g_return_if_fail (GST_IS_OBJECT (object));
g_return_if_fail (parent != NULL);
oclass = (GstObjectClass *)G_OBJECT_GET_CLASS(object);
if (oclass->restore_thyself)
oclass->restore_thyself (object, parent);
}
#endif // GST_DISABLE_LOADSAVE
/**

View file

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

View file

@ -25,27 +25,23 @@
#include <dirent.h>
#include <unistd.h>
#undef RTLD_GLOBAL
#include "gst_private.h"
#include "gstplugin.h"
#include "gstversion.h"
#include "config.h"
static GModule *main_module;
GList *_gst_plugin_static = NULL;
/* list of loaded modules and its sequence number */
GList *_gst_modules;
gint _gst_modules_seqno;
/* global list of plugins and its sequence number */
GList *_gst_plugins;
gint _gst_plugins_seqno;
gint _gst_plugin_elementfactories = 0;
gint _gst_plugin_types = 0;
GList *_gst_plugins = NULL;
gint _gst_plugins_seqno = 0;
/* list of paths to check for plugins */
GList *_gst_plugin_paths;
GList *_gst_plugin_paths = NULL;
GList *_gst_libraries;
gint _gst_libraries_seqno;
GList *_gst_libraries = NULL;
gint _gst_libraries_seqno = 0;
/* whether or not to spew library load issues */
gboolean _gst_plugin_spew = FALSE;
@ -54,8 +50,13 @@ gboolean _gst_plugin_spew = FALSE;
* this to false.) */
gboolean _gst_warn_old_registry = TRUE;
static gboolean plugin_times_older_than(time_t regtime);
static time_t get_time(const char * path);
#ifndef GST_DISABLE_REGISTRY
static gboolean plugin_times_older_than (time_t regtime);
static time_t get_time (const char * path);
#endif
static void gst_plugin_register_statics (GModule *module);
static GstPlugin* gst_plugin_register_func (GstPluginDesc *desc, GstPlugin *plugin,
GModule *module);
void
_gst_plugin_initialize (void)
@ -64,13 +65,8 @@ _gst_plugin_initialize (void)
xmlDocPtr doc;
#endif
_gst_modules = NULL;
_gst_modules_seqno = 0;
_gst_plugins = NULL;
_gst_plugins_seqno = 0;
_gst_plugin_paths = NULL;
_gst_libraries = NULL;
_gst_libraries_seqno = 0;
main_module = g_module_open (NULL, G_MODULE_BIND_LAZY);
gst_plugin_register_statics (main_module);
/* add the main (installed) library path */
_gst_plugin_paths = g_list_prepend (_gst_plugin_paths, PLUGINS_DIR);
@ -103,6 +99,7 @@ _gst_plugin_initialize (void)
if (_gst_warn_old_registry)
g_warning ("gstplugin: registry needs rebuild: run gstreamer-register\n");
gst_plugin_load_all ();
//gst_plugin_unload_all ();
return;
}
gst_plugin_load_thyself (doc->xmlRootNode);
@ -111,6 +108,36 @@ _gst_plugin_initialize (void)
#endif // GST_DISABLE_REGISTRY
}
void
_gst_plugin_register_static (GstPluginDesc *desc)
{
_gst_plugin_static = g_list_prepend (_gst_plugin_static, desc);
}
static void
gst_plugin_register_statics (GModule *module)
{
GList *walk = _gst_plugin_static;
while (walk) {
GstPluginDesc *desc = (GstPluginDesc *) walk->data;
GstPlugin *plugin;
plugin = g_new0 (GstPlugin, 1);
plugin->filename = NULL;
plugin->module = NULL;
plugin = gst_plugin_register_func (desc, plugin, module);
if (plugin) {
_gst_plugins = g_list_prepend (_gst_plugins, plugin);
_gst_plugins_seqno++;
plugin->module = module;
}
walk = g_list_next (walk);
}
}
/**
* gst_plugin_add_path:
* @path: the directory to add to the search path
@ -123,6 +150,7 @@ gst_plugin_add_path (const gchar *path)
_gst_plugin_paths = g_list_prepend (_gst_plugin_paths,g_strdup(path));
}
#ifndef GST_DISABLE_REGISTRY
static time_t
get_time(const char * path)
{
@ -184,6 +212,7 @@ plugin_times_older_than(time_t regtime)
}
return TRUE;
}
#endif
static gboolean
gst_plugin_load_recurse (gchar *directory, gchar *name)
@ -232,7 +261,7 @@ gst_plugin_load_recurse (gchar *directory, gchar *name)
* Load all plugins in the path.
*/
void
gst_plugin_load_all(void)
gst_plugin_load_all (void)
{
GList *path;
@ -242,8 +271,39 @@ gst_plugin_load_all(void)
gst_plugin_load_recurse(path->data,NULL);
path = g_list_next(path);
}
GST_INFO (GST_CAT_PLUGIN_LOADING,"loaded %d plugins with %d elements and %d types",
_gst_plugins_seqno,_gst_plugin_elementfactories,_gst_plugin_types);
GST_INFO (GST_CAT_PLUGIN_LOADING,"loaded %d plugins", _gst_plugins_seqno);
}
void
gst_plugin_unload_all (void)
{
GList *walk = _gst_plugins;
while (walk) {
GstPlugin *plugin = (GstPlugin *) walk->data;
GST_INFO (GST_CAT_PLUGIN_LOADING, "unloading plugin %s", plugin->name);
if (plugin->module) {
GList *features = gst_plugin_get_feature_list (plugin);
while (features) {
GstPluginFeature *feature = GST_PLUGIN_FEATURE (features->data);
GST_INFO (GST_CAT_PLUGIN_LOADING, "unloading feature %s", GST_OBJECT_NAME (feature));
gst_plugin_feature_unload_thyself (feature);
features = g_list_next (features);
}
if (g_module_close (plugin->module)) {
plugin->module = NULL;
}
else {
g_warning ("error closing module");
}
}
walk = g_list_next (walk);
}
}
/**
@ -277,22 +337,6 @@ gst_library_load (const gchar *name)
return res;
}
static void
gst_plugin_remove (GstPlugin *plugin)
{
GList *factories;
factories = plugin->elements;
while (factories) {
gst_elementfactory_destroy ((GstElementFactory*)(factories->data));
factories = g_list_next(factories);
}
_gst_plugins = g_list_remove(_gst_plugins, plugin);
// don't free the stuct because someone can have a handle to it
}
/**
* gst_plugin_load:
* @name: name of plugin to load
@ -307,14 +351,15 @@ gst_plugin_load (const gchar *name)
{
GList *path;
gchar *libspath;
GstPlugin *plugin;
gchar *pluginname;
//g_print("attempting to load plugin '%s'\n",name);
GstPlugin *plugin;
g_return_val_if_fail (name != NULL, FALSE);
plugin = gst_plugin_find (name);
if (plugin && plugin->loaded) return TRUE;
if (plugin && plugin->module)
return TRUE;
path = _gst_plugin_paths;
while (path != NULL) {
@ -345,6 +390,79 @@ gst_plugin_load (const gchar *name)
return FALSE;
}
/**
* gst_plugin_load:
* @name: name of plugin to load
*
* Load the named plugin. Name should be given as
* &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:
* @name: name of plugin to load
@ -352,105 +470,60 @@ gst_plugin_load (const gchar *name)
* Returns: whether or not the plugin loaded
*/
gboolean
gst_plugin_load_absolute (const gchar *name)
gst_plugin_load_plugin (GstPlugin *plugin)
{
GModule *module;
GstPluginDesc *desc;
GstPlugin *plugin;
struct stat file_status;
gchar *filename;
GST_INFO (GST_CAT_PLUGIN_LOADING,"plugin \"%s\" loading", name);
g_return_val_if_fail (plugin != NULL, FALSE);
if (g_module_supported() == FALSE) {
if (plugin->module)
return TRUE;
filename = plugin->filename;
GST_INFO (GST_CAT_PLUGIN_LOADING, "plugin \"%s\" loading", filename);
if (g_module_supported () == FALSE) {
g_warning("gstplugin: wow, you built this on a platform without dynamic loading???\n");
return FALSE;
}
if (stat(name,&file_status)) {
//g_print("problem opening file %s\n",name);
if (stat (filename, &file_status)) {
//g_print("problem opening file %s\n",filename);
return FALSE;
}
module = g_module_open(name,G_MODULE_BIND_LAZY);
module = g_module_open (filename, G_MODULE_BIND_LAZY);
if (module != NULL) {
if (g_module_symbol(module,"plugin_desc",(gpointer *)&desc)) {
GST_INFO (GST_CAT_PLUGIN_LOADING,"loading plugin \"%s\"...", name);
plugin = gst_plugin_new(desc->name, desc->major_version, desc->minor_version);
if (plugin != NULL) {
plugin->filename = g_strdup(name);
if (!((desc->plugin_init)(module, plugin))) {
GST_INFO (GST_CAT_PLUGIN_LOADING,"plugin \"%s\" failed to initialise",
plugin->name);
g_free(plugin);
plugin = NULL;
}
}
if (g_module_symbol (module, "plugin_desc", (gpointer *)&desc)) {
GST_INFO (GST_CAT_PLUGIN_LOADING,"loading plugin \"%s\"...", filename);
plugin->filename = g_strdup (filename);
plugin = gst_plugin_register_func (desc, plugin, module);
if (plugin != NULL) {
GST_INFO (GST_CAT_PLUGIN_LOADING,"plugin \"%s\" loaded: %d elements, %d types",
plugin->name,plugin->numelements,plugin->numtypes);
plugin->loaded = TRUE;
_gst_modules = g_list_prepend(_gst_modules,module);
_gst_modules_seqno++;
_gst_plugins = g_list_prepend(_gst_plugins,plugin);
_gst_plugins_seqno++;
_gst_plugin_elementfactories += plugin->numelements;
_gst_plugin_types += plugin->numtypes;
GST_INFO (GST_CAT_PLUGIN_LOADING,"plugin \"%s\" loaded",
plugin->filename);
plugin->module = module;
return TRUE;
}
}
return TRUE;
} else if (_gst_plugin_spew) {
// FIXME this should be some standard gst mechanism!!!
g_printerr ("error loading plugin %s, reason: %s\n", name, g_module_error());
g_printerr ("error loading plugin %s, reason: %s\n", filename, g_module_error());
}
else {
GST_INFO (GST_CAT_PLUGIN_LOADING, "error loading plugin %s, reason: %s\n", name, g_module_error());
GST_INFO (GST_CAT_PLUGIN_LOADING, "error loading plugin %s, reason: %s\n", filename, g_module_error());
}
return FALSE;
}
/**
* gst_plugin_new:
* @name: name of new plugin
* @major: major version number of core that plugin is compatible with
* @minor: minor version number of core that plugin is compatible with
*
* Create a new plugin with given name.
*
* Returns: new plugin, or NULL if plugin couldn't be created, due to
* incompatible version number, or name already being allocated)
*/
GstPlugin*
gst_plugin_new (const gchar *name, gint major, gint minor)
{
GstPlugin *plugin;
// return NULL if the major and minor version numbers are not compatible
// with ours.
if (major != GST_VERSION_MAJOR || minor != GST_VERSION_MINOR) return NULL;
// return NULL if the plugin is allready loaded
plugin = gst_plugin_find (name);
if (plugin) return NULL;
plugin = (GstPlugin *)g_malloc(sizeof(GstPlugin));
plugin->name = g_strdup(name);
plugin->longname = NULL;
plugin->elements = NULL;
plugin->numelements = 0;
plugin->types = NULL;
plugin->numtypes = 0;
#ifndef GST_DISABLE_AUTOPLUG
plugin->autopluggers = NULL;
plugin->numautopluggers = 0;
#endif // GST_DISABLE_AUTOPLUG
plugin->loaded = TRUE;
return plugin;
}
/**
* gst_plugin_get_name:
@ -549,7 +622,7 @@ gst_plugin_is_loaded (GstPlugin *plugin)
{
g_return_val_if_fail (plugin != NULL, FALSE);
return plugin->loaded;
return (plugin->module != NULL);
}
@ -566,38 +639,55 @@ gst_plugin_find (const gchar *name)
{
GList *plugins = _gst_plugins;
g_return_val_if_fail(name != NULL, NULL);
g_return_val_if_fail (name != NULL, NULL);
while (plugins) {
GstPlugin *plugin = (GstPlugin *)plugins->data;
// g_print("plugin name is '%s'\n",plugin->name);
if (plugin->name) {
if (!strcmp(plugin->name,name)) {
if (!strcmp (plugin->name, name)) {
return plugin;
}
}
plugins = g_list_next(plugins);
plugins = g_list_next (plugins);
}
return NULL;
}
static GstElementFactory*
gst_plugin_find_elementfactory (const gchar *name)
static GstPluginFeature*
gst_plugin_find_feature_func (GstPlugin *plugin, const gchar *name, GType type)
{
GList *plugins, *factories;
GstElementFactory *factory;
GList *features = plugin->features;
g_return_val_if_fail(name != NULL, NULL);
g_return_val_if_fail (name != NULL, NULL);
while (features) {
GstPluginFeature *feature = GST_PLUGIN_FEATURE (features->data);
if (!strcmp(GST_OBJECT_NAME (feature), name) && G_OBJECT_TYPE (feature) == type)
return GST_PLUGIN_FEATURE (feature);
features = g_list_next (features);
}
return NULL;
}
GstPluginFeature*
gst_plugin_find_feature (const gchar *name, GType type)
{
GList *plugins;
plugins = _gst_plugins;
while (plugins) {
factories = ((GstPlugin *)(plugins->data))->elements;
while (factories) {
factory = (GstElementFactory*)(factories->data);
if (!strcmp(factory->name, name))
return (GstElementFactory*)(factory);
factories = g_list_next(factories);
}
GstPlugin *plugin = (GstPlugin *)plugins->data;
GstPluginFeature *feature;
feature = gst_plugin_find_feature_func (plugin, name, type);
if (feature)
return feature;
plugins = g_list_next(plugins);
}
@ -605,234 +695,30 @@ gst_plugin_find_elementfactory (const gchar *name)
}
/**
* gst_plugin_load_elementfactory:
* @name: name of elementfactory to load
* gst_plugin_add_feature:
* @plugin: plugin to add feature to
* @feature: feature to add
*
* Load a registered elementfactory by name.
*
* Returns: @GstElementFactory if loaded, NULL if not
*/
GstElementFactory*
gst_plugin_load_elementfactory (const gchar *name)
{
GList *plugins, *factories;
GstElementFactory *factory = NULL;
GstPlugin *plugin;
g_return_val_if_fail(name != NULL, NULL);
plugins = _gst_plugins;
while (plugins) {
plugin = (GstPlugin *)plugins->data;
factories = plugin->elements;
while (factories) {
factory = (GstElementFactory*)(factories->data);
if (!strcmp(factory->name,name)) {
if (!plugin->loaded) {
gchar *filename = g_strdup (plugin->filename);
gchar *pluginname = g_strdup (plugin->name);
GST_INFO (GST_CAT_PLUGIN_LOADING,"loaded elementfactory %s from plugin %s",name,plugin->name);
gst_plugin_remove(plugin);
if (!gst_plugin_load_absolute(filename)) {
GST_DEBUG (0,"gstplugin: error loading element factory %s from plugin %s\n", name, pluginname);
}
g_free (pluginname);
g_free (filename);
}
factory = gst_plugin_find_elementfactory(name);
return factory;
}
factories = g_list_next(factories);
}
plugins = g_list_next(plugins);
}
return factory;
}
#ifndef GST_DISABLE_AUTOPLUG
static GstAutoplugFactory*
gst_plugin_find_autoplugfactory (const gchar *name)
{
GList *plugins, *factories;
GstAutoplugFactory *factory;
g_return_val_if_fail(name != NULL, NULL);
plugins = _gst_plugins;
while (plugins) {
factories = ((GstPlugin *)(plugins->data))->autopluggers;
while (factories) {
factory = (GstAutoplugFactory*)(factories->data);
if (!strcmp(factory->name, name))
return (GstAutoplugFactory*)(factory);
factories = g_list_next(factories);
}
plugins = g_list_next(plugins);
}
return NULL;
}
/**
* gst_plugin_load_autoplugfactory:
* @name: name of autoplugfactory to load
*
* Load a registered autoplugfactory by name.
*
* Returns: @GstAutoplugFactory if loaded, NULL if not
*/
GstAutoplugFactory*
gst_plugin_load_autoplugfactory (const gchar *name)
{
GList *plugins, *factories;
GstAutoplugFactory *factory = NULL;
GstPlugin *plugin;
g_return_val_if_fail(name != NULL, NULL);
plugins = _gst_plugins;
while (plugins) {
plugin = (GstPlugin *)plugins->data;
factories = plugin->autopluggers;
while (factories) {
factory = (GstAutoplugFactory*)(factories->data);
if (!strcmp(factory->name,name)) {
if (!plugin->loaded) {
gchar *filename = g_strdup (plugin->filename);
gchar *pluginname = g_strdup (plugin->name);
GST_INFO (GST_CAT_PLUGIN_LOADING,"loaded autoplugfactory %s from plugin %s",name,plugin->name);
gst_plugin_remove(plugin);
if (!gst_plugin_load_absolute(filename)) {
GST_DEBUG (0,"gstplugin: error loading autoplug factory %s from plugin %s\n", name, pluginname);
}
g_free (pluginname);
g_free (filename);
}
factory = gst_plugin_find_autoplugfactory(name);
return factory;
}
factories = g_list_next(factories);
}
plugins = g_list_next(plugins);
}
return factory;
}
#endif // GST_DISABLE_AUTOPLUG
/**
* gst_plugin_load_typefactory:
* @mime: name of typefactory to load
*
* Load a registered typefactory by mime type.
* Add feature to the list of those provided by the plugin.
*/
void
gst_plugin_load_typefactory (const gchar *mime)
gst_plugin_add_feature (GstPlugin *plugin, GstPluginFeature *feature)
{
GList *plugins, *factories;
GstTypeFactory *factory;
GstPlugin *plugin;
GstPluginFeature *oldfeature;
g_return_if_fail (mime != NULL);
plugins = g_list_copy (_gst_plugins);
while (plugins) {
plugin = (GstPlugin *)plugins->data;
factories = g_list_copy (plugin->types);
while (factories) {
factory = (GstTypeFactory*)(factories->data);
if (!strcmp(factory->mime,mime)) {
if (!plugin->loaded) {
gchar *filename = g_strdup (plugin->filename);
gchar *pluginname = g_strdup (plugin->name);
GST_INFO (GST_CAT_PLUGIN_LOADING,"loading type factory for \"%s\" from plugin %s",mime,plugin->name);
plugin->loaded = TRUE;
gst_plugin_remove(plugin);
if (!gst_plugin_load_absolute(filename)) {
GST_DEBUG (0,"gstplugin: error loading type factory \"%s\" from plugin %s\n", mime, pluginname);
}
g_free (filename);
g_free (pluginname);
}
//return;
}
factories = g_list_next(factories);
}
g_list_free (factories);
plugins = g_list_next(plugins);
}
g_list_free (plugins);
return;
}
/**
* gst_plugin_add_factory:
* @plugin: plugin to add factory to
* @factory: factory to add
*
* Add factory to the list of those provided by the plugin.
*/
void
gst_plugin_add_factory (GstPlugin *plugin, GstElementFactory *factory)
{
g_return_if_fail (plugin != NULL);
g_return_if_fail (factory != NULL);
g_return_if_fail (GST_IS_PLUGIN_FEATURE (feature));
g_return_if_fail (feature != NULL);
// g_print("adding factory to plugin\n");
plugin->elements = g_list_prepend (plugin->elements, factory);
plugin->numelements++;
oldfeature = gst_plugin_find_feature_func (plugin, GST_OBJECT_NAME (feature), G_OBJECT_TYPE (feature));
if (!oldfeature) {
feature->manager = plugin;
plugin->features = g_list_prepend (plugin->features, feature);
plugin->numfeatures++;
}
}
/**
* gst_plugin_add_type:
* @plugin: plugin to add type to
* @factory: the typefactory to add
*
* Add a typefactory to the list of those provided by the plugin.
*/
void
gst_plugin_add_type (GstPlugin *plugin, GstTypeFactory *factory)
{
g_return_if_fail (plugin != NULL);
g_return_if_fail (factory != NULL);
// g_print("adding factory to plugin\n");
plugin->types = g_list_prepend (plugin->types, factory);
plugin->numtypes++;
gst_type_register (factory);
}
/**
* gst_plugin_add_autoplugger:
* @plugin: plugin to add the autoplugger to
* @factory: the autoplugfactory to add
*
* Add an autoplugfactory to the list of those provided by the plugin.
*/
#ifndef GST_DISABLE_AUTOPLUG
void
gst_plugin_add_autoplugger (GstPlugin *plugin, GstAutoplugFactory *factory)
{
g_return_if_fail (plugin != NULL);
g_return_if_fail (factory != NULL);
// g_print("adding factory to plugin\n");
plugin->autopluggers = g_list_prepend (plugin->autopluggers, factory);
plugin->numautopluggers++;
}
#endif // GST_DISABLE_AUTOPLUG
/**
* gst_plugin_get_list:
*
@ -859,49 +745,35 @@ xmlNodePtr
gst_plugin_save_thyself (xmlNodePtr parent)
{
xmlNodePtr tree, subtree;
GList *plugins = NULL, *elements = NULL, *types = NULL, *autopluggers = NULL;
GList *plugins = NULL;
plugins = g_list_copy (_gst_plugins);
plugins = _gst_plugins;
while (plugins) {
GstPlugin *plugin = (GstPlugin *)plugins->data;
GList *features;
plugins = g_list_next (plugins);
if (!plugin->name)
continue;
tree = xmlNewChild (parent, NULL, "plugin", NULL);
xmlNewChild (tree, NULL, "name", plugin->name);
xmlNewChild (tree, NULL, "longname", plugin->longname);
xmlNewChild (tree, NULL, "filename", plugin->filename);
types = plugin->types;
while (types) {
GstTypeFactory *factory = (GstTypeFactory *)types->data;
subtree = xmlNewChild(tree, NULL, "typefactory", NULL);
features = plugin->features;
while (features) {
GstPluginFeature *feature = GST_PLUGIN_FEATURE (features->data);
gst_typefactory_save_thyself (factory, subtree);
subtree = xmlNewChild(tree, NULL, "feature", NULL);
xmlNewProp (subtree, "typename", g_type_name (G_OBJECT_TYPE (feature)));
types = g_list_next (types);
gst_object_save_thyself (GST_OBJECT (feature), subtree);
features = g_list_next (features);
}
elements = plugin->elements;
while (elements) {
GstElementFactory *factory = (GstElementFactory *)elements->data;
subtree = xmlNewChild (tree, NULL, "elementfactory", NULL);
gst_elementfactory_save_thyself (factory, subtree);
elements = g_list_next (elements);
}
#ifndef GST_DISABLE_AUTOPLUG
autopluggers = plugin->autopluggers;
while (autopluggers) {
GstAutoplugFactory *factory = (GstAutoplugFactory *)autopluggers->data;
subtree = xmlNewChild (tree, NULL, "autoplugfactory", NULL);
gst_autoplugfactory_save_thyself (factory, subtree);
autopluggers = g_list_next (autopluggers);
}
#endif // GST_DISABLE_AUTOPLUG
plugins = g_list_next (plugins);
}
g_list_free (plugins);
return parent;
}
@ -915,9 +787,7 @@ void
gst_plugin_load_thyself (xmlNodePtr parent)
{
xmlNodePtr kinderen;
gint elementcount = 0;
gint autoplugcount = 0;
gint typecount = 0;
gint featurecount = 0;
gchar *pluginname;
kinderen = parent->xmlChildrenNode; // Dutch invasion :-)
@ -926,9 +796,9 @@ gst_plugin_load_thyself (xmlNodePtr parent)
xmlNodePtr field = kinderen->xmlChildrenNode;
GstPlugin *plugin = g_new0 (GstPlugin, 1);
plugin->elements = NULL;
plugin->types = NULL;
plugin->loaded = FALSE;
plugin->numfeatures = 0;
plugin->features = NULL;
plugin->module = NULL;
while (field) {
if (!strcmp (field->name, "name")) {
@ -948,23 +818,18 @@ gst_plugin_load_thyself (xmlNodePtr parent)
else if (!strcmp (field->name, "filename")) {
plugin->filename = xmlNodeGetContent (field);
}
else if (!strcmp (field->name, "elementfactory")) {
GstElementFactory *factory = gst_elementfactory_load_thyself (field);
gst_plugin_add_factory (plugin, factory);
elementcount++;
}
#ifndef GST_DISABLE_AUTOPLUG
else if (!strcmp (field->name, "autoplugfactory")) {
GstAutoplugFactory *factory = gst_autoplugfactory_load_thyself (field);
gst_plugin_add_autoplugger (plugin, factory);
autoplugcount++;
}
#endif // GST_DISABLE_AUTOPLUG
else if (!strcmp (field->name, "typefactory")) {
GstTypeFactory *factory = gst_typefactory_load_thyself (field);
gst_plugin_add_type (plugin, factory);
elementcount++;
typecount++;
else if (!strcmp (field->name, "feature")) {
GstPluginFeature *feature;
gchar *prop;
prop = xmlGetProp (field, "typename");
feature = GST_PLUGIN_FEATURE (g_object_new (g_type_from_name (prop), NULL));
if (feature) {
gst_object_restore_thyself (GST_OBJECT (feature), field);
gst_plugin_add_feature (plugin, feature);
featurecount++;
}
}
field = field->next;
@ -972,63 +837,29 @@ gst_plugin_load_thyself (xmlNodePtr parent)
if (plugin) {
_gst_plugins = g_list_prepend (_gst_plugins, plugin);
_gst_plugins_seqno++;
}
}
kinderen = kinderen->next;
}
GST_INFO (GST_CAT_PLUGIN_LOADING, "added %d registered factories, %d autopluggers and %d types",
elementcount, autoplugcount, typecount);
GST_INFO (GST_CAT_PLUGIN_LOADING, "added %d features ", featurecount);
}
#endif // GST_DISABLE_REGISTRY
/**
* gst_plugin_get_factory_list:
* @plugin: the plugin to get the factories from
* gst_plugin_get_feature_list:
* @plugin: the plugin to get the features from
*
* get a list of all the factories that this plugin provides
* get a list of all the features that this plugin provides
*
* Returns: a GList of factories
* Returns: a GList of features
*/
GList*
gst_plugin_get_factory_list (GstPlugin *plugin)
gst_plugin_get_feature_list (GstPlugin *plugin)
{
g_return_val_if_fail (plugin != NULL, NULL);
return plugin->elements;
return plugin->features;
}
/**
* gst_plugin_get_type_list:
* @plugin: the plugin to get the typefactories from
*
* get a list of all the typefactories that this plugin provides
*
* Returns: a GList of factories
*/
GList*
gst_plugin_get_type_list (GstPlugin *plugin)
{
g_return_val_if_fail (plugin != NULL, NULL);
return plugin->types;
}
/**
* gst_plugin_get_autoplug_list:
* @plugin: the plugin to get the autoplugfactories from
*
* get a list of all the autoplugfactories that this plugin provides
*
* Returns: a GList of factories
*/
#ifndef GST_DISABLE_AUTOPLUG
GList*
gst_plugin_get_autoplug_list (GstPlugin *plugin)
{
g_return_val_if_fail (plugin != NULL, NULL);
return plugin->autopluggers;
}
#endif // GST_DISABLE_AUTOPLUG

View file

@ -34,10 +34,7 @@
#define xmlRootNode root
#endif
#include <gst/gsttype.h>
#include <gst/gstelement.h>
#include <gst/gstautoplug.h>
#include <gst/gstpluginfeature.h>
typedef struct _GstPlugin GstPlugin;
typedef struct _GstPluginDesc GstPluginDesc;
@ -47,16 +44,10 @@ struct _GstPlugin {
gchar *longname; /* long name of plugin */
gchar *filename; /* filename it came from */
GList *types; /* list of types provided */
gint numtypes;
GList *elements; /* list of elements provided */
gint numelements;
#ifndef GST_DISABLE_AUTOPLUG
GList *autopluggers; /* list of autopluggers provided */
gint numautopluggers;
#endif // GST_DISABLE_AUTOPLUG
GList *features; /* list of features provided */
gint numfeatures;
gboolean loaded; /* if the plugin is in memory */
GModule *module; /* contains the module if the plugin is loaded */
};
/* Initialiser function: returns TRUE if plugin initialised successfully */
@ -69,7 +60,36 @@ struct _GstPluginDesc {
GstPluginInitFunc plugin_init; /* pointer to plugin_init function */
};
#ifndef GST_PLUGIN_STATIC
#define GST_PLUGIN_DESC_DYNAMIC(major,minor,name,init) \
GstPluginDesc plugin_desc = { \
major, \
minor, \
name, \
init \
};
#else
#define GST_PLUGIN_DESC_DYNAMIC(major,minor,name,init)
#endif
#define GST_PLUGIN_DESC_STATIC(major,minor,name,init) \
static void __attribute__ ((constructor)) \
_gst_plugin_static_init__ ##init (void) \
{ \
static GstPluginDesc plugin_desc_ = { \
major, \
minor, \
name, \
init \
}; \
_gst_plugin_register_static (&plugin_desc_); \
}
#define GST_PLUGIN_DESC(major,minor,name,init) \
GST_PLUGIN_DESC_DYNAMIC (major,minor,name,init) \
GST_PLUGIN_DESC_STATIC (major,minor,name,init)
void _gst_plugin_initialize (void);
void _gst_plugin_register_static (GstPluginDesc *desc);
GstPlugin* gst_plugin_new (const gchar *name, gint major, gint minor);
@ -83,39 +103,28 @@ void gst_plugin_set_longname (GstPlugin *plugin, const gchar *longname);
const gchar* gst_plugin_get_filename (GstPlugin *plugin);
gboolean gst_plugin_is_loaded (GstPlugin *plugin);
GList* gst_plugin_get_type_list (GstPlugin *plugin);
GList* gst_plugin_get_factory_list (GstPlugin *plugin);
#ifndef GST_DISABLE_AUTOPLUG
GList* gst_plugin_get_autoplug_list (GstPlugin *plugin);
#else
#pragma GCC poison gst_plugin_get_autoplug_list
#endif // GST_DISABLE_AUTOPLUG
GList* gst_plugin_get_feature_list (GstPlugin *plugin);
void gst_plugin_load_all (void);
void gst_plugin_unload_all (void);
gboolean gst_plugin_load (const gchar *name);
gboolean gst_plugin_load_absolute (const gchar *name);
gboolean gst_library_load (const gchar *name);
gboolean gst_plugin_load_plugin (GstPlugin *plugin);
void gst_plugin_add_factory (GstPlugin *plugin, GstElementFactory *factory);
void gst_plugin_add_type (GstPlugin *plugin, GstTypeFactory *factory);
#ifndef GST_DISABLE_AUTOPLUG
void gst_plugin_add_autoplugger (GstPlugin *plugin, GstAutoplugFactory *factory);
#else
#pragma GCC poison gst_plugin_add_autoplugger
#endif // GST_DISABLE_AUTOPLUG
void gst_plugin_add_feature (GstPlugin *plugin, GstPluginFeature *feature);
GstPlugin* gst_plugin_find (const gchar *name);
GList* gst_plugin_get_list (void);
GstElementFactory* gst_plugin_load_elementfactory (const gchar *name);
void gst_plugin_load_typefactory (const gchar *mime);
#ifndef GST_DISABLE_AUTOPLUG
GstAutoplugFactory* gst_plugin_load_autoplugfactory (const gchar *name);
#else
#pragma GCC poison gst_plugin_add_autoplugger
#endif // GST_DISABLE_AUTOPLUG
#ifndef GST_DISABLE_REGISTRY
xmlNodePtr gst_plugin_save_thyself (xmlNodePtr parent);
void gst_plugin_load_thyself (xmlNodePtr parent);
#else
#pragma GCC poison gst_plugin_save_thyself
#pragma GCC poison gst_plugin_load_thyself
#endif
#endif /* __GST_PLUGIN_H__ */

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

View file

@ -30,26 +30,101 @@
#include "gst_private.h"
#include "gsttype.h"
#include "gstplugin.h"
/* global list of registered types */
GList *_gst_types;
guint16 _gst_maxtype;
static GList *_gst_types;
static guint16 _gst_maxtype;
struct _GstTypeFindInfo {
GstTypeFindFunc typefindfunc; /* typefind function */
static GList *_gst_typefactories;
GstPlugin *plugin; /* the plugin with this typefind function */
};
static void gst_typefactory_class_init (GstTypeFactoryClass *klass);
static void gst_typefactory_init (GstTypeFactory *factory);
static GstCaps* gst_type_typefind_dummy (GstBuffer *buffer, gpointer priv);
void
_gst_type_initialize (void)
static xmlNodePtr gst_typefactory_save_thyself (GstObject *object, xmlNodePtr parent);
static void gst_typefactory_restore_thyself (GstObject *object, xmlNodePtr parent);
static void gst_typefactory_unload_thyself (GstPluginFeature *feature);
static GstPluginFeatureClass *parent_class = NULL;
//static guint gst_typefactory_signals[LAST_SIGNAL] = { 0 };
GType
gst_typefactory_get_type (void)
{
static GType typefactory_type = 0;
if (!typefactory_type) {
static const GTypeInfo typefactory_info = {
sizeof (GstTypeFactoryClass),
NULL,
NULL,
(GClassInitFunc) gst_typefactory_class_init,
NULL,
NULL,
sizeof(GstTypeFactory),
0,
(GInstanceInitFunc) gst_typefactory_init,
};
typefactory_type = g_type_register_static (GST_TYPE_PLUGIN_FEATURE,
"GstTypeFactory", &typefactory_info, 0);
}
return typefactory_type;
}
static void
gst_typefactory_class_init (GstTypeFactoryClass *klass)
{
GObjectClass *gobject_class;
GstObjectClass *gstobject_class;
GstPluginFeatureClass *gstpluginfeature_class;
gobject_class = (GObjectClass*)klass;
gstobject_class = (GstObjectClass*)klass;
gstpluginfeature_class = (GstPluginFeatureClass*) klass;
parent_class = g_type_class_ref (GST_TYPE_PLUGIN_FEATURE);
gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_typefactory_save_thyself);
gstobject_class->restore_thyself = GST_DEBUG_FUNCPTR (gst_typefactory_restore_thyself);
gstpluginfeature_class->unload_thyself = GST_DEBUG_FUNCPTR (gst_typefactory_unload_thyself);
_gst_types = NULL;
_gst_maxtype = 1; /* type 0 is undefined */
_gst_typefactories = NULL;
}
static void
gst_typefactory_init (GstTypeFactory *factory)
{
_gst_typefactories = g_list_prepend (_gst_typefactories, factory);
}
GstTypeFactory*
gst_typefactory_new (GstTypeDefinition *definition)
{
GstTypeFactory *factory;
g_return_val_if_fail (definition != NULL, NULL);
g_return_val_if_fail (definition->name != NULL, NULL);
g_return_val_if_fail (definition->mime != NULL, NULL);
factory = gst_typefactory_find (definition->name);
if (!factory) {
factory = GST_TYPEFACTORY (g_object_new (GST_TYPE_TYPEFACTORY, NULL));
}
gst_object_set_name (GST_OBJECT (factory), definition->name);
factory->mime = g_strdup (definition->mime);
factory->exts = g_strdup (definition->exts);
factory->typefindfunc = definition->typefindfunc;
return factory;
}
/**
@ -77,10 +152,10 @@ gst_type_register (GstTypeFactory *factory)
type->id = _gst_maxtype++;
type->mime = factory->mime;
type->exts = factory->exts;
type->factories = NULL;
_gst_types = g_list_prepend (_gst_types, type);
id = type->id;
GST_DEBUG (GST_CAT_TYPES,"gsttype: new mime type '%s', id %d\n", type->mime, type->id);
} else {
type = gst_type_find_by_id (id);
@ -90,15 +165,15 @@ gst_type_register (GstTypeFactory *factory)
/* if there is no existing typefind function, try to use new one */
}
if (factory->typefindfunc) {
type->typefindfuncs = g_slist_prepend (type->typefindfuncs, factory->typefindfunc);
}
GST_DEBUG (GST_CAT_TYPES,"gsttype: %s(%p) gave new mime type '%s', id %d\n",
GST_OBJECT_NAME (factory), factory, type->mime, type->id);
type->factories = g_slist_prepend (type->factories, factory);
return id;
}
static
guint16 gst_type_find_by_mime_func (const gchar *mime)
static guint16
gst_type_find_by_mime_func (const gchar *mime)
{
GList *walk;
GstType *type;
@ -202,18 +277,56 @@ gst_type_get_list (void)
return _gst_types;
}
/**
* gst_typefactory_save_thyself:
* @factory: the type factory to save
* @parent: the parent node to save into
* gst_typefactory_find:
* @name: the name of the typefactory to find
*
* Save a typefactory into an XML representation.
* Return the TypeFactory with the given name.
*
* Returns: the new xmlNodePtr
* Returns: a GstTypeFactory with the given name;
*/
xmlNodePtr
gst_typefactory_save_thyself (GstTypeFactory *factory, xmlNodePtr parent)
GstTypeFactory*
gst_typefactory_find (const gchar *name)
{
GList *walk = _gst_typefactories;
GstTypeFactory *factory;
while (walk) {
factory = GST_TYPEFACTORY (walk->data);
if (!strcmp (GST_OBJECT_NAME (factory), name))
return factory;
walk = g_list_next (walk);
}
return NULL;
}
static void
gst_typefactory_unload_thyself (GstPluginFeature *feature)
{
GstTypeFactory *factory;
g_return_if_fail (GST_IS_TYPEFACTORY (feature));
factory = GST_TYPEFACTORY (feature);
if (factory->typefindfunc)
factory->typefindfunc = gst_type_typefind_dummy;
}
static xmlNodePtr
gst_typefactory_save_thyself (GstObject *object, xmlNodePtr parent)
{
GstTypeFactory *factory;
g_return_val_if_fail (GST_IS_TYPEFACTORY (object), parent);
factory = GST_TYPEFACTORY (object);
if (GST_OBJECT_CLASS (parent_class)->save_thyself) {
GST_OBJECT_CLASS (parent_class)->save_thyself (object, parent);
}
xmlNewChild (parent, NULL, "mime", factory->mime);
if (factory->exts) {
xmlNewChild (parent, NULL, "extensions", factory->exts);
@ -225,52 +338,43 @@ gst_typefactory_save_thyself (GstTypeFactory *factory, xmlNodePtr parent)
return parent;
}
static GstCaps *
static GstCaps*
gst_type_typefind_dummy (GstBuffer *buffer, gpointer priv)
{
GstType *type = (GstType *)priv;
guint16 typeid;
GSList *funcs;
GstTypeFactory *factory = (GstTypeFactory *)priv;
GST_DEBUG (GST_CAT_TYPES,"gsttype: need to load typefind function for %s\n", type->mime);
GST_DEBUG (GST_CAT_TYPES,"gsttype: need to load typefind function for %s\n", factory->mime);
type->typefindfuncs = NULL;
gst_plugin_load_typefactory (type->mime);
typeid = gst_type_find_by_mime (type->mime);
type = gst_type_find_by_id (typeid);
gst_plugin_feature_ensure_loaded (GST_PLUGIN_FEATURE (factory));
funcs = type->typefindfuncs;
while (funcs) {
GstTypeFindFunc func = (GstTypeFindFunc) funcs->data;
if (func) {
GstCaps *res = func (buffer, type);
if (res) return res;
}
funcs = g_slist_next (funcs);
if (factory->typefindfunc) {
GstCaps *res = factory->typefindfunc (buffer, factory);
if (res)
return res;
}
return FALSE;
return NULL;
}
/**
* gst_typefactory_load_thyself:
* gst_typefactory_restore_thyself:
* @parent: the parent node to load from
*
* Load a typefactory from an XML representation.
*
* Returns: the new typefactory
*/
GstTypeFactory*
gst_typefactory_load_thyself (xmlNodePtr parent)
static void
gst_typefactory_restore_thyself (GstObject *object, xmlNodePtr parent)
{
GstTypeFactory *factory = g_new0 (GstTypeFactory, 1);
GstTypeFactory *factory = GST_TYPEFACTORY (object);
xmlNodePtr field = parent->xmlChildrenNode;
factory->typefindfunc = NULL;
if (GST_OBJECT_CLASS (parent_class)->restore_thyself) {
GST_OBJECT_CLASS (parent_class)->restore_thyself (object, parent);
}
while (field) {
if (!strcmp (field->name, "mime")) {
factory->mime = xmlNodeGetContent (field);
@ -284,6 +388,6 @@ gst_typefactory_load_thyself (xmlNodePtr parent)
field = field->next;
}
return factory;
gst_type_register (factory);
}

View file

@ -26,13 +26,16 @@
#include <gst/gstbuffer.h>
#include <gst/gstcaps.h>
#include <gst/gstpluginfeature.h>
/* type of function used to check a stream for equality with type */
typedef GstCaps *(*GstTypeFindFunc) (GstBuffer *buf,gpointer priv);
typedef GstCaps *(*GstTypeFindFunc) (GstBuffer *buf, gpointer priv);
typedef struct _GstType GstType;
typedef struct _GstTypeDefinition GstTypeDefinition;
typedef struct _GstTypeFactory GstTypeFactory;
typedef struct _GstTypeFactoryClass GstTypeFactoryClass;
struct _GstType {
guint16 id; /* type id (assigned) */
@ -40,34 +43,58 @@ struct _GstType {
gchar *mime; /* MIME type */
gchar *exts; /* space-delimited list of extensions */
GSList *typefindfuncs; /* typefind functions */
GSList *factories; /* factories providing this type */
};
struct _GstTypeFactory {
struct _GstTypeDefinition {
gchar *name;
gchar *mime;
gchar *exts;
GstTypeFindFunc typefindfunc;
};
#define GST_TYPE_TYPEFACTORY \
(gst_typefactory_get_type())
#define GST_TYPEFACTORY(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_TYPEFACTORY,GstTypeFactory))
#define GST_TYPEFACTORY_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_TYPEFACTORY,GstTypeFactoryClass))
#define GST_IS_TYPEFACTORY(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_TYPEFACTORY))
#define GST_IS_TYPEFACTORY_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_TYPEFACTORY))
/* initialize the subsystem */
void _gst_type_initialize (void);
struct _GstTypeFactory {
GstPluginFeature feature;
gchar *mime;
gchar *exts;
GstTypeFindFunc typefindfunc;
};
struct _GstTypeFactoryClass {
GstPluginFeatureClass parent;
};
GType gst_typefactory_get_type (void);
GstTypeFactory* gst_typefactory_new (GstTypeDefinition *definition);
GstTypeFactory* gst_typefactory_find (const gchar *name);
/* create a new type, or find/merge an existing one */
guint16 gst_type_register (GstTypeFactory *factory);
guint16 gst_type_register (GstTypeFactory *factory);
/* look up a type by mime or extension */
guint16 gst_type_find_by_mime (const gchar *mime);
guint16 gst_type_find_by_ext (const gchar *ext);
guint16 gst_type_find_by_mime (const gchar *mime);
guint16 gst_type_find_by_ext (const gchar *ext);
/* get GstType by id */
GstType* gst_type_find_by_id (guint16 id);
GstType* gst_type_find_by_id (guint16 id);
/* get the list of registered types (returns list of GstType!) */
GList* gst_type_get_list (void);
xmlNodePtr gst_typefactory_save_thyself (GstTypeFactory *factory, xmlNodePtr parent);
GstTypeFactory* gst_typefactory_load_thyself (xmlNodePtr parent);
GList* gst_type_get_list (void);
#endif /* __GST_TYPE_H__ */

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

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. */
static void gst_example_class_init (GstExampleClass *klass);
static void gst_example_init (GstExample *example);
static void gst_example_class_init (GstExampleClass *klass);
static void gst_example_init (GstExample *example);
static void gst_example_chain (GstPad *pad, GstBuffer *buf);
static void gst_example_chain (GstPad *pad, GstBuffer *buf);
static void gst_example_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
static void gst_example_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
/* These hold the constructed pad templates, which are created during
* plugin load, and used during element instantiation.
*/
static GstPadTemplate *src_template, *sink_template;
static void gst_example_set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec);
static void gst_example_get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec);
/* The parent class pointer needs to be kept around for some object
* operations.
@ -189,10 +186,10 @@ static void
gst_example_init(GstExample *example)
{
/* First we create the sink pad, which is the input to the element.
* We will use the sink_template constructed in the plugin_init function
* (below) to quickly generate the pad we need.
* We will use the template constructed by the factory.
*/
example->sinkpad = gst_pad_new_from_template (sink_template, "sink");
example->sinkpad = gst_pad_new_from_template (
GST_PADTEMPLATE_GET (sink_factory), "sink");
/* Setting the chain function allows us to supply the function that will
* actually be performing the work. Without this, the element would do
* nothing, with undefined results (assertion failures and such).
@ -208,7 +205,8 @@ gst_example_init(GstExample *example)
* pads don't have chain functions, because they can't accept buffers,
* they only produce them.
*/
example->srcpad = gst_pad_new_from_template (src_template, "src");
example->srcpad = gst_pad_new_from_template (
GST_PADTEMPLATE_GET (src_factory), "src");
gst_element_add_pad(GST_ELEMENT(example),example->srcpad);
/* Initialization of element's private variables. */
@ -344,17 +342,12 @@ plugin_init (GModule *module, GstPlugin *plugin)
/* The pad templates can be easily generated from the factories above,
* and then added to the list of padtemplates for the elementfactory.
* Note that the generated padtemplates are stored in static global
* variables, for the gst_example_init function to use later on.
*/
sink_template = sink_factory ();
gst_elementfactory_add_padtemplate (factory, sink_template);
src_template = src_factory ();
gst_elementfactory_add_padtemplate (factory, src_template);
gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (sink_factory));
gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (src_factory));
/* The very last thing is to register the elementfactory with the plugin. */
gst_plugin_add_factory (plugin, factory);
gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
/* Now we can return successfully. */
return TRUE;

View file

@ -1,4 +1,4 @@
SUBDIRS = refcounting capsnego
SUBDIRS = refcounting capsnego plugin
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) {
GstPlugin *plugin = (GstPlugin *)plugins->data;
g_print ("plugin: %s, loaded %d\n", plugin->name, plugin->loaded);
g_print ("plugin: %s, loaded %d\n", plugin->name, gst_plugin_is_loaded (plugin));
plugins = g_list_next (plugins);
}
@ -24,7 +24,7 @@ dump_factories (void)
while (factories) {
GstElementFactory *factory = (GstElementFactory *)factories->data;
g_print ("factory: %s %d\n", factory->name, factory->type);
g_print ("factory: %s %d\n", gst_object_get_name (GST_OBJECT (factory)), factory->type);
factories = g_list_next (factories);
}

View file

@ -1,4 +1,4 @@
SUBDIRS = refcounting capsnego
SUBDIRS = refcounting capsnego plugin
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 \
gstreamer-complete.1 gstreamer-compprep.1

View file

@ -4,9 +4,7 @@
int main(int argc,char *argv[]) {
xmlDocPtr doc;
xmlNodePtr factorynode, padnode, argnode, optionnode;
GList *plugins, *factories, *padtemplates, *pads;
GstPlugin *plugin;
GstElementFactory *factory;
GList *plugins, *features, *padtemplates, *pads;
GstElement *element;
GstPad *pad;
GstPadTemplate *padtemplate;
@ -22,20 +20,31 @@ int main(int argc,char *argv[]) {
plugins = gst_plugin_get_list();
while (plugins) {
GstPlugin *plugin;
plugin = (GstPlugin *)(plugins->data);
plugins = g_list_next (plugins);
factories = gst_plugin_get_factory_list(plugin);
while (factories) {
factory = (GstElementFactory *)(factories->data);
factories = g_list_next (factories);
features = gst_plugin_get_feature_list(plugin);
while (features) {
GstPluginFeature *feature;
GstElementFactory *factory;
feature = GST_PLUGIN_FEATURE (features->data);
features = g_list_next (features);
if (!GST_IS_ELEMENTFACTORY (feature))
continue;
factory = GST_ELEMENTFACTORY (feature);
factorynode = xmlNewChild (doc->xmlRootNode, NULL, "element", NULL);
xmlNewChild (factorynode, NULL, "name", factory->name);
xmlNewChild (factorynode, NULL, "name", gst_object_get_name (GST_OBJECT (factory)));
element = gst_elementfactory_create(factory,"element");
if (element == NULL) {
fprintf(stderr,"couldn't construct element from factory %s\n",factory->name);
fprintf(stderr,"couldn't construct element from factory %s\n",
gst_object_get_name (GST_OBJECT (factory)));
return 1;
}

View file

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