diff --git a/examples/xml/.gitignore b/examples/xml/.gitignore new file mode 100644 index 0000000000..be5981bce1 --- /dev/null +++ b/examples/xml/.gitignore @@ -0,0 +1,2 @@ +Makefile +queue4 diff --git a/examples/xml/Makefile b/examples/xml/Makefile new file mode 100644 index 0000000000..5f74b38f7d --- /dev/null +++ b/examples/xml/Makefile @@ -0,0 +1,15 @@ + +CC = gcc + +all: createxml runxml + +createxml: createxml.c + $(CC) -Wall `gstreamer-config --cflags --libs` createxml.c -o createxml + +runxml: runxml.c + $(CC) -Wall `gstreamer-config --cflags --libs` runxml.c -o runxml + +clean: + rm -f *.o createxml runxml + + diff --git a/examples/xml/createxml.c b/examples/xml/createxml.c new file mode 100644 index 0000000000..36810a823f --- /dev/null +++ b/examples/xml/createxml.c @@ -0,0 +1,73 @@ +#include + +gboolean playing; + +int main(int argc,char *argv[]) +{ + GstElement *disksrc, *audiosink, *queue, *queue2, *parse, *decode; + GstElement *bin; + GstElement *thread, *thread2; + + if (argc != 2) { + g_print("usage: %s \n", argv[0]); + exit(-1); + } + + gst_init(&argc,&argv); + + /* create a new thread to hold the elements */ + thread = gst_thread_new("thread"); + g_assert(thread != NULL); + thread2 = gst_thread_new("thread2"); + g_assert(thread2 != NULL); + + /* create a new bin to hold the elements */ + bin = gst_bin_new("bin"); + g_assert(bin != NULL); + + /* create a disk reader */ + disksrc = gst_elementfactory_make("disksrc", "disk_source"); + g_assert(disksrc != NULL); + gtk_object_set(GTK_OBJECT(disksrc),"location", argv[1],NULL); + + queue = gst_elementfactory_make("queue", "queue"); + queue2 = gst_elementfactory_make("queue", "queue2"); + + /* and an audio sink */ + audiosink = gst_elementfactory_make("audiosink", "play_audio"); + g_assert(audiosink != NULL); + + parse = gst_elementfactory_make("mp3parse", "parse"); + decode = gst_elementfactory_make("mpg123", "decode"); + + /* add objects to the main bin */ + gst_bin_add(GST_BIN(bin), disksrc); + gst_bin_add(GST_BIN(bin), queue); + + gst_bin_add(GST_BIN(thread), parse); + gst_bin_add(GST_BIN(thread), decode); + gst_bin_add(GST_BIN(thread), queue2); + + gst_bin_add(GST_BIN(thread2), audiosink); + + gst_pad_connect(gst_element_get_pad(disksrc,"src"), + gst_element_get_pad(queue,"sink")); + + gst_pad_connect(gst_element_get_pad(queue,"src"), + gst_element_get_pad(parse,"sink")); + gst_pad_connect(gst_element_get_pad(parse,"src"), + gst_element_get_pad(decode,"sink")); + gst_pad_connect(gst_element_get_pad(decode,"src"), + gst_element_get_pad(queue2,"sink")); + + gst_pad_connect(gst_element_get_pad(queue2,"src"), + gst_element_get_pad(audiosink,"sink")); + + gst_bin_add(GST_BIN(bin), thread); + gst_bin_add(GST_BIN(bin), thread2); + + xmlSaveFile("xmlTest.gst", gst_xml_write(GST_ELEMENT(bin))); + + exit(0); +} + diff --git a/examples/xml/runxml.c b/examples/xml/runxml.c new file mode 100644 index 0000000000..b3f8739cf1 --- /dev/null +++ b/examples/xml/runxml.c @@ -0,0 +1,37 @@ +#include + +gboolean playing; + +/* eos will be called when the src element has an end of stream */ +void eos(GstSrc *src, gpointer data) +{ + g_print("have eos, quitting\n"); + + playing = FALSE; +} + +int main(int argc,char *argv[]) +{ + GstXML *xml; + GstElement *bin; + + gst_init(&argc,&argv); + + xml = gst_xml_new("xmlTest.gst", NULL); + + bin = gst_xml_get_element(xml, "bin"); + + gst_element_set_state(bin, GST_STATE_READY); + gst_element_set_state(bin, GST_STATE_PLAYING); + + playing = TRUE; + + while (playing) { + gst_bin_iterate(GST_BIN(bin)); + } + + gst_element_set_state(bin, GST_STATE_NULL); + + exit(0); +} + diff --git a/gst/gstbin.c b/gst/gstbin.c index 9c038868d4..38ad526966 100644 --- a/gst/gstbin.c +++ b/gst/gstbin.c @@ -108,6 +108,7 @@ gst_bin_class_init(GstBinClass *klass) { gstelement_class->change_state = gst_bin_change_state; gstelement_class->save_thyself = gst_bin_save_thyself; + gstelement_class->elementfactory = gst_elementfactory_find("bin"); gtkobject_class->destroy = gst_bin_real_destroy; } diff --git a/gst/gstconnection.h b/gst/gstconnection.h index a98ca1b04e..cde0cb1366 100644 --- a/gst/gstconnection.h +++ b/gst/gstconnection.h @@ -39,7 +39,7 @@ extern "C" { #define GST_IS_CONNECTION(obj) \ (GTK_CHECK_TYPE((obj),GST_TYPE_CONNECTION)) #define GST_IS_CONNECTION_CLASS(obj) \ - (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_CONNECTION))) + (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_CONNECTION)) typedef struct _GstConnection GstConnection; typedef struct _GstConnectionClass GstConnectionClass; diff --git a/gst/gstelementfactory.c b/gst/gstelementfactory.c index 6debdf435d..d1d6796bcb 100644 --- a/gst/gstelementfactory.c +++ b/gst/gstelementfactory.c @@ -120,6 +120,9 @@ GstElement *gst_elementfactory_create(GstElementFactory *factory, factory = gst_plugin_load_elementfactory(factory->name); + if (factory->type == 0) { + factory = gst_elementfactory_find(name); + } g_return_val_if_fail(factory->type != 0, NULL); // create an instance of the element diff --git a/gst/gstpipeline.c b/gst/gstpipeline.c index 3b520842cc..b5f1289e1b 100644 --- a/gst/gstpipeline.c +++ b/gst/gstpipeline.c @@ -88,6 +88,7 @@ gst_pipeline_class_init(GstPipelineClass *klass) { parent_class = gtk_type_class(gst_bin_get_type()); gstelement_class->change_state = gst_pipeline_change_state; + gstelement_class->elementfactory = gst_elementfactory_find("pipeline"); } static void gst_pipeline_init(GstPipeline *pipeline) { @@ -300,7 +301,7 @@ gboolean gst_pipeline_autoplug(GstPipeline *pipeline) { GstElement *element, *srcelement = NULL, *sinkelement= NULL; GList *factories; GstElementFactory *factory; - GList *src_types, *sink_types; + GList *src_types; guint16 src_type = 0, sink_type = 0; gboolean complete = FALSE; @@ -367,27 +368,6 @@ gboolean gst_pipeline_autoplug(GstPipeline *pipeline) { pads = g_list_next(pads); } - /* - if (GST_IS_SINK(element)) { - g_print("GstPipeline: found sink \"%s\"\n", gst_element_get_name(element)); - - sinkelement = element; - factory = gst_element_get_factory(element); - - sink_types = factory->sink_types; - if (sink_types == NULL) { - g_print("GstPipeline: sink \"%s\" has no MIME type, can't autoplug \n", - gst_element_get_name(element)); - return FALSE; - } - else { - sink_type = GPOINTER_TO_UINT(sink_types->data); - g_print("GstPipeline: sink \"%s\" has MIME type %d \n", - gst_element_get_name(element), sink_type); - } - } - */ - elements = g_list_next(elements); } diff --git a/gst/gsttee.h b/gst/gsttee.h index 1953325bb3..1e819248a9 100644 --- a/gst/gsttee.h +++ b/gst/gsttee.h @@ -38,7 +38,7 @@ extern "C" { #define GST_IS_TEE(obj) \ (GTK_CHECK_TYPE((obj),GST_TYPE_TEE)) #define GST_IS_TEE_CLASS(obj) \ - (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_TEE))) + (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_TEE)) typedef struct _GstTee GstTee; typedef struct _GstTeeClass GstTeeClass; diff --git a/gst/gstthread.c b/gst/gstthread.c index 5ad60ea6af..c26f018e1e 100644 --- a/gst/gstthread.c +++ b/gst/gstthread.c @@ -100,11 +100,13 @@ gst_thread_class_init(GstThreadClass *klass) { gstelement_class->change_state = gst_thread_change_state; gstelement_class->save_thyself = gst_thread_save_thyself; + gstelement_class->elementfactory = gst_elementfactory_find("thread"); gstbin_class->create_plan = gst_thread_create_plan_dummy; gtkobject_class->set_arg = gst_thread_set_arg; gtkobject_class->get_arg = gst_thread_get_arg; + } static void gst_thread_init(GstThread *thread) { diff --git a/gst/gstthread.h b/gst/gstthread.h index 7e221f2632..ceac92dcdc 100644 --- a/gst/gstthread.h +++ b/gst/gstthread.h @@ -49,7 +49,7 @@ typedef enum { #define GST_IS_THREAD(obj) \ (GTK_CHECK_TYPE((obj),GST_TYPE_THREAD)) #define GST_IS_THREAD_CLASS(obj) \ - (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_THREAD))) + (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_THREAD)) typedef struct _GstThread GstThread; typedef struct _GstThreadClass GstThreadClass; diff --git a/gst/gstxml.c b/gst/gstxml.c index f4321000f6..c4ef8f2bc0 100644 --- a/gst/gstxml.c +++ b/gst/gstxml.c @@ -19,11 +19,43 @@ #include +static void gst_xml_class_init(GstXMLClass *klass); +static void gst_xml_init(GstXML *xml); + +static GstObjectClass *parent_class = NULL; + +GtkType gst_xml_get_type(void) { + static GtkType xml_type = 0; + + if (!xml_type) { + static const GtkTypeInfo xml_info = { + "GstXML", + sizeof(GstElement), + sizeof(GstElementClass), + (GtkClassInitFunc)gst_xml_class_init, + (GtkObjectInitFunc)gst_xml_init, + (GtkArgSetFunc)NULL, + (GtkArgGetFunc)NULL, + (GtkClassInitFunc)NULL, + }; + xml_type = gtk_type_unique(GST_TYPE_XML,&xml_info); + } + return xml_type; +} + +static void +gst_xml_class_init(GstXMLClass *klass) { + parent_class = gtk_type_class(GST_TYPE_OBJECT); +} + +static void gst_xml_init(GstXML *xml) { +} + /** * gst_xml_write: * @element: The element to write out * - * converts the given elkement into an XML presentation + * converts the given element into an XML presentation * * Returns: a pointer to an XML document */ @@ -37,3 +69,61 @@ xmlDocPtr gst_xml_write(GstElement *element) { return doc; } + +/** + * gst_xml_new: + * @fname: The filename with the xml description + * @root: The name of the root object to build + * + * Creates a new GstXML object (and the corresponding elements) from + * the XML file fname. Optionally it will only build the element from + * the element node root (if it is not NULL). This feature is useful + * if you only want to build a specific element from an XML file + * but not the pipeline it is embedded in. Note also that the XML parse + * tree is cached to speed up creating another GstXML object for + * the same file + * + * Returns: a pointer to a new GstElement + */ +GstXML *gst_xml_new(const guchar *fname, const guchar *root) { + xmlDocPtr doc; + GstXML *xml; + + g_return_val_if_fail(fname != NULL, NULL); + + doc = xmlParseFile(fname); + + if (!doc) { + g_print("gstxml: XML file \"%s\" could not be read\n", fname); + return NULL; + } + if (strcmp(doc->root->name, "GST-Pipeline")) { + g_print("gstxml: XML file \"%s\" is in wrong format\n", fname); + return NULL; + } + + xml = GST_XML(gtk_type_new(GST_TYPE_XML)); + + return xml; +} + +/** + * gst_xml_get_element: + * @xml: The GstXML to get the element from + * @name: The name of element to retreive + * + * This function is used to get a pointer to the GStElement corresponding + * to name in the pipeline description. You would use this if you have + * to do anything to the element after loading. + * + * Returns: a pointer to a new GstElement + */ +GstElement *gst_xml_get_element(GstXML *xml, const guchar *name) { + + g_return_val_if_fail(xml != NULL, NULL); + g_return_val_if_fail(name != NULL, NULL); + + g_print("gstxml: getting element \"%s\" (implement me)\n", name); + + return NULL; +} diff --git a/gst/gstxml.h b/gst/gstxml.h index e2538810e3..a0adf592ee 100644 --- a/gst/gstxml.h +++ b/gst/gstxml.h @@ -24,7 +24,43 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define GST_TYPE_XML \ + (gst_object_get_type()) +#define GST_XML(obj) \ + (GTK_CHECK_CAST((obj),GST_TYPE_XML,GstXML)) +#define GST_XML_CLASS(klass) \ + (GTK_CHECK_CLASS_CAST((klass),GST_TYPE_XML,GstXMLClass)) +#define GST_IS_XML(obj) \ + (GTK_CHECK_TYPE((obj),GST_TYPE_XML)) +#define GST_IS_XML_CLASS(obj) \ + (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_XML)) + +typedef struct _GstXML GstXML; +typedef struct _GstXMLClass GstXMLClass; + +struct _GstXML { + GtkObject object; +}; + +struct _GstXMLClass { + GtkObjectClass parent_class; +}; + +GtkType gst_xml_get_type(void); + + /* create an XML document out of a pipeline */ xmlDocPtr gst_xml_write(GstElement *element); +GstXML *gst_xml_new(const guchar *fname, const guchar *root); + +GstElement *gst_xml_get_element(GstXML *xml, const guchar *name); +#ifdef __cplusplus +} +#endif /* __cplusplus */ + #endif /* __GST_XML_H__ */ diff --git a/tests/old/examples/xml/.gitignore b/tests/old/examples/xml/.gitignore new file mode 100644 index 0000000000..be5981bce1 --- /dev/null +++ b/tests/old/examples/xml/.gitignore @@ -0,0 +1,2 @@ +Makefile +queue4 diff --git a/tests/old/examples/xml/Makefile b/tests/old/examples/xml/Makefile new file mode 100644 index 0000000000..5f74b38f7d --- /dev/null +++ b/tests/old/examples/xml/Makefile @@ -0,0 +1,15 @@ + +CC = gcc + +all: createxml runxml + +createxml: createxml.c + $(CC) -Wall `gstreamer-config --cflags --libs` createxml.c -o createxml + +runxml: runxml.c + $(CC) -Wall `gstreamer-config --cflags --libs` runxml.c -o runxml + +clean: + rm -f *.o createxml runxml + + diff --git a/tests/old/examples/xml/createxml.c b/tests/old/examples/xml/createxml.c new file mode 100644 index 0000000000..36810a823f --- /dev/null +++ b/tests/old/examples/xml/createxml.c @@ -0,0 +1,73 @@ +#include + +gboolean playing; + +int main(int argc,char *argv[]) +{ + GstElement *disksrc, *audiosink, *queue, *queue2, *parse, *decode; + GstElement *bin; + GstElement *thread, *thread2; + + if (argc != 2) { + g_print("usage: %s \n", argv[0]); + exit(-1); + } + + gst_init(&argc,&argv); + + /* create a new thread to hold the elements */ + thread = gst_thread_new("thread"); + g_assert(thread != NULL); + thread2 = gst_thread_new("thread2"); + g_assert(thread2 != NULL); + + /* create a new bin to hold the elements */ + bin = gst_bin_new("bin"); + g_assert(bin != NULL); + + /* create a disk reader */ + disksrc = gst_elementfactory_make("disksrc", "disk_source"); + g_assert(disksrc != NULL); + gtk_object_set(GTK_OBJECT(disksrc),"location", argv[1],NULL); + + queue = gst_elementfactory_make("queue", "queue"); + queue2 = gst_elementfactory_make("queue", "queue2"); + + /* and an audio sink */ + audiosink = gst_elementfactory_make("audiosink", "play_audio"); + g_assert(audiosink != NULL); + + parse = gst_elementfactory_make("mp3parse", "parse"); + decode = gst_elementfactory_make("mpg123", "decode"); + + /* add objects to the main bin */ + gst_bin_add(GST_BIN(bin), disksrc); + gst_bin_add(GST_BIN(bin), queue); + + gst_bin_add(GST_BIN(thread), parse); + gst_bin_add(GST_BIN(thread), decode); + gst_bin_add(GST_BIN(thread), queue2); + + gst_bin_add(GST_BIN(thread2), audiosink); + + gst_pad_connect(gst_element_get_pad(disksrc,"src"), + gst_element_get_pad(queue,"sink")); + + gst_pad_connect(gst_element_get_pad(queue,"src"), + gst_element_get_pad(parse,"sink")); + gst_pad_connect(gst_element_get_pad(parse,"src"), + gst_element_get_pad(decode,"sink")); + gst_pad_connect(gst_element_get_pad(decode,"src"), + gst_element_get_pad(queue2,"sink")); + + gst_pad_connect(gst_element_get_pad(queue2,"src"), + gst_element_get_pad(audiosink,"sink")); + + gst_bin_add(GST_BIN(bin), thread); + gst_bin_add(GST_BIN(bin), thread2); + + xmlSaveFile("xmlTest.gst", gst_xml_write(GST_ELEMENT(bin))); + + exit(0); +} + diff --git a/tests/old/examples/xml/runxml.c b/tests/old/examples/xml/runxml.c new file mode 100644 index 0000000000..b3f8739cf1 --- /dev/null +++ b/tests/old/examples/xml/runxml.c @@ -0,0 +1,37 @@ +#include + +gboolean playing; + +/* eos will be called when the src element has an end of stream */ +void eos(GstSrc *src, gpointer data) +{ + g_print("have eos, quitting\n"); + + playing = FALSE; +} + +int main(int argc,char *argv[]) +{ + GstXML *xml; + GstElement *bin; + + gst_init(&argc,&argv); + + xml = gst_xml_new("xmlTest.gst", NULL); + + bin = gst_xml_get_element(xml, "bin"); + + gst_element_set_state(bin, GST_STATE_READY); + gst_element_set_state(bin, GST_STATE_PLAYING); + + playing = TRUE; + + while (playing) { + gst_bin_iterate(GST_BIN(bin)); + } + + gst_element_set_state(bin, GST_STATE_NULL); + + exit(0); +} +