More Caps changes, this change introduces the padfactory. the GstPadFactory will be used to describe the pads that an...

Original commit message from CVS:
More Caps changes, this change introduces the padfactory. the GstPadFactory
will be used to describe the pads that an element will contain during
its lifetime.
mpg123 and mp3parse serve as an example.
More XML changes to incorporate the padfactories.
This commit is contained in:
Wim Taymans 2000-12-12 19:29:43 +00:00
parent 5f7a20ff6f
commit d78215be9d
11 changed files with 309 additions and 154 deletions

View file

@ -54,7 +54,7 @@ get_type_for_mime (gchar *mime)
* Returns: The registered capability
*/
GstCaps *
gst_caps_register (GstCapsFactory factory)
gst_caps_register (GstCapsFactory *factory)
{
GstCapsFactoryEntry tag;
gint i = 0;
@ -63,7 +63,7 @@ gst_caps_register (GstCapsFactory factory)
g_return_val_if_fail (factory != NULL, NULL);
tag = factory[i++];
tag = (*factory)[i++];
g_return_val_if_fail (tag != NULL, NULL);
@ -73,7 +73,7 @@ gst_caps_register (GstCapsFactory factory)
g_return_val_if_fail (caps != NULL, NULL);
caps->id = typeid;
caps->properties = gst_props_register (&factory[i]);
caps->properties = gst_props_register (&(*factory)[i]);
return caps;
}

View file

@ -43,7 +43,7 @@ struct _GstCaps {
/* initialize the subsystem */
void _gst_caps_initialize (void);
GstCaps* gst_caps_register (GstCapsFactory factory);
GstCaps* gst_caps_register (GstCapsFactory *factory);
gboolean gst_caps_check_compatibility (GstCaps *caps1, GstCaps *caps2);

View file

@ -153,8 +153,7 @@ struct _GstElementFactory {
GstElementDetails *details; /* pointer to details struct */
GList *src_caps;
GList *sink_caps;
GList *padfactories;
};
GtkType gst_element_get_type (void);
@ -197,12 +196,8 @@ GstElementFactory* gst_elementfactory_new (gchar *name,GtkType type,
void gst_elementfactory_register (GstElementFactory *elementfactory);
void gst_elementfactory_unregister (GstElementFactory *elementfactory);
void gst_elementfactory_add_src_caps (GstElementFactory *elementfactory,
GstCapsDefinition def,
GstCaps *caps);
void gst_elementfactory_add_sink_caps(GstElementFactory *elementfactory,
GstCapsDefinition def,
GstCaps *caps);
void gst_elementfactory_add_pad (GstElementFactory *elementfactory,
GstPadFactory *pad);
GstElementFactory* gst_elementfactory_find (gchar *name);
GList* gst_elementfactory_get_list (void);

View file

@ -28,7 +28,9 @@
/* global list of registered elementfactories */
GList* _gst_elementfactories;
void _gst_elementfactory_initialize() {
void
_gst_elementfactory_initialize (void)
{
_gst_elementfactories = NULL;
}
@ -39,10 +41,12 @@ void _gst_elementfactory_initialize() {
* Adds the elementfactory to the global list, so it can be retrieved by
* name.
*/
void gst_elementfactory_register(GstElementFactory *elementfactory) {
void
gst_elementfactory_register (GstElementFactory *elementfactory)
{
g_return_if_fail(elementfactory != NULL);
_gst_elementfactories = g_list_prepend(_gst_elementfactories,elementfactory);
_gst_elementfactories = g_list_prepend (_gst_elementfactories, elementfactory);
}
/**
@ -52,24 +56,34 @@ void gst_elementfactory_register(GstElementFactory *elementfactory) {
* Removes the elementfactory from the global list.
*/
void
gst_elementfactory_unregister(GstElementFactory *factory)
gst_elementfactory_unregister (GstElementFactory *factory)
{
GList *caps;
GList *padfactories;
g_return_if_fail (factory != NULL);
caps = factory->sink_caps;
while (caps) {
_gst_type_remove_sink (((GstCaps *)caps->data)->id, factory);
caps = g_list_next (caps);
padfactories = factory->padfactories;
while (padfactories) {
GstPadFactory *padfactory = (GstPadFactory *)padfactories->data;
GstCaps *caps = gst_padfactory_get_caps (padfactory);
if (caps) {
switch (padfactory->direction) {
case GST_PAD_SRC:
_gst_type_remove_src (caps->id, factory);
break;
case GST_PAD_SINK:
_gst_type_remove_sink (caps->id, factory);
break;
default:
break;
}
}
padfactories = g_list_next (padfactories);
}
caps = factory->src_caps;
while (caps) {
_gst_type_remove_src (((GstCaps *)caps->data)->id, factory);
caps = g_list_next (caps);
}
_gst_elementfactories = g_list_remove(_gst_elementfactories, factory);
_gst_elementfactories = g_list_remove (_gst_elementfactories, factory);
g_free (factory);
}
@ -82,7 +96,9 @@ gst_elementfactory_unregister(GstElementFactory *factory)
*
* Returns: #GstElementFactory if found, NULL otherwise
*/
GstElementFactory *gst_elementfactory_find(gchar *name) {
GstElementFactory*
gst_elementfactory_find (gchar *name)
{
GList *walk;
GstElementFactory *factory;
@ -106,7 +122,9 @@ GstElementFactory *gst_elementfactory_find(gchar *name) {
*
* Returns: GList of type #GstElementFactory
*/
GList *gst_elementfactory_get_list() {
GList*
gst_elementfactory_get_list (void)
{
return _gst_elementfactories;
}
@ -122,14 +140,16 @@ GList *gst_elementfactory_get_list() {
*
* Returns: new elementfactory
*/
GstElementFactory *gst_elementfactory_new(gchar *name,GtkType type,
GstElementDetails *details) {
GstElementFactory*
gst_elementfactory_new (gchar *name, GtkType type,
GstElementDetails *details)
{
GstElementFactory *factory = g_new0(GstElementFactory, 1);
factory->name = g_strdup(name);
factory->type = type;
factory->details = details;
factory->src_caps = NULL;
factory->sink_caps = NULL;
factory->padfactories = NULL;
return factory;
}
@ -144,8 +164,10 @@ GstElementFactory *gst_elementfactory_new(gchar *name,GtkType type,
*
* Returns: new #GstElement
*/
GstElement *gst_elementfactory_create(GstElementFactory *factory,
gchar *name) {
GstElement *
gst_elementfactory_create (GstElementFactory *factory,
gchar *name)
{
GstElement *element;
GstElementClass *oclass;
@ -186,7 +208,9 @@ GstElement *gst_elementfactory_create(GstElementFactory *factory,
*
* Returns: new #GstElement
*/
GstElement *gst_elementfactory_make(gchar *factoryname,gchar *name) {
GstElement*
gst_elementfactory_make (gchar *factoryname, gchar *name)
{
GstElementFactory *factory;
GstElement *element;
@ -200,44 +224,38 @@ GstElement *gst_elementfactory_make(gchar *factoryname,gchar *name) {
}
/**
* gst_elementfactory_add_src_caps :
* gst_elementfactory_add_pad :
* @elementfactory: factory to add the src id to
* @id: the mime id of the src
* @pad: the padfactory to add
*
* Use this function to indicate that this factory can src
* the given type id.
* Add the given padfactory to this element.
*
*/
void
gst_elementfactory_add_src_caps (GstElementFactory *factory,
GstCapsDefinition def,
GstCaps *caps)
gst_elementfactory_add_pad (GstElementFactory *factory,
GstPadFactory *padfactory)
{
GstCaps *caps;
g_return_if_fail(factory != NULL);
g_return_if_fail(padfactory != NULL);
factory->padfactories = g_list_append (factory->padfactories, padfactory);
caps = gst_padfactory_get_caps (padfactory);
if (caps) {
factory->src_caps = g_list_append (factory->src_caps, caps);
_gst_type_add_src (caps->id, factory);
}
}
/**
* gst_elementfactory_add_sink_caps :
* @elementfactory: factory to add the sink id to
* @id: the type id of the sink
*
* Use this function to indicate that this factory can sink
* the given type id.
*/
void
gst_elementfactory_add_sink_caps (GstElementFactory *factory,
GstCapsDefinition def,
GstCaps *caps)
{
g_return_if_fail(factory != NULL);
if (caps) {
factory->sink_caps = g_list_append (factory->sink_caps, caps);
_gst_type_add_sink (caps->id, factory);
switch (padfactory->direction) {
case GST_PAD_SRC:
_gst_type_add_src (caps->id, factory);
break;
case GST_PAD_SINK:
_gst_type_add_sink (caps->id, factory);
break;
default:
g_print ("gstelementfactory: uh? no pad direction\n");
break;
}
}
}
@ -250,9 +268,11 @@ gst_elementfactory_add_sink_caps (GstElementFactory *factory,
*
* Returns: the new xmlNodePtr
*/
xmlNodePtr gst_elementfactory_save_thyself(GstElementFactory *factory, xmlNodePtr parent) {
GList *caps;
xmlNodePtr subtree, subsubtree;
xmlNodePtr
gst_elementfactory_save_thyself (GstElementFactory *factory,
xmlNodePtr parent)
{
GList *pads;
xmlNewChild(parent,NULL,"name",factory->name);
xmlNewChild(parent,NULL,"longname", factory->details->longname);
@ -262,31 +282,18 @@ xmlNodePtr gst_elementfactory_save_thyself(GstElementFactory *factory, xmlNodePt
xmlNewChild(parent,NULL,"author", factory->details->author);
xmlNewChild(parent,NULL,"copyright", factory->details->copyright);
caps = factory->src_caps;
if (caps) {
subtree = xmlNewChild(parent,NULL,"sources",NULL);
while (caps) {
GstCaps *cap = (GstCaps *)caps->data;
pads = factory->padfactories;
if (pads) {
while (pads) {
xmlNodePtr subtree;
GstPadFactory *padfactory = (GstPadFactory *)pads->data;
subsubtree = xmlNewChild(subtree,NULL,"capabilities",NULL);
gst_caps_save_thyself(cap, subsubtree);
subtree = xmlNewChild(parent, NULL, "padfactory", NULL);
gst_padfactory_save_thyself(padfactory, subtree);
caps = g_list_next(caps);
pads = g_list_next (pads);
}
}
caps = factory->sink_caps;
if (caps) {
subtree = xmlNewChild(parent,NULL,"sinks",NULL);
while (caps) {
GstCaps *cap = (GstCaps *)caps->data;
subsubtree = xmlNewChild(subtree,NULL,"capabilities",NULL);
gst_caps_save_thyself(cap, subsubtree);
caps = g_list_next(caps);
}
}
return parent;
}
@ -304,8 +311,7 @@ gst_elementfactory_load_thyself (xmlNodePtr parent)
GstElementFactory *factory = g_new0(GstElementFactory, 1);
xmlNodePtr children = parent->childs;
factory->details = g_new0(GstElementDetails, 1);
factory->sink_caps = NULL;
factory->src_caps = NULL;
factory->padfactories = NULL;
while (children) {
if (!strcmp(children->name, "name")) {
@ -329,25 +335,12 @@ gst_elementfactory_load_thyself (xmlNodePtr parent)
if (!strcmp(children->name, "copyright")) {
factory->details->copyright = g_strdup(xmlNodeGetContent(children));
}
if (!strcmp(children->name, "sources")) {
xmlNodePtr field = children->childs;
while (field) {
if (!strcmp(field->name, "capabilities")) {
GstCaps *caps = gst_caps_load_thyself (field);
gst_elementfactory_add_src_caps (factory, 0, caps);
}
field = field->next;
}
}
if (!strcmp(children->name, "sinks")) {
xmlNodePtr field = children->childs;
while (field) {
if (!strcmp(field->name, "capabilities")) {
GstCaps *caps = gst_caps_load_thyself (field);
gst_elementfactory_add_sink_caps (factory, 0, caps);
}
field = field->next;
}
if (!strcmp(children->name, "padfactory")) {
GstPadFactory *padfactory;
padfactory = gst_padfactory_load_thyself (children);
gst_elementfactory_add_pad (factory, padfactory);
}
children = children->next;

View file

@ -387,7 +387,7 @@ gst_pad_pull (GstPad *pad)
(pad->pullfunc)(pad->peer);
} else {
DEBUG("no buffer in pen, and no handler (# %p) to get one there!!!\n",&pad->pullfunc);
g_return_if_fail(pad->pullfunc != NULL);
g_return_val_if_fail(pad->pullfunc != NULL, NULL);
}
}
@ -399,7 +399,7 @@ gst_pad_pull (GstPad *pad)
// else we have a big problem...
} else {
DEBUG("no buffer in pen, and no handler\n");
g_return_if_fail(pad->pullfunc != NULL);
g_return_val_if_fail(pad->pullfunc != NULL, NULL);
return NULL;
}
@ -693,7 +693,6 @@ gst_pad_set_caps (GstPad *pad,
{
g_return_if_fail (pad != NULL);
g_return_if_fail (GST_IS_PAD (pad));
g_return_if_fail (caps != NULL);
pad->caps = caps;
}
@ -848,3 +847,104 @@ gst_pad_ghost_save_thyself (GstPad *pad,
return self;
}
/**
* gst_padfactory_create:
* @factory: the pad factory
* @name: the name of the new pad
*
* crrates a new pad form the given factory
*
* Returns: the new pad;
*/
GstPad*
gst_padfactory_create (GstPadFactory *factory,
gchar *name)
{
GstPad *newpad;
GstCaps *caps;
newpad = gst_pad_new (name, factory->direction);
caps = gst_padfactory_get_caps (factory);
gst_pad_set_caps (newpad, caps);
return newpad;
}
GstCaps*
gst_padfactory_get_caps (GstPadFactory *factory)
{
if (factory->priv) {
return (GstCaps *) factory->priv;
}
else if (factory->caps) {
GstCaps *caps;
caps = gst_caps_register (factory->caps);
factory->priv = caps;
return caps;
}
else return NULL;
}
xmlNodePtr
gst_padfactory_save_thyself (GstPadFactory *pad, xmlNodePtr parent)
{
xmlNodePtr subtree;
xmlNewChild(parent,NULL,"nametemplate", pad->nametemplate);
xmlNewChild(parent,NULL,"direction", (pad->direction == GST_PAD_SINK? "sink":"src"));
xmlNewChild(parent,NULL,"presence", (pad->presence == GST_PAD_ALWAYS? "always":"sometimes"));
subtree = xmlNewChild(parent,NULL,"caps", NULL);
gst_caps_save_thyself (gst_padfactory_get_caps (pad), subtree);
return parent;
}
GstPadFactory*
gst_padfactory_load_thyself (xmlNodePtr parent)
{
xmlNodePtr field = parent->childs;
GstPadFactory *factory = g_new0 (GstPadFactory, 1);
while (field) {
if (!strcmp(field->name, "nametemplate")) {
factory->nametemplate = g_strdup(xmlNodeGetContent(field));
}
if (!strcmp(field->name, "direction")) {
gchar *value = xmlNodeGetContent(field);
factory->direction = GST_PAD_UNKNOWN;
if (!strcmp(value, "sink")) {
factory->direction = GST_PAD_SINK;
}
else if (!strcmp(value, "src")) {
factory->direction = GST_PAD_SRC;
}
}
if (!strcmp(field->name, "presence")) {
gchar *value = xmlNodeGetContent(field);
if (!strcmp(value, "always")) {
factory->presence = GST_PAD_ALWAYS;
}
else if (!strcmp(value, "sometimes")) {
factory->presence = GST_PAD_SOMETIMES;
}
}
else if (!strcmp(field->name, "caps")) {
factory->priv = gst_caps_load_thyself (field);
}
field = field->next;
}
return factory;
}

View file

@ -98,8 +98,25 @@ struct _GstPadClass {
void (*caps_changed) (GstPad *pad, GstCaps *newcaps);
};
typedef enum {
GST_PAD_ALWAYS,
GST_PAD_SOMETIMES,
} GstPadPresence;
typedef struct _GstPadFactory GstPadFactory;
/* factory */
struct _GstPadFactory {
gchar *nametemplate;
GstCapsFactory *caps;
GstPadDirection direction;
GstPadPresence presence;
gpointer priv;
};
GtkType gst_pad_get_type (void);
GstPad* gst_pad_new (gchar *name, GstPadDirection direction);
#define gst_pad_destroy(pad) gst_object_destroy (GST_OBJECT (pad))
@ -136,6 +153,14 @@ xmlNodePtr gst_pad_save_thyself (GstPad *pad, xmlNodePtr parent);
void gst_pad_load_and_connect (xmlNodePtr parent, GstObject *element, GHashTable *elements);
/* factory */
GstPad* gst_padfactory_create (GstPadFactory *factory, gchar *name);
GstCaps* gst_padfactory_get_caps (GstPadFactory *factory);
xmlNodePtr gst_padfactory_save_thyself (GstPadFactory *pad, xmlNodePtr parent);
GstPadFactory* gst_padfactory_load_thyself (xmlNodePtr parent);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View file

@ -322,9 +322,11 @@ gst_pipeline_autoplug (GstPipeline *pipeline)
return FALSE;
}
// FIXME check the factory???
factory = gst_element_get_factory(pipeline->src);
src_types = factory->src_caps;
//src_types = factory->pads;
src_types = NULL; // FIXME
if (src_types == NULL) {
g_print("GstPipeline: source \"%s\" has no MIME type, running typefind...\n",
gst_element_get_name(pipeline->src));

View file

@ -130,6 +130,8 @@ guint16 gst_type_find_by_mime_func (gchar *mime)
gint typelen,mimelen;
gchar *search, *found;
g_return_val_if_fail (mime != NULL, 0);
walk = _gst_types;
// DEBUG("searching for '%s'\n",mime);
mimelen = strlen (mime);
@ -219,15 +221,16 @@ gst_type_dump_converter (gpointer key,
{
GList *walk = (GList *)value;
GstElementFactory *factory;
guint16 id = GPOINTER_TO_UINT (key);
GstType *type = gst_type_find_by_id (id);
g_print ("gsttype: %u, (", GPOINTER_TO_UINT (key));
g_print ("\ngsttype: %u (%s), ", type->id, type->mime);
while (walk) {
factory = (GstElementFactory *) walk->data;
g_print("%s, ", factory->name);
g_print("\"%s\" ", factory->name);
walk = g_list_next (walk);
}
g_print ("NULL)), ");
}
/**
@ -246,9 +249,9 @@ gst_type_dump(void)
while (walk) {
type = (GstType *)walk->data;
g_print ("gst_type: %d (%s) -> (", type->id, type->mime);
g_print ("gsttype: %d (%s)", type->id, type->mime);
g_hash_table_foreach (type->converters, gst_type_dump_converter, NULL);
g_print ("NULL)\n");
g_print ("\n");
walk = g_list_next (walk);
}
@ -263,39 +266,52 @@ gst_type_handle_src (guint16 id, GstElementFactory *src, gboolean remove)
g_return_if_fail (type != NULL);
g_return_if_fail (src != NULL);
g_print ("gsttype: add src %d, \"%s\"\n", id, src->name);
g_print ("gsttype: handle src \"%s\" %d\n", src->name, remove);
if (remove)
type->srcs = g_list_remove (type->srcs, src);
else
type->srcs = g_list_prepend (type->srcs, src);
// find out if the element has to be indexed in the matrix
walk = src->sink_caps;
walk = src->padfactories;
while (walk) {
GstType *type2;
GList *converters;
GList *orig;
GstPadFactory *factory;
type2 = gst_type_find_by_id (((GstCaps *)walk->data)->id);
converters = (GList *)g_hash_table_lookup (type2->converters, GUINT_TO_POINTER ((guint)id));
orig = converters;
factory = (GstPadFactory *) walk->data;
while (converters) {
if (converters->data == src) {
break;
if (factory->direction == GST_PAD_SINK) {
GstType *type2;
GList *converters;
GList *orig;
GstCaps *caps;
caps = gst_padfactory_get_caps (factory);
if (caps)
type2 = gst_type_find_by_id (caps->id);
else
goto next;
converters = (GList *)g_hash_table_lookup (type2->converters, GUINT_TO_POINTER ((guint)id));
orig = converters;
while (converters) {
if (converters->data == src) {
break;
}
converters = g_list_next (converters);
}
converters = g_list_next (converters);
}
if (!converters) {
if (remove)
orig = g_list_remove (orig, src);
else
else if (!converters)
orig = g_list_prepend (orig, src);
g_hash_table_insert (type2->converters, GUINT_TO_POINTER ((guint)id), orig);
}
next:
walk = g_list_next (walk);
}
}
@ -337,33 +353,52 @@ gst_type_handle_sink (guint16 id, GstElementFactory *sink, gboolean remove)
g_return_if_fail (type != NULL);
g_return_if_fail (sink != NULL);
g_print ("gsttype: handle sink \"%s\" %d\n", sink->name, remove);
if (remove)
type->sinks = g_list_remove (type->sinks, sink);
else
type->sinks = g_list_prepend (type->sinks, sink);
// find out if the element has to be indexed in the matrix
walk = sink->src_caps;
walk = sink->padfactories;
while (walk) {
GList *converters = (GList *)g_hash_table_lookup (type->converters, walk->data);
GList *orig = converters;
GstPadFactory *factory;
while (converters) {
if (converters->data == sink) {
break;
factory = (GstPadFactory *) walk->data;
if (factory->direction == GST_PAD_SRC) {
guint16 id2;
GList *converters;
GList *orig;
GstCaps *caps;
caps = gst_padfactory_get_caps (factory);
if (caps)
id2 = caps->id;
else
goto next;
converters = (GList *)g_hash_table_lookup (type->converters, GUINT_TO_POINTER ((guint)id2));
orig = converters;
while (converters) {
if (converters->data == sink) {
break;
}
converters = g_list_next (converters);
}
converters = g_list_next (converters);
}
if (!converters) {
if (remove)
orig = g_list_remove (orig, sink);
else
else if (!converters)
orig = g_list_prepend (orig, sink);
g_hash_table_insert (type->converters, walk->data, orig);
g_hash_table_insert (type->converters, GUINT_TO_POINTER ((guint)id2), orig);
}
next:
walk = g_list_next (walk);
}
}

2
tests/.gitignore vendored
View file

@ -11,3 +11,5 @@ loadall
simplefake
states
caps
queue
registry

View file

@ -78,23 +78,23 @@ int main(int argc,char *argv[])
_gst_type_initialize ();
sinkcaps = gst_caps_register (mpeg2dec_sink_caps);
sinkcaps = gst_caps_register (&mpeg2dec_sink_caps);
parent = xmlNewChild (doc->root, NULL, "Capabilities1", NULL);
gst_caps_save_thyself (sinkcaps, parent);
rawcaps = gst_caps_register (mpeg2dec_src_caps);
rawcaps = gst_caps_register (&mpeg2dec_src_caps);
parent = xmlNewChild (doc->root, NULL, "Capabilities2", NULL);
gst_caps_save_thyself (rawcaps, parent);
rawcaps2 = gst_caps_register (raw_sink_caps);
rawcaps2 = gst_caps_register (&raw_sink_caps);
parent = xmlNewChild (doc->root, NULL, "Capabilities3", NULL);
gst_caps_save_thyself (rawcaps2, parent);
mp1parsecaps = gst_caps_register (mp1parse_src_caps);
mp1parsecaps = gst_caps_register (&mp1parse_src_caps);
parent = xmlNewChild (doc->root, NULL, "Capabilities4", NULL);
gst_caps_save_thyself (mp1parsecaps, parent);
rawcaps3 = gst_caps_register (raw2_sink_caps);
rawcaps3 = gst_caps_register (&raw2_sink_caps);
parent = xmlNewChild (doc->root, NULL, "Capabilities5", NULL);
gst_caps_save_thyself (rawcaps3, parent);

View file

@ -101,12 +101,14 @@ int main(int argc,char *argv[])
dump_plugins ();
dump_factories ();
dump_types ();
gst_type_dump ();
print_some_providers ("audio/mp3");
load_something ("mpg123");
print_some_providers ("audio/mp3");
gst_type_dump ();
load_something ("mpg123");
@ -114,4 +116,5 @@ int main(int argc,char *argv[])
dump_factories ();
dump_types ();
gst_type_dump ();
}