gsti386.h \
gstppc.h
-CFLAGS += -O6 -Wall
+CFLAGS += -g -O6 -Wall
libgst_la_LIBADD = $(GLIB_LIBS) $(GTK_LIBS) $(XML_LIBS)
libgst_la_LDFLAGS = -version-info $(STREAMER_CURRENT):$(STREAMER_REVISION):$(STREAMER_AGE)
/* 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())
static GtkType
static GstSinkClass *parent_class = NULL;
static guint gst_audiosink_signals[LAST_SIGNAL] = { 0 };
-static guint16 gst_audiosink_type_audio = 0;
+static GstCaps *gst_audiosink_sink_caps = NULL;
GtkType
gst_audiosink_get_type (void)
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;
}
{
audiosink->sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
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);
gboolean
gst_audiosink_factory_init (GstElementFactory *factory)
{
- if (!gst_audiosink_type_audio)
- gst_audiosink_type_audio = gst_type_find_by_mime ("audio/raw");
-
- gst_type_add_sink (gst_audiosink_type_audio, factory);
+ gst_audiosink_sink_caps = gst_caps_register (audiosink_sink_caps);
return TRUE;
}
GstPad *pad;
gboolean dedicated = TRUE;
cothread_state *threadstate;
- _GstBinOutsideSchedule *sched;
+ _GstBinOutsideSchedule *sched = NULL;
// walk through all the pads, find out of this is hard or not
pads = gst_element_get_pad_list (element);
cothread_setfunc (sched->threadstate, gst_bin_sched_wrapper,
0, (char **)sched);
}
+ return sched;
}
static 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:
* @factory: the factory to register
g_return_val_if_fail (tag != NULL, NULL);
- typeid = gst_type_find_by_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);
- }
+ typeid = get_type_for_mime ((gchar *)tag);
caps = g_new0 (GstCaps, 1);
g_return_val_if_fail (caps != NULL, NULL);
/**
- * 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:
* @fromcaps: a capabilty
* @tocaps: a capabilty
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;
+}
+
+
+
typedef GstCapsFactoryEntry GstCapsFactory[];
typedef GstCapsFactory *GstCapsListFactory[];
+typedef enum {
+ GST_CAPS_ALWAYS = 1,
+ GST_CAPS_MAYBE = 2,
+} GstCapsDefinition;
+
struct _GstCaps {
guint16 id; /* type id (major type) */
GstCaps* gst_caps_register (GstCapsFactory factory);
-void gst_caps_dump (GstCaps *caps);
-
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__ */
#include <gst/gstobject.h>
#include <gst/gstpad.h>
#include <gst/gstbuffer.h>
+#include <gst/gstcaps.h>
#include <gst/cothreads.h>
struct _GstElementDetails {
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 *version; /* version of the element */
gchar *author; /* who wrote this thing? */
GstElementDetails *details; /* pointer to details struct */
- GList *src_types;
- GList *sink_types;
+ GList *src_caps;
+ GList *sink_caps;
};
GtkType gst_element_get_type (void);
GstElementFactory* gst_elementfactory_new (gchar *name,GtkType type,
GstElementDetails *details);
-void gst_elementfactory_register (GstElementFactory *elementfactory);
-void gst_elementfactory_add_src (GstElementFactory *elementfactory, guint16 id);
-void gst_elementfactory_add_sink (GstElementFactory *elementfactory, guint16 id);
+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);
GstElementFactory* gst_elementfactory_find (gchar *name);
GList* gst_elementfactory_get_list (void);
}
/**
+ * 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:
* @name: name of factory to find
*
DEBUG("gstelementfactory: find \"%s\"\n", name);
- gst_plugin_load_elementfactory(name);
-
walk = _gst_elementfactories;
while (walk) {
factory = (GstElementFactory *)(walk->data);
factory->name = g_strdup(name);
factory->type = type;
factory->details = details;
- factory->src_types = NULL;
- factory->sink_types = NULL;
+ factory->src_caps = NULL;
+ factory->sink_caps = NULL;
return factory;
}
DEBUG("gstelementfactory: create \"%s\" \"%s\"\n", factory->name, name);
+ // it's not loaded, try to load the plugin
if (factory->type == 0) {
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->type != 0, NULL);
}
/**
- * gst_elementfactory_add_src:
+ * gst_elementfactory_add_src_caps :
* @elementfactory: factory to add the src id to
* @id: the mime id of the src
*
* Use this function to indicate that this factory can src
* the given type id.
*/
-void gst_elementfactory_add_src(GstElementFactory *elementfactory, guint16 id) {
- guint type = id;
-
- elementfactory->src_types = g_list_prepend(elementfactory->src_types, GUINT_TO_POINTER(type));
+void
+gst_elementfactory_add_src_caps (GstElementFactory *factory,
+ GstCapsDefinition def,
+ GstCaps *caps)
+{
+ g_return_if_fail(factory != NULL);
+
+ 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
* @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(GstElementFactory *elementfactory, guint16 id) {
- guint type = id;
-
- elementfactory->sink_types = g_list_prepend(elementfactory->sink_types, GUINT_TO_POINTER(type));
+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);
+ }
}
/**
* Returns: the new xmlNodePtr
*/
xmlNodePtr gst_elementfactory_save_thyself(GstElementFactory *factory, xmlNodePtr parent) {
- GList *types;
+ GList *caps;
xmlNodePtr subtree, subsubtree;
xmlNewChild(parent,NULL,"name",factory->name);
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,"version", factory->details->version);
xmlNewChild(parent,NULL,"author", factory->details->author);
xmlNewChild(parent,NULL,"copyright", factory->details->copyright);
- types = factory->src_types;
- if (types) {
+ caps = factory->src_caps;
+ if (caps) {
subtree = xmlNewChild(parent,NULL,"sources",NULL);
- while (types) {
- guint16 typeid = GPOINTER_TO_UINT(types->data);
- GstType *type = gst_type_find_by_id(typeid);
+ while (caps) {
+ GstCaps *cap = (GstCaps *)caps->data;
- subsubtree = xmlNewChild(subtree,NULL,"type",NULL);
- gst_type_save_thyself(type, subsubtree);
+ subsubtree = xmlNewChild(subtree,NULL,"capabilities",NULL);
+ gst_caps_save_thyself(cap, subsubtree);
- types = g_list_next(types);
+ caps = g_list_next(caps);
}
}
- types = factory->sink_types;
- if (types) {
+ caps = factory->sink_caps;
+ if (caps) {
subtree = xmlNewChild(parent,NULL,"sinks",NULL);
- while (types) {
- guint16 typeid = GPOINTER_TO_UINT(types->data);
- GstType *type = gst_type_find_by_id(typeid);
+ while (caps) {
+ GstCaps *cap = (GstCaps *)caps->data;
- subsubtree = xmlNewChild(subtree,NULL,"type",NULL);
- gst_type_save_thyself(type, subsubtree);
+ subsubtree = xmlNewChild(subtree,NULL,"capabilities",NULL);
+ gst_caps_save_thyself(cap, subsubtree);
- types = g_list_next(types);
+ caps = g_list_next(caps);
}
}
*
* Returns: the new factory
*/
-GstElementFactory *gst_elementfactory_load_thyself(xmlNodePtr parent) {
+GstElementFactory *
+gst_elementfactory_load_thyself (xmlNodePtr parent)
+{
GstElementFactory *factory = g_new0(GstElementFactory, 1);
xmlNodePtr children = parent->childs;
factory->details = g_new0(GstElementDetails, 1);
- factory->sink_types = NULL;
- factory->src_types = NULL;
+ factory->sink_caps = NULL;
+ factory->src_caps = NULL;
while (children) {
if (!strcmp(children->name, "name")) {
factory->details->longname = g_strdup(xmlNodeGetContent(children));
}
if (!strcmp(children->name, "class")) {
- factory->details->class = g_strdup(xmlNodeGetContent(children));
+ factory->details->klass = g_strdup(xmlNodeGetContent(children));
}
if (!strcmp(children->name, "description")) {
factory->details->description = g_strdup(xmlNodeGetContent(children));
if (!strcmp(children->name, "sources")) {
xmlNodePtr field = children->childs;
while (field) {
- if (!strcmp(field->name, "type")) {
- guint16 typeid = gst_type_load_thyself(field);
-
- gst_type_add_src(typeid, factory);
+ 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, "type")) {
- guint16 typeid = gst_type_load_thyself(field);
-
- gst_type_add_sink(typeid, factory);
+ if (!strcmp(field->name, "capabilities")) {
+ GstCaps *caps = gst_caps_load_thyself (field);
+ gst_elementfactory_add_sink_caps (factory, 0, caps);
}
field = field->next;
}
/* Pad signals and args */
enum {
SET_ACTIVE,
+ CAPS_CHANGED,
/* FILL ME */
LAST_SIGNAL
};
GTK_SIGNAL_OFFSET (GstPadClass, set_active),
gtk_marshal_NONE__BOOL, GTK_TYPE_NONE, 1,
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_ARG_READWRITE, ARG_ACTIVE);
pad->qosfunc = NULL;
pad->parent = NULL;
pad->ghostparents = NULL;
- pad->types = NULL;
+ pad->caps = NULL;
}
static void
}
/**
- * 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:
* @pad: the pad to set the caps to
* @caps: the caps to attach to this pad
}
/**
- * 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:
* @pad: the pad to get the peer from
*
GstObject object;
gchar *name;
- GList *types;
GstCaps *caps;
cothread_state *threadstate;
GstObjectClass parent_class;
/* signal callbacks */
- void (*set_active) (GstPad *pad,gboolean active);
+ void (*set_active) (GstPad *pad, gboolean active);
+ void (*caps_changed) (GstPad *pad, GstCaps *newcaps);
};
void gst_pad_set_pullregion_function (GstPad *pad, GstPadPullRegionFunction pullregion);
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);
GstCaps* gst_pad_get_caps (GstPad *pad);
if (found) {
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"),
return type_id;
}
-static void
+static gboolean
gst_pipeline_pads_autoplug_func (GstElement *src, GstPad *pad, GstElement *sink)
{
GList *sinkpads;
gboolean connected = FALSE;
- guint16 type;
-
- type = GPOINTER_TO_INT (pad->types->data);
- g_print("gstpipeline: autoplug pad connect function type %d for \"%s\" to \"%s\"\n", type,
+ g_print("gstpipeline: autoplug pad connect function for \"%s\" to \"%s\"\n",
gst_element_get_name(src), gst_element_get_name(sink));
sinkpads = gst_element_get_pad_list(sink);
while (sinkpads) {
GstPad *sinkpad = (GstPad *)sinkpads->data;
- guint16 sinktype = GPOINTER_TO_INT (sinkpad->types->data);
// if we have a match, connect the pads
- if (sinktype == type &&
- sinkpad->direction == GST_PAD_SINK &&
- !GST_PAD_CONNECTED(sinkpad))
+ if (sinkpad->direction == GST_PAD_SINK &&
+ !GST_PAD_CONNECTED(sinkpad) &&
+ gst_caps_check_compatibility (pad->caps, sinkpad->caps))
{
gst_pad_connect(pad, sinkpad);
- g_print("gstpipeline: autoconnect pad \"%s\" (%d) in element %s <-> ", pad->name,
- type, gst_element_get_name(src));
- g_print("pad \"%s\" (%d) in element %s\n", sinkpad->name, sinktype,
+ g_print("gstpipeline: autoconnect pad \"%s\" in element %s <-> ", pad->name,
+ gst_element_get_name(src));
+ g_print("pad \"%s\" in element %s\n", sinkpad->name,
gst_element_get_name(sink));
connected = TRUE;
break;
}
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
gst_pipeline_pads_autoplug (GstElement *src, GstElement *sink)
{
- GList *srcpads, *sinkpads;
+ GList *srcpads;
gboolean connected = FALSE;
srcpads = gst_element_get_pad_list(src);
- while (srcpads) {
+ while (srcpads && !connected) {
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)) {
-
- 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);
- }
- }
+
+ connected = gst_pipeline_pads_autoplug_func (src, srcpad, sink);
+
srcpads = g_list_next(srcpads);
}
-end:
if (!connected) {
g_print("gstpipeline: delaying pad connections for \"%s\" to \"%s\"\n",
gst_element_get_name(src), gst_element_get_name(sink));
factory = gst_element_get_factory(pipeline->src);
- src_types = factory->src_types;
+ src_types = factory->src_caps;
if (src_types == NULL) {
g_print("GstPipeline: source \"%s\" has no MIME type, running typefind...\n",
gst_element_get_name(pipeline->src));
pad = (GstPad *)pads->data;
if (pad->direction == GST_PAD_SINK) {
+ /*
GList *types = gst_pad_get_type_ids(pad);
if (types) {
sink_type = GPOINTER_TO_INT (types->data);
break;
}
else
+ */
sink_type = 0;
}
while (sinkpads) {
sinkpad = (GstPad *)sinkpads->data;
+ /*
// FIXME connect matching pads, not just the first one...
if (sinkpad->direction == GST_PAD_SINK &&
!GST_PAD_CONNECTED(sinkpad)) {
gst_pad_set_type_id (gst_element_get_pad(queue, "sink"), sinktype);
break;
}
+ */
sinkpads = g_list_next(sinkpads);
}
gst_pipeline_pads_autoplug(thesrcelement, queue);
_gst_libraries = NULL;
_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 */
#ifdef PLUGINS_USE_SRCDIR
PLUGINS_SRCDIR "/gst/elements");
_gst_plugin_paths = g_list_append(_gst_plugin_paths,
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 */
doc = xmlParseFile("/etc/gstreamer/reg.xml");
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:
* @name: name of plugin to load
GModule *module;
GstPluginInitFunc initfunc;
GstPlugin *plugin;
- GList *plugins;
struct stat file_status;
if (g_module_supported() == 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)) {
// g_print("problem opening file %s\n",name);
return FALSE;
if (module != NULL) {
if (g_module_symbol(module,"plugin_init",(gpointer *)&initfunc)) {
if ((plugin = (initfunc)(module))) {
- GList *factories;
g_print("gstplugin: plugin %s loaded\n", plugin->name);
plugin->filename = g_strdup(name);
plugin->loaded = TRUE;
_gst_modules = g_list_append(_gst_modules,module);
_gst_modules_seqno++;
- _gst_plugins = g_list_append(_gst_plugins,plugin);
+ _gst_plugins = g_list_prepend(_gst_plugins,plugin);
_gst_plugins_seqno++;
- factories = plugin->elements;
- while (factories) {
- gst_elementfactory_register((GstElementFactory*)(factories->data));
- factories = g_list_next(factories);
- }
return TRUE;
}
}
plugin->longname = NULL;
plugin->types = NULL;
plugin->elements = NULL;
- plugin->loaded = FALSE;
+ plugin->loaded = TRUE;
return plugin;
}
factories = ((GstPlugin *)(plugins->data))->elements;
while (factories) {
factory = (GstElementFactory*)(factories->data);
- if (!strcmp(factory->name,name))
+ if (!strcmp(factory->name, name))
return (GstElementFactory*)(factory);
factories = g_list_next(factories);
}
factory = (GstElementFactory*)(factories->data);
if (!strcmp(factory->name,name)) {
if (!plugin->loaded) {
+ gchar *filename = g_strdup (plugin->filename);
g_print("gstplugin: loading element factory %s from plugin %s\n", name, plugin->name);
- _gst_plugins = g_list_remove(_gst_plugins, plugin);
- if (!gst_plugin_load_absolute(plugin->filename)) {
+ gst_plugin_remove(plugin);
+ if (!gst_plugin_load_absolute(filename)) {
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;
}
factory = (GstTypeFactory*)(factories->data);
if (!strcmp(factory->mime,mime)) {
if (!plugin->loaded) {
+ gchar *filename = g_strdup (plugin->filename);
g_print("gstplugin: loading type factory for \"%s\" from plugin %s\n", mime, plugin->name);
- _gst_plugins = g_list_remove(_gst_plugins, plugin);
- if (!gst_plugin_load_absolute(plugin->filename)) {
+ gst_plugin_remove(plugin);
+ if (!gst_plugin_load_absolute(filename)) {
g_print("gstplugin: error loading type factory \"%s\" from plugin %s\n", mime, plugin->name);
}
+ g_free (filename);
}
return;
}
// g_print("adding factory to plugin\n");
plugin->elements = g_list_append(plugin->elements,factory);
+ gst_elementfactory_register (factory);
}
/**
while (kinderen) {
if (!strcmp(kinderen->name, "plugin")) {
xmlNodePtr field = kinderen->childs;
- GstPlugin *plugin = (GstPlugin *)g_malloc(sizeof(GstPlugin));
+ GstPlugin *plugin = g_new0 (GstPlugin, 1);
plugin->elements = NULL;
plugin->types = NULL;
plugin->loaded = FALSE;
}
else if (!strcmp(field->name, "element")) {
GstElementFactory *factory = gst_elementfactory_load_thyself(field);
- plugin->elements = g_list_prepend(plugin->elements, factory);
+ gst_plugin_add_factory (plugin, factory);
elementcount++;
}
else if (!strcmp(field->name, "type")) {
GstTypeFactory *factory = gst_typefactory_load_thyself(field);
- gst_type_register(factory);
- plugin->types = g_list_prepend(plugin->types, factory);
+ gst_plugin_add_type (plugin, factory);
+ elementcount++;
typecount++;
}
void _gst_plugin_initialize (void);
GstPlugin* gst_plugin_new (gchar *name);
+void gst_plugin_set_longname (GstPlugin *plugin, gchar *longname);
void gst_plugin_load_all (void);
gboolean gst_plugin_load (gchar *name);
-gboolean gst_library_load (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_type (GstPlugin *plugin, GstTypeFactory *factory);
GstPlugin* gst_plugin_find (const gchar *name);
GList* gst_plugin_get_list (void);
+
GstElementFactory* gst_plugin_find_elementfactory (gchar *name);
GstElementFactory* gst_plugin_load_elementfactory (gchar *name);
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 */
static gboolean
gst_props_entry_check_list_compatibility (GstPropsEntry *entry1, GstPropsEntry *entry2)
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;
+}
+
GstProps* gst_props_register (GstPropsFactory factory);
-void gst_props_dump (GstProps *props);
-
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__ */
GList *_gst_types;
guint16 _gst_maxtype;
+struct _GstTypeFindInfo {
+ GstTypeFindFunc typefindfunc; /* typefind function */
+
+ GstPlugin *plugin; /* the plugin with this typefind function */
+};
+
#define MAX_COST 999999
struct _gst_type_node
type->id = _gst_maxtype++;
type->mime = factory->mime;
type->exts = factory->exts;
- type->typefindfunc = factory->typefindfunc;
+ //type->typefindfunc = factory->typefindfunc;
type->srcs = NULL;
type->sinks = NULL;
type->converters = g_hash_table_new (NULL, NULL);
/* FIXME: do extension merging here, not that easy */
/* if there is no existing typefind function, try to use new one */
+ /*
if ((type->typefindfunc == gst_type_typefind_dummy ||
type->typefindfunc == NULL) && factory->typefindfunc)
type->typefindfunc = factory->typefindfunc;
+ */
}
return id;
guint16
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);
}
}
}
-/**
- * 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)
+static void
+gst_type_handle_src (guint16 id, GstElementFactory *src, gboolean remove)
{
GList *walk;
GstType *type = gst_type_find_by_id (id);
g_return_if_fail (type != NULL);
g_return_if_fail (src != NULL);
- type->srcs = g_list_prepend (type->srcs, src);
- gst_elementfactory_add_src (src, id);
+ g_print ("gsttype: add src %d, \"%s\"\n", id, src->name);
+ 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_types;
+ walk = src->sink_caps;
while (walk) {
- GstType *type2 = gst_type_find_by_id (GPOINTER_TO_UINT (walk->data));
- GList *converters = (GList *)g_hash_table_lookup (type2->converters, GUINT_TO_POINTER ((guint)id));
- GList *orig = converters;
+ GstType *type2;
+ GList *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) {
if (converters->data == src) {
}
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);
}
}
/**
- * gst_type_add_sink:
- * @id: the type id to add the sink factory to
- * @sink: the sink factory for the type
+ * gst_type_add_src:
+ * @id: the type id to add the source factory to
+ * @src: the source factory for the type
*
- * register the sink factory as being a sink for the
+ * 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_add_sink (guint16 id, GstElementFactory *sink)
+_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);
- type->sinks = g_list_prepend (type->sinks, sink);
- gst_elementfactory_add_sink (sink, id);
+ 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_types;
+ walk = sink->src_caps;
while (walk) {
GList *converters = (GList *)g_hash_table_lookup (type->converters, walk->data);
}
if (!converters) {
- orig = g_list_prepend (orig, sink);
+ if (remove)
+ orig = g_list_remove (orig, sink);
+ else
+ orig = g_list_prepend (orig, sink);
g_hash_table_insert (type->converters, walk->data, orig);
}
}
/**
+ * gst_type_add_sink:
+ * @id: the type id to add the sink factory to
+ * @sink: the sink factory for the type
+ *
+ * register the sink factory as being a sink for the
+ * given type id
+ */
+void
+_gst_type_add_sink (guint16 id, GstElementFactory *sink)
+{
+ gst_type_handle_sink (id, sink, FALSE);
+}
+
+/**
+ * gst_type_remove_sink:
+ * @id: the type id to remove the sink factory from
+ * @sink: the sink factory for the type
+ *
+ * remove the sink factory as being a sink for the
+ * given type id
+ */
+void
+_gst_type_remove_sink (guint16 id, GstElementFactory *sink)
+{
+ gst_type_handle_sink (id, sink, TRUE);
+}
+
+/**
* gst_type_get_srcs:
* @id: the id to fetch the source factories for
*
guint16 typeid;
g_print ("gsttype: need to load typefind function\n");
- type->typefindfunc = NULL;
+ type->typefindfuncs = NULL;
gst_plugin_load_typefactory (type->mime);
typeid = gst_type_find_by_mime (type->mime);
type = gst_type_find_by_id (typeid);
+ /*
if (type->typefindfunc) {
return type->typefindfunc (buffer, type);
}
+ */
return FALSE;
}
factory->exts = g_strdup (xmlNodeGetContent (field));
}
else if (!strcmp (field->name, "typefind")) {
- factory->typefindfunc = gst_type_typefind_dummy;
+ //factory->typefindfunc = gst_type_typefind_dummy;
}
field = field->next;
}
gchar *mime; /* MIME type */
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 *sinks; /* list of sink objects for type */
guint16 gst_type_find_by_ext (gchar *ext);
/* add src or sink object */
-void gst_type_add_src (guint16 id, GstElementFactory *src);
-void gst_type_add_sink (guint16 id, GstElementFactory *sink);
+void _gst_type_add_src (guint16 id, GstElementFactory *src);
+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 */
GList* gst_type_get_srcs (guint16 id);
GList* gst_type_get_sinks (guint16 id);
glade_init();
glade_gnome_init();
+ gst_type_dump ();
+
play = gst_media_play_new ();
if (argc > 1) {
/* 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())
static GtkType
static GstSinkClass *parent_class = NULL;
static guint gst_audiosink_signals[LAST_SIGNAL] = { 0 };
-static guint16 gst_audiosink_type_audio = 0;
+static GstCaps *gst_audiosink_sink_caps = NULL;
GtkType
gst_audiosink_get_type (void)
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;
}
{
audiosink->sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
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);
gboolean
gst_audiosink_factory_init (GstElementFactory *factory)
{
- if (!gst_audiosink_type_audio)
- gst_audiosink_type_audio = gst_type_find_by_mime ("audio/raw");
-
- gst_type_add_sink (gst_audiosink_type_audio, factory);
+ gst_audiosink_sink_caps = gst_caps_register (audiosink_sink_caps);
return TRUE;
}
-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
CFLAGS = -Wall
int main(int argc,char *argv[])
{
gboolean testret;
+ xmlDocPtr doc;
+ xmlNodePtr parent;
+
+ doc = xmlNewDoc ("1.0");
+ doc->root = xmlNewDocNode (doc, NULL, "Capabilities", NULL);
_gst_type_initialize ();
sinkcaps = gst_caps_register (mpeg2dec_sink_caps);
- g_print ("caps 1:\n");
- gst_caps_dump (sinkcaps);
+ parent = xmlNewChild (doc->root, NULL, "Capabilities1", NULL);
+ gst_caps_save_thyself (sinkcaps, parent);
+
rawcaps = gst_caps_register (mpeg2dec_src_caps);
- g_print ("caps 2:\n");
- gst_caps_dump (rawcaps);
+ parent = xmlNewChild (doc->root, NULL, "Capabilities2", NULL);
+ gst_caps_save_thyself (rawcaps, parent);
+
rawcaps2 = gst_caps_register (raw_sink_caps);
- g_print ("caps 3:\n");
- gst_caps_dump (rawcaps2);
+ parent = xmlNewChild (doc->root, NULL, "Capabilities3", NULL);
+ gst_caps_save_thyself (rawcaps2, parent);
+
mp1parsecaps = gst_caps_register (mp1parse_src_caps);
- g_print ("caps 4:\n");
- gst_caps_dump (mp1parsecaps);
+ parent = xmlNewChild (doc->root, NULL, "Capabilities4", NULL);
+ gst_caps_save_thyself (mp1parsecaps, parent);
+
rawcaps3 = gst_caps_register (raw2_sink_caps);
- g_print ("caps 5:\n");
- gst_caps_dump (rawcaps3);
+ parent = xmlNewChild (doc->root, NULL, "Capabilities5", NULL);
+ gst_caps_save_thyself (rawcaps3, parent);
+
+ xmlDocDump(stdout, doc);
testret = gst_caps_check_compatibility (mp1parsecaps, rawcaps);
g_print ("4 <-> 2 == %d (invalid, wrong major type)\n", testret);
pipeline = GST_BIN(gst_pipeline_new("pipeline"));
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");
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");
g_return_val_if_fail(3,thr2 != NULL);
fprintf(stderr,"QUEUE: fakesrc\n");
gst_element_connect(queue,"src",thr2,"sink");
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);
if (GST_STATE(src) != GST_STATE_PLAYING) fprintf(stderr,"error: state not set\n");