mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-26 02:00:33 +00:00
d0bcc34dad
Original commit message from CVS: * docs/manual/advanced-autoplugging.xml: * docs/manual/advanced-clocks.xml: * docs/manual/advanced-interfaces.xml: * docs/manual/advanced-metadata.xml: * docs/manual/advanced-position.xml: * docs/manual/advanced-schedulers.xml: * docs/manual/advanced-threads.xml: * docs/manual/appendix-gnome.xml: * docs/manual/appendix-programs.xml: * docs/manual/appendix-quotes.xml: * docs/manual/autoplugging.xml: * docs/manual/basics-bins.xml: * docs/manual/basics-data.xml: * docs/manual/basics-elements.xml: * docs/manual/basics-helloworld.xml: * docs/manual/basics-init.xml: * docs/manual/basics-pads.xml: * docs/manual/basics-plugins.xml: * docs/manual/bins-api.xml: * docs/manual/bins.xml: * docs/manual/buffers-api.xml: * docs/manual/buffers.xml: * docs/manual/clocks.xml: * docs/manual/components.xml: * docs/manual/cothreads.xml: * docs/manual/debugging.xml: * docs/manual/dparams-app.xml: * docs/manual/dynamic.xml: * docs/manual/elements-api.xml: * docs/manual/elements.xml: * docs/manual/factories.xml: * docs/manual/gnome.xml: * docs/manual/goals.xml: * docs/manual/helloworld.xml: * docs/manual/helloworld2.xml: * docs/manual/highlevel-components.xml: * docs/manual/highlevel-xml.xml: * docs/manual/init-api.xml: * docs/manual/intro-basics.xml: * docs/manual/intro-motivation.xml: * docs/manual/intro-preface.xml: * docs/manual/intro.xml: * docs/manual/links-api.xml: * docs/manual/links.xml: * docs/manual/manual.xml: * docs/manual/motivation.xml: * docs/manual/pads-api.xml: * docs/manual/pads.xml: * docs/manual/plugins-api.xml: * docs/manual/plugins.xml: * docs/manual/programs.xml: * docs/manual/queues.xml: * docs/manual/quotes.xml: * docs/manual/schedulers.xml: * docs/manual/states-api.xml: * docs/manual/states.xml: * docs/manual/threads.xml: * docs/manual/typedetection.xml: * docs/manual/win32.xml: * docs/manual/xml.xml: Try 2. This time, include a short preface as a "general introduction", also add code blocks around all code samples so they get compiled. We still need a way to tell readers the filename of the code sample. In some cases, don't show all code in the documentation, but do include it in the generated code. This allows for focussing on specific bits in the docs, while still having a full test application available. * examples/manual/Makefile.am: Fix up examples for new ADM. Add several of the new examples that were either added or were missing from the build system. * examples/manual/extract.pl: Allow nameless blocks.
199 lines
8.2 KiB
XML
199 lines
8.2 KiB
XML
<chapter id="chapter-helloworld">
|
|
<title>Your first application</title>
|
|
<para>
|
|
This chapter will summarize everything you've learned in the previous
|
|
chapters. It describes all aspects of a simple &GStreamer; application,
|
|
including initializing libraries, creating elements, packing elements
|
|
together in a pipeline and playing this pipeline. By doing all this,
|
|
you will be able to build a simple Ogg/Vorbis audio player.
|
|
</para>
|
|
|
|
<sect1 id="section-helloworld">
|
|
<title>Hello world</title>
|
|
<para>
|
|
We're going to create a simple first application, a simple Ogg/Vorbis
|
|
command-line audio player. For this, we will use only standard
|
|
&GStreamer; components. The player will read a file specified on
|
|
the command-line. Let's get started!
|
|
</para>
|
|
<para>
|
|
We've learned, in <xref linkend="chapter-init"/>, that the first thing
|
|
to do in your application is to initialize &GStreamer; by calling
|
|
<function>gst_init ()</function>. Also, make sure that the application
|
|
includes <filename>gst/gst.h</filename> so all function names and
|
|
objects are properly defined. Use <function>#include
|
|
<gst/gst.h></function> to do that.
|
|
</para>
|
|
<para>
|
|
Next, you'll want to create the different elements using
|
|
<function>gst_element_factory_make ()</function>. For an Ogg/Vorbis
|
|
audio player, we'll need a source element that reads files from a
|
|
disk. &GStreamer; includes this element under the name
|
|
<quote>filesrc</quote>. Next, we'll need something to parse the
|
|
file and decoder it into raw audio. &GStreamer; has two elements
|
|
for this: the first parses Ogg streams into elementary streams (video,
|
|
audio) and is called <quote>oggdemux</quote>. The second is a Vorbis
|
|
audio decoder, it's conveniently called <quote>vorbisdec</quote>.
|
|
Since <quote>oggdemux</quote> creates dynamic pads for each elementary
|
|
stream, you'll need to set a <quote>new-pad</quote> event handler
|
|
on the <quote>oggdemux</quote> element, like you've learned in
|
|
<xref linkend="section-pads-dynamic"/>, to link the Ogg parser and
|
|
the Vorbis decoder elements together. At last, we'll also need an
|
|
audio output element, we will use <quote>alsasink</quote>, which
|
|
outputs sound to an ALSA audio device.
|
|
</para>
|
|
<para>
|
|
The last thing left to do is to add all elements into a container
|
|
element, a <classname>GstPipeline</classname>, and iterate this
|
|
pipeline until we've played the whole song. We've previously
|
|
learned how to add elements to a container bin in <xref
|
|
linkend="chapter-bins"/>, and we've learned about element states
|
|
in <xref linkend="section-elements-states"/>. We will use the function
|
|
<function>gst_bin_sync_children_state ()</function> to synchronize
|
|
the state of a bin on all of its contained children.
|
|
</para>
|
|
<para>
|
|
Let's now add all the code together to get our very first audio
|
|
player:
|
|
</para>
|
|
<programlisting>
|
|
<!-- example-begin helloworld.c -->
|
|
#include <gst/gst.h>
|
|
|
|
/*
|
|
* Global objects are usually a bad thing. For the purpose of this
|
|
* example, we will use them, however.
|
|
*/
|
|
|
|
GstElement *pipeline, *source, *parser, *decoder, *sink;
|
|
|
|
static void
|
|
new_pad (GstElement *element,
|
|
GstPad *pad,
|
|
gpointer data)
|
|
{
|
|
/* We can now link this pad with the audio decoder and
|
|
* add both decoder and audio output to the pipeline. */
|
|
gst_pad_link (pad, gst_element_get_pad (decoder, "sink"));
|
|
gst_bin_add_many (GST_BIN (pipeline), decoder, sink, NULL);
|
|
|
|
/* This function synchronizes a bins state on all of its
|
|
* contained children. */
|
|
gst_bin_sync_children_state (GST_BIN (pipeline));
|
|
}
|
|
|
|
int
|
|
main (int argc,
|
|
char *argv[])
|
|
{
|
|
/* initialize GStreamer */
|
|
gst_init (&argc, &argv);
|
|
|
|
/* check input arguments */
|
|
if (argc != 2) {
|
|
g_print ("Usage: %s <Ogg/Vorbis filename>\n", argv[0]);
|
|
return -1;
|
|
}
|
|
|
|
/* create elements */
|
|
pipeline = gst_pipeline_new ("audio-player");
|
|
source = gst_element_factory_make ("filesrc", "file-source");
|
|
parser = gst_element_factory_make ("oggdemux", "ogg-parser");
|
|
decoder = gst_element_factory_make ("vorbisdec", "vorbis-decoder");
|
|
sink = gst_element_factory_make ("alsasink", "alsa-output");
|
|
|
|
/* set filename property on the file source */
|
|
g_object_set (G_OBJECT (source), "location", argv[1], NULL);
|
|
|
|
/* link together - note that we cannot link the parser and
|
|
* decoder yet, becuse the parser uses dynamic pads. For that,
|
|
* we set a new-pad signal handler. */
|
|
gst_element_link (source, parser);
|
|
gst_element_link (decoder, sink);
|
|
g_signal_connect (parser, "new-pad", G_CALLBACK (new_pad), NULL);
|
|
|
|
/* put all elements in a bin - or at least the ones we will use
|
|
* instantly. */
|
|
gst_bin_add_many (GST_BIN (pipeline), source, parser, NULL);
|
|
|
|
/* Now set to playing and iterate. We will set the decoder and
|
|
* audio output to ready so they initialize their memory already.
|
|
* This will decrease the amount of time spent on linking these
|
|
* elements when the Ogg parser emits the new-pad signal. */
|
|
gst_element_set_state (decoder, GST_STATE_READY);
|
|
gst_element_set_state (sink, GST_STATE_READY);
|
|
gst_element_set_state (pipeline, GST_STATE_PLAYING);
|
|
|
|
/* and now iterate - the rest will be automatic from here on.
|
|
* When the file is finished, gst_bin_iterate () will return
|
|
* FALSE, thereby terminating this loop. */
|
|
while (gst_bin_iterate (GST_BIN (pipeline))) ;
|
|
|
|
/* clean up nicely */
|
|
gst_element_set_state (pipeline, GST_STATE_NULL);
|
|
gst_object_unref (GST_OBJECT (pipeline));
|
|
|
|
return 0;
|
|
}
|
|
<!-- example-end helloworld.c -->
|
|
</programlisting>
|
|
<!-- FIXME: this image needs updating -->
|
|
<para>
|
|
We now have created a complete pipeline. We can visualise the
|
|
pipeline as follows:
|
|
</para>
|
|
<figure float="1" id="section-hello-img">
|
|
<title>The "hello world" pipeline</title>
|
|
<mediaobject>
|
|
<imageobject>
|
|
<imagedata fileref="images/hello-world.ℑ" format="&IMAGE;" />
|
|
</imageobject>
|
|
</mediaobject>
|
|
</figure>
|
|
</sect1>
|
|
|
|
<sect1 id="section-helloworld-compilerun">
|
|
<title>Compiling and Running helloworld.c</title>
|
|
<para>
|
|
To compile the helloworld example, use: <command>gcc -Wall
|
|
$(pkg-config --cflags --libs gstreamer-&GST_MAJORMINOR;)
|
|
helloworld.c -o helloworld</command>. &GStreamer; makes use of
|
|
<command>pkg-config</command> to get compiler and linker flags
|
|
needed to compile this application. If you're running a
|
|
non-standard installation, make sure the
|
|
<classname>PKG_CONFIG_PATH</classname> environment variable is
|
|
set to the correct location (<filename>$libdir/pkgconfig</filename>).
|
|
application against the uninstalled location.
|
|
</para>
|
|
<para>
|
|
You can run this example application with <command>./helloworld
|
|
file.ogg</command>. Substitute <filename>file.ogg</filename>
|
|
with your favourite Ogg/Vorbis file.
|
|
</para>
|
|
</sect1>
|
|
|
|
<sect1 id="section-hello-world-conclusion">
|
|
<title>Conclusion</title>
|
|
<para>
|
|
This concludes our first example. As you see, setting up a pipeline
|
|
is very low-level but powerful. You will see later in this manual how
|
|
you can create a more powerful media player with even less effort
|
|
using higher-level interfaces. We will discuss all that in <xref
|
|
linkend="part-highlevel"/>. We will first, however, go more in-depth
|
|
into more advanced &GStreamer; internals.
|
|
</para>
|
|
<para>
|
|
It should be clear from the example that we can very easily replace
|
|
the <quote>filesrc</quote> element with some other element that
|
|
reads data from a network, or some other data source element that
|
|
is better integrated with your desktop environment. Also, you can
|
|
use other decoders and parsers to support other media types. You
|
|
can use another audio sink if you're not running Linux, but Mac OS X,
|
|
Windows or FreeBSD, or you can instead use a filesink to write audio
|
|
files to disk instead of playing them back. By using an audio card
|
|
source, you can even do audio capture instead of playback. All this
|
|
shows the reusability of &GStreamer; elements, which is its greatest
|
|
advantage.
|
|
</para>
|
|
</sect1>
|
|
</chapter>
|