From 284ecaecca393f21e974a5ca005021e0e8e0bcca Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 18 Aug 2000 20:38:54 +0000 Subject: [PATCH] helloworld example. and docs Original commit message from CVS: helloworld example. and docs --- docs/manual/fig/hello-world.fig | 51 +++ docs/manual/helloworld.sgml | 362 +++++++++++++++++++++ examples/helloworld/Makefile | 10 + examples/helloworld/helloworld.c | 78 +++++ tests/old/examples/helloworld/Makefile | 10 + tests/old/examples/helloworld/helloworld.c | 78 +++++ 6 files changed, 589 insertions(+) create mode 100644 docs/manual/fig/hello-world.fig create mode 100644 docs/manual/helloworld.sgml create mode 100644 examples/helloworld/Makefile create mode 100644 examples/helloworld/helloworld.c create mode 100644 tests/old/examples/helloworld/Makefile create mode 100644 tests/old/examples/helloworld/helloworld.c diff --git a/docs/manual/fig/hello-world.fig b/docs/manual/fig/hello-world.fig new file mode 100644 index 0000000000..3069a94ab3 --- /dev/null +++ b/docs/manual/fig/hello-world.fig @@ -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 diff --git a/docs/manual/helloworld.sgml b/docs/manual/helloworld.sgml new file mode 100644 index 0000000000..ab47368299 --- /dev/null +++ b/docs/manual/helloworld.sgml @@ -0,0 +1,362 @@ + + Your first application + + 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. + + + + Hello world + + 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. + + + + + +#include <gst/gst.h> + +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 <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), 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); +} + + + + + Let's go through this example step by step. + + + + The first thing you have to do is to include the standard GStreamer headers and + initialize the framework. + + + +#include <gst/gst.h> + + ... + +int main(int argc,char *argv[]) +{ + ... + gst_init(&argc,&argv); + ... + + + + + 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. + + + ... + gst_plugin_load_all(); + ... + + + + We are going to create 4 elements and one bin. Since all objects are + in fact elements, we can define them as: + + + ... + GstElement *bin, *disksrc, *parse, *decoder, *audiosink; + ... + + + + 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. + + + /* create a new bin to hold the elements */ + bin = gst_bin_new("bin"); + + + + 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. + + + /* 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); + + + 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; + + + + You can check if the disksrc != NULL to verify the creation of the + disk source element. + + + + +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; +} + + + + 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. + + + /* now it's time to get the parser */ + parse = gst_elementfactory_make("mp3parse","parse"); + decoder = gst_elementfactory_make("mpg123","decoder"); + + + 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. + + + + Finally we create our audio sink element. This element will be able + to playback the audio using OSS. + + + /* and an audio sink */ + audiosink = gst_elementfactory_make("audiosink", "play_audio"); + + + + We then add the elements to the bin. + + + /* 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); + + + + We connect the different pads of the elements together like this: + + + /* 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")); + + + + We now have a created a complete pipeline. We can visualise the + pipeline as follows: + +
+ The Hello world pipeline + +
+ + + 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. + + + /* find out how to handle this bin */ + gst_bin_create_plan(GST_BIN(bin)); + + + + Everything is now set up to start the streaming. We use the following + statements to change the state of the bin: + + + /* make it ready */ + gst_element_set_state(bin, GST_STATE_READY); + /* start playing */ + gst_element_set_state(bin, GST_STATE_PLAYING); + + playing = TRUE; + + + + 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. + + + + + 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. + + + while (playing) { + gst_bin_iterate(GST_BIN(bin)); + } + + + 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: + + + /* 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); + + + + don't forget to set the state of the bin to NULL. This will free + all of the resources held by the elements. + + + +
+ + + compiling helloworld.c + + To compile the helloworld example, use: + + + gcc -Wall `gstreamer-config --cflags` `gtk-config --cflags` helloworld.c \ + -o helloworld `gstreamer-config --libs` `gtk-config --libs` + + + 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. + + + You can run the example with (substitute helloworld.mp3 with you favorite MP3 file): + + + ./helloworld helloworld.mp3 + + + + + conclusion + + 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. + + + 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. + + + 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. + + + + +
diff --git a/examples/helloworld/Makefile b/examples/helloworld/Makefile new file mode 100644 index 0000000000..8057681985 --- /dev/null +++ b/examples/helloworld/Makefile @@ -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 + + diff --git a/examples/helloworld/helloworld.c b/examples/helloworld/helloworld.c new file mode 100644 index 0000000000..bee8275344 --- /dev/null +++ b/examples/helloworld/helloworld.c @@ -0,0 +1,78 @@ +#include + +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 \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); +} + diff --git a/tests/old/examples/helloworld/Makefile b/tests/old/examples/helloworld/Makefile new file mode 100644 index 0000000000..8057681985 --- /dev/null +++ b/tests/old/examples/helloworld/Makefile @@ -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 + + diff --git a/tests/old/examples/helloworld/helloworld.c b/tests/old/examples/helloworld/helloworld.c new file mode 100644 index 0000000000..bee8275344 --- /dev/null +++ b/tests/old/examples/helloworld/helloworld.c @@ -0,0 +1,78 @@ +#include + +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 \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); +} +