summary: fix xml in gstreamer 1) make clear distinction between loading xml that...
authorAndy Wingo <wingo@pobox.com>
Fri, 11 Jan 2002 15:49:47 +0000 (15:49 +0000)
committerAndy Wingo <wingo@pobox.com>
Fri, 11 Jan 2002 15:49:47 +0000 (15:49 +0000)
Original commit message from CVS:
summary: fix xml in gstreamer

1) make clear distinction between loading xml that actually creates objects and loading xml that just
synchronizes properties with objects. moved most of gst_element_restore_thyself functionality to
gst_xml_make_element. this new function name can change if it sucks.
2) many various fixes. createxml and runxml work now.
3) doc updates.
4) GstSignalObject is stil broken. i have no idea what it's supposed to do.

20 files changed:
docs/manual/highlevel-xml.xml
docs/manual/xml.xml
examples/autoplug/autoplug.c
examples/mixer/mixer.c
examples/xml/createxml.c
examples/xml/runxml.c
gst/gstbin.c
gst/gstelement.c
gst/gstelement.h
gst/gstobject.c
gst/gstqueue.c
gst/gstxml.c
gst/gstxml.h
plugins/elements/gstqueue.c
tests/old/examples/autoplug/autoplug.c
tests/old/examples/mixer/mixer.c
tests/old/examples/xml/createxml.c
tests/old/examples/xml/runxml.c
tests/sched/dynamic-pipeline.c
tools/gst-launch.c

index cab7182..c9aeba8 100644 (file)
@@ -17,9 +17,9 @@
     <title>Turning GstElements into XML</title>
 
     <para>
-      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.
     </para>
 
     <programlisting>
@@ -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:
     </para>
     <programlisting>
-  xmlSaveFile ("xmlTest.gst", gst_xml_write (GST_ELEMENT (bin)));
+  gst_xml_write_file (GST_ELEMENT (bin), stdout);
     </programlisting>
     <para>
-      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.
     </para>
     <para>
       The complete element hierarchy will be saved along with the inter element
index cab7182..c9aeba8 100644 (file)
@@ -17,9 +17,9 @@
     <title>Turning GstElements into XML</title>
 
     <para>
-      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.
     </para>
 
     <programlisting>
@@ -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:
     </para>
     <programlisting>
-  xmlSaveFile ("xmlTest.gst", gst_xml_write (GST_ELEMENT (bin)));
+  gst_xml_write_file (GST_ELEMENT (bin), stdout);
     </programlisting>
     <para>
-      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.
     </para>
     <para>
       The complete element hierarchy will be saved along with the inter element
index 4fef339..1f2c85c 100644 (file)
@@ -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
 }
 
index f0dbfcd..2221d95 100644 (file)
@@ -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);
index 7dd4326..00b09c5 100644 (file)
@@ -2,25 +2,27 @@
 #include <gst/gst.h>
 
 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);
 }
 
index 36fa425..07fecc0 100644 (file)
@@ -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);
 }
index c9a6260..4a936da 100644 (file)
@@ -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;
index a92fcd9..0c19d1b 100644 (file)
@@ -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<num_args; i++) {
-      if ((args[i].type > 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; i<nspecs; i++) {
+    spec = specs[i];
+    if (spec->flags & 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);
 
-  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);
+  element = GST_ELEMENT (object);
+  g_return_if_fail (element != NULL);
 
-  /* 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);
 }
-
index f05656d..88a9c72 100644 (file)
@@ -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
index 081fd1c..a33ce0f 100644 (file)
@@ -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 */
 
index 48d6b55..bf67c98 100644 (file)
@@ -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);
index 6e8036c..1f40f09 100644 (file)
@@ -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");
-  ns = xmlNewNs (doc->xmlRootNode, "http://gstreamer.net/gst-core/1.0/", "gst");
-
-  doc->xmlRootNode = xmlNewDocNode (doc, ns, "gstreamer", NULL);
 
+  doc->xmlRootNode = xmlNewDocNode (doc, NULL, "gstreamer", NULL);
+  
+  ns = xmlNewNs (doc->xmlRootNode, "http://gstreamer.net/gst-core/1.0/", "gst");
+  
   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;
+}
index 6c5d156..e3f83b7 100644 (file)
@@ -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 */
index 48d6b55..bf67c98 100644 (file)
@@ -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);
index 4fef339..1f2c85c 100644 (file)
@@ -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
 }
 
index f0dbfcd..2221d95 100644 (file)
@@ -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);
index 7dd4326..00b09c5 100644 (file)
@@ -2,25 +2,27 @@
 #include <gst/gst.h>
 
 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);
 }
 
index 36fa425..07fecc0 100644 (file)
@@ -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);
 }
index 8f094e8..48faaef 100644 (file)
@@ -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);
index 415d830..698bacf 100644 (file)
@@ -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) {