manual: talk about playsink

Talk about playsink and give an example of its usage.
This commit is contained in:
Wim Taymans 2012-10-10 16:43:58 +02:00
parent 36c47c89eb
commit fa14d42a1e
2 changed files with 205 additions and 8 deletions

View file

@ -193,9 +193,12 @@ main (gint argc,
responsible for reporting the error to the user.
</para>
<programlisting><!-- example-begin decodebin.c a -->
#include &lt;gst/gst.h&gt;
<![CDATA[
#include <gst/gst.h>
]]>
<!-- example-end decodebin.c a -->
[.. my_bus_callback goes here ..]<!-- example-begin decodebin.c b --><!--
[.. my_bus_callback goes here ..]<!-- example-begin decodebin.c b -->
<!--
static gboolean
my_bus_callback (GstBus *bus,
GstMessage *message,
@ -230,6 +233,7 @@ my_bus_callback (GstBus *bus,
}
--><!-- example-end decodebin.c b -->
<!-- example-begin decodebin.c c -->
<![CDATA[
GstElement *pipeline, *audio;
static void
@ -274,12 +278,12 @@ main (gint argc,
GstBus *bus;
/* init GStreamer */
gst_init (&amp;argc, &amp;argv);
gst_init (&argc, &argv);
loop = g_main_loop_new (NULL, FALSE);
/* make sure we have input */
if (argc != 2) {
g_print ("Usage: %s &lt;filename&gt;\n", argv[0]);
g_print ("Usage: %s <filename>\n", argv[0]);
return -1;
}
@ -319,8 +323,8 @@ main (gint argc,
return 0;
}
]]>
<!-- example-end decodebin.c c --></programlisting>
<para>
Decodebin, similar to playbin, supports the following features:
</para>
@ -419,4 +423,195 @@ main (gint argc,
! audioconvert ! audioresample ! autoaudiosink</command>.
</para>
</sect1>
<sect1 id="section-components-playsink">
<title>Playsink</title>
<para>
The playsink element is a powerful sink element. It has request pads
for raw decoded audio, video and text and it will configure itself to
play the media streams. It has the following features:
</para>
<itemizedlist>
<listitem>
<para>
It exposes GstStreamVolume, GstVideoOverlay, GstNavigation and
GstColorBalance interfaces and automatically plugs software
elements to implement the interfaces when needed.
</para>
</listitem>
<listitem>
<para>
It will automatically plug conversion elements.
</para>
</listitem>
<listitem>
<para>
Can optionally render visualizations when there is no video input.
</para>
</listitem>
<listitem>
<para>
Configurable sink elements.
</para>
</listitem>
<listitem>
<para>
Configurable audio/video sync offset to fine-tune synchronization
in badly muxed files.
</para>
</listitem>
<listitem>
<para>
Support for taking a snapshot of the last video frame.
</para>
</listitem>
</itemizedlist>
<para>
Below is an example of how you can use playsink. We use a uridecodebin
element to decode into raw audio and video streams which we then link
to the playsink request pads. We only link the first audio and video
pads, you could use an input-selector to link all pads.
</para>
<programlisting>
<!-- example-begin playsink.c a -->
<![CDATA[
#include <gst/gst.h>
]]>
<!-- example-end playsink.c a -->
[.. my_bus_callback goes here ..]
<!-- example-begin playsink.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 playsink.c b -->
<!-- example-begin playsink.c c -->
<![CDATA[
GstElement *pipeline, *sink;
static void
cb_pad_added (GstElement *dec,
GstPad *pad,
gpointer data)
{
GstCaps *caps;
GstStructure *str;
const gchar *name;
GstPadTemplate *templ;
GstElementClass *klass;
/* check media type */
caps = gst_pad_query_caps (pad, NULL);
str = gst_caps_get_structure (caps, 0);
name = gst_structure_get_name (str);
klass = GST_ELEMENT_GET_CLASS (sink);
if (g_str_has_prefix (name, "audio")) {
templ = gst_element_class_get_pad_template (klass, "audio_sink");
} else if (g_str_has_prefix (name, "video")) {
templ = gst_element_class_get_pad_template (klass, "video_sink");
} else if (g_str_has_prefix (name, "text")) {
templ = gst_element_class_get_pad_template (klass, "text_sink");
} else {
templ = NULL;
}
if (templ) {
GstPad *sinkpad;
sinkpad = gst_element_request_pad (sink, templ, NULL, NULL);
if (!gst_pad_is_linked (sinkpad))
gst_pad_link (pad, sinkpad);
gst_object_unref (sinkpad);
}
}
gint
main (gint argc,
gchar *argv[])
{
GMainLoop *loop;
GstElement *dec;
GstBus *bus;
/* init GStreamer */
gst_init (&argc, &argv);
loop = g_main_loop_new (NULL, FALSE);
/* make sure we have input */
if (argc != 2) {
g_print ("Usage: %s <uri>\n", argv[0]);
return -1;
}
/* setup */
pipeline = gst_pipeline_new ("pipeline");
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
gst_bus_add_watch (bus, my_bus_callback, loop);
gst_object_unref (bus);
dec = gst_element_factory_make ("uridecodebin", "source");
g_object_set (G_OBJECT (dec), "uri", argv[1], NULL);
g_signal_connect (dec, "pad-added", G_CALLBACK (cb_pad_added), NULL);
/* create audio output */
sink = gst_element_factory_make ("playsink", "sink");
gst_util_set_object_arg (G_OBJECT (sink), "flags",
"soft-colorbalance+soft-volume+vis+text+audio+video");
gst_bin_add_many (GST_BIN (pipeline), dec, sink, NULL);
/* run */
gst_element_set_state (pipeline, GST_STATE_PLAYING);
g_main_loop_run (loop);
/* cleanup */
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (GST_OBJECT (pipeline));
return 0;
}
]]>
<!-- example-end playsink.c c -->
</programlisting>
<para>
This example will show audio and video depending on what you
give it. Try this example on an audio file and you will see that
it shows visualizations. You can change the visualization at runtime by
changing the vis-plugin property.
</para>
</sect1>
</chapter>

View file

@ -42,7 +42,8 @@ EXAMPLES = \
effectswitch \
testrtpool \
playbin \
decodebin
decodebin \
playsink
BUILT_SOURCES = \
elementmake.c elementcreate.c elementget.c elementlink.c elementfactory.c \
@ -60,7 +61,8 @@ BUILT_SOURCES = \
dynformat.c \
effectswitch.c \
testrtpool.c \
playbin.c decodebin.c
playbin.c decodebin.c \
playsink.c
CLEANFILES = core core.* test-registry.* *.gcno *.gcda $(BUILT_SOURCES)
@ -110,7 +112,7 @@ dynformat.c: $(top_srcdir)/docs/manual/advanced-dataaccess.xml
effectswitch.c: $(top_srcdir)/docs/manual/advanced-dataaccess.xml
$(PERL_PATH) $(srcdir)/extract.pl $@ $<
playbin.c decodebin.c: $(top_srcdir)/docs/manual/highlevel-playback.xml
playbin.c decodebin.c playsink.c: $(top_srcdir)/docs/manual/highlevel-playback.xml
$(PERL_PATH) $(srcdir)/extract.pl $@ $<
testrtpool.c: $(top_srcdir)/docs/manual/advanced-threads.xml