Manual updates. fixes to gstxml.c gst_xml_get_element was broken

Original commit message from CVS:
Manual updates.
fixes to gstxml.c gst_xml_get_element was broken
This commit is contained in:
Wim Taymans 2001-01-08 22:08:40 +00:00
parent 7291b0f7e8
commit 2a4a536fee
13 changed files with 393 additions and 10 deletions

View file

@ -1,4 +1,4 @@
SUBDIRS = manual fwg gst libs SUBDIRS = manual fwg gst libs
EXTRA_DIST = random slides manuals.mak EXTRA_DIST = random slides manuals.mak

View file

@ -1,11 +1,14 @@
<chapter id="cha-components"> <chapter id="cha-components">
<title>Components</title> <title>Components</title>
<para> <para>
<application>GStreamer</application> includes components that people can include
in their programs.
</para> </para>
<sect1> <sect1>
<title>GstPlay</title> <title>GstPlay</title>
<para> <para>
GstPlay is a GtkWidget with a simple API to play, pause and stop a media file.
</para> </para>
</sect1> </sect1>
@ -13,6 +16,7 @@
<sect1> <sect1>
<title>GstMediaPlay</title> <title>GstMediaPlay</title>
<para> <para>
GstMediaply is a complete player widget.
</para> </para>
</sect1> </sect1>
@ -20,6 +24,8 @@
<sect1> <sect1>
<title>GstEditor</title> <title>GstEditor</title>
<para> <para>
GstEditor is a set of widgets to display a graphical representation of a
pipeline.
</para> </para>
</sect1> </sect1>

View file

@ -8,13 +8,13 @@
<para> <para>
A buffer that is sinked to a Queue will not automatically be pushed to the A buffer that is sinked to a Queue will not automatically be pushed to the
next connected element but will be buffered. It will be pushed to the next next connected element but will be buffered. It will be pushed to the next
element as soon as gst_connection_push () is called. element as soon as a gst_pad_pull () is called on the queues srcpad.
</para> </para>
<para> <para>
Queues are mostly used in conjunction with a <classname>GstThread</classname> to Queues are mostly used in conjunction with a <classname>GstThread</classname> to
provide an external connection for the thread elements. You could have one provide an external connection for the thread elements. You could have one
thread feeding buffers into a <classname>GstQueue</classname> and another thread feeding buffers into a <classname>GstQueue</classname> and another
thread repeadedly calling gst_connection_push () on the queue to feed its thread repeadedly calling gst_pad_pull () on the queue to feed its
internal elements. internal elements.
</para> </para>
@ -27,6 +27,110 @@
<graphic fileref="images/queue" format="png"></graphic> <graphic fileref="images/queue" format="png"></graphic>
</figure> </figure>
<para>
The standard <application>GStreamer</application> queue implementation has some
properties that can be changed using the gtk_objet_set () method. To set the
maximum number of buffers that can be queued to 30, do:
</para>
<programlisting>
gtk_object_set (GTK_OBJECT (queue), "max_level", 30, NULL);
</programlisting>
<para>
The following mp3 player shows you how to create the above pipeline using a
thread and a queue.
</para>
<programlisting>
#include &lt;stdlib.h&gt;
#include &lt;gst/gst.h&gt;
gboolean playing;
/* eos will be called when the src element has an end of stream */
void
eos (GstElement *element, gpointer data)
{
g_print ("have eos, quitting\n");
playing = FALSE;
}
int
main (int argc, char *argv[])
{
GstElement *disksrc, *audiosink, *queue, *parse, *decode;
GstElement *bin;
GstElement *thread;
gst_init (&amp;argc,&amp;argv);
if (argc != 2) {
g_print ("usage: %s &lt;filename&gt;\n", argv[0]);
exit (-1);
}
/* create a new thread to hold the elements */
thread = gst_thread_new ("thread");
g_assert (thread != NULL);
/* create a new bin to hold the elements */
bin = gst_bin_new ("bin");
g_assert (bin != NULL);
/* create a disk reader */
disksrc = gst_elementfactory_make ("disksrc", "disk_source");
g_assert (disksrc != NULL);
gtk_object_set (GTK_OBJECT (disksrc), "location", argv[1], NULL);
gtk_signal_connect (GTK_OBJECT (disksrc), "eos",
GTK_SIGNAL_FUNC (eos), thread);
queue = gst_elementfactory_make ("queue", "queue");
/* and an audio sink */
audiosink = gst_elementfactory_make ("audiosink", "play_audio");
g_assert (audiosink != NULL);
parse = gst_elementfactory_make ("mp3parse", "parse");
decode = gst_elementfactory_make ("mpg123", "decode");
/* add objects to the main bin */
gst_bin_add (GST_BIN (bin), disksrc);
gst_bin_add (GST_BIN (bin), queue);
gst_bin_add (GST_BIN (thread), parse);
gst_bin_add (GST_BIN (thread), decode);
gst_bin_add (GST_BIN (thread), audiosink);
gst_pad_connect (gst_element_get_pad (disksrc,"src"),
gst_element_get_pad (queue,"sink"));
gst_pad_connect (gst_element_get_pad (queue, "src"),
gst_element_get_pad (parse, "sink"));
gst_pad_connect (gst_element_get_pad (parse, "src"),
gst_element_get_pad (decode, "sink"));
gst_pad_connect (gst_element_get_pad (decode, "src"),
gst_element_get_pad (audiosink, "sink"));
gst_bin_add (GST_BIN (bin), thread);
/* make it ready */
gst_element_set_state (GST_ELEMENT (bin), GST_STATE_READY);
/* start playing */
gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PLAYING);
playing = TRUE;
while (playing) {
gst_bin_iterate (GST_BIN (bin));
}
gst_element_set_state (GST_ELEMENT (bin), GST_STATE_NULL);
exit (0);
}
</programlisting>
</chapter> </chapter>

View file

@ -44,6 +44,38 @@
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>5/6 Jan 2001</term>
<listitem>
<para>
<emphasis>wtay:</emphasis>
we need to cut down the time to create an mp3 player down to
seconds...
</para>
<para>
<emphasis>richardb:</emphasis>
:)
</para>
<para>
<emphasis>Omega:</emphasis>
I'm wanting to something more interesting soon, I did the "draw an mp3
player in 15sec" back in October '99.
</para>
<para>
<emphasis>wtay:</emphasis>
by the time Omega gets his hands on the editor, you'll see a
complete audio mixer in the editor :-)
</para>
<para>
<emphasis>richardb:</emphasis>
Well, it clearly has the potential...
</para>
<para>
<emphasis>Omega:</emphasis>
Working on it... ;-)
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term>28 Dec 2000</term> <term>28 Dec 2000</term>
<listitem> <listitem>

View file

@ -41,6 +41,55 @@
<graphic fileref="images/state-diagram" format="png"></graphic> <graphic fileref="images/state-diagram" format="png"></graphic>
</figure> </figure>
</para> </para>
<para>
The state of an element can be changed with the following code:
</para>
<programlisting>
GstElement *bin;
// create a bin, put elements in it and connect them
...
gst_element_set_state (bin, GST_STATE_PLAYING);
...
</programlisting>
<para>
You can set the following states to an element:
</para>
<informaltable pgwide=1 frame="none" role="enum">
<tgroup cols="2">
<colspec colwidth="2*">
<colspec colwidth="8*">
<tbody>
<row>
<entry><literal>GST_STATE_NONE_PENDING</literal></entry>
<entry>The element is in the desired state.
</entry>
</row>
<row>
<entry><literal>GST_STATE_NULL</literal></entry>
<entry>Reset the state of an element.
</entry>
</row>
<row>
<entry><literal>GST_STATE_READY</literal></entry>
<entry>will make the element ready to start processing data.
</entry>
</row>
<row>
<entry><literal>GST_STATE_PLAYING</literal></entry>
<entry>means there really is data flowing through the graph.
</entry>
</row>
<row>
<entry><literal>GST_STATE_PAUSED</literal></entry>
<entry>temporary stops the data flow.
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</sect1> </sect1>
<sect1 id="sec-states-null"> <sect1 id="sec-states-null">

View file

@ -1,6 +1,178 @@
<chapter id="cha-xml"> <chapter id="cha-xml">
<title>XML in GStreamer</title> <title>XML in <application>GStreamer</application></title>
<para> <para>
<application>GStreamer</application> uses XML to store and load
its pipeline definitions. XML is also used internally to manage the
plugin registry. The plugin registry is a file that contains the definition
of all the plugins <application>GStreamer</application> knows about to have
quick access to the specifics of the plugins.
</para> </para>
<para>
We will show you how you can save a pipeline to XML and how you can reload that
XML file again for later use.
</para>
<sect1 id="sec-xml-write">
<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.
</para>
<programlisting>
#include &lt;stdlib.h&gt;
#include &lt;gst/gst.h&gt;
gboolean playing;
int
main (int argc, char *argv[])
{
GstElement *disksrc, *audiosink, *queue, *queue2, *parse, *decode;
GstElement *bin;
GstElement *thread, *thread2;
gst_init (&amp;argc,&amp;argv);
if (argc != 2) {
g_print ("usage: %s &lt;filename&gt;\n", argv[0]);
exit (-1);
}
/* create a new thread to hold the elements */
thread = gst_elementfactory_make ("thread", "thread");
g_assert (thread != NULL);
thread2 = gst_elementfactory_make ("thread", "thread2");
g_assert (thread2 != NULL);
/* create a new bin to hold the elements */
bin = gst_bin_new ("bin");
g_assert (bin != NULL);
/* create a disk reader */
disksrc = gst_elementfactory_make ("disksrc", "disk_source");
g_assert (disksrc != NULL);
gtk_object_set (GTK_OBJECT (disksrc), "location", argv[1], NULL);
queue = gst_elementfactory_make ("queue", "queue");
queue2 = gst_elementfactory_make ("queue", "queue2");
/* and an audio sink */
audiosink = gst_elementfactory_make ("audiosink", "play_audio");
g_assert (audiosink != NULL);
parse = gst_elementfactory_make ("mp3parse", "parse");
decode = gst_elementfactory_make ("mpg123", "decode");
/* add objects to the main bin */
gst_bin_add (GST_BIN (bin), disksrc);
gst_bin_add (GST_BIN (bin), queue);
gst_bin_add (GST_BIN (thread), parse);
gst_bin_add (GST_BIN (thread), decode);
gst_bin_add (GST_BIN (thread), queue2);
gst_bin_add (GST_BIN (thread2), audiosink);
gst_pad_connect (gst_element_get_pad (disksrc,"src"),
gst_element_get_pad (queue,"sink"));
gst_pad_connect (gst_element_get_pad (queue,"src"),
gst_element_get_pad (parse,"sink"));
gst_pad_connect (gst_element_get_pad (parse,"src"),
gst_element_get_pad (decode,"sink"));
gst_pad_connect (gst_element_get_pad (decode,"src"),
gst_element_get_pad (queue2,"sink"));
gst_pad_connect (gst_element_get_pad (queue2,"src"),
gst_element_get_pad (audiosink,"sink"));
gst_bin_add (GST_BIN (bin), thread);
gst_bin_add (GST_BIN (bin), thread2);
// write the bin to disk
xmlSaveFile ("xmlTest.gst", gst_xml_write (GST_ELEMENT (bin)));
exit (0);
}
</programlisting>
<para>
The most important line is:
</para>
<programlisting>
xmlSaveFile ("xmlTest.gst", gst_xml_write (GST_ELEMENT (bin)));
</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.
</para>
<para>
The complete element hierarchy will be saved along with the inter element
pad connections and the element parameters. Future <application>GStreamer</application>
versions will also allow you to store the signals in the XML file.
</para>
</sect1>
<sect1 id="sec-xml-load">
<title>Loading a GstElement from an XML file</title>
<para>
A saved XML file can be loade with the gst_xml_new (filename, rootelement).
The root element can optionally left NULL. The following code example loads
the previously created XML file and runs it.
</para>
<programlisting>
#include &lt;stdlib.h&gt;
#include &lt;gst/gst.h&gt;
gboolean playing;
/* eos will be called when the src element has an end of stream */
void
eos (GstElement *element, gpointer data)
{
g_print ("have eos, quitting\n");
playing = FALSE;
}
int
main(int argc, char *argv[])
{
GstXML *xml;
GstElement *bin;
GstElement *disk;
gst_init (&amp;argc, &amp;argv);
xml = gst_xml_new ("xmlTest.gst", NULL);
bin = gst_xml_get_element (xml, "bin");
gst_element_set_state (bin, GST_STATE_PLAYING);
playing = TRUE;
while (playing) {
gst_bin_iterate (GST_BIN (bin));
}
gst_element_set_state (bin, GST_STATE_NULL);
exit (0);
}
</programlisting>
<para>
gst_xml_get_element (xml, "name") can be used to get a specific element
from the XML file.
</para>
<para>
gst_xml_get_topelements (xml) can be used to get a list of all toplevel elements
in the XML file.
</para>
</sect1>
</chapter> </chapter>

View file

@ -15,7 +15,7 @@ LDADD = $(GLIB_LIBS) $(GTK_LIBS) $(top_srcdir)/gst/libgst.la
CFLAGS = `gstreamer-config --cflags` -Wall -g CFLAGS = `gstreamer-config --cflags` -Wall -g
LDFLAGS = `gstreamer-config --libs` LDFLAGS = `gstreamer-config --libs`
EXTRA_DIST=$(DOC_MODULE).types.in EXTRA_DIST=$(DOC_MODULE).types.in $(DOC_MODULE)-sections.txt $(DOC_MAIN_SGML_FILE) gstdoc-mkdb gstdoc-mktmpl gstdoc-scanobj
HTML_DIR=$(datadir)/$(DOC_MODULE)/html HTML_DIR=$(datadir)/$(DOC_MODULE)/html

View file

@ -835,7 +835,8 @@ output_widget_pads (FILE *fp, GstElement *element)
GstPad *pad = (GstPad *)pads->data; GstPad *pad = (GstPad *)pads->data;
GstType *type; GstType *type;
type = gst_type_find_by_id(pad->type); //type = gst_type_find_by_id(pad->type);
type = gst_type_find_by_id(1);
fprintf (fp, "<PAD>\n<NAME>%s::%s</NAME>\n", fprintf (fp, "<PAD>\n<NAME>%s::%s</NAME>\n",
gtk_type_name(factory->type), pad->name); gtk_type_name(factory->type), pad->name);

View file

@ -21,6 +21,7 @@ tcS: id1, element, signalname (attach to signal in an element)
tcS: id2, element, signalname tcS: id2, element, signalname
... ...
tcI: the number of iterations on the top bin tcI: the number of iterations on the top bin
tcT: a timeout value in mSecs
tcR: id1,1,id2,1,.. (the pattern of signals trigered) tcR: id1,1,id2,1,.. (the pattern of signals trigered)
or or
tcR: id1==id2,... (denote an equal number of signals) tcR: id1==id2,... (denote an equal number of signals)

View file

@ -23,7 +23,6 @@ int main(int argc,char *argv[])
bin = gst_xml_get_element(xml, "bin"); bin = gst_xml_get_element(xml, "bin");
gst_element_set_state(bin, GST_STATE_READY);
gst_element_set_state(bin, GST_STATE_PLAYING); gst_element_set_state(bin, GST_STATE_PLAYING);
playing = TRUE; playing = TRUE;

View file

@ -23,6 +23,7 @@
#include "gst_private.h" #include "gst_private.h"
#include "gstxml.h" #include "gstxml.h"
#include "gstbin.h"
static void gst_xml_class_init (GstXMLClass *klass); static void gst_xml_class_init (GstXMLClass *klass);
@ -175,13 +176,30 @@ GstElement*
gst_xml_get_element (GstXML *xml, const guchar *name) gst_xml_get_element (GstXML *xml, const guchar *name)
{ {
GstElement *element; GstElement *element;
GList *topelements;
g_return_val_if_fail(xml != NULL, NULL); g_return_val_if_fail(xml != NULL, NULL);
g_return_val_if_fail(name != NULL, NULL); g_return_val_if_fail(name != NULL, NULL);
GST_DEBUG (0,"gstxml: getting element \"%s\"\n", name); GST_DEBUG (0,"gstxml: getting element \"%s\"\n", name);
element = g_hash_table_lookup(xml->elements, name); topelements = gst_xml_get_topelements (xml);
return element; while (topelements) {
GstElement *top = GST_ELEMENT (topelements->data);
if (!strcmp (gst_element_get_name (top), name)) {
return top;
}
else {
if (GST_IS_BIN (top)) {
element = gst_bin_get_by_name (GST_BIN (top), name);
if (element)
return element;
}
}
topelements = g_list_next (topelements);
}
return NULL;
} }

View file

@ -23,7 +23,6 @@ int main(int argc,char *argv[])
bin = gst_xml_get_element(xml, "bin"); bin = gst_xml_get_element(xml, "bin");
gst_element_set_state(bin, GST_STATE_READY);
gst_element_set_state(bin, GST_STATE_PLAYING); gst_element_set_state(bin, GST_STATE_PLAYING);
playing = TRUE; playing = TRUE;

View file

@ -3,6 +3,7 @@ tcP: fakesrc ! fakesink
tcS: A, fakesrc0, handoff tcS: A, fakesrc0, handoff
tcS: B, fakesink0, handoff tcS: B, fakesink0, handoff
tcI: 2 tcI: 2
tcT: 2000
tcR: A,1,B,1,A,1,B,1 tcR: A,1,B,1,A,1,B,1
@ -12,5 +13,6 @@ tcS: A, fakesrc0, handoff
tcS: B, identity, handoff tcS: B, identity, handoff
tcS: C, fakesink0, handoff tcS: C, fakesink0, handoff
tcI: 2 tcI: 2
tcT: 2000
tcR: A,1,B,1,C,1,A,1,B,1,C,1 tcR: A,1,B,1,C,1,A,1,B,1,C,1