mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 01:00:37 +00:00
7c24fc7450
MIME-type -> media types Fix up the manual in various places with the 1.0 way of doing things such as probes, static elements, scheduling, ... Add porting from 0.10 to 1.0 chapter. Add probe example to build. Remove some docs for remove components such as GstMixer and GstPropertyProbe, XML...
289 lines
12 KiB
XML
289 lines
12 KiB
XML
<chapter id="chapter-bus">
|
|
<title>Bus</title>
|
|
<para>
|
|
A bus is a simple system that takes care of forwarding messages from
|
|
the pipeline threads to an application in its own thread context. The
|
|
advantage of a bus is that an application does not need to be
|
|
thread-aware in order to use &GStreamer;, even though &GStreamer;
|
|
itself is heavily threaded.
|
|
</para>
|
|
<para>
|
|
Every pipeline contains a bus by default, so applications do not need
|
|
to create a bus or anything. The only thing applications should do is
|
|
set a message handler on a bus, which is similar to a signal handler
|
|
to an object. When the mainloop is running, the bus will periodically
|
|
be checked for new messages, and the callback will be called when any
|
|
message is available.
|
|
</para>
|
|
|
|
<sect1 id="section-bus-howto">
|
|
<title>How to use a bus</title>
|
|
<para>
|
|
There are two different ways to use a bus:
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>
|
|
Run a GLib/Gtk+ main loop (or iterate the default GLib main
|
|
context yourself regularly) and attach some kind of watch to the
|
|
bus. This way the GLib main loop will check the bus for new
|
|
messages and notify you whenever there are messages.
|
|
</para>
|
|
<para>
|
|
Typically you would use <function>gst_bus_add_watch ()</function>
|
|
or <function>gst_bus_add_signal_watch ()</function> in this case.
|
|
</para>
|
|
<para>
|
|
To use a bus, attach a message handler to the bus of a pipeline
|
|
using <function>gst_bus_add_watch ()</function>. This handler will
|
|
be called whenever the pipeline emits a message to the bus. In this
|
|
handler, check the signal type (see next section) and do something
|
|
accordingly. The return value of the handler should be TRUE to
|
|
keep the handler attached to the bus, return FALSE to remove it.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
Check for messages on the bus yourself. This can be done using
|
|
<function>gst_bus_peek ()</function> and/or
|
|
<function>gst_bus_poll ()</function>.
|
|
</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
<programlisting><!-- example-begin bus.c a -->
|
|
#include <gst/gst.h>
|
|
|
|
static GMainLoop *loop;
|
|
|
|
static gboolean
|
|
my_bus_callback (GstBus *bus,
|
|
GstMessage *message,
|
|
gpointer data)
|
|
{
|
|
g_print ("Got %s message\n", GST_MESSAGE_TYPE_NAME (message));
|
|
|
|
switch (GST_MESSAGE_TYPE (message)) {
|
|
case GST_MESSAGE_ERROR: {
|
|
GError *err;
|
|
gchar *debug;
|
|
|
|
gst_message_parse_error (message, &err, &debug);
|
|
g_print ("Error: %s\n", err->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;
|
|
}
|
|
|
|
/* we want to be notified again the next time there is a message
|
|
* on the bus, so returning TRUE (FALSE means we want to stop watching
|
|
* for messages on the bus and our callback should not be called again)
|
|
*/
|
|
return TRUE;
|
|
}
|
|
|
|
gint
|
|
main (gint argc,
|
|
gchar *argv[])
|
|
{
|
|
GstElement *pipeline;
|
|
GstBus *bus;
|
|
guint bus_watch_id;
|
|
|
|
/* init */
|
|
gst_init (&argc, &argv);
|
|
|
|
/* create pipeline, add handler */
|
|
pipeline = gst_pipeline_new ("my_pipeline");
|
|
|
|
/* adds a watch for new message on our pipeline's message bus to
|
|
* the default GLib main context, which is the main context that our
|
|
* GLib main loop is attached to below
|
|
*/
|
|
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
|
|
bus_watch_id = gst_bus_add_watch (bus, my_bus_callback, NULL);
|
|
gst_object_unref (bus);
|
|
<!-- example-end bus.c a -->
|
|
[..]<!-- example-begin bus.c b -->
|
|
<!-- example-begin bus.c c -->
|
|
/* create a mainloop that runs/iterates the default GLib main context
|
|
* (context NULL), in other words: makes the context check if anything
|
|
* it watches for has happened. When a message has been posted on the
|
|
* bus, the default main context will automatically call our
|
|
* my_bus_callback() function to notify us of that message.
|
|
* The main loop will be run until someone calls g_main_loop_quit()
|
|
*/
|
|
loop = g_main_loop_new (NULL, FALSE);
|
|
g_main_loop_run (loop);
|
|
|
|
/* clean up */
|
|
gst_element_set_state (pipeline, GST_STATE_NULL);
|
|
gst_object_unref (pipeline);
|
|
g_source_remove (bus_watch_id);
|
|
g_main_loop_unref (loop);
|
|
|
|
return 0;
|
|
}
|
|
<!-- example-end bus.c c -->
|
|
</programlisting>
|
|
<para>
|
|
It is important to know that the handler will be called in the thread
|
|
context of the mainloop. This means that the interaction between the
|
|
pipeline and application over the bus is
|
|
<emphasis>asynchronous</emphasis>, and thus not suited for some
|
|
real-time purposes, such as cross-fading between audio tracks, doing
|
|
(theoretically) gapless playback or video effects. All such things
|
|
should be done in the pipeline context, which is easiest by writing
|
|
a &GStreamer; plug-in. It is very useful for its primary purpose,
|
|
though: passing messages from pipeline to application.
|
|
The advantage of this approach is that all the threading that
|
|
&GStreamer; does internally is hidden from the application and the
|
|
application developer does not have to worry about thread issues at
|
|
all.
|
|
</para>
|
|
<para>
|
|
Note that if you're using the default GLib mainloop integration, you
|
|
can, instead of attaching a watch, connect to the <quote>message</quote>
|
|
signal on the bus. This way you don't have to
|
|
<function>switch()</function>
|
|
on all possible message types; just connect to the interesting signals
|
|
in form of <quote>message::<type></quote>, where <type>
|
|
is a specific message type (see the next section for an explanation of
|
|
message types).
|
|
</para>
|
|
<para>
|
|
The above snippet could then also be written as:
|
|
</para>
|
|
<programlisting>
|
|
GstBus *bus;
|
|
|
|
[..]
|
|
|
|
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline);
|
|
gst_bus_add_signal_watch (bus);
|
|
g_signal_connect (bus, "message::error", G_CALLBACK (cb_message_error), NULL);
|
|
g_signal_connect (bus, "message::eos", G_CALLBACK (cb_message_eos), NULL);
|
|
|
|
[..]
|
|
</programlisting>
|
|
<para>
|
|
If you aren't using GLib mainloop, the asynchronous message signals won't
|
|
be available by default. You can however install a custom sync handler
|
|
that wakes up the custom mainloop and that uses
|
|
<function>gst_bus_async_signal_func ()</function> to emit the signals.
|
|
(see also <ulink type="http"
|
|
url="&URLAPI;GstBus.html">documentation</ulink> for details)
|
|
</para>
|
|
</sect1>
|
|
|
|
<sect1 id="section-bus-message-types">
|
|
<title>Message types</title>
|
|
<para>
|
|
&GStreamer; has a few pre-defined message types that can be passed
|
|
over the bus. The messages are extensible, however. Plug-ins can
|
|
define additional messages, and applications can decide to either
|
|
have specific code for those or ignore them. All applications are
|
|
strongly recommended to at least handle error messages by providing
|
|
visual feedback to the user.
|
|
</para>
|
|
<para>
|
|
All messages have a message source, type and timestamp. The message
|
|
source can be used to see which element emitted the message. For some
|
|
messages, for example, only the ones emitted by the top-level pipeline
|
|
will be interesting to most applications (e.g. for state-change
|
|
notifications). Below is a list of all messages and a short explanation
|
|
of what they do and how to parse message-specific content.
|
|
</para>
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>
|
|
Error, warning and information notifications: those are used
|
|
by elements if a message should be shown to the user about the
|
|
state of the pipeline. Error messages are fatal and terminate
|
|
the data-passing. The error should be repaired to resume pipeline
|
|
activity. Warnings are not fatal, but imply a problem nevertheless.
|
|
Information messages are for non-problem notifications. All those
|
|
messages contain a <classname>GError</classname> with the main
|
|
error type and message, and optionally a debug string. Both
|
|
can be extracted using <function>gst_message_parse_error
|
|
()</function>, <function>_parse_warning ()</function> and
|
|
<function>_parse_info ()</function>. Both error and debug strings
|
|
should be freed after use.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
End-of-stream notification: this is emitted when the stream has
|
|
ended. The state of the pipeline will not change, but further
|
|
media handling will stall. Applications can use this to skip to
|
|
the next song in their playlist. After end-of-stream, it is also
|
|
possible to seek back in the stream. Playback will then continue
|
|
automatically. This message has no specific arguments.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
Tags: emitted when metadata was found in the stream. This can be
|
|
emitted multiple times for a pipeline (e.g. once for descriptive
|
|
metadata such as artist name or song title, and another one for
|
|
stream-information, such as samplerate and bitrate). Applications
|
|
should cache metadata internally. <function>gst_message_parse_tag
|
|
()</function> should be used to parse the taglist, which should
|
|
be <function>gst_tag_list_unref ()</function>'ed when no longer
|
|
needed.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
State-changes: emitted after a successful state change.
|
|
<function>gst_message_parse_state_changed ()</function> can be
|
|
used to parse the old and new state of this transition.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
Buffering: emitted during caching of network-streams. One can
|
|
manually extract the progress (in percent) from the message by
|
|
extracting the <quote>buffer-percent</quote> property from the
|
|
structure returned by <function>gst_message_get_structure
|
|
()</function>.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
Element messages: these are special messages that are unique to
|
|
certain elements and usually represent additional features. The
|
|
element's documentation should mention in detail which
|
|
element messages a particular element may send. As an example,
|
|
the 'qtdemux' QuickTime demuxer element may send a 'redirect'
|
|
element message on certain occasions if the stream contains a
|
|
redirect instruction.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
Application-specific messages: any information on those can
|
|
be extracted by getting the message structure (see above) and
|
|
reading its fields. Usually these messages can safely be ignored.
|
|
</para>
|
|
<para>
|
|
Application messages are primarily meant for internal
|
|
use in applications in case the application needs to marshal
|
|
information from some thread into the main thread. This is
|
|
particularly useful when the application is making use of element
|
|
signals (as those signals will be emitted in the context of the
|
|
streaming thread).
|
|
</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
</sect1>
|
|
</chapter>
|