mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-27 18:50:48 +00:00
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:
parent
7291b0f7e8
commit
2a4a536fee
13 changed files with 393 additions and 10 deletions
|
@ -1,4 +1,4 @@
|
|||
SUBDIRS = manual fwg gst libs
|
||||
SUBDIRS = manual fwg gst libs
|
||||
|
||||
EXTRA_DIST = random slides manuals.mak
|
||||
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
<chapter id="cha-components">
|
||||
<title>Components</title>
|
||||
<para>
|
||||
<application>GStreamer</application> includes components that people can include
|
||||
in their programs.
|
||||
</para>
|
||||
|
||||
<sect1>
|
||||
<title>GstPlay</title>
|
||||
<para>
|
||||
GstPlay is a GtkWidget with a simple API to play, pause and stop a media file.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
@ -13,6 +16,7 @@
|
|||
<sect1>
|
||||
<title>GstMediaPlay</title>
|
||||
<para>
|
||||
GstMediaply is a complete player widget.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
@ -20,6 +24,8 @@
|
|||
<sect1>
|
||||
<title>GstEditor</title>
|
||||
<para>
|
||||
GstEditor is a set of widgets to display a graphical representation of a
|
||||
pipeline.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
|
|
|
@ -8,13 +8,13 @@
|
|||
<para>
|
||||
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
|
||||
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>
|
||||
Queues are mostly used in conjunction with a <classname>GstThread</classname> to
|
||||
provide an external connection for the thread elements. You could have one
|
||||
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.
|
||||
</para>
|
||||
|
||||
|
@ -27,6 +27,110 @@
|
|||
<graphic fileref="images/queue" format="png"></graphic>
|
||||
</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 <stdlib.h>
|
||||
#include <gst/gst.h>
|
||||
|
||||
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 (&argc,&argv);
|
||||
|
||||
if (argc != 2) {
|
||||
g_print ("usage: %s <filename>\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>
|
||||
|
|
|
@ -44,6 +44,38 @@
|
|||
</para>
|
||||
</listitem>
|
||||
</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>
|
||||
<term>28 Dec 2000</term>
|
||||
<listitem>
|
||||
|
|
|
@ -41,6 +41,55 @@
|
|||
<graphic fileref="images/state-diagram" format="png"></graphic>
|
||||
</figure>
|
||||
</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 id="sec-states-null">
|
||||
|
|
|
@ -1,6 +1,178 @@
|
|||
<chapter id="cha-xml">
|
||||
<title>XML in GStreamer</title>
|
||||
<title>XML in <application>GStreamer</application></title>
|
||||
<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>
|
||||
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 <stdlib.h>
|
||||
#include <gst/gst.h>
|
||||
|
||||
gboolean playing;
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
GstElement *disksrc, *audiosink, *queue, *queue2, *parse, *decode;
|
||||
GstElement *bin;
|
||||
GstElement *thread, *thread2;
|
||||
|
||||
gst_init (&argc,&argv);
|
||||
|
||||
if (argc != 2) {
|
||||
g_print ("usage: %s <filename>\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 <stdlib.h>
|
||||
#include <gst/gst.h>
|
||||
|
||||
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 (&argc, &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>
|
||||
|
|
|
@ -15,7 +15,7 @@ LDADD = $(GLIB_LIBS) $(GTK_LIBS) $(top_srcdir)/gst/libgst.la
|
|||
CFLAGS = `gstreamer-config --cflags` -Wall -g
|
||||
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
|
||||
|
||||
|
|
|
@ -835,7 +835,8 @@ output_widget_pads (FILE *fp, GstElement *element)
|
|||
GstPad *pad = (GstPad *)pads->data;
|
||||
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",
|
||||
gtk_type_name(factory->type), pad->name);
|
||||
|
|
|
@ -21,6 +21,7 @@ tcS: id1, element, signalname (attach to signal in an element)
|
|||
tcS: id2, element, signalname
|
||||
...
|
||||
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)
|
||||
or
|
||||
tcR: id1==id2,... (denote an equal number of signals)
|
||||
|
|
|
@ -23,7 +23,6 @@ int main(int argc,char *argv[])
|
|||
|
||||
bin = gst_xml_get_element(xml, "bin");
|
||||
|
||||
gst_element_set_state(bin, GST_STATE_READY);
|
||||
gst_element_set_state(bin, GST_STATE_PLAYING);
|
||||
|
||||
playing = TRUE;
|
||||
|
|
22
gst/gstxml.c
22
gst/gstxml.c
|
@ -23,6 +23,7 @@
|
|||
#include "gst_private.h"
|
||||
|
||||
#include "gstxml.h"
|
||||
#include "gstbin.h"
|
||||
|
||||
|
||||
static void gst_xml_class_init (GstXMLClass *klass);
|
||||
|
@ -175,13 +176,30 @@ GstElement*
|
|||
gst_xml_get_element (GstXML *xml, const guchar *name)
|
||||
{
|
||||
GstElement *element;
|
||||
GList *topelements;
|
||||
|
||||
g_return_val_if_fail(xml != NULL, NULL);
|
||||
g_return_val_if_fail(name != NULL, NULL);
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@ int main(int argc,char *argv[])
|
|||
|
||||
bin = gst_xml_get_element(xml, "bin");
|
||||
|
||||
gst_element_set_state(bin, GST_STATE_READY);
|
||||
gst_element_set_state(bin, GST_STATE_PLAYING);
|
||||
|
||||
playing = TRUE;
|
||||
|
|
|
@ -3,6 +3,7 @@ tcP: fakesrc ! fakesink
|
|||
tcS: A, fakesrc0, handoff
|
||||
tcS: B, fakesink0, handoff
|
||||
tcI: 2
|
||||
tcT: 2000
|
||||
tcR: A,1,B,1,A,1,B,1
|
||||
|
||||
|
||||
|
@ -12,5 +13,6 @@ tcS: A, fakesrc0, handoff
|
|||
tcS: B, identity, handoff
|
||||
tcS: C, fakesink0, handoff
|
||||
tcI: 2
|
||||
tcT: 2000
|
||||
tcR: A,1,B,1,C,1,A,1,B,1,C,1
|
||||
|
||||
|
|
Loading…
Reference in a new issue