docs/manual/: Fix playbin/decodebin examples, update docs a bit, mention bus instead of signals in various places, me...

Original commit message from CVS:
* docs/manual/advanced-autoplugging.xml:
* docs/manual/appendix-checklist.xml:
* docs/manual/appendix-integration.xml:
* docs/manual/highlevel-components.xml:
Fix playbin/decodebin examples, update docs a bit, mention bus
instead of signals in various places, mention kmplayer and
kaffeine since they have a working GStreamer backend in the KDE
section.
This commit is contained in:
Ronald S. Bultje 2005-06-30 12:32:17 +00:00
parent 4507397788
commit edcaf2cd4f
5 changed files with 177 additions and 78 deletions

View file

@ -1,3 +1,14 @@
2005-06-30 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
* docs/manual/advanced-autoplugging.xml:
* docs/manual/appendix-checklist.xml:
* docs/manual/appendix-integration.xml:
* docs/manual/highlevel-components.xml:
Fix playbin/decodebin examples, update docs a bit, mention bus
instead of signals in various places, mention kmplayer and
kaffeine since they have a working GStreamer backend in the KDE
section.
2005-06-30 Wim Taymans <wim@fluendo.com> 2005-06-30 Wim Taymans <wim@fluendo.com>
* CHANGES-0.9: * CHANGES-0.9:

View file

@ -117,7 +117,7 @@
<programlisting><!-- example-begin typefind.c a --> <programlisting><!-- example-begin typefind.c a -->
#include &lt;gst/gst.h&gt; #include &lt;gst/gst.h&gt;
<!-- example-end typefind.c a --> <!-- example-end typefind.c a -->
<!-- example-begin typefind.c b --><!-- [.. my_bus_callback goes here ..]<!-- example-begin typefind.c b --><!--
static gboolean static gboolean
my_bus_callback (GstBus *bus, my_bus_callback (GstBus *bus,
GstMessage *message, GstMessage *message,

View file

@ -15,8 +15,9 @@
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para> <para>
Always connect to the <quote>error</quote> signal of your topmost Always add a <classname>GstBus</classname> handler to your
pipeline to be notified of errors in your pipeline. pipeline. Always report errors in your application, and try
to do something with warnings and information messages, too.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
@ -26,14 +27,30 @@
and <function>gst_element_set_state ()</function>. and <function>gst_element_set_state ()</function>.
</para> </para>
</listitem> </listitem>
<listitem>
<para>
Dereference return values of all functions returning a non-base
type, such as <function>gst_element_get_pad ()</function>. Also,
always free non-const string returns, such as
<function>gst_object_get_name ()</function>.
</para>
</listitem>
<listitem> <listitem>
<para> <para>
Always use your pipeline object to keep track of the current state Always use your pipeline object to keep track of the current state
of your pipeline. Don't keep private variables in your application. of your pipeline. Don't keep private variables in your application.
Also, don't update your user interface if a user presses the Also, don't update your user interface if a user presses the
<quote>play</quote> button. Instead, connect to the <quote>play</quote> button. Instead, listen for the
<quote>state-changed</quote> signal of your topmost pipeline and <quote>state-changed</quote> message on the
update the user interface whenever this signal is triggered. <classname>GstBus</classname> and only update the user interface
whenever this message is received.
</para>
</listitem>
<listitem>
<para>
Report all bugs that you find in &GStreamer; bugzilla at
<ulink type="http"
url="http://bugzilla.gnome.org">http://bugzilla.gnome.org/</ulink>.
</para> </para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
@ -81,7 +98,9 @@
<option>--gst-debug=<replaceable>LIST</replaceable></option> <option>--gst-debug=<replaceable>LIST</replaceable></option>
takes a comma-separated list of category_name:level pairs to takes a comma-separated list of category_name:level pairs to
set specific levels for the individual categories. Example: set specific levels for the individual categories. Example:
<option>GST_AUTOPLUG:5,avidemux:3</option>. <option>GST_AUTOPLUG:5,avidemux:3</option>. Alternatively, you
can also set the <classname>GST_DEBUG</classname> environment
variable, which has the same effect.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>

View file

@ -123,11 +123,12 @@ main (gint argc,
&GStreamer; has been proposed for inclusion in KDE-4.0. Currently, &GStreamer; has been proposed for inclusion in KDE-4.0. Currently,
&GStreamer; is included as an optional component, and it's used by &GStreamer; is included as an optional component, and it's used by
several KDE applications, including <ulink type="http" several KDE applications, including <ulink type="http"
url="http://amarok.kde.org/">AmaroK</ulink> and <ulink type="http" url="http://amarok.kde.org/">AmaroK</ulink>, <ulink type="http"
url="http://developer.kde.org/~wheeler/juk.html">JuK</ulink>. A url="http://developer.kde.org/~wheeler/juk.html">JuK</ulink>,
backend for <ulink type="http" <ulink type="http"
url="http://www.xs4all.nl/~jjvrieze/kmplayer.html">KMPlayer</ulink> url="http://www.xs4all.nl/~jjvrieze/kmplayer.html">KMPlayer</ulink> and
is currently under development. <ulink type="http"
url="http://kaffeine.sourceforge.net/">Kaffeine</ulink>.
</para> </para>
<para> <para>
Although not yet as complete as the GNOME integration bits, there Although not yet as complete as the GNOME integration bits, there

View file

@ -14,10 +14,12 @@
<para> <para>
We currently recommend people to use either playbin (see <xref We currently recommend people to use either playbin (see <xref
linkend="section-components-playbin"/>) or decodebin (see <xref linkend="section-components-playbin"/>) or decodebin (see <xref
linkend="section-components-decodebin"/>), depending on their needs. The linkend="section-components-decodebin"/>), depending on their needs.
other components discussed here are either outdated or deprecated. The Playbin is the recommended solution for everything related to simple
documentation is provided for legacy purposes. Use of those other playback of media that should just work. Decodebin is a more flexible
components is not recommended. autoplugger that could be used to add more advanced featuers, such
as playlist support, crossfading of audio tracks and so on. Its
programming interface is more low-level than that of playbin, though.
</para> </para>
<sect1 id="section-components-playbin"> <sect1 id="section-components-playbin">
@ -27,7 +29,8 @@
Playbin is an element that can be created using the standard &GStreamer; Playbin is an element that can be created using the standard &GStreamer;
API (e.g. <function>gst_element_factory_make ()</function>). The factory API (e.g. <function>gst_element_factory_make ()</function>). The factory
is conveniently called <quote>playbin</quote>. By being a is conveniently called <quote>playbin</quote>. By being a
<classname>GstElement</classname>, playbin automatically supports all <classname>GstPipeline</classname> (and thus a
<classname>GstElement</classname>), playbin automatically supports all
of the features of this class, including error handling, tag support, of the features of this class, including error handling, tag support,
state handling, getting stream positions, seeking, and so on. state handling, getting stream positions, seeking, and so on.
</para> </para>
@ -39,43 +42,57 @@
file:///tmp/my.ogg or http://www.example.org/stream.ogg) using the file:///tmp/my.ogg or http://www.example.org/stream.ogg) using the
<quote>uri</quote> property on playbin, and then setting the element <quote>uri</quote> property on playbin, and then setting the element
to the <classname>GST_STATE_PLAYING</classname> state. Internally, to the <classname>GST_STATE_PLAYING</classname> state. Internally,
playbin uses threads, so there's no need to iterate the element or playbin will set up a pipeline to playback the media location.
anything. However, one thing to keep in mind is that signals fired
by playbin might come from another than the main thread, so be sure
to keep this in mind in your signal handles. Most application
programmers will want to use a function such as <function>g_idle_add
()</function> to make sure that the signal is handled in the main
thread.
</para> </para>
<programlisting><!-- example-begin playbin.c --> <programlisting><!-- example-begin playbin.c a -->
#include &lt;gst/gst.h&gt; #include &lt;gst/gst.h&gt;
<!-- example-end playbin.c a -->
static void [.. my_bus_callback goes here ..]<!-- example-begin playbin.c b --><!--
cb_eos (GstElement *play, static gboolean
gpointer data) my_bus_callback (GstBus *bus,
GstMessage *message,
gpointer data)
{ {
gst_main_quit (); GMainLoop *loop = data;
}
static void switch (GST_MESSAGE_TYPE (message)) {
cb_error (GstElement *play, case GST_MESSAGE_ERROR: {
GstElement *src, GError *err;
GError *err, gchar *debug;
gchar *debug,
gpointer data)
{
g_print ("Error: %s\n", err->message);
}
gst_message_parse_error (message, &amp;err, &amp;debug);
g_print ("Error: %s\n", err-&gt;message);
g_error_free (err);
g_free (debug);
g_main_loop_quit (loop);
break;
}
case GST_MESSAGE_EOS:
/* end-of-stream */
g_main_loop_quit (loop);
break;
default:
/* unhandled message */
break;
}
/* remove message from the queue */
return TRUE;
}
--><!-- example-end playbin.c b -->
<!-- example-begin playbin.c c -->
gint gint
main (gint argc, main (gint argc,
gchar *argv[]) gchar *argv[])
{ {
GMainLoop *loop;
GstElement *play; GstElement *play;
/* init GStreamer */ /* init GStreamer */
gst_init (&amp;argc, &amp;argv); gst_init (&amp;argc, &amp;argv);
loop = g_main_loop_new (NULL, FALSE);
/* make sure we have a URI */ /* make sure we have a URI */
if (argc != 2) { if (argc != 2) {
@ -86,15 +103,12 @@ main (gint argc,
/* set up */ /* set up */
play = gst_element_factory_make ("playbin", "play"); play = gst_element_factory_make ("playbin", "play");
g_object_set (G_OBJECT (play), "uri", argv[1], NULL); g_object_set (G_OBJECT (play), "uri", argv[1], NULL);
g_signal_connect (play, "eos", G_CALLBACK (cb_eos), NULL); gst_bus_add_watch (gst_pipeline_get_bus (GST_PIPELINE (play)),
g_signal_connect (play, "error", G_CALLBACK (cb_error), NULL); my_bus_callback, loop);
if (gst_element_set_state (play, GST_STATE_PLAYING) != GST_STATE_SUCCESS) { gst_element_set_state (play, GST_STATE_PLAYING);
g_print ("Failed to play\n");
return -1;
}
/* now run */ /* now run */
gst_main (); g_main_loop_run (loop);
/* also clean up */ /* also clean up */
gst_element_set_state (play, GST_STATE_NULL); gst_element_set_state (play, GST_STATE_NULL);
@ -102,7 +116,7 @@ main (gint argc,
return 0; return 0;
} }
<!-- example-end playbin.c --></programlisting> <!-- example-end playbin.c c --></programlisting>
<para> <para>
Playbin has several features that have been discussed previously: Playbin has several features that have been discussed previously:
@ -118,13 +132,15 @@ main (gint argc,
<para> <para>
Mostly controllable and trackable as a Mostly controllable and trackable as a
<classname>GstElement</classname>, including error handling, eos <classname>GstElement</classname>, including error handling, eos
handling, tag handling, state handling, media position handling and handling, tag handling, state handling (through the
<classname>GstBus</classname>), media position handling and
seeking. seeking.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
Buffers network-sources. Buffers network-sources, with buffer fullness notifications being
passed through the <classname>GstBus</classname>.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
@ -135,7 +151,8 @@ main (gint argc,
<listitem> <listitem>
<para> <para>
Supports subtitles, both in the media as well as from separate Supports subtitles, both in the media as well as from separate
files. files. For separate subtitle files, use the <quote>suburi</quote>
property.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
@ -143,10 +160,17 @@ main (gint argc,
Supports stream selection and disabling. If your media has Supports stream selection and disabling. If your media has
multiple audio or subtitle tracks, you can dynamically choose multiple audio or subtitle tracks, you can dynamically choose
which one to play back, or decide to turn it off alltogther which one to play back, or decide to turn it off alltogther
(which is especially useful to turn off subtitles). (which is especially useful to turn off subtitles). For each
of those, use the <quote>current-text</quote> and other related
properties.
</para> </para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
<para>
For convenience, it is possible to test <quote>playbin</quote> on
the commandline, using the command <quote>gst-launch-0.9 playbin
uri=file:///path/to/file</quote>.
</para>
</sect1> </sect1>
<sect1 id="section-components-decodebin"> <sect1 id="section-components-decodebin">
@ -164,18 +188,45 @@ main (gint argc,
the <quote>unknown-type</quote> signal. The application is then the <quote>unknown-type</quote> signal. The application is then
responsible for reporting the error to the user. responsible for reporting the error to the user.
</para> </para>
<programlisting><!-- example-begin decodebin.c a -->
<para>
The example code below will play back an audio stream of an input
file. For readability, it does not include any error handling of
any sort.
</para>
<programlisting><!-- example-begin decodebin.c -->
#include &lt;gst/gst.h&gt; #include &lt;gst/gst.h&gt;
<!-- example-end decodebin.c a -->
[.. my_bus_callback goes here ..]<!-- example-begin decodebin.c b --><!--
static gboolean
my_bus_callback (GstBus *bus,
GstMessage *message,
gpointer data)
{
GMainLoop *loop = data;
switch (GST_MESSAGE_TYPE (message)) {
case GST_MESSAGE_ERROR: {
GError *err;
gchar *debug;
gst_message_parse_error (message, &amp;err, &amp;debug);
g_print ("Error: %s\n", err-&gt;message);
g_error_free (err);
g_free (debug);
g_main_loop_quit (loop);
break;
}
case GST_MESSAGE_EOS:
/* end-of-stream */
g_main_loop_quit (loop);
break;
default:
/* unhandled message */
break;
}
/* remove message from the queue */
return TRUE;
}
--><!-- example-end decodebin.c b -->
<!-- example-begin decodebin.c c -->
GstElement *pipeline, *audio; GstElement *pipeline, *audio;
GstPad *audiopad;
static void static void
cb_newpad (GstElement *decodebin, cb_newpad (GstElement *decodebin,
@ -185,29 +236,40 @@ cb_newpad (GstElement *decodebin,
{ {
GstCaps *caps; GstCaps *caps;
GstStructure *str; GstStructure *str;
GstPad *audiopad;
/* only link audio; only link once */ /* only link once */
if (GST_PAD_IS_LINKED (audiopad)) audiopad = gst_element_get_pad (audio, "sink");
if (GST_PAD_IS_LINKED (audiopad)) {
g_object_unref (audiopad);
return; return;
}
/* check media type */
caps = gst_pad_get_caps (pad); caps = gst_pad_get_caps (pad);
str = gst_caps_get_structure (caps, 0); str = gst_caps_get_structure (caps, 0);
if (!g_strrstr (gst_structure_get_name (str), "audio")) if (!g_strrstr (gst_structure_get_name (str), "audio")) {
gst_caps_unref (caps);
gst_object_unref (audiopad);
return; return;
}
gst_caps_unref (caps);
/* link'n'play */ /* link'n'play */
gst_pad_link (pad, audiopad); gst_pad_link (pad, audiopad);
gst_bin_add (GST_BIN (pipeline), audio);
gst_bin_sync_children_state (GST_BIN (pipeline));
} }
gint gint
main (gint argc, main (gint argc,
gchar *argv[]) gchar *argv[])
{ {
GstElement *src, *dec, *conv, *scale, *sink; GMainLoop *loop;
GstElement *src, *dec, *conv, *sink;
GstPad *audiopad;
/* init GStreamer */ /* init GStreamer */
gst_init (&amp;argc, &amp;argv); gst_init (&amp;argc, &amp;argv);
loop = g_main_loop_new (NULL, FALSE);
/* make sure we have input */ /* make sure we have input */
if (argc != 2) { if (argc != 2) {
@ -217,24 +279,30 @@ main (gint argc,
/* setup */ /* setup */
pipeline = gst_pipeline_new ("pipeline"); pipeline = gst_pipeline_new ("pipeline");
gst_bus_add_watch (gst_pipeline_get_bus (GST_PIPELINE (pipeline)),
my_bus_callback, loop);
src = gst_element_factory_make ("filesrc", "source"); src = gst_element_factory_make ("filesrc", "source");
g_object_set (G_OBJECT (src), "location", argv[1], NULL); g_object_set (G_OBJECT (src), "location", argv[1], NULL);
dec = gst_element_factory_make ("decodebin", "decoder"); dec = gst_element_factory_make ("decodebin", "decoder");
g_signal_connect (dec, "new-decoded-pad", G_CALLBACK (cb_newpad), NULL); g_signal_connect (dec, "new-decoded-pad", G_CALLBACK (cb_newpad), NULL);
audio = gst_bin_new ("audiobin");
conv = gst_element_factory_make ("audioconvert", "aconv");
audiopad = gst_element_get_pad (conv, "sink");
scale = gst_element_factory_make ("audioscale", "scale");
sink = gst_element_factory_make ("alsasink", "sink");
gst_bin_add_many (GST_BIN (audio), conv, scale, sink, NULL);
gst_element_link_many (conv, scale, sink, NULL);
gst_bin_add_many (GST_BIN (pipeline), src, dec, NULL); gst_bin_add_many (GST_BIN (pipeline), src, dec, NULL);
gst_element_link (src, dec); gst_element_link (src, dec);
/* create audio output */
audio = gst_bin_new ("audiobin");
conv = gst_element_factory_make ("audioconvert", "aconv");
audiopad = gst_element_get_pad (conv, "sink");
sink = gst_element_factory_make ("alsasink", "sink");
gst_bin_add_many (GST_BIN (audio), conv, sink, NULL);
gst_element_link (conv, sink);
gst_element_add_pad (audio,
gst_ghost_pad_new ("sink", audiopad));
gst_object_unref (audiopad);
gst_bin_add (GST_BIN (pipeline), audio);
/* run */ /* run */
gst_element_set_state (audio, GST_STATE_PAUSED);
gst_element_set_state (pipeline, GST_STATE_PLAYING); gst_element_set_state (pipeline, GST_STATE_PLAYING);
while (gst_bin_iterate (GST_BIN (pipeline))) ; g_main_loop_run (loop);
/* cleanup */ /* cleanup */
gst_element_set_state (pipeline, GST_STATE_NULL); gst_element_set_state (pipeline, GST_STATE_NULL);
@ -242,7 +310,7 @@ main (gint argc,
return 0; return 0;
} }
<!-- example-end decodebin.c --></programlisting> <!-- example-end decodebin.c c --></programlisting>
<para> <para>
Decodebin, similar to playbin, supports the following features: Decodebin, similar to playbin, supports the following features:
@ -287,7 +355,7 @@ main (gint argc,
<para> <para>
Decodebin can be easily tested on the commandline, e.g. by using the Decodebin can be easily tested on the commandline, e.g. by using the
command <command>gst-launch-0.8 filesrc location=file.ogg ! decodebin command <command>gst-launch-0.8 filesrc location=file.ogg ! decodebin
! audioconvert ! audioscale ! alsasink</command>. ! audioconvert ! alsasink</command>.
</para> </para>
</sect1> </sect1>