helloworld example. and docs

Original commit message from CVS:
helloworld example. and docs
This commit is contained in:
Wim Taymans 2000-08-18 20:38:54 +00:00
parent 6661696de0
commit 284ecaecca
6 changed files with 589 additions and 0 deletions

View file

@ -0,0 +1,51 @@
#FIG 3.2
Landscape
Center
Inches
Letter
100.00
Single
-2
1200 2
2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
2100 2775 4050 2775 4050 4425 2100 4425 2100 2775
2 2 0 1 0 6 50 0 20 0.000 0 0 -1 0 0 5
3300 3600 4050 3600 4050 4125 3300 4125 3300 3600
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 90.00 120.00
4050 3750 4575 3750
2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
4575 2775 6525 2775 6525 4425 4575 4425 4575 2775
2 2 0 1 0 6 50 0 20 0.000 0 0 -1 0 0 5
4575 3600 5325 3600 5325 4125 4575 4125 4575 3600
2 2 0 1 0 6 50 0 20 0.000 0 0 -1 0 0 5
5775 3600 6525 3600 6525 4125 5775 4125 5775 3600
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 90.00 120.00
6525 3750 7125 3750
2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
7125 2775 9075 2775 9075 4425 7125 4425 7125 2775
2 2 0 1 0 6 50 0 20 0.000 0 0 -1 0 0 5
7125 3600 7875 3600 7875 4125 7125 4125 7125 3600
2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
9600 2775 11550 2775 11550 4425 9600 4425 9600 2775
2 2 0 1 0 6 50 0 20 0.000 0 0 -1 0 0 5
8325 3600 9075 3600 9075 4125 8325 4125 8325 3600
2 2 0 1 0 6 50 0 20 0.000 0 0 -1 0 0 5
9600 3600 10350 3600 10350 4125 9600 4125 9600 3600
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 90.00 120.00
9075 3750 9600 3750
2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
1950 1950 11700 1950 11700 4800 1950 4800 1950 1950
4 0 0 50 0 16 12 0.0000 4 135 255 2175 2250 bin\001
4 0 0 50 0 16 12 0.0000 4 105 255 3525 3975 src\001
4 0 0 50 0 16 12 0.0000 4 135 330 4725 3975 sink\001
4 0 0 50 0 16 12 0.0000 4 105 255 6075 3975 src\001
4 0 0 50 0 16 12 0.0000 4 135 330 7350 3975 sink\001
4 0 0 50 0 16 12 0.0000 4 105 255 8625 3975 src\001
4 0 0 50 0 16 12 0.0000 4 135 330 9750 3975 sink\001
4 0 0 50 0 16 12 0.0000 4 165 1005 2250 3075 disk_source\001
4 0 0 50 0 16 12 0.0000 4 150 465 4725 3075 parse\001
4 0 0 50 0 16 12 0.0000 4 135 690 7275 3075 decoder\001
4 0 0 50 0 16 12 0.0000 4 180 930 9750 3075 play_audio\001

362
docs/manual/helloworld.sgml Normal file
View file

@ -0,0 +1,362 @@
<chapter id="cha-hello">
<title>Your first application</title>
<para>
This chapter describes the most rudimentary aspects of a GStreamer application,
including initializing the libraries, creating elements, packing them into
a pipeline and playing, pause and stop the pipeline.
</para>
<sect1>
<title>Hello world</title>
<para>
We will create a simple first application. In fact it will be a complete
MP3 player, using standard GStreamer components. The player will read from
a file that is given as the first argument of the program.
</para>
<programlisting>
#include &lt;gst/gst.h&gt;
gboolean playing;
/* eos will be called when the src element has an end of stream */
void eos(GstSrc *src)
{
g_print("have eos, quitting\n");
playing = FALSE;
}
int main(int argc,char *argv[])
{
GstElement *bin, *disksrc, *parse, *decoder, *audiosink;
if (argc != 2) {
g_print("usage: %s &lt;filename&gt;n", argv[0]);
exit(-1);
}
gst_init(&amp;argc,&amp;argv);
gst_plugin_load_all();
g_print("\n");
/* create a new bin to hold the elements */
bin = gst_bin_new("bin");
/* create a disk reader */
disksrc = gst_elementfactory_make("disksrc", "disk_source");
gtk_object_set(GTK_OBJECT(disksrc),"location", argv[1],NULL);
gtk_signal_connect(GTK_OBJECT(disksrc),"eos",
GTK_SIGNAL_FUNC(eos),NULL);
/* now it's time to get the parser */
parse = gst_elementfactory_make("mp3parse","parse");
decoder = gst_elementfactory_make("mpg123","decoder");
/* and an audio sink */
audiosink = gst_elementfactory_make("audiosink", "play_audio");
/* add objects to the main pipeline */
gst_bin_add(GST_BIN(bin), disksrc);
gst_bin_add(GST_BIN(bin), parse);
gst_bin_add(GST_BIN(bin), decoder);
gst_bin_add(GST_BIN(bin), audiosink);
/* connect src to sink */
gst_pad_connect(gst_element_get_pad(disksrc,"src"),
gst_element_get_pad(parse,"sink"));
gst_pad_connect(gst_element_get_pad(parse,"src"),
gst_element_get_pad(decoder,"sink"));
gst_pad_connect(gst_element_get_pad(decoder,"src"),
gst_element_get_pad(audiosink,"sink"));
/* find out how to handle this bin */
gst_bin_create_plan(GST_BIN(bin));
/* make it ready */
gst_element_set_state(bin, GST_STATE_READY);
/* start playing */
gst_element_set_state(bin, GST_STATE_PLAYING);
playing = TRUE;
while (playing) {
gst_bin_iterate(GST_BIN(bin));
}
/* stop the bin */
gst_element_set_state(bin, GST_STATE_NULL);
gst_object_destroy(GST_OBJECT(audiosink));
gst_object_destroy(GST_OBJECT(decoder));
gst_object_destroy(GST_OBJECT(disksrc));
gst_object_destroy(GST_OBJECT(bin));
exit(0);
}
</programlisting>
<para>
Let's go through this example step by step.
</para>
<para>
The first thing you have to do is to include the standard GStreamer headers and
initialize the framework.
</para>
<programlisting>
#include &lt;gst/gst.h&gt;
...
int main(int argc,char *argv[])
{
...
gst_init(&amp;argc,&amp;argv);
...
</programlisting>
<para>
For simplicity, we are going to load all known plugins. This has the effect
that all the codecs known to GStreamer are registered to the system.
</para>
<programlisting>
...
gst_plugin_load_all();
...
</programlisting>
<para>
We are going to create 4 elements and one bin. Since all objects are
in fact elements, we can define them as:
</para>
<programlisting>
...
GstElement *bin, *disksrc, *parse, *decoder, *audiosink;
...
</programlisting>
<para>
Next, we are going to create an empty bin. As you have seen in the basic
introduction, this bin will hold and manage all the elements we are
going to stuff into it.
</para>
<programlisting>
/* create a new bin to hold the elements */
bin = gst_bin_new("bin");
</programlisting>
<para>
We then create a disk source element. The disk source element is able to
read from a file. We use the standard GTK+ argument mechanism to set
a property of the element: the file to read from.
</para>
<programlisting>
/* create a disk reader */
disksrc = gst_elementfactory_make("disksrc", "disk_source");
gtk_object_set(GTK_OBJECT(disksrc),"location", argv[1],NULL);
gtk_signal_connect(GTK_OBJECT(disksrc),"eos",
GTK_SIGNAL_FUNC(eos),NULL);
</programlisting>
<para>
We also connected the eos signal to our function. When the
disk source has reached an end-of-stream, this function will be called.
We will use it to set a gboolean value to FALSE;
</para>
<note>
<para>
You can check if the disksrc != NULL to verify the creation of the
disk source element.
</para>
</note>
<programlisting>
gboolean playing;
...
/* eos will be called when the src element has an end of stream */
void eos(GstSrc *src)
{
g_print("have eos, quitting\n");
playing = FALSE;
}
</programlisting>
<para>
We now create the MP3 decoder element. GStreamer requires you
to put a parser in front of the decoder. This parser will
cut the raw data from the disk source into MP3 frames
suitable for the decoder. In the advanced concepts chapter we will
see how this can be avoided.
</para>
<programlisting>
/* now it's time to get the parser */
parse = gst_elementfactory_make("mp3parse","parse");
decoder = gst_elementfactory_make("mpg123","decoder");
</programlisting>
<para>
gst_elementfactory_make() takes two arguments: a string that will
identify the element you need and a second argument: how you want
to name the element. The name of the element is something you can
choose yourself and might be used to retrieve the element from a
bin.
</para>
<para>
Finally we create our audio sink element. This element will be able
to playback the audio using OSS.
</para>
<programlisting>
/* and an audio sink */
audiosink = gst_elementfactory_make("audiosink", "play_audio");
</programlisting>
<para>
We then add the elements to the bin.
</para>
<programlisting>
/* add objects to the main pipeline */
gst_bin_add(GST_BIN(bin), disksrc);
gst_bin_add(GST_BIN(bin), parse);
gst_bin_add(GST_BIN(bin), decoder);
gst_bin_add(GST_BIN(bin), audiosink);
</programlisting>
<para>
We connect the different pads of the elements together like this:
</para>
<programlisting>
/* connect src to sink */
gst_pad_connect(gst_element_get_pad(disksrc,"src"),
gst_element_get_pad(parse,"sink"));
gst_pad_connect(gst_element_get_pad(parse,"src"),
gst_element_get_pad(decoder,"sink"));
gst_pad_connect(gst_element_get_pad(decoder,"src"),
gst_element_get_pad(audiosink,"sink"));
</programlisting>
<para>
We now have a created a complete pipeline. We can visualise the
pipeline as follows:
</para>
<figure float="1" id="sec-hello-img">
<title>The Hello world pipeline</title>
<graphic fileref="images/hello-world" format="png"></graphic>
</figure>
<para>
Before we can run it, we have to instruct the bin to analyse its contents
and come up with a plan to handle the media streams.
</para>
<programlisting>
/* find out how to handle this bin */
gst_bin_create_plan(GST_BIN(bin));
</programlisting>
<para>
Everything is now set up to start the streaming. We use the following
statements to change the state of the bin:
</para>
<programlisting>
/* make it ready */
gst_element_set_state(bin, GST_STATE_READY);
/* start playing */
gst_element_set_state(bin, GST_STATE_PLAYING);
playing = TRUE;
</programlisting>
<note>
<para>
Before you set the bin to the PLAYING state, you must go through the
READY state. The READY state will, in this example, open the file, open
the audio device and initialise the MP3 decoder.
</para>
</note>
<para>
Since we do not use threads, nothing will happen yet. We manually have to
call gst_bin_iterate() to execute one iteration of the bin.
</para>
<programlisting>
while (playing) {
gst_bin_iterate(GST_BIN(bin));
}
</programlisting>
<para>
Remember that the variable playing will become false if the disk source
has reached an end-of-file. When that happens, the follwing code takes
care of the cleanup:
</para>
<programlisting>
/* stop the bin */
gst_element_set_state(bin, GST_STATE_NULL);
gst_object_destroy(GST_OBJECT(audiosink));
gst_object_destroy(GST_OBJECT(decoder));
gst_object_destroy(GST_OBJECT(disksrc));
gst_object_destroy(GST_OBJECT(bin));
exit(0);
</programlisting>
<note>
<para>
don't forget to set the state of the bin to NULL. This will free
all of the resources held by the elements.
</para>
</note>
</sect1>
<sect1>
<title>compiling helloworld.c</title>
<para>
To compile the helloworld example, use:
</para>
<programlisting>
gcc -Wall `gstreamer-config --cflags` `gtk-config --cflags` helloworld.c \
-o helloworld `gstreamer-config --libs` `gtk-config --libs`
</programlisting>
<para>
This uses the program gstreamer-config, which comes with GStreamer. This program "knows"
what compiler switches are needed to compile programs that use GStreamer.
gstreamer-config --cflags will output a list of include
directories for the compiler to look in, and gstreamer-config --libs will output the
list of libraries for the compiler to link with and the directories to find them
in.
</para>
<para>
You can run the example with (substitute helloworld.mp3 with you favorite MP3 file):
</para>
<programlisting>
./helloworld helloworld.mp3
</programlisting>
</sect1>
<sect1>
<title>conclusion</title>
<para>
This concludes our first example. As you see, setting up a pipeline
is very lowlevel but powerfull. You will later in this manual how
you can create a custom MP3 element with a more high level API.
</para>
<para>
It should be clear from the example that we can vary easily replace the
disksrc element with a httpsrc, giving you instant network streaming.
An element could be build to handle icecast connections, for example.
</para>
<para>
We can also choose to use another type of sink instead of the audiosink.
We could use a disksink to write the raw samples to a file, for example.
It should also be clear that inserting filters, like a stereo effect,
into the pipeline is not that hard to do. The most important thing is
that you can reuse allready existing codecs.
</para>
</sect1>
</chapter>

View file

@ -0,0 +1,10 @@
CC = gcc
helloworld: helloworld.c
$(CC) -Wall `gstreamer-config --cflags` `gtk-config --cflags` helloworld.c -o helloworld `gstreamer-config --libs` `gtk-config --libs`
clean:
rm -f *.o helloworld

View file

@ -0,0 +1,78 @@
#include <gst/gst.h>
gboolean playing;
/* eos will be called when the src element has an end os stream */
void eos(GstSrc *src)
{
g_print("have eos, quitting\n");
playing = FALSE;
}
int main(int argc,char *argv[])
{
GstElement *bin, *disksrc, *parse, *decoder, *audiosink;
if (argc != 2) {
g_print("usage: %s <filename>\n", argv[0]);
exit(-1);
}
gst_init(&argc,&argv);
gst_plugin_load_all();
g_print("\n");
/* create a new bin to hold the elements */
bin = gst_bin_new("bin");
/* create a disk reader */
disksrc = gst_elementfactory_make("disksrc", "disk_source");
gtk_object_set(GTK_OBJECT(disksrc),"location", argv[1],NULL);
gtk_signal_connect(GTK_OBJECT(disksrc),"eos",
GTK_SIGNAL_FUNC(eos),NULL);
/* now it's time to get the parser */
parse = gst_elementfactory_make("mp3parse","parse");
decoder = gst_elementfactory_make("mpg123","decoder");
/* and an audio sink */
audiosink = gst_elementfactory_make("audiosink", "play_audio");
/* add objects to the main pipeline */
gst_bin_add(GST_BIN(bin), disksrc);
gst_bin_add(GST_BIN(bin), decoder);
gst_bin_add(GST_BIN(bin), audiosink);
/* connect src to sink */
gst_pad_connect(gst_element_get_pad(disksrc,"src"),
gst_element_get_pad(parse,"sink"));
gst_pad_connect(gst_element_get_pad(parse,"src"),
gst_element_get_pad(decoder,"sink"));
gst_pad_connect(gst_element_get_pad(decoder,"src"),
gst_element_get_pad(audiosink,"sink"));
/* find out how to handle this bin */
gst_bin_create_plan(GST_BIN(bin));
/* make it ready */
gst_element_set_state(bin, GST_STATE_READY);
/* start playing */
gst_element_set_state(bin, GST_STATE_PLAYING);
playing = TRUE;
while (playing) {
gst_bin_iterate(GST_BIN(bin));
}
/* stop the bin */
gst_element_set_state(bin, GST_STATE_NULL);
gst_object_destroy(GST_OBJECT(audiosink));
gst_object_destroy(GST_OBJECT(decoder));
gst_object_destroy(GST_OBJECT(disksrc));
gst_object_destroy(GST_OBJECT(bin));
exit(0);
}

View file

@ -0,0 +1,10 @@
CC = gcc
helloworld: helloworld.c
$(CC) -Wall `gstreamer-config --cflags` `gtk-config --cflags` helloworld.c -o helloworld `gstreamer-config --libs` `gtk-config --libs`
clean:
rm -f *.o helloworld

View file

@ -0,0 +1,78 @@
#include <gst/gst.h>
gboolean playing;
/* eos will be called when the src element has an end os stream */
void eos(GstSrc *src)
{
g_print("have eos, quitting\n");
playing = FALSE;
}
int main(int argc,char *argv[])
{
GstElement *bin, *disksrc, *parse, *decoder, *audiosink;
if (argc != 2) {
g_print("usage: %s <filename>\n", argv[0]);
exit(-1);
}
gst_init(&argc,&argv);
gst_plugin_load_all();
g_print("\n");
/* create a new bin to hold the elements */
bin = gst_bin_new("bin");
/* create a disk reader */
disksrc = gst_elementfactory_make("disksrc", "disk_source");
gtk_object_set(GTK_OBJECT(disksrc),"location", argv[1],NULL);
gtk_signal_connect(GTK_OBJECT(disksrc),"eos",
GTK_SIGNAL_FUNC(eos),NULL);
/* now it's time to get the parser */
parse = gst_elementfactory_make("mp3parse","parse");
decoder = gst_elementfactory_make("mpg123","decoder");
/* and an audio sink */
audiosink = gst_elementfactory_make("audiosink", "play_audio");
/* add objects to the main pipeline */
gst_bin_add(GST_BIN(bin), disksrc);
gst_bin_add(GST_BIN(bin), decoder);
gst_bin_add(GST_BIN(bin), audiosink);
/* connect src to sink */
gst_pad_connect(gst_element_get_pad(disksrc,"src"),
gst_element_get_pad(parse,"sink"));
gst_pad_connect(gst_element_get_pad(parse,"src"),
gst_element_get_pad(decoder,"sink"));
gst_pad_connect(gst_element_get_pad(decoder,"src"),
gst_element_get_pad(audiosink,"sink"));
/* find out how to handle this bin */
gst_bin_create_plan(GST_BIN(bin));
/* make it ready */
gst_element_set_state(bin, GST_STATE_READY);
/* start playing */
gst_element_set_state(bin, GST_STATE_PLAYING);
playing = TRUE;
while (playing) {
gst_bin_iterate(GST_BIN(bin));
}
/* stop the bin */
gst_element_set_state(bin, GST_STATE_NULL);
gst_object_destroy(GST_OBJECT(audiosink));
gst_object_destroy(GST_OBJECT(decoder));
gst_object_destroy(GST_OBJECT(disksrc));
gst_object_destroy(GST_OBJECT(bin));
exit(0);
}