summary: fix xml in gstreamer 1) make clear distinction between loading xml that actually creates objects and loading...

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.
This commit is contained in:
Andy Wingo 2002-01-11 15:49:47 +00:00
parent c51e7cd2fe
commit d262bea863
20 changed files with 292 additions and 298 deletions

View file

@ -17,9 +17,9 @@
<title>Turning GstElements into XML</title> <title>Turning GstElements into XML</title>
<para> <para>
We create a simple pipeline and save it to disk with gst_xml_write (). The following 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 finaly writes it to disk. code constructs an mp3 player pipeline with two threads and then writes out the XML both to
use this program with one argument: the mp3 file on disk. stdout and to a file. Use this program with one argument: the mp3 file on disk.
</para> </para>
<programlisting> <programlisting>
@ -31,7 +31,7 @@ gboolean playing;
int int
main (int argc, char *argv[]) main (int argc, char *argv[])
{ {
GstElement *filesrc, *audiosink, *queue, *queue2, *parse, *decode; GstElement *filesrc, *osssink, *queue, *queue2, *parse, *decode;
GstElement *bin; GstElement *bin;
GstElement *thread, *thread2; GstElement *thread, *thread2;
@ -61,40 +61,40 @@ main (int argc, char *argv[])
queue2 = gst_elementfactory_make ("queue", "queue2"); queue2 = gst_elementfactory_make ("queue", "queue2");
/* and an audio sink */ /* and an audio sink */
audiosink = gst_elementfactory_make ("audiosink", "play_audio"); osssink = gst_elementfactory_make ("osssink", "play_audio");
g_assert (audiosink != NULL); g_assert (osssink != NULL);
parse = gst_elementfactory_make ("mp3parse", "parse"); decode = gst_elementfactory_make ("mad", "decode");
decode = gst_elementfactory_make ("mpg123", "decode"); g_assert (decode != NULL);
/* add objects to the main bin */ /* add objects to the main bin */
gst_bin_add (GST_BIN (bin), filesrc); gst_bin_add (GST_BIN (bin), filesrc);
gst_bin_add (GST_BIN (bin), queue); 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), decode);
gst_bin_add (GST_BIN (thread), queue2); 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_pad_connect (gst_element_get_pad (filesrc,"src"),
gst_element_get_pad (queue,"sink")); gst_element_get_pad (queue,"sink"));
gst_pad_connect (gst_element_get_pad (queue,"src"), 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_element_get_pad (decode,"sink"));
gst_pad_connect (gst_element_get_pad (decode,"src"), gst_pad_connect (gst_element_get_pad (decode,"src"),
gst_element_get_pad (queue2,"sink")); gst_element_get_pad (queue2,"sink"));
gst_pad_connect (gst_element_get_pad (queue2,"src"), 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), thread);
gst_bin_add (GST_BIN (bin), thread2); gst_bin_add (GST_BIN (bin), thread2);
// write the bin to disk /* write the bin to stdout */
xmlSaveFile ("xmlTest.gst", gst_xml_write (GST_ELEMENT (bin))); 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); exit (0);
} }
@ -103,12 +103,12 @@ main (int argc, char *argv[])
The most important line is: The most important line is:
</para> </para>
<programlisting> <programlisting>
xmlSaveFile ("xmlTest.gst", gst_xml_write (GST_ELEMENT (bin))); gst_xml_write_file (GST_ELEMENT (bin), stdout);
</programlisting> </programlisting>
<para> <para>
gst_xml_write () will turn the given element into and xmlDocPtr that gst_xml_write_file () will turn the given element into an xmlDocPtr that
can be saved with the xmlSaveFile () function found in the gnome-xml is then formatted and saved to a file. To save to disk, pass the result
package. The result is an XML file named xmlTest.gst. of a fopen(2) as the second argument.
</para> </para>
<para> <para>
The complete element hierarchy will be saved along with the inter element The complete element hierarchy will be saved along with the inter element

View file

@ -17,9 +17,9 @@
<title>Turning GstElements into XML</title> <title>Turning GstElements into XML</title>
<para> <para>
We create a simple pipeline and save it to disk with gst_xml_write (). The following 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 finaly writes it to disk. code constructs an mp3 player pipeline with two threads and then writes out the XML both to
use this program with one argument: the mp3 file on disk. stdout and to a file. Use this program with one argument: the mp3 file on disk.
</para> </para>
<programlisting> <programlisting>
@ -31,7 +31,7 @@ gboolean playing;
int int
main (int argc, char *argv[]) main (int argc, char *argv[])
{ {
GstElement *filesrc, *audiosink, *queue, *queue2, *parse, *decode; GstElement *filesrc, *osssink, *queue, *queue2, *parse, *decode;
GstElement *bin; GstElement *bin;
GstElement *thread, *thread2; GstElement *thread, *thread2;
@ -61,40 +61,40 @@ main (int argc, char *argv[])
queue2 = gst_elementfactory_make ("queue", "queue2"); queue2 = gst_elementfactory_make ("queue", "queue2");
/* and an audio sink */ /* and an audio sink */
audiosink = gst_elementfactory_make ("audiosink", "play_audio"); osssink = gst_elementfactory_make ("osssink", "play_audio");
g_assert (audiosink != NULL); g_assert (osssink != NULL);
parse = gst_elementfactory_make ("mp3parse", "parse"); decode = gst_elementfactory_make ("mad", "decode");
decode = gst_elementfactory_make ("mpg123", "decode"); g_assert (decode != NULL);
/* add objects to the main bin */ /* add objects to the main bin */
gst_bin_add (GST_BIN (bin), filesrc); gst_bin_add (GST_BIN (bin), filesrc);
gst_bin_add (GST_BIN (bin), queue); 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), decode);
gst_bin_add (GST_BIN (thread), queue2); 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_pad_connect (gst_element_get_pad (filesrc,"src"),
gst_element_get_pad (queue,"sink")); gst_element_get_pad (queue,"sink"));
gst_pad_connect (gst_element_get_pad (queue,"src"), 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_element_get_pad (decode,"sink"));
gst_pad_connect (gst_element_get_pad (decode,"src"), gst_pad_connect (gst_element_get_pad (decode,"src"),
gst_element_get_pad (queue2,"sink")); gst_element_get_pad (queue2,"sink"));
gst_pad_connect (gst_element_get_pad (queue2,"src"), 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), thread);
gst_bin_add (GST_BIN (bin), thread2); gst_bin_add (GST_BIN (bin), thread2);
// write the bin to disk /* write the bin to stdout */
xmlSaveFile ("xmlTest.gst", gst_xml_write (GST_ELEMENT (bin))); 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); exit (0);
} }
@ -103,12 +103,12 @@ main (int argc, char *argv[])
The most important line is: The most important line is:
</para> </para>
<programlisting> <programlisting>
xmlSaveFile ("xmlTest.gst", gst_xml_write (GST_ELEMENT (bin))); gst_xml_write_file (GST_ELEMENT (bin), stdout);
</programlisting> </programlisting>
<para> <para>
gst_xml_write () will turn the given element into and xmlDocPtr that gst_xml_write_file () will turn the given element into an xmlDocPtr that
can be saved with the xmlSaveFile () function found in the gnome-xml is then formatted and saved to a file. To save to disk, pass the result
package. The result is an XML file named xmlTest.gst. of a fopen(2) as the second argument.
</para> </para>
<para> <para>
The complete element hierarchy will be saved along with the inter element The complete element hierarchy will be saved along with the inter element

View file

@ -95,7 +95,7 @@ gst_play_have_type (GstElement *typefind, GstCaps *caps, GstElement *pipeline)
gst_element_set_state (pipeline, GST_STATE_PLAYING); gst_element_set_state (pipeline, GST_STATE_PLAYING);
#ifndef GST_DISABLE_LOADSAVE #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 #endif
} }

View 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 */ env_register_cp (channel_in->volenv, num_channels * 10.0 , 1.0 / num_channels); /* to end level */
#ifndef GST_DISABLE_LOADSAVE #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 #endif
/* start playing */ /* start playing */
@ -358,7 +358,7 @@ create_input_channel (int id, char* location)
#endif #endif
#ifndef GST_DISABLE_LOADSAVE #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 #endif
gst_bin_add (GST_BIN(channel->pipe), channel->volenv); gst_bin_add (GST_BIN(channel->pipe), channel->volenv);

View file

@ -2,25 +2,27 @@
#include <gst/gst.h> #include <gst/gst.h>
gboolean playing; gboolean playing;
xmlNsPtr ns;
static void static void
object_saved (GstObject *object, xmlNodePtr parent, gpointer data) object_saved (GstObject *object, xmlNodePtr parent, gpointer data)
{ {
xmlNodePtr child; 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); 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[]) int main(int argc,char *argv[])
{ {
GstElement *filesrc, *osssink, *queue, *queue2, *parse, *decode; GstElement *filesrc, *osssink, *queue, *queue2, *parse, *decode;
GstElement *bin; GstElement *pipeline;
GstElement *thread, *thread2; GstElement *thread, *thread2;
ns = xmlNewNs (NULL, "http://gstreamer.net/gst-test/1.0/", "test");
gst_init(&argc,&argv); gst_init(&argc,&argv);
if (argc != 2) { if (argc != 2) {
@ -28,68 +30,68 @@ int main(int argc,char *argv[])
exit(-1); exit(-1);
} }
/* create a new thread to hold the elements */ /* create new threads to hold the elements */
//thread = gst_thread_new("thread"); thread = gst_elementfactory_make ("thread", "thread");
thread = gst_elementfactory_make("thread", "thread"); g_assert (thread != NULL);
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_signal_connect (G_OBJECT (thread), "object_saved",
G_CALLBACK (object_saved), G_CALLBACK (object_saved),
g_strdup ("decoder thread")); 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_signal_connect (G_OBJECT (thread2), "object_saved",
G_CALLBACK (object_saved), G_CALLBACK (object_saved),
g_strdup ("render thread")); g_strdup ("render thread"));
/* create a new bin to hold the elements */ /* create a new bin to hold the elements */
bin = gst_bin_new("bin"); pipeline = gst_pipeline_new ("pipeline");
g_assert(bin != NULL); g_assert (pipeline != NULL);
/* create a disk reader */ /* create a disk reader */
filesrc = gst_elementfactory_make("filesrc", "disk_source"); filesrc = gst_elementfactory_make ("filesrc", "disk_source");
g_assert(filesrc != NULL); g_assert (filesrc != NULL);
g_object_set(G_OBJECT(filesrc),"location", argv[1],NULL); g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL);
queue = gst_elementfactory_make("queue", "queue"); queue = gst_elementfactory_make ("queue", "queue");
queue2 = gst_elementfactory_make("queue", "queue2"); queue2 = gst_elementfactory_make ("queue", "queue2");
/* and an audio sink */ /* and an audio sink */
osssink = gst_elementfactory_make("osssink", "play_audio"); osssink = gst_elementfactory_make ("osssink", "play_audio");
g_assert(osssink != NULL); g_assert (osssink != NULL);
parse = gst_elementfactory_make("mp3parse", "parse"); decode = gst_elementfactory_make ("mad", "decode");
decode = gst_elementfactory_make("mpg123", "decode"); g_assert (decode != NULL);
/* add objects to the main bin */ /* add objects to the main pipeline */
gst_bin_add(GST_BIN(bin), filesrc); gst_bin_add (GST_BIN (pipeline), filesrc);
gst_bin_add(GST_BIN(bin), queue); 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), decode); gst_bin_add (GST_BIN (thread), queue2);
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_pad_connect (gst_element_get_pad (queue,"src"),
gst_element_get_pad(queue,"sink")); 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_pad_connect (gst_element_get_pad (queue2,"src"),
gst_element_get_pad(parse,"sink")); gst_element_get_pad (osssink,"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_bin_add (GST_BIN (pipeline), thread);
gst_element_get_pad(osssink,"sink")); gst_bin_add (GST_BIN (pipeline), thread2);
gst_bin_add(GST_BIN(bin), thread); /* write the bin to stdout */
gst_bin_add(GST_BIN(bin), thread2); 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);
} }

View file

@ -29,27 +29,27 @@ xml_loaded (GstXML *xml, GstObject *object, xmlNodePtr self, gpointer data)
int main(int argc,char *argv[]) int main(int argc,char *argv[])
{ {
GstXML *xml; GstXML *xml;
GstElement *bin; GstElement *pipeline;
gboolean ret; gboolean ret;
gst_init(&argc,&argv); gst_init(&argc,&argv);
xml = gst_xml_new (); xml = gst_xml_new ();
g_signal_connect (G_OBJECT (xml), "object_loaded", // g_signal_connect (G_OBJECT (xml), "object_loaded",
G_CALLBACK (xml_loaded), xml); // G_CALLBACK (xml_loaded), xml);
ret = gst_xml_parse_file(xml, "xmlTest.gst", NULL); ret = gst_xml_parse_file(xml, "xmlTest.gst", NULL);
g_assert (ret == TRUE); g_assert (ret == TRUE);
bin = gst_xml_get_element(xml, "bin"); pipeline = gst_xml_get_element(xml, "pipeline");
g_assert (bin != NULL); 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); exit(0);
} }

View file

@ -717,8 +717,13 @@ gst_bin_restore_thyself (GstObject * object, xmlNodePtr self)
childlist = field->xmlChildrenNode; childlist = field->xmlChildrenNode;
while (childlist) { while (childlist) {
if (!strcmp (childlist->name, "element")) { 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); gst_bin_add (bin, element);
} }
childlist = childlist->next; childlist = childlist->next;

View file

@ -65,7 +65,7 @@ static void gst_element_send_event_func (GstElement *element, GstEvent *even
#ifndef GST_DISABLE_LOADSAVE #ifndef GST_DISABLE_LOADSAVE
static xmlNodePtr gst_element_save_thyself (GstObject *object, xmlNodePtr parent); 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 #endif
GType _gst_element_type = 0; GType _gst_element_type = 0;
@ -1094,9 +1094,11 @@ gst_element_save_thyself (GstObject *object,
{ {
GList *pads; GList *pads;
GstElementClass *oclass; GstElementClass *oclass;
/* FIXME : this is needed for glib2 */ GParamSpec **specs, *spec;
/* GType type; */ gint nspecs, i;
GValue value = { 0, };
GstElement *element; GstElement *element;
gchar *str;
g_return_val_if_fail (GST_IS_ELEMENT (object), parent); 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); xmlNewChild (parent, NULL, "version", factory->details->version);
} }
/* FIXME: what is this? */
/* if (element->manager) */ /* if (element->manager) */
/* xmlNewChild(parent, NULL, "manager", GST_ELEMENT_NAME(element->manager)); */ /* xmlNewChild(parent, NULL, "manager", GST_ELEMENT_NAME(element->manager)); */
/* FIXME FIXME FIXME! */ #ifdef USE_GLIB2
/* output all args to the element */ /* params */
/* specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (object), &nspecs);
type = G_OBJECT_TYPE (element);
while (type != G_TYPE_INVALID) { for (i=0; i<nspecs; i++) {
GtkArg *args; spec = specs[i];
guint32 *flags; if (spec->flags & G_PARAM_READABLE) {
guint num_args,i; xmlNodePtr param;
args = gtk_object_query_args (type, &flags, &num_args); g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE (spec));
for (i=0; i<num_args; i++) { g_object_get_property (G_OBJECT (element), spec->name, &value);
if ((args[i].type > G_TYPE_NONE) && param = xmlNewChild (parent, NULL, "param", NULL);
(flags[i] & GTK_ARG_READABLE)) { xmlNewChild (param, NULL, "name", spec->name);
xmlNodePtr arg;
gtk_object_getv (G_OBJECT (element), 1, &args[i]); if (G_IS_PARAM_SPEC_STRING (spec))
arg = xmlNewChild (parent, NULL, "arg", NULL); xmlNewChild (param, NULL, "value", g_value_dup_string (&value));
xmlNewChild (arg, NULL, "name", args[i].name); else if (G_IS_PARAM_SPEC_ENUM (spec))
switch (args[i].type) { xmlNewChild (param, NULL, "value", g_strdup_printf ("%d", g_value_get_enum (&value)));
case G_TYPE_CHAR: else
xmlNewChild (arg, NULL, "value", xmlNewChild (param, NULL, "value", g_strdup_value_contents (&value));
g_strdup_printf ("%c", G_VALUE_CHAR (args[i])));
break; g_value_unset(&value);
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;
}
}
} }
type = gtk_type_parent (type);
} }
*/ #endif
pads = GST_ELEMENT_PADS (element); pads = GST_ELEMENT_PADS (element);
@ -1197,53 +1161,21 @@ gst_element_save_thyself (GstObject *object,
return parent; return parent;
} }
/** static void
* gst_element_restore_thyself: gst_element_restore_thyself (GstObject *object, xmlNodePtr self)
* @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)
{ {
xmlNodePtr children = self->xmlChildrenNode; xmlNodePtr children;
GstElement *element; GstElement *element;
GstObjectClass *oclass;
guchar *name = NULL; guchar *name = NULL;
guchar *value = NULL; guchar *value = NULL;
guchar *type = NULL;
/* first get the needed tags to construct the element */ element = GST_ELEMENT (object);
while (children) { g_return_if_fail (element != NULL);
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); /* parameters */
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 */
children = self->xmlChildrenNode; children = self->xmlChildrenNode;
while (children) { while (children) {
if (!strcmp (children->name, "arg")) { if (!strcmp (children->name, "param")) {
xmlNodePtr child = children->xmlChildrenNode; xmlNodePtr child = children->xmlChildrenNode;
while (child) { while (child) {
@ -1255,13 +1187,14 @@ gst_element_restore_thyself (xmlNodePtr self, GstObject *parent)
} }
child = child->next; child = child->next;
} }
/* FIXME: can this just be g_object_set ? */
gst_util_set_object_arg ((GObject *)G_OBJECT (element), name, value); gst_util_set_object_arg ((GObject *)G_OBJECT (element), name, value);
} }
children = children->next; children = children->next;
} }
/* we have the element now, set the pads */
/* pads */
children = self->xmlChildrenNode; children = self->xmlChildrenNode;
while (children) { while (children) {
if (!strcmp (children->name, "pad")) { if (!strcmp (children->name, "pad")) {
gst_pad_load_and_connect (children, GST_OBJECT (element)); gst_pad_load_and_connect (children, GST_OBJECT (element));
@ -1269,16 +1202,8 @@ gst_element_restore_thyself (xmlNodePtr self, GstObject *parent)
children = children->next; children = children->next;
} }
oclass = GST_OBJECT_CLASS (G_OBJECT_GET_CLASS(element)); if (GST_OBJECT_CLASS(parent_class)->restore_thyself)
if (oclass->restore_thyself) (GST_OBJECT_CLASS(parent_class)->restore_thyself) (object, self);
(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;
} }
#endif /* GST_DISABLE_LOADSAVE */ #endif /* GST_DISABLE_LOADSAVE */
@ -1560,4 +1485,3 @@ gst_element_install_std_props (GstElementClass * klass, const char *first_name,
va_end (args); va_end (args);
} }

View file

@ -226,12 +226,6 @@ void gst_element_install_std_props (GstElementClass *klass,
const char *first_name, ...); const char *first_name, ...);
#ifndef GST_DISABLE_LOADSAVE
/* XML write and read */
GstElement* gst_element_restore_thyself (xmlNodePtr self, GstObject *parent);
#endif
/* /*
* *
* factories stuff * factories stuff

View 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_dispose (GObject *object);
static void gst_object_finalize (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 GObjectClass *parent_class = NULL;
static guint gst_object_signals[LAST_SIGNAL] = { 0 }; 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_STRUCT_OFFSET (GstObjectClass, object_saved), NULL, NULL,
g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1,
G_TYPE_POINTER); G_TYPE_POINTER);
klass->restore_thyself = gst_object_real_restore_thyself;
#endif #endif
klass->path_string_separator = "/"; 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->dispose = gst_object_dispose;
gobject_class->finalize = gst_object_finalize; gobject_class->finalize = gst_object_finalize;
@ -495,22 +501,35 @@ gst_object_save_thyself (GstObject *object, xmlNodePtr parent)
/** /**
* gst_object_restore_thyself: * gst_object_restore_thyself:
* @object: GstObject to load into * @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. * Restores the given object with the data from the parent XML node.
*/ */
void void
gst_object_restore_thyself (GstObject *object, xmlNodePtr parent) gst_object_restore_thyself (GstObject *object, xmlNodePtr self)
{ {
GstObjectClass *oclass; GstObjectClass *oclass;
g_return_if_fail (object != NULL); g_return_if_fail (object != NULL);
g_return_if_fail (GST_IS_OBJECT (object)); 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) 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 */ #endif /* GST_DISABLE_LOADSAVE_REGISTRY */

View file

@ -565,7 +565,7 @@ gst_queue_set_property (GObject *object, guint prop_id, const GValue *value, GPa
switch (prop_id) { switch (prop_id) {
case ARG_LEAKY: case ARG_LEAKY:
queue->leaky = g_value_get_int (value); queue->leaky = g_value_get_enum (value);
break; break;
case ARG_MAX_LEVEL: case ARG_MAX_LEVEL:
queue->size_buffers = g_value_get_int (value); 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) { switch (prop_id) {
case ARG_LEAKY: case ARG_LEAKY:
g_value_set_int (value, queue->leaky); g_value_set_enum (value, queue->leaky);
break; break;
case ARG_LEVEL: case ARG_LEVEL:
g_value_set_int (value, queue->level_buffers); g_value_set_int (value, queue->level_buffers);

View file

@ -113,11 +113,11 @@ gst_xml_write (GstElement *element)
xmlNsPtr ns; xmlNsPtr ns;
doc = xmlNewDoc ("1.0"); 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"); 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); elementnode = xmlNewChild (doc->xmlRootNode, ns, "element", NULL);
gst_object_save_thyself (GST_OBJECT (element), elementnode); 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)) { if (!strcmp(field->name, "element") && (field->ns == xml->ns)) {
GstElement *element; GstElement *element;
element = gst_element_restore_thyself(field, NULL); element = gst_xml_make_element (field, NULL);
xml->topelements = g_list_prepend (xml->topelements, element); xml->topelements = g_list_prepend (xml->topelements, element);
} }
@ -363,3 +363,49 @@ gst_xml_get_element (GstXML *xml, const guchar *name)
} }
return NULL; 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;
}

View 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); GstElement* gst_xml_get_element (GstXML *xml, const guchar *name);
GList* gst_xml_get_topelements (GstXML *xml); GList* gst_xml_get_topelements (GstXML *xml);
GstElement* gst_xml_make_element (xmlNodePtr cur, GstObject *parent);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */

View file

@ -565,7 +565,7 @@ gst_queue_set_property (GObject *object, guint prop_id, const GValue *value, GPa
switch (prop_id) { switch (prop_id) {
case ARG_LEAKY: case ARG_LEAKY:
queue->leaky = g_value_get_int (value); queue->leaky = g_value_get_enum (value);
break; break;
case ARG_MAX_LEVEL: case ARG_MAX_LEVEL:
queue->size_buffers = g_value_get_int (value); 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) { switch (prop_id) {
case ARG_LEAKY: case ARG_LEAKY:
g_value_set_int (value, queue->leaky); g_value_set_enum (value, queue->leaky);
break; break;
case ARG_LEVEL: case ARG_LEVEL:
g_value_set_int (value, queue->level_buffers); g_value_set_int (value, queue->level_buffers);

View file

@ -95,7 +95,7 @@ gst_play_have_type (GstElement *typefind, GstCaps *caps, GstElement *pipeline)
gst_element_set_state (pipeline, GST_STATE_PLAYING); gst_element_set_state (pipeline, GST_STATE_PLAYING);
#ifndef GST_DISABLE_LOADSAVE #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 #endif
} }

View 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 */ env_register_cp (channel_in->volenv, num_channels * 10.0 , 1.0 / num_channels); /* to end level */
#ifndef GST_DISABLE_LOADSAVE #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 #endif
/* start playing */ /* start playing */
@ -358,7 +358,7 @@ create_input_channel (int id, char* location)
#endif #endif
#ifndef GST_DISABLE_LOADSAVE #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 #endif
gst_bin_add (GST_BIN(channel->pipe), channel->volenv); gst_bin_add (GST_BIN(channel->pipe), channel->volenv);

View file

@ -2,25 +2,27 @@
#include <gst/gst.h> #include <gst/gst.h>
gboolean playing; gboolean playing;
xmlNsPtr ns;
static void static void
object_saved (GstObject *object, xmlNodePtr parent, gpointer data) object_saved (GstObject *object, xmlNodePtr parent, gpointer data)
{ {
xmlNodePtr child; 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); 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[]) int main(int argc,char *argv[])
{ {
GstElement *filesrc, *osssink, *queue, *queue2, *parse, *decode; GstElement *filesrc, *osssink, *queue, *queue2, *parse, *decode;
GstElement *bin; GstElement *pipeline;
GstElement *thread, *thread2; GstElement *thread, *thread2;
ns = xmlNewNs (NULL, "http://gstreamer.net/gst-test/1.0/", "test");
gst_init(&argc,&argv); gst_init(&argc,&argv);
if (argc != 2) { if (argc != 2) {
@ -28,68 +30,68 @@ int main(int argc,char *argv[])
exit(-1); exit(-1);
} }
/* create a new thread to hold the elements */ /* create new threads to hold the elements */
//thread = gst_thread_new("thread"); thread = gst_elementfactory_make ("thread", "thread");
thread = gst_elementfactory_make("thread", "thread"); g_assert (thread != NULL);
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_signal_connect (G_OBJECT (thread), "object_saved",
G_CALLBACK (object_saved), G_CALLBACK (object_saved),
g_strdup ("decoder thread")); 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_signal_connect (G_OBJECT (thread2), "object_saved",
G_CALLBACK (object_saved), G_CALLBACK (object_saved),
g_strdup ("render thread")); g_strdup ("render thread"));
/* create a new bin to hold the elements */ /* create a new bin to hold the elements */
bin = gst_bin_new("bin"); pipeline = gst_pipeline_new ("pipeline");
g_assert(bin != NULL); g_assert (pipeline != NULL);
/* create a disk reader */ /* create a disk reader */
filesrc = gst_elementfactory_make("filesrc", "disk_source"); filesrc = gst_elementfactory_make ("filesrc", "disk_source");
g_assert(filesrc != NULL); g_assert (filesrc != NULL);
g_object_set(G_OBJECT(filesrc),"location", argv[1],NULL); g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL);
queue = gst_elementfactory_make("queue", "queue"); queue = gst_elementfactory_make ("queue", "queue");
queue2 = gst_elementfactory_make("queue", "queue2"); queue2 = gst_elementfactory_make ("queue", "queue2");
/* and an audio sink */ /* and an audio sink */
osssink = gst_elementfactory_make("osssink", "play_audio"); osssink = gst_elementfactory_make ("osssink", "play_audio");
g_assert(osssink != NULL); g_assert (osssink != NULL);
parse = gst_elementfactory_make("mp3parse", "parse"); decode = gst_elementfactory_make ("mad", "decode");
decode = gst_elementfactory_make("mpg123", "decode"); g_assert (decode != NULL);
/* add objects to the main bin */ /* add objects to the main pipeline */
gst_bin_add(GST_BIN(bin), filesrc); gst_bin_add (GST_BIN (pipeline), filesrc);
gst_bin_add(GST_BIN(bin), queue); 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), decode); gst_bin_add (GST_BIN (thread), queue2);
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_pad_connect (gst_element_get_pad (queue,"src"),
gst_element_get_pad(queue,"sink")); 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_pad_connect (gst_element_get_pad (queue2,"src"),
gst_element_get_pad(parse,"sink")); gst_element_get_pad (osssink,"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_bin_add (GST_BIN (pipeline), thread);
gst_element_get_pad(osssink,"sink")); gst_bin_add (GST_BIN (pipeline), thread2);
gst_bin_add(GST_BIN(bin), thread); /* write the bin to stdout */
gst_bin_add(GST_BIN(bin), thread2); 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);
} }

View file

@ -29,27 +29,27 @@ xml_loaded (GstXML *xml, GstObject *object, xmlNodePtr self, gpointer data)
int main(int argc,char *argv[]) int main(int argc,char *argv[])
{ {
GstXML *xml; GstXML *xml;
GstElement *bin; GstElement *pipeline;
gboolean ret; gboolean ret;
gst_init(&argc,&argv); gst_init(&argc,&argv);
xml = gst_xml_new (); xml = gst_xml_new ();
g_signal_connect (G_OBJECT (xml), "object_loaded", // g_signal_connect (G_OBJECT (xml), "object_loaded",
G_CALLBACK (xml_loaded), xml); // G_CALLBACK (xml_loaded), xml);
ret = gst_xml_parse_file(xml, "xmlTest.gst", NULL); ret = gst_xml_parse_file(xml, "xmlTest.gst", NULL);
g_assert (ret == TRUE); g_assert (ret == TRUE);
bin = gst_xml_get_element(xml, "bin"); pipeline = gst_xml_get_element(xml, "pipeline");
g_assert (bin != NULL); 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); exit(0);
} }

View file

@ -40,7 +40,7 @@ int main (int argc, char *argv[])
gst_element_connect(fakesrc, "src", fakesink2, "sink"); gst_element_connect(fakesrc, "src", fakesink2, "sink");
// show the pipeline state // show the pipeline state
xmlDocDump(stdout, gst_xml_write(pipe2)); gst_xml_write_file (GST_ELEMENT (pipe2), stdout);
// try to iterate the pipeline // try to iterate the pipeline
gst_element_set_state(pipe2, GST_STATE_PLAYING); gst_element_set_state(pipe2, GST_STATE_PLAYING);

View file

@ -141,7 +141,7 @@ main(int argc, char *argv[])
#ifndef GST_DISABLE_LOADSAVE #ifndef GST_DISABLE_LOADSAVE
if (save_pipeline) { if (save_pipeline) {
xmlSaveFile (savefile, gst_xml_write (pipeline)); gst_xml_write_file (GST_ELEMENT (pipeline), fopen (savefile, "w"));
} }
#endif #endif
if (run_pipeline) { if (run_pipeline) {