diff --git a/docs/manual/highlevel-xml.xml b/docs/manual/highlevel-xml.xml index cab7182719..c9aeba8c14 100644 --- a/docs/manual/highlevel-xml.xml +++ b/docs/manual/highlevel-xml.xml @@ -17,9 +17,9 @@ Turning GstElements into XML - We create a simple pipeline and save it to disk with gst_xml_write (). The following - code constructs an mp3 player pipeline with two threads and finaly writes it to disk. - use this program with one argument: the mp3 file on disk. + We create a simple pipeline and write it to stdout with gst_xml_write_file (). The following + code constructs an mp3 player pipeline with two threads and then writes out the XML both to + stdout and to a file. Use this program with one argument: the mp3 file on disk. @@ -31,7 +31,7 @@ gboolean playing; int main (int argc, char *argv[]) { - GstElement *filesrc, *audiosink, *queue, *queue2, *parse, *decode; + GstElement *filesrc, *osssink, *queue, *queue2, *parse, *decode; GstElement *bin; GstElement *thread, *thread2; @@ -61,40 +61,40 @@ main (int argc, char *argv[]) queue2 = gst_elementfactory_make ("queue", "queue2"); /* and an audio sink */ - audiosink = gst_elementfactory_make ("audiosink", "play_audio"); - g_assert (audiosink != NULL); + osssink = gst_elementfactory_make ("osssink", "play_audio"); + g_assert (osssink != NULL); - parse = gst_elementfactory_make ("mp3parse", "parse"); - decode = gst_elementfactory_make ("mpg123", "decode"); + decode = gst_elementfactory_make ("mad", "decode"); + g_assert (decode != NULL); /* add objects to the main bin */ gst_bin_add (GST_BIN (bin), filesrc); 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_bin_add (GST_BIN (thread2), osssink); gst_pad_connect (gst_element_get_pad (filesrc,"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_element_get_pad (osssink,"sink")); gst_bin_add (GST_BIN (bin), thread); gst_bin_add (GST_BIN (bin), thread2); - // write the bin to disk - xmlSaveFile ("xmlTest.gst", gst_xml_write (GST_ELEMENT (bin))); + /* write the bin to stdout */ + gst_xml_write_file (GST_ELEMENT (bin), stdout); + + /* write the bin to a file */ + gst_xml_write_file (GST_ELEMENT (bin), fopen ("xmlTest.gst", "w")); exit (0); } @@ -103,12 +103,12 @@ main (int argc, char *argv[]) The most important line is: - xmlSaveFile ("xmlTest.gst", gst_xml_write (GST_ELEMENT (bin))); + gst_xml_write_file (GST_ELEMENT (bin), stdout); - gst_xml_write () will turn the given element into and xmlDocPtr that - can be saved with the xmlSaveFile () function found in the gnome-xml - package. The result is an XML file named xmlTest.gst. + gst_xml_write_file () will turn the given element into an xmlDocPtr that + is then formatted and saved to a file. To save to disk, pass the result + of a fopen(2) as the second argument. The complete element hierarchy will be saved along with the inter element diff --git a/docs/manual/xml.xml b/docs/manual/xml.xml index cab7182719..c9aeba8c14 100644 --- a/docs/manual/xml.xml +++ b/docs/manual/xml.xml @@ -17,9 +17,9 @@ Turning GstElements into XML - We create a simple pipeline and save it to disk with gst_xml_write (). The following - code constructs an mp3 player pipeline with two threads and finaly writes it to disk. - use this program with one argument: the mp3 file on disk. + We create a simple pipeline and write it to stdout with gst_xml_write_file (). The following + code constructs an mp3 player pipeline with two threads and then writes out the XML both to + stdout and to a file. Use this program with one argument: the mp3 file on disk. @@ -31,7 +31,7 @@ gboolean playing; int main (int argc, char *argv[]) { - GstElement *filesrc, *audiosink, *queue, *queue2, *parse, *decode; + GstElement *filesrc, *osssink, *queue, *queue2, *parse, *decode; GstElement *bin; GstElement *thread, *thread2; @@ -61,40 +61,40 @@ main (int argc, char *argv[]) queue2 = gst_elementfactory_make ("queue", "queue2"); /* and an audio sink */ - audiosink = gst_elementfactory_make ("audiosink", "play_audio"); - g_assert (audiosink != NULL); + osssink = gst_elementfactory_make ("osssink", "play_audio"); + g_assert (osssink != NULL); - parse = gst_elementfactory_make ("mp3parse", "parse"); - decode = gst_elementfactory_make ("mpg123", "decode"); + decode = gst_elementfactory_make ("mad", "decode"); + g_assert (decode != NULL); /* add objects to the main bin */ gst_bin_add (GST_BIN (bin), filesrc); 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_bin_add (GST_BIN (thread2), osssink); gst_pad_connect (gst_element_get_pad (filesrc,"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_element_get_pad (osssink,"sink")); gst_bin_add (GST_BIN (bin), thread); gst_bin_add (GST_BIN (bin), thread2); - // write the bin to disk - xmlSaveFile ("xmlTest.gst", gst_xml_write (GST_ELEMENT (bin))); + /* write the bin to stdout */ + gst_xml_write_file (GST_ELEMENT (bin), stdout); + + /* write the bin to a file */ + gst_xml_write_file (GST_ELEMENT (bin), fopen ("xmlTest.gst", "w")); exit (0); } @@ -103,12 +103,12 @@ main (int argc, char *argv[]) The most important line is: - xmlSaveFile ("xmlTest.gst", gst_xml_write (GST_ELEMENT (bin))); + gst_xml_write_file (GST_ELEMENT (bin), stdout); - gst_xml_write () will turn the given element into and xmlDocPtr that - can be saved with the xmlSaveFile () function found in the gnome-xml - package. The result is an XML file named xmlTest.gst. + gst_xml_write_file () will turn the given element into an xmlDocPtr that + is then formatted and saved to a file. To save to disk, pass the result + of a fopen(2) as the second argument. The complete element hierarchy will be saved along with the inter element diff --git a/examples/autoplug/autoplug.c b/examples/autoplug/autoplug.c index 4fef339b43..1f2c85c794 100644 --- a/examples/autoplug/autoplug.c +++ b/examples/autoplug/autoplug.c @@ -95,7 +95,7 @@ gst_play_have_type (GstElement *typefind, GstCaps *caps, GstElement *pipeline) gst_element_set_state (pipeline, GST_STATE_PLAYING); #ifndef GST_DISABLE_LOADSAVE - xmlSaveFile("xmlTest.gst", gst_xml_write (GST_ELEMENT (pipeline))); + gst_xml_write_file (GST_ELEMENT (pipeline), fopen ("xmlTest.gst", "w")); #endif } diff --git a/examples/mixer/mixer.c b/examples/mixer/mixer.c index f0dbfcda10..2221d95b32 100644 --- a/examples/mixer/mixer.c +++ b/examples/mixer/mixer.c @@ -182,7 +182,7 @@ int main(int argc,char *argv[]) env_register_cp (channel_in->volenv, num_channels * 10.0 , 1.0 / num_channels); /* to end level */ #ifndef GST_DISABLE_LOADSAVE - xmlSaveFile("mixer.xml", gst_xml_write(GST_ELEMENT(main_bin))); + gst_xml_write_file (GST_ELEMENT (main_bin), fopen ("mixer.xml", "w")); #endif /* start playing */ @@ -358,7 +358,7 @@ create_input_channel (int id, char* location) #endif #ifndef GST_DISABLE_LOADSAVE - xmlSaveFile ("mixer.gst", gst_xml_write (new_element)); + gst_xml_write_file (GST_ELEMENT (new_element), fopen ("mixer.gst", "w")); #endif gst_bin_add (GST_BIN(channel->pipe), channel->volenv); diff --git a/examples/xml/createxml.c b/examples/xml/createxml.c index 7dd432670a..00b09c56b1 100644 --- a/examples/xml/createxml.c +++ b/examples/xml/createxml.c @@ -2,25 +2,27 @@ #include gboolean playing; -xmlNsPtr ns; static void object_saved (GstObject *object, xmlNodePtr parent, gpointer data) { xmlNodePtr child; - + xmlNsPtr ns; + + /* i'm not sure why both of these Ns things are necessary, but they are */ + ns = xmlNewNs (NULL, "http://gstreamer.net/gst-test/1.0/", "test"); child = xmlNewChild(parent, ns, "comment", NULL); - xmlNewChild(child, ns, "text", (gchar *)data); + xmlNewNs (child, "http://gstreamer.net/gst-test/1.0/", "test"); + + xmlNewChild(child, NULL, "text", (gchar *)data); } int main(int argc,char *argv[]) { GstElement *filesrc, *osssink, *queue, *queue2, *parse, *decode; - GstElement *bin; + GstElement *pipeline; GstElement *thread, *thread2; - ns = xmlNewNs (NULL, "http://gstreamer.net/gst-test/1.0/", "test"); - gst_init(&argc,&argv); if (argc != 2) { @@ -28,68 +30,68 @@ int main(int argc,char *argv[]) exit(-1); } - /* create a new thread to hold the elements */ - //thread = gst_thread_new("thread"); - thread = gst_elementfactory_make("thread", "thread"); - g_assert(thread != NULL); + /* create new threads to hold the elements */ + thread = gst_elementfactory_make ("thread", "thread"); + g_assert (thread != NULL); + thread2 = gst_elementfactory_make ("thread", "thread2"); + g_assert (thread2 != NULL); + + /* these signals will allow us to save custom tags with the gst xml output */ g_signal_connect (G_OBJECT (thread), "object_saved", G_CALLBACK (object_saved), g_strdup ("decoder thread")); - - thread2 = gst_elementfactory_make("thread", "thread2"); - //thread2 = gst_thread_new("thread2"); - g_assert(thread2 != NULL); g_signal_connect (G_OBJECT (thread2), "object_saved", G_CALLBACK (object_saved), g_strdup ("render thread")); - + /* create a new bin to hold the elements */ - bin = gst_bin_new("bin"); - g_assert(bin != NULL); + pipeline = gst_pipeline_new ("pipeline"); + g_assert (pipeline != NULL); /* create a disk reader */ - filesrc = gst_elementfactory_make("filesrc", "disk_source"); - g_assert(filesrc != NULL); - g_object_set(G_OBJECT(filesrc),"location", argv[1],NULL); + filesrc = gst_elementfactory_make ("filesrc", "disk_source"); + g_assert (filesrc != NULL); + g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL); - queue = gst_elementfactory_make("queue", "queue"); - queue2 = gst_elementfactory_make("queue", "queue2"); + queue = gst_elementfactory_make ("queue", "queue"); + queue2 = gst_elementfactory_make ("queue", "queue2"); /* and an audio sink */ - osssink = gst_elementfactory_make("osssink", "play_audio"); - g_assert(osssink != NULL); + osssink = gst_elementfactory_make ("osssink", "play_audio"); + g_assert (osssink != NULL); - parse = gst_elementfactory_make("mp3parse", "parse"); - decode = gst_elementfactory_make("mpg123", "decode"); + decode = gst_elementfactory_make ("mad", "decode"); + g_assert (decode != NULL); - /* add objects to the main bin */ - gst_bin_add(GST_BIN(bin), filesrc); - gst_bin_add(GST_BIN(bin), queue); + /* add objects to the main pipeline */ + gst_bin_add (GST_BIN (pipeline), filesrc); + gst_bin_add (GST_BIN (pipeline), 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 (thread), decode); + gst_bin_add (GST_BIN (thread), queue2); - gst_bin_add(GST_BIN(thread2), osssink); + gst_bin_add (GST_BIN (thread2), osssink); + + gst_pad_connect (gst_element_get_pad (filesrc,"src"), + gst_element_get_pad (queue,"sink")); - gst_pad_connect(gst_element_get_pad(filesrc,"src"), - gst_element_get_pad(queue,"sink")); + gst_pad_connect (gst_element_get_pad (queue,"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(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 (osssink,"sink")); - gst_pad_connect(gst_element_get_pad(queue2,"src"), - gst_element_get_pad(osssink,"sink")); + gst_bin_add (GST_BIN (pipeline), thread); + gst_bin_add (GST_BIN (pipeline), thread2); - gst_bin_add(GST_BIN(bin), thread); - gst_bin_add(GST_BIN(bin), thread2); + /* write the bin to stdout */ + gst_xml_write_file (GST_ELEMENT (pipeline), stdout); - xmlSaveFile("xmlTest.gst", gst_xml_write(GST_ELEMENT(bin))); + /* write the bin to a file */ + gst_xml_write_file (GST_ELEMENT (pipeline), fopen ("xmlTest.gst", "w")); - exit(0); + exit (0); } diff --git a/examples/xml/runxml.c b/examples/xml/runxml.c index 36fa425073..07fecc0751 100644 --- a/examples/xml/runxml.c +++ b/examples/xml/runxml.c @@ -29,27 +29,27 @@ xml_loaded (GstXML *xml, GstObject *object, xmlNodePtr self, gpointer data) int main(int argc,char *argv[]) { GstXML *xml; - GstElement *bin; + GstElement *pipeline; gboolean ret; gst_init(&argc,&argv); xml = gst_xml_new (); - g_signal_connect (G_OBJECT (xml), "object_loaded", - G_CALLBACK (xml_loaded), xml); +// g_signal_connect (G_OBJECT (xml), "object_loaded", +// G_CALLBACK (xml_loaded), xml); ret = gst_xml_parse_file(xml, "xmlTest.gst", NULL); g_assert (ret == TRUE); - bin = gst_xml_get_element(xml, "bin"); - g_assert (bin != NULL); + pipeline = gst_xml_get_element(xml, "pipeline"); + g_assert (pipeline != NULL); - gst_element_set_state(bin, GST_STATE_PLAYING); + gst_element_set_state(pipeline, GST_STATE_PLAYING); - while (gst_bin_iterate(GST_BIN(bin))); + while (gst_bin_iterate(GST_BIN(pipeline))); - gst_element_set_state(bin, GST_STATE_NULL); + gst_element_set_state(pipeline, GST_STATE_NULL); exit(0); } diff --git a/gst/gstbin.c b/gst/gstbin.c index c9a626097e..4a936da00c 100644 --- a/gst/gstbin.c +++ b/gst/gstbin.c @@ -717,8 +717,13 @@ gst_bin_restore_thyself (GstObject * object, xmlNodePtr self) childlist = field->xmlChildrenNode; while (childlist) { if (!strcmp (childlist->name, "element")) { - GstElement *element = gst_element_restore_thyself (childlist, GST_OBJECT (bin)); - + GstElement *element = gst_xml_make_element (childlist, GST_OBJECT (bin)); + + /* it had to be parented to find the pads, now we ref and unparent so + * we can add it to the bin */ + gst_object_ref (GST_OBJECT (element)); + gst_object_unparent (GST_OBJECT (element)); + gst_bin_add (bin, element); } childlist = childlist->next; diff --git a/gst/gstelement.c b/gst/gstelement.c index a92fcd9ccb..0c19d1bca7 100644 --- a/gst/gstelement.c +++ b/gst/gstelement.c @@ -65,7 +65,7 @@ static void gst_element_send_event_func (GstElement *element, GstEvent *even #ifndef GST_DISABLE_LOADSAVE static xmlNodePtr gst_element_save_thyself (GstObject *object, xmlNodePtr parent); -GstElement* gst_element_restore_thyself (xmlNodePtr self, GstObject *parent); +static void gst_element_restore_thyself (GstObject *parent, xmlNodePtr self); #endif GType _gst_element_type = 0; @@ -1094,9 +1094,11 @@ gst_element_save_thyself (GstObject *object, { GList *pads; GstElementClass *oclass; - /* FIXME : this is needed for glib2 */ - /* GType type; */ + GParamSpec **specs, *spec; + gint nspecs, i; + GValue value = { 0, }; GstElement *element; + gchar *str; g_return_val_if_fail (GST_IS_ELEMENT (object), parent); @@ -1113,74 +1115,36 @@ gst_element_save_thyself (GstObject *object, xmlNewChild (parent, NULL, "version", factory->details->version); } +/* FIXME: what is this? */ /* if (element->manager) */ /* xmlNewChild(parent, NULL, "manager", GST_ELEMENT_NAME(element->manager)); */ -/* FIXME FIXME FIXME! */ - /* output all args to the element */ - /* - type = G_OBJECT_TYPE (element); - while (type != G_TYPE_INVALID) { - GtkArg *args; - guint32 *flags; - guint num_args,i; - - args = gtk_object_query_args (type, &flags, &num_args); - - for (i=0; i G_TYPE_NONE) && - (flags[i] & GTK_ARG_READABLE)) { - xmlNodePtr arg; - gtk_object_getv (G_OBJECT (element), 1, &args[i]); - arg = xmlNewChild (parent, NULL, "arg", NULL); - xmlNewChild (arg, NULL, "name", args[i].name); - switch (args[i].type) { - case G_TYPE_CHAR: - xmlNewChild (arg, NULL, "value", - g_strdup_printf ("%c", G_VALUE_CHAR (args[i]))); - break; - case G_TYPE_UCHAR: - xmlNewChild (arg, NULL, "value", - g_strdup_printf ("%d", G_VALUE_UCHAR (args[i]))); - break; - case G_TYPE_BOOLEAN: - xmlNewChild (arg, NULL, "value", - G_VALUE_BOOL (args[i]) ? "true" : "false"); - break; - case G_TYPE_INT: - xmlNewChild (arg, NULL, "value", - g_strdup_printf ("%d", G_VALUE_INT (args[i]))); - break; - case G_TYPE_LONG: - xmlNewChild (arg, NULL, "value", - g_strdup_printf ("%ld", G_VALUE_LONG (args[i]))); - break; - case G_TYPE_ULONG: - xmlNewChild (arg, NULL, "value", - g_strdup_printf ("%lu", G_VALUE_ULONG (args[i]))); - break; - case G_TYPE_FLOAT: - xmlNewChild (arg, NULL, "value", - g_strdup_printf ("%f", G_VALUE_FLOAT (args[i]))); - break; - case G_TYPE_DOUBLE: - xmlNewChild (arg, NULL, "value", - g_strdup_printf ("%g", G_VALUE_DOUBLE (args[i]))); - break; - case G_TYPE_STRING: - xmlNewChild (arg, NULL, "value", G_VALUE_STRING (args[i])); - break; - default: - if (args[i].type == GST_TYPE_FILENAME) { - xmlNewChild (arg, NULL, "value", G_VALUE_STRING (args[i])); - } - break; - } - } +#ifdef USE_GLIB2 + /* params */ + specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (object), &nspecs); + + for (i=0; iflags & G_PARAM_READABLE) { + xmlNodePtr param; + + g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE (spec)); + + g_object_get_property (G_OBJECT (element), spec->name, &value); + param = xmlNewChild (parent, NULL, "param", NULL); + xmlNewChild (param, NULL, "name", spec->name); + + if (G_IS_PARAM_SPEC_STRING (spec)) + xmlNewChild (param, NULL, "value", g_value_dup_string (&value)); + else if (G_IS_PARAM_SPEC_ENUM (spec)) + xmlNewChild (param, NULL, "value", g_strdup_printf ("%d", g_value_get_enum (&value))); + else + xmlNewChild (param, NULL, "value", g_strdup_value_contents (&value)); + + g_value_unset(&value); } - type = gtk_type_parent (type); } -*/ +#endif pads = GST_ELEMENT_PADS (element); @@ -1197,53 +1161,21 @@ gst_element_save_thyself (GstObject *object, return parent; } -/** - * gst_element_restore_thyself: - * @self: the xml node - * @parent: the parent of this object when it's loaded - * - * Load the element from the XML description - * - * Returns: the new element - */ -GstElement* -gst_element_restore_thyself (xmlNodePtr self, GstObject *parent) +static void +gst_element_restore_thyself (GstObject *object, xmlNodePtr self) { - xmlNodePtr children = self->xmlChildrenNode; + xmlNodePtr children; GstElement *element; - GstObjectClass *oclass; guchar *name = NULL; guchar *value = NULL; - guchar *type = NULL; - /* first get the needed tags to construct the element */ - while (children) { - if (!strcmp (children->name, "name")) { - name = xmlNodeGetContent (children); - } else if (!strcmp (children->name, "type")) { - type = xmlNodeGetContent (children); - } - children = children->next; - } - g_return_val_if_fail (name != NULL, NULL); - g_return_val_if_fail (type != NULL, NULL); + element = GST_ELEMENT (object); + g_return_if_fail (element != NULL); - GST_INFO (GST_CAT_XML,"loading \"%s\" of type \"%s\"", name, type); - - element = gst_elementfactory_make (type, name); - - g_return_val_if_fail (element != NULL, NULL); - - /* ne need to set the parent on this object bacause the pads */ - /* will go through the hierarchy to connect to thier peers */ - if (parent) - gst_object_set_parent (GST_OBJECT (element), parent); - - /* we have the element now, set the arguments */ + /* parameters */ children = self->xmlChildrenNode; - while (children) { - if (!strcmp (children->name, "arg")) { + if (!strcmp (children->name, "param")) { xmlNodePtr child = children->xmlChildrenNode; while (child) { @@ -1255,13 +1187,14 @@ gst_element_restore_thyself (xmlNodePtr self, GstObject *parent) } child = child->next; } + /* FIXME: can this just be g_object_set ? */ gst_util_set_object_arg ((GObject *)G_OBJECT (element), name, value); } children = children->next; } - /* we have the element now, set the pads */ + + /* pads */ children = self->xmlChildrenNode; - while (children) { if (!strcmp (children->name, "pad")) { gst_pad_load_and_connect (children, GST_OBJECT (element)); @@ -1269,16 +1202,8 @@ gst_element_restore_thyself (xmlNodePtr self, GstObject *parent) children = children->next; } - oclass = GST_OBJECT_CLASS (G_OBJECT_GET_CLASS(element)); - if (oclass->restore_thyself) - (oclass->restore_thyself) (GST_OBJECT (element), self); - - if (parent) - gst_object_unparent (GST_OBJECT (element)); - - gst_class_signal_emit_by_name (GST_OBJECT (element), "object_loaded", self); - - return element; + if (GST_OBJECT_CLASS(parent_class)->restore_thyself) + (GST_OBJECT_CLASS(parent_class)->restore_thyself) (object, self); } #endif /* GST_DISABLE_LOADSAVE */ @@ -1560,4 +1485,3 @@ gst_element_install_std_props (GstElementClass * klass, const char *first_name, va_end (args); } - diff --git a/gst/gstelement.h b/gst/gstelement.h index f05656d608..88a9c7247c 100644 --- a/gst/gstelement.h +++ b/gst/gstelement.h @@ -226,12 +226,6 @@ void gst_element_install_std_props (GstElementClass *klass, const char *first_name, ...); -#ifndef GST_DISABLE_LOADSAVE -/* XML write and read */ -GstElement* gst_element_restore_thyself (xmlNodePtr self, GstObject *parent); -#endif - - /* * * factories stuff diff --git a/gst/gstobject.c b/gst/gstobject.c index 081fd1cf10..a33ce0fbd4 100644 --- a/gst/gstobject.c +++ b/gst/gstobject.c @@ -66,6 +66,10 @@ static void gst_object_get_property (GObject * object, guint prop_id, GValue static void gst_object_dispose (GObject *object); static void gst_object_finalize (GObject *object); +#ifndef GST_DISABLE_LOADSAVE_REGISTRY +static void gst_object_real_restore_thyself (GstObject *object, xmlNodePtr self); +#endif + static GObjectClass *parent_class = NULL; static guint gst_object_signals[LAST_SIGNAL] = { 0 }; @@ -117,11 +121,13 @@ gst_object_class_init (GstObjectClass *klass) G_STRUCT_OFFSET (GstObjectClass, object_saved), NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); + + klass->restore_thyself = gst_object_real_restore_thyself; #endif klass->path_string_separator = "/"; -/* FIXME!!! */ -/* klass->signal_object = g_object_new(gst_signal_object_get_type (,NULL)); */ + + klass->signal_object = g_object_new (gst_signal_object_get_type (), NULL); gobject_class->dispose = gst_object_dispose; gobject_class->finalize = gst_object_finalize; @@ -495,22 +501,35 @@ gst_object_save_thyself (GstObject *object, xmlNodePtr parent) /** * gst_object_restore_thyself: * @object: GstObject to load into - * @parent: The parent XML node to load the object from + * @self: The XML node to load the object from * * Restores the given object with the data from the parent XML node. */ void -gst_object_restore_thyself (GstObject *object, xmlNodePtr parent) +gst_object_restore_thyself (GstObject *object, xmlNodePtr self) { GstObjectClass *oclass; g_return_if_fail (object != NULL); g_return_if_fail (GST_IS_OBJECT (object)); - g_return_if_fail (parent != NULL); + g_return_if_fail (self != NULL); - oclass = (GstObjectClass *)G_OBJECT_GET_CLASS(object); + oclass = (GstObjectClass *) G_OBJECT_GET_CLASS(object); if (oclass->restore_thyself) - oclass->restore_thyself (object, parent); + oclass->restore_thyself (object, self); +} + +static void +gst_object_real_restore_thyself (GstObject *object, xmlNodePtr self) +{ + GstObjectClass *oclass; + + g_return_if_fail (object != NULL); + g_return_if_fail (GST_IS_OBJECT (object)); + g_return_if_fail (self != NULL); + +/* FIXME: the signalobject stuff doesn't work + * gst_class_signal_emit_by_name (object, "object_loaded", self); */ } #endif /* GST_DISABLE_LOADSAVE_REGISTRY */ diff --git a/gst/gstqueue.c b/gst/gstqueue.c index 48d6b55b19..bf67c98388 100644 --- a/gst/gstqueue.c +++ b/gst/gstqueue.c @@ -565,7 +565,7 @@ gst_queue_set_property (GObject *object, guint prop_id, const GValue *value, GPa switch (prop_id) { case ARG_LEAKY: - queue->leaky = g_value_get_int (value); + queue->leaky = g_value_get_enum (value); break; case ARG_MAX_LEVEL: queue->size_buffers = g_value_get_int (value); @@ -591,7 +591,7 @@ gst_queue_get_property (GObject *object, guint prop_id, GValue *value, GParamSpe switch (prop_id) { case ARG_LEAKY: - g_value_set_int (value, queue->leaky); + g_value_set_enum (value, queue->leaky); break; case ARG_LEVEL: g_value_set_int (value, queue->level_buffers); diff --git a/gst/gstxml.c b/gst/gstxml.c index 6e8036cd16..1f40f0903f 100644 --- a/gst/gstxml.c +++ b/gst/gstxml.c @@ -113,11 +113,11 @@ gst_xml_write (GstElement *element) xmlNsPtr ns; doc = xmlNewDoc ("1.0"); - xmlNewGlobalNs (doc, "http://gstreamer.net/gst-core/1.0/", "gst"); + + doc->xmlRootNode = xmlNewDocNode (doc, NULL, "gstreamer", NULL); + ns = xmlNewNs (doc->xmlRootNode, "http://gstreamer.net/gst-core/1.0/", "gst"); - - doc->xmlRootNode = xmlNewDocNode (doc, ns, "gstreamer", NULL); - + elementnode = xmlNewChild (doc->xmlRootNode, ns, "element", NULL); gst_object_save_thyself (GST_OBJECT (element), elementnode); @@ -228,7 +228,7 @@ gst_xml_parse_doc (GstXML *xml, xmlDocPtr doc, const guchar *root) if (!strcmp(field->name, "element") && (field->ns == xml->ns)) { GstElement *element; - element = gst_element_restore_thyself(field, NULL); + element = gst_xml_make_element (field, NULL); xml->topelements = g_list_prepend (xml->topelements, element); } @@ -363,3 +363,49 @@ gst_xml_get_element (GstXML *xml, const guchar *name) } return NULL; } + +/** + * gst_xml_make_element: + * @cur: the xml node + * @parent: the parent of this object when it's loaded + * + * Load the element from the XML description + * + * Returns: the new element + */ +GstElement* +gst_xml_make_element (xmlNodePtr cur, GstObject *parent) +{ + xmlNodePtr children = cur->xmlChildrenNode; + GstElement *element; + GstObjectClass *oclass; + guchar *name = NULL; + guchar *type = NULL; + + /* first get the needed tags to construct the element */ + while (children) { + if (!strcmp (children->name, "name")) { + name = xmlNodeGetContent (children); + } else if (!strcmp (children->name, "type")) { + type = xmlNodeGetContent (children); + } + children = children->next; + } + g_return_val_if_fail (name != NULL, NULL); + g_return_val_if_fail (type != NULL, NULL); + + GST_INFO (GST_CAT_XML,"loading \"%s\" of type \"%s\"", name, type); + + element = gst_elementfactory_make (type, name); + + g_return_val_if_fail (element != NULL, NULL); + + /* ne need to set the parent on this object bacause the pads */ + /* will go through the hierarchy to connect to thier peers */ + if (parent) + gst_object_set_parent (GST_OBJECT (element), parent); + + gst_object_restore_thyself (GST_OBJECT (element), cur); + + return element; +} diff --git a/gst/gstxml.h b/gst/gstxml.h index 6c5d156492..e3f83b79d9 100644 --- a/gst/gstxml.h +++ b/gst/gstxml.h @@ -82,6 +82,8 @@ gboolean gst_xml_parse_memory (GstXML *xml, guchar *buffer, guint size, const gc GstElement* gst_xml_get_element (GstXML *xml, const guchar *name); GList* gst_xml_get_topelements (GstXML *xml); +GstElement* gst_xml_make_element (xmlNodePtr cur, GstObject *parent); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/plugins/elements/gstqueue.c b/plugins/elements/gstqueue.c index 48d6b55b19..bf67c98388 100644 --- a/plugins/elements/gstqueue.c +++ b/plugins/elements/gstqueue.c @@ -565,7 +565,7 @@ gst_queue_set_property (GObject *object, guint prop_id, const GValue *value, GPa switch (prop_id) { case ARG_LEAKY: - queue->leaky = g_value_get_int (value); + queue->leaky = g_value_get_enum (value); break; case ARG_MAX_LEVEL: queue->size_buffers = g_value_get_int (value); @@ -591,7 +591,7 @@ gst_queue_get_property (GObject *object, guint prop_id, GValue *value, GParamSpe switch (prop_id) { case ARG_LEAKY: - g_value_set_int (value, queue->leaky); + g_value_set_enum (value, queue->leaky); break; case ARG_LEVEL: g_value_set_int (value, queue->level_buffers); diff --git a/tests/old/examples/autoplug/autoplug.c b/tests/old/examples/autoplug/autoplug.c index 4fef339b43..1f2c85c794 100644 --- a/tests/old/examples/autoplug/autoplug.c +++ b/tests/old/examples/autoplug/autoplug.c @@ -95,7 +95,7 @@ gst_play_have_type (GstElement *typefind, GstCaps *caps, GstElement *pipeline) gst_element_set_state (pipeline, GST_STATE_PLAYING); #ifndef GST_DISABLE_LOADSAVE - xmlSaveFile("xmlTest.gst", gst_xml_write (GST_ELEMENT (pipeline))); + gst_xml_write_file (GST_ELEMENT (pipeline), fopen ("xmlTest.gst", "w")); #endif } diff --git a/tests/old/examples/mixer/mixer.c b/tests/old/examples/mixer/mixer.c index f0dbfcda10..2221d95b32 100644 --- a/tests/old/examples/mixer/mixer.c +++ b/tests/old/examples/mixer/mixer.c @@ -182,7 +182,7 @@ int main(int argc,char *argv[]) env_register_cp (channel_in->volenv, num_channels * 10.0 , 1.0 / num_channels); /* to end level */ #ifndef GST_DISABLE_LOADSAVE - xmlSaveFile("mixer.xml", gst_xml_write(GST_ELEMENT(main_bin))); + gst_xml_write_file (GST_ELEMENT (main_bin), fopen ("mixer.xml", "w")); #endif /* start playing */ @@ -358,7 +358,7 @@ create_input_channel (int id, char* location) #endif #ifndef GST_DISABLE_LOADSAVE - xmlSaveFile ("mixer.gst", gst_xml_write (new_element)); + gst_xml_write_file (GST_ELEMENT (new_element), fopen ("mixer.gst", "w")); #endif gst_bin_add (GST_BIN(channel->pipe), channel->volenv); diff --git a/tests/old/examples/xml/createxml.c b/tests/old/examples/xml/createxml.c index 7dd432670a..00b09c56b1 100644 --- a/tests/old/examples/xml/createxml.c +++ b/tests/old/examples/xml/createxml.c @@ -2,25 +2,27 @@ #include gboolean playing; -xmlNsPtr ns; static void object_saved (GstObject *object, xmlNodePtr parent, gpointer data) { xmlNodePtr child; - + xmlNsPtr ns; + + /* i'm not sure why both of these Ns things are necessary, but they are */ + ns = xmlNewNs (NULL, "http://gstreamer.net/gst-test/1.0/", "test"); child = xmlNewChild(parent, ns, "comment", NULL); - xmlNewChild(child, ns, "text", (gchar *)data); + xmlNewNs (child, "http://gstreamer.net/gst-test/1.0/", "test"); + + xmlNewChild(child, NULL, "text", (gchar *)data); } int main(int argc,char *argv[]) { GstElement *filesrc, *osssink, *queue, *queue2, *parse, *decode; - GstElement *bin; + GstElement *pipeline; GstElement *thread, *thread2; - ns = xmlNewNs (NULL, "http://gstreamer.net/gst-test/1.0/", "test"); - gst_init(&argc,&argv); if (argc != 2) { @@ -28,68 +30,68 @@ int main(int argc,char *argv[]) exit(-1); } - /* create a new thread to hold the elements */ - //thread = gst_thread_new("thread"); - thread = gst_elementfactory_make("thread", "thread"); - g_assert(thread != NULL); + /* create new threads to hold the elements */ + thread = gst_elementfactory_make ("thread", "thread"); + g_assert (thread != NULL); + thread2 = gst_elementfactory_make ("thread", "thread2"); + g_assert (thread2 != NULL); + + /* these signals will allow us to save custom tags with the gst xml output */ g_signal_connect (G_OBJECT (thread), "object_saved", G_CALLBACK (object_saved), g_strdup ("decoder thread")); - - thread2 = gst_elementfactory_make("thread", "thread2"); - //thread2 = gst_thread_new("thread2"); - g_assert(thread2 != NULL); g_signal_connect (G_OBJECT (thread2), "object_saved", G_CALLBACK (object_saved), g_strdup ("render thread")); - + /* create a new bin to hold the elements */ - bin = gst_bin_new("bin"); - g_assert(bin != NULL); + pipeline = gst_pipeline_new ("pipeline"); + g_assert (pipeline != NULL); /* create a disk reader */ - filesrc = gst_elementfactory_make("filesrc", "disk_source"); - g_assert(filesrc != NULL); - g_object_set(G_OBJECT(filesrc),"location", argv[1],NULL); + filesrc = gst_elementfactory_make ("filesrc", "disk_source"); + g_assert (filesrc != NULL); + g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL); - queue = gst_elementfactory_make("queue", "queue"); - queue2 = gst_elementfactory_make("queue", "queue2"); + queue = gst_elementfactory_make ("queue", "queue"); + queue2 = gst_elementfactory_make ("queue", "queue2"); /* and an audio sink */ - osssink = gst_elementfactory_make("osssink", "play_audio"); - g_assert(osssink != NULL); + osssink = gst_elementfactory_make ("osssink", "play_audio"); + g_assert (osssink != NULL); - parse = gst_elementfactory_make("mp3parse", "parse"); - decode = gst_elementfactory_make("mpg123", "decode"); + decode = gst_elementfactory_make ("mad", "decode"); + g_assert (decode != NULL); - /* add objects to the main bin */ - gst_bin_add(GST_BIN(bin), filesrc); - gst_bin_add(GST_BIN(bin), queue); + /* add objects to the main pipeline */ + gst_bin_add (GST_BIN (pipeline), filesrc); + gst_bin_add (GST_BIN (pipeline), 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 (thread), decode); + gst_bin_add (GST_BIN (thread), queue2); - gst_bin_add(GST_BIN(thread2), osssink); + gst_bin_add (GST_BIN (thread2), osssink); + + gst_pad_connect (gst_element_get_pad (filesrc,"src"), + gst_element_get_pad (queue,"sink")); - gst_pad_connect(gst_element_get_pad(filesrc,"src"), - gst_element_get_pad(queue,"sink")); + gst_pad_connect (gst_element_get_pad (queue,"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(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 (osssink,"sink")); - gst_pad_connect(gst_element_get_pad(queue2,"src"), - gst_element_get_pad(osssink,"sink")); + gst_bin_add (GST_BIN (pipeline), thread); + gst_bin_add (GST_BIN (pipeline), thread2); - gst_bin_add(GST_BIN(bin), thread); - gst_bin_add(GST_BIN(bin), thread2); + /* write the bin to stdout */ + gst_xml_write_file (GST_ELEMENT (pipeline), stdout); - xmlSaveFile("xmlTest.gst", gst_xml_write(GST_ELEMENT(bin))); + /* write the bin to a file */ + gst_xml_write_file (GST_ELEMENT (pipeline), fopen ("xmlTest.gst", "w")); - exit(0); + exit (0); } diff --git a/tests/old/examples/xml/runxml.c b/tests/old/examples/xml/runxml.c index 36fa425073..07fecc0751 100644 --- a/tests/old/examples/xml/runxml.c +++ b/tests/old/examples/xml/runxml.c @@ -29,27 +29,27 @@ xml_loaded (GstXML *xml, GstObject *object, xmlNodePtr self, gpointer data) int main(int argc,char *argv[]) { GstXML *xml; - GstElement *bin; + GstElement *pipeline; gboolean ret; gst_init(&argc,&argv); xml = gst_xml_new (); - g_signal_connect (G_OBJECT (xml), "object_loaded", - G_CALLBACK (xml_loaded), xml); +// g_signal_connect (G_OBJECT (xml), "object_loaded", +// G_CALLBACK (xml_loaded), xml); ret = gst_xml_parse_file(xml, "xmlTest.gst", NULL); g_assert (ret == TRUE); - bin = gst_xml_get_element(xml, "bin"); - g_assert (bin != NULL); + pipeline = gst_xml_get_element(xml, "pipeline"); + g_assert (pipeline != NULL); - gst_element_set_state(bin, GST_STATE_PLAYING); + gst_element_set_state(pipeline, GST_STATE_PLAYING); - while (gst_bin_iterate(GST_BIN(bin))); + while (gst_bin_iterate(GST_BIN(pipeline))); - gst_element_set_state(bin, GST_STATE_NULL); + gst_element_set_state(pipeline, GST_STATE_NULL); exit(0); } diff --git a/tests/sched/dynamic-pipeline.c b/tests/sched/dynamic-pipeline.c index 8f094e88ef..48faaefc31 100644 --- a/tests/sched/dynamic-pipeline.c +++ b/tests/sched/dynamic-pipeline.c @@ -40,7 +40,7 @@ int main (int argc, char *argv[]) gst_element_connect(fakesrc, "src", fakesink2, "sink"); // show the pipeline state - xmlDocDump(stdout, gst_xml_write(pipe2)); + gst_xml_write_file (GST_ELEMENT (pipe2), stdout); // try to iterate the pipeline gst_element_set_state(pipe2, GST_STATE_PLAYING); diff --git a/tools/gst-launch.c b/tools/gst-launch.c index 415d830581..698bacf07e 100644 --- a/tools/gst-launch.c +++ b/tools/gst-launch.c @@ -141,7 +141,7 @@ main(int argc, char *argv[]) #ifndef GST_DISABLE_LOADSAVE if (save_pipeline) { - xmlSaveFile (savefile, gst_xml_write (pipeline)); + gst_xml_write_file (GST_ELEMENT (pipeline), fopen (savefile, "w")); } #endif if (run_pipeline) {