First attempt at rebuilding the type/plugin system

Original commit message from CVS:
First attempt at rebuilding the type/plugin system
- make sure caps/props are saved in the registry
autoplugging is completely broken.
removed the typefactories and typeids from all the pads in the plugins
XML load/save is ok (be sure to rerun gstreamer-register)
This commit is contained in:
Wim Taymans 2000-12-11 00:04:25 +00:00
parent 6ba0668cd8
commit 6fa6cd8ce4
21 changed files with 478 additions and 382 deletions

View file

@ -83,7 +83,7 @@ noinst_HEADERS = \
gsti386.h \ gsti386.h \
gstppc.h gstppc.h
CFLAGS += -O6 -Wall CFLAGS += -g -O6 -Wall
libgst_la_LIBADD = $(GLIB_LIBS) $(GTK_LIBS) $(XML_LIBS) libgst_la_LIBADD = $(GLIB_LIBS) $(GTK_LIBS) $(XML_LIBS)
libgst_la_LDFLAGS = -version-info $(STREAMER_CURRENT):$(STREAMER_REVISION):$(STREAMER_AGE) libgst_la_LDFLAGS = -version-info $(STREAMER_CURRENT):$(STREAMER_REVISION):$(STREAMER_AGE)

View file

@ -67,6 +67,18 @@ enum {
/* FILL ME */ /* FILL ME */
}; };
static GstCapsFactory audiosink_sink_caps = {
"audio/raw",
"format", GST_PROPS_INT (AFMT_S16_LE),
"depth", GST_PROPS_LIST (
GST_PROPS_INT (8),
GST_PROPS_INT (16)
),
"rate", GST_PROPS_INT_RANGE (8000, 48000),
"channels", GST_PROPS_INT_RANGE (1, 2),
NULL
};
#define GST_TYPE_AUDIOSINK_FORMATS (gst_audiosink_formats_get_type()) #define GST_TYPE_AUDIOSINK_FORMATS (gst_audiosink_formats_get_type())
static GtkType static GtkType
@ -103,7 +115,7 @@ gst_audiosink_channels_get_type(void) {
static GstSinkClass *parent_class = NULL; static GstSinkClass *parent_class = NULL;
static guint gst_audiosink_signals[LAST_SIGNAL] = { 0 }; static guint gst_audiosink_signals[LAST_SIGNAL] = { 0 };
static guint16 gst_audiosink_type_audio = 0; static GstCaps *gst_audiosink_sink_caps = NULL;
GtkType GtkType
gst_audiosink_get_type (void) gst_audiosink_get_type (void)
@ -124,9 +136,6 @@ gst_audiosink_get_type (void)
audiosink_type = gtk_type_unique (GST_TYPE_SINK, &audiosink_info); audiosink_type = gtk_type_unique (GST_TYPE_SINK, &audiosink_info);
} }
if (!gst_audiosink_type_audio)
gst_audiosink_type_audio = gst_type_find_by_mime ("audio/raw");
return audiosink_type; return audiosink_type;
} }
@ -169,7 +178,7 @@ gst_audiosink_init (GstAudioSink *audiosink)
{ {
audiosink->sinkpad = gst_pad_new ("sink", GST_PAD_SINK); audiosink->sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
gst_element_add_pad (GST_ELEMENT (audiosink), audiosink->sinkpad); gst_element_add_pad (GST_ELEMENT (audiosink), audiosink->sinkpad);
gst_pad_set_type_id (audiosink->sinkpad, gst_audiosink_type_audio); gst_pad_set_caps (audiosink->sinkpad, gst_audiosink_sink_caps);
gst_pad_set_chain_function (audiosink->sinkpad, gst_audiosink_chain); gst_pad_set_chain_function (audiosink->sinkpad, gst_audiosink_chain);
@ -401,10 +410,7 @@ gst_audiosink_change_state (GstElement *element)
gboolean gboolean
gst_audiosink_factory_init (GstElementFactory *factory) gst_audiosink_factory_init (GstElementFactory *factory)
{ {
if (!gst_audiosink_type_audio) gst_audiosink_sink_caps = gst_caps_register (audiosink_sink_caps);
gst_audiosink_type_audio = gst_type_find_by_mime ("audio/raw");
gst_type_add_sink (gst_audiosink_type_audio, factory);
return TRUE; return TRUE;
} }

View file

@ -698,7 +698,7 @@ gst_bin_create_plan_outside (GstBin *bin, GstElement *element)
GstPad *pad; GstPad *pad;
gboolean dedicated = TRUE; gboolean dedicated = TRUE;
cothread_state *threadstate; cothread_state *threadstate;
_GstBinOutsideSchedule *sched; _GstBinOutsideSchedule *sched = NULL;
// walk through all the pads, find out of this is hard or not // walk through all the pads, find out of this is hard or not
pads = gst_element_get_pad_list (element); pads = gst_element_get_pad_list (element);
@ -755,6 +755,7 @@ gst_bin_create_plan_outside (GstBin *bin, GstElement *element)
cothread_setfunc (sched->threadstate, gst_bin_sched_wrapper, cothread_setfunc (sched->threadstate, gst_bin_sched_wrapper,
0, (char **)sched); 0, (char **)sched);
} }
return sched;
} }
static void static void

View file

@ -26,6 +26,25 @@ void
_gst_caps_initialize (void) _gst_caps_initialize (void)
{ {
} }
static guint16
get_type_for_mime (gchar *mime)
{
guint16 typeid;
typeid = gst_type_find_by_mime (mime);
if (typeid == 0) {
GstTypeFactory *factory = g_new0 (GstTypeFactory, 1);
factory->mime = g_strdup (mime);
factory->exts = NULL;
factory->typefindfunc = NULL;
typeid = gst_type_register (factory);
}
return typeid;
}
/** /**
* gst_caps_register: * gst_caps_register:
* @factory: the factory to register * @factory: the factory to register
@ -48,16 +67,7 @@ gst_caps_register (GstCapsFactory factory)
g_return_val_if_fail (tag != NULL, NULL); g_return_val_if_fail (tag != NULL, NULL);
typeid = gst_type_find_by_mime ((gchar *)tag); typeid = get_type_for_mime ((gchar *)tag);
if (typeid == 0) {
GstTypeFactory *factory = g_new0 (GstTypeFactory, 1);
factory->mime = g_strdup ((gchar *)tag);
factory->exts = NULL;
factory->typefindfunc = NULL;
typeid = gst_type_register (factory);
}
caps = g_new0 (GstCaps, 1); caps = g_new0 (GstCaps, 1);
g_return_val_if_fail (caps != NULL, NULL); g_return_val_if_fail (caps != NULL, NULL);
@ -69,25 +79,6 @@ gst_caps_register (GstCapsFactory factory)
} }
/**
* gst_caps_dump:
* @caps: the capability to dump
*
* Dumps the contents of the capabilty one the console
*/
void
gst_caps_dump (GstCaps *caps)
{
g_return_if_fail (caps != NULL);
g_print("gstcaps: {\ngstcaps: mime type \"%d\"\n", caps->id);
gst_props_dump (caps->properties);
g_print("gstcaps: }\n");
}
/** /**
* gst_caps_check_compatibility: * gst_caps_check_compatibility:
* @fromcaps: a capabilty * @fromcaps: a capabilty
@ -109,3 +100,42 @@ gst_caps_check_compatibility (GstCaps *fromcaps, GstCaps *tocaps)
return gst_props_check_compatibility (fromcaps->properties, tocaps->properties); return gst_props_check_compatibility (fromcaps->properties, tocaps->properties);
} }
xmlNodePtr
gst_caps_save_thyself (GstCaps *caps, xmlNodePtr parent)
{
xmlNodePtr subtree;
g_return_val_if_fail (caps != NULL, NULL);
xmlNewChild (parent, NULL, "type", gst_type_find_by_id (caps->id)->mime);
if (caps->properties) {
subtree = xmlNewChild (parent, NULL, "properties", NULL);
gst_props_save_thyself (caps->properties, subtree);
}
return parent;
}
GstCaps*
gst_caps_load_thyself (xmlNodePtr parent)
{
GstCaps *caps = g_new0 (GstCaps, 1);
xmlNodePtr field = parent->childs;
while (field) {
if (!strcmp (field->name, "type")) {
caps->id = get_type_for_mime (xmlNodeGetContent (field));
}
else if (!strcmp (field->name, "properties")) {
caps->properties = gst_props_load_thyself (field);
}
field = field->next;
}
return caps;
}

View file

@ -29,6 +29,11 @@ typedef gpointer GstCapsFactoryEntry;
typedef GstCapsFactoryEntry GstCapsFactory[]; typedef GstCapsFactoryEntry GstCapsFactory[];
typedef GstCapsFactory *GstCapsListFactory[]; typedef GstCapsFactory *GstCapsListFactory[];
typedef enum {
GST_CAPS_ALWAYS = 1,
GST_CAPS_MAYBE = 2,
} GstCapsDefinition;
struct _GstCaps { struct _GstCaps {
guint16 id; /* type id (major type) */ guint16 id; /* type id (major type) */
@ -40,8 +45,9 @@ void _gst_caps_initialize (void);
GstCaps* gst_caps_register (GstCapsFactory factory); GstCaps* gst_caps_register (GstCapsFactory factory);
void gst_caps_dump (GstCaps *caps);
gboolean gst_caps_check_compatibility (GstCaps *caps1, GstCaps *caps2); gboolean gst_caps_check_compatibility (GstCaps *caps1, GstCaps *caps2);
xmlNodePtr gst_caps_save_thyself (GstCaps *caps, xmlNodePtr parent);
GstCaps* gst_caps_load_thyself (xmlNodePtr parent);
#endif /* __GST_CAPS_H__ */ #endif /* __GST_CAPS_H__ */

View file

@ -27,6 +27,7 @@
#include <gst/gstobject.h> #include <gst/gstobject.h>
#include <gst/gstpad.h> #include <gst/gstpad.h>
#include <gst/gstbuffer.h> #include <gst/gstbuffer.h>
#include <gst/gstcaps.h>
#include <gst/cothreads.h> #include <gst/cothreads.h>
@ -139,7 +140,7 @@ struct _GstElementClass {
struct _GstElementDetails { struct _GstElementDetails {
gchar *longname; /* long, english name */ gchar *longname; /* long, english name */
gchar *class; /* type of element, kinda */ gchar *klass; /* type of element, kinda */
gchar *description; /* insights of one form or another */ gchar *description; /* insights of one form or another */
gchar *version; /* version of the element */ gchar *version; /* version of the element */
gchar *author; /* who wrote this thing? */ gchar *author; /* who wrote this thing? */
@ -152,8 +153,8 @@ struct _GstElementFactory {
GstElementDetails *details; /* pointer to details struct */ GstElementDetails *details; /* pointer to details struct */
GList *src_types; GList *src_caps;
GList *sink_types; GList *sink_caps;
}; };
GtkType gst_element_get_type (void); GtkType gst_element_get_type (void);
@ -192,10 +193,16 @@ GstElement* gst_element_load_thyself (xmlNodePtr parent, GHashTable *elements);
GstElementFactory* gst_elementfactory_new (gchar *name,GtkType type, GstElementFactory* gst_elementfactory_new (gchar *name,GtkType type,
GstElementDetails *details); GstElementDetails *details);
void gst_elementfactory_register (GstElementFactory *elementfactory);
void gst_elementfactory_add_src (GstElementFactory *elementfactory, guint16 id); void gst_elementfactory_register (GstElementFactory *elementfactory);
void gst_elementfactory_add_sink (GstElementFactory *elementfactory, guint16 id); 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);
GstElementFactory* gst_elementfactory_find (gchar *name); GstElementFactory* gst_elementfactory_find (gchar *name);
GList* gst_elementfactory_get_list (void); GList* gst_elementfactory_get_list (void);

View file

@ -45,6 +45,35 @@ void gst_elementfactory_register(GstElementFactory *elementfactory) {
_gst_elementfactories = g_list_prepend(_gst_elementfactories,elementfactory); _gst_elementfactories = g_list_prepend(_gst_elementfactories,elementfactory);
} }
/**
* gst_elementfactory_unregister:
* @elementfactory: factory to register
*
* Removes the elementfactory from the global list.
*/
void
gst_elementfactory_unregister(GstElementFactory *factory)
{
GList *caps;
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);
}
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);
g_free (factory);
}
/** /**
* gst_elementfactory_find: * gst_elementfactory_find:
* @name: name of factory to find * @name: name of factory to find
@ -59,8 +88,6 @@ GstElementFactory *gst_elementfactory_find(gchar *name) {
DEBUG("gstelementfactory: find \"%s\"\n", name); DEBUG("gstelementfactory: find \"%s\"\n", name);
gst_plugin_load_elementfactory(name);
walk = _gst_elementfactories; walk = _gst_elementfactories;
while (walk) { while (walk) {
factory = (GstElementFactory *)(walk->data); factory = (GstElementFactory *)(walk->data);
@ -101,8 +128,8 @@ GstElementFactory *gst_elementfactory_new(gchar *name,GtkType type,
factory->name = g_strdup(name); factory->name = g_strdup(name);
factory->type = type; factory->type = type;
factory->details = details; factory->details = details;
factory->src_types = NULL; factory->src_caps = NULL;
factory->sink_types = NULL; factory->sink_caps = NULL;
return factory; return factory;
} }
@ -126,9 +153,9 @@ GstElement *gst_elementfactory_create(GstElementFactory *factory,
DEBUG("gstelementfactory: create \"%s\" \"%s\"\n", factory->name, name); DEBUG("gstelementfactory: create \"%s\" \"%s\"\n", factory->name, name);
// it's not loaded, try to load the plugin
if (factory->type == 0) { if (factory->type == 0) {
factory = gst_plugin_load_elementfactory(factory->name); factory = gst_plugin_load_elementfactory(factory->name);
//factory = gst_elementfactory_find(factory->name);
} }
g_return_val_if_fail(factory != NULL, NULL); g_return_val_if_fail(factory != NULL, NULL);
g_return_val_if_fail(factory->type != 0, NULL); g_return_val_if_fail(factory->type != 0, NULL);
@ -173,31 +200,45 @@ GstElement *gst_elementfactory_make(gchar *factoryname,gchar *name) {
} }
/** /**
* gst_elementfactory_add_src: * gst_elementfactory_add_src_caps :
* @elementfactory: factory to add the src id to * @elementfactory: factory to add the src id to
* @id: the mime id of the src * @id: the mime id of the src
* *
* Use this function to indicate that this factory can src * Use this function to indicate that this factory can src
* the given type id. * the given type id.
*/ */
void gst_elementfactory_add_src(GstElementFactory *elementfactory, guint16 id) { void
guint type = id; gst_elementfactory_add_src_caps (GstElementFactory *factory,
GstCapsDefinition def,
GstCaps *caps)
{
g_return_if_fail(factory != NULL);
elementfactory->src_types = g_list_prepend(elementfactory->src_types, GUINT_TO_POINTER(type)); if (caps) {
factory->src_caps = g_list_append (factory->src_caps, caps);
_gst_type_add_src (caps->id, factory);
}
} }
/** /**
* gst_elementfactory_add_sink: * gst_elementfactory_add_sink_caps :
* @elementfactory: factory to add the sink id to * @elementfactory: factory to add the sink id to
* @id: the type id of the sink * @id: the type id of the sink
* *
* Use this function to indicate that this factory can sink * Use this function to indicate that this factory can sink
* the given type id. * the given type id.
*/ */
void gst_elementfactory_add_sink(GstElementFactory *elementfactory, guint16 id) { void
guint type = id; gst_elementfactory_add_sink_caps (GstElementFactory *factory,
GstCapsDefinition def,
GstCaps *caps)
{
g_return_if_fail(factory != NULL);
elementfactory->sink_types = g_list_prepend(elementfactory->sink_types, GUINT_TO_POINTER(type)); if (caps) {
factory->sink_caps = g_list_append (factory->sink_caps, caps);
_gst_type_add_sink (caps->id, factory);
}
} }
/** /**
@ -210,41 +251,39 @@ void gst_elementfactory_add_sink(GstElementFactory *elementfactory, guint16 id)
* Returns: the new xmlNodePtr * Returns: the new xmlNodePtr
*/ */
xmlNodePtr gst_elementfactory_save_thyself(GstElementFactory *factory, xmlNodePtr parent) { xmlNodePtr gst_elementfactory_save_thyself(GstElementFactory *factory, xmlNodePtr parent) {
GList *types; GList *caps;
xmlNodePtr subtree, subsubtree; xmlNodePtr subtree, subsubtree;
xmlNewChild(parent,NULL,"name",factory->name); xmlNewChild(parent,NULL,"name",factory->name);
xmlNewChild(parent,NULL,"longname", factory->details->longname); xmlNewChild(parent,NULL,"longname", factory->details->longname);
xmlNewChild(parent,NULL,"class", factory->details->class); xmlNewChild(parent,NULL,"class", factory->details->klass);
xmlNewChild(parent,NULL,"description", factory->details->description); xmlNewChild(parent,NULL,"description", factory->details->description);
xmlNewChild(parent,NULL,"version", factory->details->version); xmlNewChild(parent,NULL,"version", factory->details->version);
xmlNewChild(parent,NULL,"author", factory->details->author); xmlNewChild(parent,NULL,"author", factory->details->author);
xmlNewChild(parent,NULL,"copyright", factory->details->copyright); xmlNewChild(parent,NULL,"copyright", factory->details->copyright);
types = factory->src_types; caps = factory->src_caps;
if (types) { if (caps) {
subtree = xmlNewChild(parent,NULL,"sources",NULL); subtree = xmlNewChild(parent,NULL,"sources",NULL);
while (types) { while (caps) {
guint16 typeid = GPOINTER_TO_UINT(types->data); GstCaps *cap = (GstCaps *)caps->data;
GstType *type = gst_type_find_by_id(typeid);
subsubtree = xmlNewChild(subtree,NULL,"type",NULL); subsubtree = xmlNewChild(subtree,NULL,"capabilities",NULL);
gst_type_save_thyself(type, subsubtree); gst_caps_save_thyself(cap, subsubtree);
types = g_list_next(types); caps = g_list_next(caps);
} }
} }
types = factory->sink_types; caps = factory->sink_caps;
if (types) { if (caps) {
subtree = xmlNewChild(parent,NULL,"sinks",NULL); subtree = xmlNewChild(parent,NULL,"sinks",NULL);
while (types) { while (caps) {
guint16 typeid = GPOINTER_TO_UINT(types->data); GstCaps *cap = (GstCaps *)caps->data;
GstType *type = gst_type_find_by_id(typeid);
subsubtree = xmlNewChild(subtree,NULL,"type",NULL); subsubtree = xmlNewChild(subtree,NULL,"capabilities",NULL);
gst_type_save_thyself(type, subsubtree); gst_caps_save_thyself(cap, subsubtree);
types = g_list_next(types); caps = g_list_next(caps);
} }
} }
@ -259,12 +298,14 @@ xmlNodePtr gst_elementfactory_save_thyself(GstElementFactory *factory, xmlNodePt
* *
* Returns: the new factory * Returns: the new factory
*/ */
GstElementFactory *gst_elementfactory_load_thyself(xmlNodePtr parent) { GstElementFactory *
gst_elementfactory_load_thyself (xmlNodePtr parent)
{
GstElementFactory *factory = g_new0(GstElementFactory, 1); GstElementFactory *factory = g_new0(GstElementFactory, 1);
xmlNodePtr children = parent->childs; xmlNodePtr children = parent->childs;
factory->details = g_new0(GstElementDetails, 1); factory->details = g_new0(GstElementDetails, 1);
factory->sink_types = NULL; factory->sink_caps = NULL;
factory->src_types = NULL; factory->src_caps = NULL;
while (children) { while (children) {
if (!strcmp(children->name, "name")) { if (!strcmp(children->name, "name")) {
@ -274,7 +315,7 @@ GstElementFactory *gst_elementfactory_load_thyself(xmlNodePtr parent) {
factory->details->longname = g_strdup(xmlNodeGetContent(children)); factory->details->longname = g_strdup(xmlNodeGetContent(children));
} }
if (!strcmp(children->name, "class")) { if (!strcmp(children->name, "class")) {
factory->details->class = g_strdup(xmlNodeGetContent(children)); factory->details->klass = g_strdup(xmlNodeGetContent(children));
} }
if (!strcmp(children->name, "description")) { if (!strcmp(children->name, "description")) {
factory->details->description = g_strdup(xmlNodeGetContent(children)); factory->details->description = g_strdup(xmlNodeGetContent(children));
@ -291,10 +332,9 @@ GstElementFactory *gst_elementfactory_load_thyself(xmlNodePtr parent) {
if (!strcmp(children->name, "sources")) { if (!strcmp(children->name, "sources")) {
xmlNodePtr field = children->childs; xmlNodePtr field = children->childs;
while (field) { while (field) {
if (!strcmp(field->name, "type")) { if (!strcmp(field->name, "capabilities")) {
guint16 typeid = gst_type_load_thyself(field); GstCaps *caps = gst_caps_load_thyself (field);
gst_elementfactory_add_src_caps (factory, 0, caps);
gst_type_add_src(typeid, factory);
} }
field = field->next; field = field->next;
} }
@ -302,10 +342,9 @@ GstElementFactory *gst_elementfactory_load_thyself(xmlNodePtr parent) {
if (!strcmp(children->name, "sinks")) { if (!strcmp(children->name, "sinks")) {
xmlNodePtr field = children->childs; xmlNodePtr field = children->childs;
while (field) { while (field) {
if (!strcmp(field->name, "type")) { if (!strcmp(field->name, "capabilities")) {
guint16 typeid = gst_type_load_thyself(field); GstCaps *caps = gst_caps_load_thyself (field);
gst_elementfactory_add_sink_caps (factory, 0, caps);
gst_type_add_sink(typeid, factory);
} }
field = field->next; field = field->next;
} }

View file

@ -28,6 +28,7 @@
/* Pad signals and args */ /* Pad signals and args */
enum { enum {
SET_ACTIVE, SET_ACTIVE,
CAPS_CHANGED,
/* FILL ME */ /* FILL ME */
LAST_SIGNAL LAST_SIGNAL
}; };
@ -85,6 +86,11 @@ gst_pad_class_init (GstPadClass *klass)
GTK_SIGNAL_OFFSET (GstPadClass, set_active), GTK_SIGNAL_OFFSET (GstPadClass, set_active),
gtk_marshal_NONE__BOOL, GTK_TYPE_NONE, 1, gtk_marshal_NONE__BOOL, GTK_TYPE_NONE, 1,
GTK_TYPE_BOOL); GTK_TYPE_BOOL);
gst_pad_signals[CAPS_CHANGED] =
gtk_signal_new ("caps_changed", GTK_RUN_LAST, gtkobject_class->type,
GTK_SIGNAL_OFFSET (GstPadClass, caps_changed),
gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1,
GTK_TYPE_POINTER);
gtk_object_add_arg_type ("GstPad::active", GTK_TYPE_BOOL, gtk_object_add_arg_type ("GstPad::active", GTK_TYPE_BOOL,
GTK_ARG_READWRITE, ARG_ACTIVE); GTK_ARG_READWRITE, ARG_ACTIVE);
@ -106,7 +112,7 @@ gst_pad_init (GstPad *pad)
pad->qosfunc = NULL; pad->qosfunc = NULL;
pad->parent = NULL; pad->parent = NULL;
pad->ghostparents = NULL; pad->ghostparents = NULL;
pad->types = NULL; pad->caps = NULL;
} }
static void static void
@ -669,30 +675,6 @@ gst_pad_get_ghost_parents (GstPad *pad)
return pad->ghostparents; return pad->ghostparents;
} }
/**
* gst_pad_get_type_ids:
* @pad: the pad to get the type ids from
*
* get the list of types for this pad
*
* Returns: a GList of types of this pad
*/
GList*
gst_pad_get_type_ids (GstPad *pad)
{
g_return_val_if_fail (pad != NULL, 0);
g_return_val_if_fail (GST_IS_PAD (pad), 0);
return pad->types;
}
// FIXME remove...
void
gst_pad_set_type_id (GstPad *pad,
guint16 id)
{
gst_pad_add_type_id (pad, id);
}
/** /**
* gst_pad_set_caps: * gst_pad_set_caps:
* @pad: the pad to set the caps to * @pad: the pad to set the caps to
@ -727,24 +709,6 @@ gst_pad_get_caps (GstPad *pad)
return pad->caps; return pad->caps;
} }
/**
* gst_pad_set_type_id:
* @pad: the pad to set the type id to
* @id: the type id to set this pad to
*
* set the type of this pad
*/
void
gst_pad_add_type_id (GstPad *pad,
guint16 id)
{
g_return_if_fail (pad != NULL);
g_return_if_fail (GST_IS_PAD (pad));
g_return_if_fail (gst_type_find_by_id (id) != NULL);
pad->types = g_list_append(pad->types, GINT_TO_POINTER((gint)id));
}
/** /**
* gst_pad_get_peer: * gst_pad_get_peer:
* @pad: the pad to get the peer from * @pad: the pad to get the peer from

View file

@ -70,7 +70,6 @@ struct _GstPad {
GstObject object; GstObject object;
gchar *name; gchar *name;
GList *types;
GstCaps *caps; GstCaps *caps;
cothread_state *threadstate; cothread_state *threadstate;
@ -95,7 +94,8 @@ struct _GstPadClass {
GstObjectClass parent_class; GstObjectClass parent_class;
/* signal callbacks */ /* signal callbacks */
void (*set_active) (GstPad *pad,gboolean active); void (*set_active) (GstPad *pad, gboolean active);
void (*caps_changed) (GstPad *pad, GstCaps *newcaps);
}; };
@ -110,12 +110,6 @@ void gst_pad_set_pull_function (GstPad *pad, GstPadPullFunction pull);
void gst_pad_set_pullregion_function (GstPad *pad, GstPadPullRegionFunction pullregion); void gst_pad_set_pullregion_function (GstPad *pad, GstPadPullRegionFunction pullregion);
void gst_pad_set_qos_function (GstPad *pad, GstPadQoSFunction qos); void gst_pad_set_qos_function (GstPad *pad, GstPadQoSFunction qos);
// FIXME is here for backward compatibility until we have GstCaps working...
void gst_pad_set_type_id (GstPad *pad, guint16 id);
GList* gst_pad_get_type_ids (GstPad *pad);
void gst_pad_add_type_id (GstPad *pad, guint16 id);
void gst_pad_set_caps (GstPad *pad, GstCaps *caps); void gst_pad_set_caps (GstPad *pad, GstCaps *caps);
GstCaps* gst_pad_get_caps (GstPad *pad); GstCaps* gst_pad_get_caps (GstPad *pad);

View file

@ -169,7 +169,7 @@ gst_pipeline_typefind (GstPipeline *pipeline, GstElement *element)
if (found) { if (found) {
type_id = gst_util_get_int_arg (GTK_OBJECT (typefind), "type"); type_id = gst_util_get_int_arg (GTK_OBJECT (typefind), "type");
gst_pad_add_type_id (gst_element_get_pad (element, "src"), type_id); //gst_pad_add_type_id (gst_element_get_pad (element, "src"), type_id);
} }
gst_pad_disconnect (gst_element_get_pad (element, "src"), gst_pad_disconnect (gst_element_get_pad (element, "src"),
@ -180,32 +180,28 @@ gst_pipeline_typefind (GstPipeline *pipeline, GstElement *element)
return type_id; return type_id;
} }
static void static gboolean
gst_pipeline_pads_autoplug_func (GstElement *src, GstPad *pad, GstElement *sink) gst_pipeline_pads_autoplug_func (GstElement *src, GstPad *pad, GstElement *sink)
{ {
GList *sinkpads; GList *sinkpads;
gboolean connected = FALSE; gboolean connected = FALSE;
guint16 type;
type = GPOINTER_TO_INT (pad->types->data); g_print("gstpipeline: autoplug pad connect function for \"%s\" to \"%s\"\n",
g_print("gstpipeline: autoplug pad connect function type %d for \"%s\" to \"%s\"\n", type,
gst_element_get_name(src), gst_element_get_name(sink)); gst_element_get_name(src), gst_element_get_name(sink));
sinkpads = gst_element_get_pad_list(sink); sinkpads = gst_element_get_pad_list(sink);
while (sinkpads) { while (sinkpads) {
GstPad *sinkpad = (GstPad *)sinkpads->data; GstPad *sinkpad = (GstPad *)sinkpads->data;
guint16 sinktype = GPOINTER_TO_INT (sinkpad->types->data);
// if we have a match, connect the pads // if we have a match, connect the pads
if (sinktype == type && if (sinkpad->direction == GST_PAD_SINK &&
sinkpad->direction == GST_PAD_SINK && !GST_PAD_CONNECTED(sinkpad) &&
!GST_PAD_CONNECTED(sinkpad)) gst_caps_check_compatibility (pad->caps, sinkpad->caps))
{ {
gst_pad_connect(pad, sinkpad); gst_pad_connect(pad, sinkpad);
g_print("gstpipeline: autoconnect pad \"%s\" (%d) in element %s <-> ", pad->name, g_print("gstpipeline: autoconnect pad \"%s\" in element %s <-> ", pad->name,
type, gst_element_get_name(src)); gst_element_get_name(src));
g_print("pad \"%s\" (%d) in element %s\n", sinkpad->name, sinktype, g_print("pad \"%s\" in element %s\n", sinkpad->name,
gst_element_get_name(sink)); gst_element_get_name(sink));
connected = TRUE; connected = TRUE;
break; break;
@ -214,55 +210,27 @@ gst_pipeline_pads_autoplug_func (GstElement *src, GstPad *pad, GstElement *sink)
} }
if (!connected) { if (!connected) {
g_print("gstpipeline: no path to sinks for type %d\n", type); g_print("gstpipeline: no path to sinks for type\n");
} }
return connected;
} }
static void static void
gst_pipeline_pads_autoplug (GstElement *src, GstElement *sink) gst_pipeline_pads_autoplug (GstElement *src, GstElement *sink)
{ {
GList *srcpads, *sinkpads; GList *srcpads;
gboolean connected = FALSE; gboolean connected = FALSE;
srcpads = gst_element_get_pad_list(src); srcpads = gst_element_get_pad_list(src);
while (srcpads) { while (srcpads && !connected) {
GstPad *srcpad = (GstPad *)srcpads->data; GstPad *srcpad = (GstPad *)srcpads->data;
GList *srctypes = gst_pad_get_type_ids(srcpad);
guint16 srctype = 0;
if (srctypes)
srctype = GPOINTER_TO_INT (srctypes->data);
if (srcpad->direction == GST_PAD_SRC && !GST_PAD_CONNECTED(srcpad)) { connected = gst_pipeline_pads_autoplug_func (src, srcpad, sink);
sinkpads = gst_element_get_pad_list(sink);
// FIXME could O(n) if the types were sorted...
while (sinkpads) {
GstPad *sinkpad = (GstPad *)sinkpads->data;
GList *sinktypes = gst_pad_get_type_ids(sinkpad);
guint16 sinktype = 0;
if (sinktypes)
sinktype = GPOINTER_TO_INT (sinktypes->data);
// if we have a match, connect the pads
if (sinktype == srctype &&
sinkpad->direction == GST_PAD_SINK &&
!GST_PAD_CONNECTED(sinkpad)) {
gst_pad_connect(srcpad, sinkpad);
g_print("gstpipeline: autoconnect pad \"%s\" (%d) in element %s <-> ",
srcpad->name, srctype, gst_element_get_name(src));
g_print("pad \"%s\" (%d) in element %s\n", sinkpad->name,
sinktype, gst_element_get_name(sink));
connected = TRUE;
goto end;
}
sinkpads = g_list_next(sinkpads);
}
}
srcpads = g_list_next(srcpads); srcpads = g_list_next(srcpads);
} }
end:
if (!connected) { if (!connected) {
g_print("gstpipeline: delaying pad connections for \"%s\" to \"%s\"\n", g_print("gstpipeline: delaying pad connections for \"%s\" to \"%s\"\n",
gst_element_get_name(src), gst_element_get_name(sink)); gst_element_get_name(src), gst_element_get_name(sink));
@ -356,7 +324,7 @@ gst_pipeline_autoplug (GstPipeline *pipeline)
factory = gst_element_get_factory(pipeline->src); factory = gst_element_get_factory(pipeline->src);
src_types = factory->src_types; src_types = factory->src_caps;
if (src_types == NULL) { if (src_types == NULL) {
g_print("GstPipeline: source \"%s\" has no MIME type, running typefind...\n", g_print("GstPipeline: source \"%s\" has no MIME type, running typefind...\n",
gst_element_get_name(pipeline->src)); gst_element_get_name(pipeline->src));
@ -401,12 +369,14 @@ gst_pipeline_autoplug (GstPipeline *pipeline)
pad = (GstPad *)pads->data; pad = (GstPad *)pads->data;
if (pad->direction == GST_PAD_SINK) { if (pad->direction == GST_PAD_SINK) {
/*
GList *types = gst_pad_get_type_ids(pad); GList *types = gst_pad_get_type_ids(pad);
if (types) { if (types) {
sink_type = GPOINTER_TO_INT (types->data); sink_type = GPOINTER_TO_INT (types->data);
break; break;
} }
else else
*/
sink_type = 0; sink_type = 0;
} }
@ -501,6 +471,7 @@ differ:
while (sinkpads) { while (sinkpads) {
sinkpad = (GstPad *)sinkpads->data; sinkpad = (GstPad *)sinkpads->data;
/*
// FIXME connect matching pads, not just the first one... // FIXME connect matching pads, not just the first one...
if (sinkpad->direction == GST_PAD_SINK && if (sinkpad->direction == GST_PAD_SINK &&
!GST_PAD_CONNECTED(sinkpad)) { !GST_PAD_CONNECTED(sinkpad)) {
@ -513,6 +484,7 @@ differ:
gst_pad_set_type_id (gst_element_get_pad(queue, "sink"), sinktype); gst_pad_set_type_id (gst_element_get_pad(queue, "sink"), sinktype);
break; break;
} }
*/
sinkpads = g_list_next(sinkpads); sinkpads = g_list_next(sinkpads);
} }
gst_pipeline_pads_autoplug(thesrcelement, queue); gst_pipeline_pads_autoplug(thesrcelement, queue);

View file

@ -56,8 +56,6 @@ void _gst_plugin_initialize() {
_gst_libraries = NULL; _gst_libraries = NULL;
_gst_libraries_seqno = 0; _gst_libraries_seqno = 0;
/* add the main (installed) library path */
_gst_plugin_paths = g_list_append(_gst_plugin_paths,PLUGINS_DIR);
/* if this is set, we add build-directory paths to the list */ /* if this is set, we add build-directory paths to the list */
#ifdef PLUGINS_USE_SRCDIR #ifdef PLUGINS_USE_SRCDIR
@ -72,6 +70,9 @@ void _gst_plugin_initialize() {
PLUGINS_SRCDIR "/gst/elements"); PLUGINS_SRCDIR "/gst/elements");
_gst_plugin_paths = g_list_append(_gst_plugin_paths, _gst_plugin_paths = g_list_append(_gst_plugin_paths,
PLUGINS_SRCDIR "/gst/types"); PLUGINS_SRCDIR "/gst/types");
#else
/* add the main (installed) library path */
_gst_plugin_paths = g_list_append(_gst_plugin_paths,PLUGINS_DIR);
#endif /* PLUGINS_USE_SRCDIR */ #endif /* PLUGINS_USE_SRCDIR */
doc = xmlParseFile("/etc/gstreamer/reg.xml"); doc = xmlParseFile("/etc/gstreamer/reg.xml");
@ -164,6 +165,20 @@ gboolean gst_library_load(gchar *name) {
return res; return res;
} }
static void
gst_plugin_remove(GstPlugin *plugin)
{
GList *factories;
factories = plugin->elements;
while (factories) {
gst_elementfactory_unregister((GstElementFactory*)(factories->data));
factories = g_list_next(factories);
}
_gst_plugins = g_list_remove(_gst_plugins, plugin);
g_free (plugin);
}
/** /**
* gst_plugin_load: * gst_plugin_load:
* @name: name of plugin to load * @name: name of plugin to load
@ -209,7 +224,6 @@ gboolean gst_plugin_load_absolute(gchar *name) {
GModule *module; GModule *module;
GstPluginInitFunc initfunc; GstPluginInitFunc initfunc;
GstPlugin *plugin; GstPlugin *plugin;
GList *plugins;
struct stat file_status; struct stat file_status;
if (g_module_supported() == FALSE) { if (g_module_supported() == FALSE) {
@ -217,19 +231,6 @@ gboolean gst_plugin_load_absolute(gchar *name) {
return FALSE; return FALSE;
} }
plugins = _gst_plugins;
while (plugins) {
plugin = (GstPlugin *)plugins->data;
if (!strcmp(plugin->filename, name) && plugin->loaded) {
_gst_plugins = g_list_append(_gst_plugins,plugin);
return TRUE;
}
plugins = g_list_next(plugins);
}
//g_print("trying to absolute load '%s\n",name);
if (stat(name,&file_status)) { if (stat(name,&file_status)) {
// g_print("problem opening file %s\n",name); // g_print("problem opening file %s\n",name);
return FALSE; return FALSE;
@ -239,19 +240,13 @@ gboolean gst_plugin_load_absolute(gchar *name) {
if (module != NULL) { if (module != NULL) {
if (g_module_symbol(module,"plugin_init",(gpointer *)&initfunc)) { if (g_module_symbol(module,"plugin_init",(gpointer *)&initfunc)) {
if ((plugin = (initfunc)(module))) { if ((plugin = (initfunc)(module))) {
GList *factories;
g_print("gstplugin: plugin %s loaded\n", plugin->name); g_print("gstplugin: plugin %s loaded\n", plugin->name);
plugin->filename = g_strdup(name); plugin->filename = g_strdup(name);
plugin->loaded = TRUE; plugin->loaded = TRUE;
_gst_modules = g_list_append(_gst_modules,module); _gst_modules = g_list_append(_gst_modules,module);
_gst_modules_seqno++; _gst_modules_seqno++;
_gst_plugins = g_list_append(_gst_plugins,plugin); _gst_plugins = g_list_prepend(_gst_plugins,plugin);
_gst_plugins_seqno++; _gst_plugins_seqno++;
factories = plugin->elements;
while (factories) {
gst_elementfactory_register((GstElementFactory*)(factories->data));
factories = g_list_next(factories);
}
return TRUE; return TRUE;
} }
} }
@ -279,7 +274,7 @@ GstPlugin *gst_plugin_new(gchar *name) {
plugin->longname = NULL; plugin->longname = NULL;
plugin->types = NULL; plugin->types = NULL;
plugin->elements = NULL; plugin->elements = NULL;
plugin->loaded = FALSE; plugin->loaded = TRUE;
return plugin; return plugin;
} }
@ -343,7 +338,7 @@ GstElementFactory *gst_plugin_find_elementfactory(gchar *name) {
factories = ((GstPlugin *)(plugins->data))->elements; factories = ((GstPlugin *)(plugins->data))->elements;
while (factories) { while (factories) {
factory = (GstElementFactory*)(factories->data); factory = (GstElementFactory*)(factories->data);
if (!strcmp(factory->name,name)) if (!strcmp(factory->name, name))
return (GstElementFactory*)(factory); return (GstElementFactory*)(factory);
factories = g_list_next(factories); factories = g_list_next(factories);
} }
@ -376,12 +371,14 @@ GstElementFactory *gst_plugin_load_elementfactory(gchar *name) {
factory = (GstElementFactory*)(factories->data); factory = (GstElementFactory*)(factories->data);
if (!strcmp(factory->name,name)) { if (!strcmp(factory->name,name)) {
if (!plugin->loaded) { if (!plugin->loaded) {
gchar *filename = g_strdup (plugin->filename);
g_print("gstplugin: loading element factory %s from plugin %s\n", name, plugin->name); g_print("gstplugin: loading element factory %s from plugin %s\n", name, plugin->name);
_gst_plugins = g_list_remove(_gst_plugins, plugin); gst_plugin_remove(plugin);
if (!gst_plugin_load_absolute(plugin->filename)) { if (!gst_plugin_load_absolute(filename)) {
g_print("gstplugin: error loading element factory %s from plugin %s\n", name, plugin->name); g_print("gstplugin: error loading element factory %s from plugin %s\n", name, plugin->name);
} }
factory = gst_plugin_find_elementfactory(factory->name); g_free (filename);
factory = gst_plugin_find_elementfactory(name);
} }
return factory; return factory;
} }
@ -414,11 +411,13 @@ void gst_plugin_load_typefactory(gchar *mime) {
factory = (GstTypeFactory*)(factories->data); factory = (GstTypeFactory*)(factories->data);
if (!strcmp(factory->mime,mime)) { if (!strcmp(factory->mime,mime)) {
if (!plugin->loaded) { if (!plugin->loaded) {
gchar *filename = g_strdup (plugin->filename);
g_print("gstplugin: loading type factory for \"%s\" from plugin %s\n", mime, plugin->name); g_print("gstplugin: loading type factory for \"%s\" from plugin %s\n", mime, plugin->name);
_gst_plugins = g_list_remove(_gst_plugins, plugin); gst_plugin_remove(plugin);
if (!gst_plugin_load_absolute(plugin->filename)) { if (!gst_plugin_load_absolute(filename)) {
g_print("gstplugin: error loading type factory \"%s\" from plugin %s\n", mime, plugin->name); g_print("gstplugin: error loading type factory \"%s\" from plugin %s\n", mime, plugin->name);
} }
g_free (filename);
} }
return; return;
} }
@ -443,6 +442,7 @@ void gst_plugin_add_factory(GstPlugin *plugin,GstElementFactory *factory) {
// g_print("adding factory to plugin\n"); // g_print("adding factory to plugin\n");
plugin->elements = g_list_append(plugin->elements,factory); plugin->elements = g_list_append(plugin->elements,factory);
gst_elementfactory_register (factory);
} }
/** /**
@ -528,7 +528,7 @@ void gst_plugin_load_thyself(xmlNodePtr parent) {
while (kinderen) { while (kinderen) {
if (!strcmp(kinderen->name, "plugin")) { if (!strcmp(kinderen->name, "plugin")) {
xmlNodePtr field = kinderen->childs; xmlNodePtr field = kinderen->childs;
GstPlugin *plugin = (GstPlugin *)g_malloc(sizeof(GstPlugin)); GstPlugin *plugin = g_new0 (GstPlugin, 1);
plugin->elements = NULL; plugin->elements = NULL;
plugin->types = NULL; plugin->types = NULL;
plugin->loaded = FALSE; plugin->loaded = FALSE;
@ -552,13 +552,13 @@ void gst_plugin_load_thyself(xmlNodePtr parent) {
} }
else if (!strcmp(field->name, "element")) { else if (!strcmp(field->name, "element")) {
GstElementFactory *factory = gst_elementfactory_load_thyself(field); GstElementFactory *factory = gst_elementfactory_load_thyself(field);
plugin->elements = g_list_prepend(plugin->elements, factory); gst_plugin_add_factory (plugin, factory);
elementcount++; elementcount++;
} }
else if (!strcmp(field->name, "type")) { else if (!strcmp(field->name, "type")) {
GstTypeFactory *factory = gst_typefactory_load_thyself(field); GstTypeFactory *factory = gst_typefactory_load_thyself(field);
gst_type_register(factory); gst_plugin_add_type (plugin, factory);
plugin->types = g_list_prepend(plugin->types, factory); elementcount++;
typecount++; typecount++;
} }

View file

@ -47,18 +47,19 @@ typedef GstPlugin* (*GstPluginInitFunc) (GModule *module);
void _gst_plugin_initialize (void); void _gst_plugin_initialize (void);
GstPlugin* gst_plugin_new (gchar *name); GstPlugin* gst_plugin_new (gchar *name);
void gst_plugin_set_longname (GstPlugin *plugin, gchar *longname);
void gst_plugin_load_all (void); void gst_plugin_load_all (void);
gboolean gst_plugin_load (gchar *name); gboolean gst_plugin_load (gchar *name);
gboolean gst_library_load (gchar *name);
gboolean gst_plugin_load_absolute (gchar *name); gboolean gst_plugin_load_absolute (gchar *name);
gboolean gst_library_load (gchar *name);
void gst_plugin_set_longname (GstPlugin *plugin, gchar *longname);
void gst_plugin_add_factory (GstPlugin *plugin, GstElementFactory *factory); void gst_plugin_add_factory (GstPlugin *plugin, GstElementFactory *factory);
void gst_plugin_add_type (GstPlugin *plugin, GstTypeFactory *factory); void gst_plugin_add_type (GstPlugin *plugin, GstTypeFactory *factory);
GstPlugin* gst_plugin_find (const gchar *name); GstPlugin* gst_plugin_find (const gchar *name);
GList* gst_plugin_get_list (void); GList* gst_plugin_get_list (void);
GstElementFactory* gst_plugin_find_elementfactory (gchar *name); GstElementFactory* gst_plugin_find_elementfactory (gchar *name);
GstElementFactory* gst_plugin_load_elementfactory (gchar *name); GstElementFactory* gst_plugin_load_elementfactory (gchar *name);

View file

@ -156,78 +156,6 @@ gst_props_register (GstPropsFactory factory)
return props; return props;
} }
static void
gst_props_dump_entry_func (GstPropsEntry *entry)
{
switch (entry->propstype) {
case GST_PROPS_INT_ID_NUM:
g_print("gstprops: int %d\n", entry->data.int_data);
break;
case GST_PROPS_INT_RANGE_ID_NUM:
g_print("gstprops: int range %d %d\n",
entry->data.int_range_data.min,
entry->data.int_range_data.max);
break;
case GST_PROPS_FOURCC_ID_NUM:
g_print("gstprops: fourcc 0x%08x (%4.4s)\n", entry->data.fourcc_data, (gchar *)&entry->data.fourcc_data);
break;
case GST_PROPS_BOOL_ID_NUM:
g_print("gstprops: boolean %d\n", entry->data.bool_data);
break;
default:
g_print("gstprops: **illegal entry**\n");
break;
}
}
static void
gst_props_dump_list_func (gpointer entry,
gpointer list_entry)
{
gst_props_dump_entry_func ((GstPropsEntry *)entry);
}
static void
gst_props_dump_func (gpointer data,
gpointer user_data)
{
GstPropsEntry *entry;
entry = (GstPropsEntry *)data;
g_print("gstprops: property type \"%s\"\n", g_quark_to_string (entry->propid));
switch (entry->propstype) {
case GST_PROPS_LIST_ID_NUM:
{
g_print("gstprops: list type (\n");
g_list_foreach (entry->data.list_data.entries, gst_props_dump_list_func, entry);
g_print("gstprops: )\n");
break;
}
default:
gst_props_dump_entry_func (entry);
break;
}
}
/**
* gst_props_dump:
* @props: the capability to dump
*
* Dumps the contents of the capabilty one the console
*/
void
gst_props_dump (GstProps *props)
{
g_return_if_fail (props != NULL);
g_print("gstprops: {\n");
g_slist_foreach (props->properties, gst_props_dump_func, props);
g_print("gstprops: }\n");
}
/* entry2 is always a list, entry1 never is */ /* entry2 is always a list, entry1 never is */
static gboolean static gboolean
gst_props_entry_check_list_compatibility (GstPropsEntry *entry1, GstPropsEntry *entry2) gst_props_entry_check_list_compatibility (GstPropsEntry *entry1, GstPropsEntry *entry2)
@ -383,3 +311,71 @@ end:
return compatible; return compatible;
} }
static xmlNodePtr
gst_props_save_thyself_func (GstPropsEntry *entry, xmlNodePtr parent)
{
xmlNodePtr subtree;
switch (entry->propstype) {
case GST_PROPS_INT_ID_NUM:
subtree = xmlNewChild (parent, NULL, "int", NULL);
xmlNewProp (subtree, "name", g_quark_to_string (entry->propid));
xmlNewProp (subtree, "value", g_strdup_printf ("%d", entry->data.int_data));
break;
case GST_PROPS_INT_RANGE_ID_NUM:
subtree = xmlNewChild (parent, NULL, "range", NULL);
xmlNewProp (subtree, "name", g_quark_to_string (entry->propid));
xmlNewProp (subtree, "min", g_strdup_printf ("%d", entry->data.int_range_data.min));
xmlNewProp (subtree, "max", g_strdup_printf ("%d", entry->data.int_range_data.max));
break;
case GST_PROPS_FOURCC_ID_NUM:
xmlAddChild (parent, xmlNewComment (g_strdup_printf ("%4.4s", (gchar *)&entry->data.fourcc_data)));
subtree = xmlNewChild (parent, NULL, "fourcc", NULL);
xmlNewProp (subtree, "name", g_quark_to_string (entry->propid));
xmlNewProp (subtree, "hexvalue", g_strdup_printf ("%08x", entry->data.fourcc_data));
break;
case GST_PROPS_BOOL_ID_NUM:
subtree = xmlNewChild (parent, NULL, "boolean", NULL);
xmlNewProp (subtree, "name", g_quark_to_string (entry->propid));
xmlNewProp (subtree, "value", (entry->data.bool_data ? "true" : "false"));
break;
default:
break;
}
return parent;
}
xmlNodePtr
gst_props_save_thyself (GstProps *props, xmlNodePtr parent)
{
GSList *proplist;
xmlNodePtr subtree;
g_return_val_if_fail (props != NULL, NULL);
proplist = props->properties;
while (proplist) {
GstPropsEntry *entry = (GstPropsEntry *) proplist->data;
switch (entry->propstype) {
case GST_PROPS_LIST_ID_NUM:
subtree = xmlNewChild (parent, NULL, "list", NULL);
g_list_foreach (entry->data.list_data.entries, (GFunc) gst_props_save_thyself_func, subtree);
default:
gst_props_save_thyself_func (entry, parent);
}
proplist = g_slist_next (proplist);
}
return parent;
}
GstProps*
gst_props_load_thyself (xmlNodePtr parent)
{
return NULL;
}

View file

@ -60,8 +60,9 @@ void _gst_props_initialize (void);
GstProps* gst_props_register (GstPropsFactory factory); GstProps* gst_props_register (GstPropsFactory factory);
void gst_props_dump (GstProps *props);
gboolean gst_props_check_compatibility (GstProps *props1, GstProps *props2); gboolean gst_props_check_compatibility (GstProps *props1, GstProps *props2);
xmlNodePtr gst_props_save_thyself (GstProps *props, xmlNodePtr parent);
GstProps* gst_props_load_thyself (xmlNodePtr parent);
#endif /* __GST_PROPS_H__ */ #endif /* __GST_PROPS_H__ */

View file

@ -32,6 +32,12 @@
GList *_gst_types; GList *_gst_types;
guint16 _gst_maxtype; guint16 _gst_maxtype;
struct _GstTypeFindInfo {
GstTypeFindFunc typefindfunc; /* typefind function */
GstPlugin *plugin; /* the plugin with this typefind function */
};
#define MAX_COST 999999 #define MAX_COST 999999
struct _gst_type_node struct _gst_type_node
@ -91,7 +97,7 @@ gst_type_register (GstTypeFactory *factory)
type->id = _gst_maxtype++; type->id = _gst_maxtype++;
type->mime = factory->mime; type->mime = factory->mime;
type->exts = factory->exts; type->exts = factory->exts;
type->typefindfunc = factory->typefindfunc; //type->typefindfunc = factory->typefindfunc;
type->srcs = NULL; type->srcs = NULL;
type->sinks = NULL; type->sinks = NULL;
type->converters = g_hash_table_new (NULL, NULL); type->converters = g_hash_table_new (NULL, NULL);
@ -106,9 +112,11 @@ gst_type_register (GstTypeFactory *factory)
/* FIXME: do extension merging here, not that easy */ /* FIXME: do extension merging here, not that easy */
/* if there is no existing typefind function, try to use new one */ /* if there is no existing typefind function, try to use new one */
/*
if ((type->typefindfunc == gst_type_typefind_dummy || if ((type->typefindfunc == gst_type_typefind_dummy ||
type->typefindfunc == NULL) && factory->typefindfunc) type->typefindfunc == NULL) && factory->typefindfunc)
type->typefindfunc = factory->typefindfunc; type->typefindfunc = factory->typefindfunc;
*/
} }
return id; return id;
@ -161,14 +169,6 @@ guint16 gst_type_find_by_mime_func (gchar *mime)
guint16 guint16
gst_type_find_by_mime (gchar *mime) gst_type_find_by_mime (gchar *mime)
{ {
guint16 typeid;
typeid = gst_type_find_by_mime_func (mime);
if (!typeid) {
gst_plugin_load_typefactory (mime);
}
return gst_type_find_by_mime_func (mime); return gst_type_find_by_mime_func (mime);
} }
@ -254,16 +254,8 @@ gst_type_dump(void)
} }
} }
/** static void
* gst_type_add_src: gst_type_handle_src (guint16 id, GstElementFactory *src, gboolean remove)
* @id: the type id to add the source factory to
* @src: the source factory for the type
*
* register the src factory as being a source for the
* given type id
*/
void
gst_type_add_src (guint16 id, GstElementFactory *src)
{ {
GList *walk; GList *walk;
GstType *type = gst_type_find_by_id (id); GstType *type = gst_type_find_by_id (id);
@ -271,16 +263,23 @@ gst_type_add_src (guint16 id, GstElementFactory *src)
g_return_if_fail (type != NULL); g_return_if_fail (type != NULL);
g_return_if_fail (src != NULL); g_return_if_fail (src != NULL);
type->srcs = g_list_prepend (type->srcs, src); g_print ("gsttype: add src %d, \"%s\"\n", id, src->name);
gst_elementfactory_add_src (src, id); 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 // find out if the element has to be indexed in the matrix
walk = src->sink_types; walk = src->sink_caps;
while (walk) { while (walk) {
GstType *type2 = gst_type_find_by_id (GPOINTER_TO_UINT (walk->data)); GstType *type2;
GList *converters = (GList *)g_hash_table_lookup (type2->converters, GUINT_TO_POINTER ((guint)id)); GList *converters;
GList *orig = converters; GList *orig;
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;
while (converters) { while (converters) {
if (converters->data == src) { if (converters->data == src) {
@ -290,7 +289,10 @@ gst_type_add_src (guint16 id, GstElementFactory *src)
} }
if (!converters) { if (!converters) {
orig = g_list_prepend (orig, src); if (remove)
orig = g_list_remove (orig, src);
else
orig = g_list_prepend (orig, src);
g_hash_table_insert (type2->converters, GUINT_TO_POINTER ((guint)id), orig); g_hash_table_insert (type2->converters, GUINT_TO_POINTER ((guint)id), orig);
} }
@ -298,6 +300,74 @@ gst_type_add_src (guint16 id, GstElementFactory *src)
} }
} }
/**
* gst_type_add_src:
* @id: the type id to add the source factory to
* @src: the source factory for the type
*
* register the src factory as being a source for the
* given type id
*/
void
_gst_type_add_src (guint16 id, GstElementFactory *src)
{
gst_type_handle_src (id, src, FALSE);
}
/**
* gst_type_remove_src:
* @id: the type id to add the source factory to
* @src: the source factory for the type
*
* register the src factory as being a source for the
* given type id
*/
void
_gst_type_remove_src (guint16 id, GstElementFactory *src)
{
gst_type_handle_src (id, src, TRUE);
}
static void
gst_type_handle_sink (guint16 id, GstElementFactory *sink, gboolean remove)
{
GList *walk;
GstType *type = gst_type_find_by_id (id);
g_return_if_fail (type != NULL);
g_return_if_fail (sink != NULL);
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;
while (walk) {
GList *converters = (GList *)g_hash_table_lookup (type->converters, walk->data);
GList *orig = converters;
while (converters) {
if (converters->data == sink) {
break;
}
converters = g_list_next (converters);
}
if (!converters) {
if (remove)
orig = g_list_remove (orig, sink);
else
orig = g_list_prepend (orig, sink);
g_hash_table_insert (type->converters, walk->data, orig);
}
walk = g_list_next (walk);
}
}
/** /**
* gst_type_add_sink: * gst_type_add_sink:
* @id: the type id to add the sink factory to * @id: the type id to add the sink factory to
@ -307,38 +377,23 @@ gst_type_add_src (guint16 id, GstElementFactory *src)
* given type id * given type id
*/ */
void void
gst_type_add_sink (guint16 id, GstElementFactory *sink) _gst_type_add_sink (guint16 id, GstElementFactory *sink)
{ {
GList *walk; gst_type_handle_sink (id, sink, FALSE);
GstType *type = gst_type_find_by_id (id); }
g_return_if_fail (type != NULL); /**
g_return_if_fail (sink != NULL); * gst_type_remove_sink:
* @id: the type id to remove the sink factory from
type->sinks = g_list_prepend (type->sinks, sink); * @sink: the sink factory for the type
gst_elementfactory_add_sink (sink, id); *
* remove the sink factory as being a sink for the
// find out if the element has to be indexed in the matrix * given type id
walk = sink->src_types; */
void
while (walk) { _gst_type_remove_sink (guint16 id, GstElementFactory *sink)
GList *converters = (GList *)g_hash_table_lookup (type->converters, walk->data); {
GList *orig = converters; gst_type_handle_sink (id, sink, TRUE);
while (converters) {
if (converters->data == sink) {
break;
}
converters = g_list_next (converters);
}
if (!converters) {
orig = g_list_prepend (orig, sink);
g_hash_table_insert (type->converters, walk->data, orig);
}
walk = g_list_next (walk);
}
} }
/** /**
@ -601,14 +656,16 @@ gst_type_typefind_dummy (GstBuffer *buffer, gpointer priv)
guint16 typeid; guint16 typeid;
g_print ("gsttype: need to load typefind function\n"); g_print ("gsttype: need to load typefind function\n");
type->typefindfunc = NULL; type->typefindfuncs = NULL;
gst_plugin_load_typefactory (type->mime); gst_plugin_load_typefactory (type->mime);
typeid = gst_type_find_by_mime (type->mime); typeid = gst_type_find_by_mime (type->mime);
type = gst_type_find_by_id (typeid); type = gst_type_find_by_id (typeid);
/*
if (type->typefindfunc) { if (type->typefindfunc) {
return type->typefindfunc (buffer, type); return type->typefindfunc (buffer, type);
} }
*/
return FALSE; return FALSE;
} }
@ -637,7 +694,7 @@ gst_typefactory_load_thyself (xmlNodePtr parent)
factory->exts = g_strdup (xmlNodeGetContent (field)); factory->exts = g_strdup (xmlNodeGetContent (field));
} }
else if (!strcmp (field->name, "typefind")) { else if (!strcmp (field->name, "typefind")) {
factory->typefindfunc = gst_type_typefind_dummy; //factory->typefindfunc = gst_type_typefind_dummy;
} }
field = field->next; field = field->next;
} }

View file

@ -38,7 +38,7 @@ struct _GstType {
gchar *mime; /* MIME type */ gchar *mime; /* MIME type */
gchar *exts; /* space-delimited list of extensions */ gchar *exts; /* space-delimited list of extensions */
GstTypeFindFunc typefindfunc; /* typefind function */ GSList *typefindfuncs; /* typefind functions */
GList *srcs; /* list of src objects for this type */ GList *srcs; /* list of src objects for this type */
GList *sinks; /* list of sink objects for type */ GList *sinks; /* list of sink objects for type */
@ -66,8 +66,10 @@ guint16 gst_type_find_by_mime (gchar *mime);
guint16 gst_type_find_by_ext (gchar *ext); guint16 gst_type_find_by_ext (gchar *ext);
/* add src or sink object */ /* add src or sink object */
void gst_type_add_src (guint16 id, GstElementFactory *src); void _gst_type_add_src (guint16 id, GstElementFactory *src);
void gst_type_add_sink (guint16 id, GstElementFactory *sink); void _gst_type_add_sink (guint16 id, GstElementFactory *sink);
void _gst_type_remove_src (guint16 id, GstElementFactory *src);
void _gst_type_remove_sink (guint16 id, GstElementFactory *sink);
/* get list of src or sink objects */ /* get list of src or sink objects */
GList* gst_type_get_srcs (guint16 id); GList* gst_type_get_srcs (guint16 id);
GList* gst_type_get_sinks (guint16 id); GList* gst_type_get_sinks (guint16 id);

View file

@ -18,6 +18,8 @@ main (int argc, char *argv[])
glade_init(); glade_init();
glade_gnome_init(); glade_gnome_init();
gst_type_dump ();
play = gst_media_play_new (); play = gst_media_play_new ();
if (argc > 1) { if (argc > 1) {

View file

@ -67,6 +67,18 @@ enum {
/* FILL ME */ /* FILL ME */
}; };
static GstCapsFactory audiosink_sink_caps = {
"audio/raw",
"format", GST_PROPS_INT (AFMT_S16_LE),
"depth", GST_PROPS_LIST (
GST_PROPS_INT (8),
GST_PROPS_INT (16)
),
"rate", GST_PROPS_INT_RANGE (8000, 48000),
"channels", GST_PROPS_INT_RANGE (1, 2),
NULL
};
#define GST_TYPE_AUDIOSINK_FORMATS (gst_audiosink_formats_get_type()) #define GST_TYPE_AUDIOSINK_FORMATS (gst_audiosink_formats_get_type())
static GtkType static GtkType
@ -103,7 +115,7 @@ gst_audiosink_channels_get_type(void) {
static GstSinkClass *parent_class = NULL; static GstSinkClass *parent_class = NULL;
static guint gst_audiosink_signals[LAST_SIGNAL] = { 0 }; static guint gst_audiosink_signals[LAST_SIGNAL] = { 0 };
static guint16 gst_audiosink_type_audio = 0; static GstCaps *gst_audiosink_sink_caps = NULL;
GtkType GtkType
gst_audiosink_get_type (void) gst_audiosink_get_type (void)
@ -124,9 +136,6 @@ gst_audiosink_get_type (void)
audiosink_type = gtk_type_unique (GST_TYPE_SINK, &audiosink_info); audiosink_type = gtk_type_unique (GST_TYPE_SINK, &audiosink_info);
} }
if (!gst_audiosink_type_audio)
gst_audiosink_type_audio = gst_type_find_by_mime ("audio/raw");
return audiosink_type; return audiosink_type;
} }
@ -169,7 +178,7 @@ gst_audiosink_init (GstAudioSink *audiosink)
{ {
audiosink->sinkpad = gst_pad_new ("sink", GST_PAD_SINK); audiosink->sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
gst_element_add_pad (GST_ELEMENT (audiosink), audiosink->sinkpad); gst_element_add_pad (GST_ELEMENT (audiosink), audiosink->sinkpad);
gst_pad_set_type_id (audiosink->sinkpad, gst_audiosink_type_audio); gst_pad_set_caps (audiosink->sinkpad, gst_audiosink_sink_caps);
gst_pad_set_chain_function (audiosink->sinkpad, gst_audiosink_chain); gst_pad_set_chain_function (audiosink->sinkpad, gst_audiosink_chain);
@ -401,10 +410,7 @@ gst_audiosink_change_state (GstElement *element)
gboolean gboolean
gst_audiosink_factory_init (GstElementFactory *factory) gst_audiosink_factory_init (GstElementFactory *factory)
{ {
if (!gst_audiosink_type_audio) gst_audiosink_sink_caps = gst_caps_register (audiosink_sink_caps);
gst_audiosink_type_audio = gst_type_find_by_mime ("audio/raw");
gst_type_add_sink (gst_audiosink_type_audio, factory);
return TRUE; return TRUE;
} }

View file

@ -1,4 +1,4 @@
noinst_PROGRAMS = init loadall simplefake states caps queue noinst_PROGRAMS = init loadall simplefake states caps queue registry
LDADD = $(GLIB_LIBS) $(GTK_LIBS) $(top_builddir)/gst/libgst.la LDADD = $(GLIB_LIBS) $(GTK_LIBS) $(top_builddir)/gst/libgst.la
CFLAGS = -Wall CFLAGS = -Wall

View file

@ -70,24 +70,35 @@ static GstCaps *sinkcaps = NULL,
int main(int argc,char *argv[]) int main(int argc,char *argv[])
{ {
gboolean testret; gboolean testret;
xmlDocPtr doc;
xmlNodePtr parent;
doc = xmlNewDoc ("1.0");
doc->root = xmlNewDocNode (doc, NULL, "Capabilities", NULL);
_gst_type_initialize (); _gst_type_initialize ();
sinkcaps = gst_caps_register (mpeg2dec_sink_caps); sinkcaps = gst_caps_register (mpeg2dec_sink_caps);
g_print ("caps 1:\n"); parent = xmlNewChild (doc->root, NULL, "Capabilities1", NULL);
gst_caps_dump (sinkcaps); gst_caps_save_thyself (sinkcaps, parent);
rawcaps = gst_caps_register (mpeg2dec_src_caps); rawcaps = gst_caps_register (mpeg2dec_src_caps);
g_print ("caps 2:\n"); parent = xmlNewChild (doc->root, NULL, "Capabilities2", NULL);
gst_caps_dump (rawcaps); gst_caps_save_thyself (rawcaps, parent);
rawcaps2 = gst_caps_register (raw_sink_caps); rawcaps2 = gst_caps_register (raw_sink_caps);
g_print ("caps 3:\n"); parent = xmlNewChild (doc->root, NULL, "Capabilities3", NULL);
gst_caps_dump (rawcaps2); gst_caps_save_thyself (rawcaps2, parent);
mp1parsecaps = gst_caps_register (mp1parse_src_caps); mp1parsecaps = gst_caps_register (mp1parse_src_caps);
g_print ("caps 4:\n"); parent = xmlNewChild (doc->root, NULL, "Capabilities4", NULL);
gst_caps_dump (mp1parsecaps); gst_caps_save_thyself (mp1parsecaps, parent);
rawcaps3 = gst_caps_register (raw2_sink_caps); rawcaps3 = gst_caps_register (raw2_sink_caps);
g_print ("caps 5:\n"); parent = xmlNewChild (doc->root, NULL, "Capabilities5", NULL);
gst_caps_dump (rawcaps3); gst_caps_save_thyself (rawcaps3, parent);
xmlDocDump(stdout, doc);
testret = gst_caps_check_compatibility (mp1parsecaps, rawcaps); testret = gst_caps_check_compatibility (mp1parsecaps, rawcaps);
g_print ("4 <-> 2 == %d (invalid, wrong major type)\n", testret); g_print ("4 <-> 2 == %d (invalid, wrong major type)\n", testret);

View file

@ -9,10 +9,10 @@ int main(int argc,char *argv[]) {
pipeline = GST_BIN(gst_pipeline_new("pipeline")); pipeline = GST_BIN(gst_pipeline_new("pipeline"));
g_return_val_if_fail(1,pipeline != NULL); g_return_val_if_fail(1,pipeline != NULL);
// thr1 = GST_BIN(gst_thread_new("thr1")); //thr1 = GST_BIN(gst_thread_new("thr1"));
thr1 = gst_bin_new("thr1"); thr1 = gst_bin_new("thr1");
g_return_val_if_fail(2,thr1 != NULL); g_return_val_if_fail(2,thr1 != NULL);
// thr2 = GST_BIN(gst_thread_new("thr2")); //thr2 = GST_BIN(gst_thread_new("thr2"));
thr2 = gst_bin_new("thr2"); thr2 = gst_bin_new("thr2");
g_return_val_if_fail(3,thr2 != NULL); g_return_val_if_fail(3,thr2 != NULL);
fprintf(stderr,"QUEUE: fakesrc\n"); fprintf(stderr,"QUEUE: fakesrc\n");
@ -43,6 +43,7 @@ fprintf(stderr,"QUEUE: fakesink\n");
gst_element_connect(queue,"src",thr2,"sink"); gst_element_connect(queue,"src",thr2,"sink");
printf("QUEUE: constructed outer pipeline\n"); printf("QUEUE: constructed outer pipeline\n");
gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_READY);
gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PLAYING); gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PLAYING);
if (GST_STATE(src) != GST_STATE_PLAYING) fprintf(stderr,"error: state not set\n"); if (GST_STATE(src) != GST_STATE_PLAYING) fprintf(stderr,"error: state not set\n");