1 # Playback tutorial 7: Custom playbin sinks
5 `playbin` can be further customized by manually selecting its audio and
6 video sinks. This allows applications to rely on `playbin` to retrieve
7 and decode the media and then manage the final render/display
8 themselves. This tutorial shows:
10 - How to replace the sinks selected by `playbin`.
11 - How to use a complex pipeline as a sink.
15 Two properties of `playbin` allow selecting the desired audio and video
16 sinks: `audio-sink` and `video-sink` (respectively). The application
17 only needs to instantiate the appropriate `GstElement` and pass it to
18 `playbin` through these properties.
20 This method, though, only allows using a single Element as sink. If a
21 more complex pipeline is required, for example, an equalizer plus an
22 audio sink, it needs to be wrapped in a Bin, so it looks to
23 `playbin` as if it was a single Element.
25 A Bin (`GstBin`) is a container that encapsulates partial pipelines so
26 they can be managed as single elements. As an example, the
27 `GstPipeline` we have been using in all tutorials is a type of
28 `GstBin`, which does not interact with external Elements. Elements
29 inside a Bin connect to external elements through Ghost Pads
30 (`GstGhostPad`), this is, Pads on the surface of the Bin which simply
31 forward data from an external Pad to a given Pad on an internal Element.
33 ![](images/bin-element-ghost.png)
35 **Figure 1:** A Bin with two Elements and one Ghost Pad.
37 `GstBin`s are also a type of `GstElement`, so they can be used wherever
38 an Element is required, in particular, as sinks for `playbin` (and they
39 are then known as **sink-bins**).
41 ## An equalized player
43 Copy this code into a text file named `playback-tutorial-7.c`.
45 **playback-tutorial7.c**
50 int main(int argc, char *argv[]) {
51 GstElement *pipeline, *bin, *equalizer, *convert, *sink;
52 GstPad *pad, *ghost_pad;
56 /* Initialize GStreamer */
57 gst_init (&argc, &argv);
59 /* Build the pipeline */
60 pipeline = gst_parse_launch ("playbin uri=https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm", NULL);
62 /* Create the elements inside the sink bin */
63 equalizer = gst_element_factory_make ("equalizer-3bands", "equalizer");
64 convert = gst_element_factory_make ("audioconvert", "convert");
65 sink = gst_element_factory_make ("autoaudiosink", "audio_sink");
66 if (!equalizer || !convert || !sink) {
67 g_printerr ("Not all elements could be created.\n");
71 /* Create the sink bin, add the elements and link them */
72 bin = gst_bin_new ("audio_sink_bin");
73 gst_bin_add_many (GST_BIN (bin), equalizer, convert, sink, NULL);
74 gst_element_link_many (equalizer, convert, sink, NULL);
75 pad = gst_element_get_static_pad (equalizer, "sink");
76 ghost_pad = gst_ghost_pad_new ("sink", pad);
77 gst_pad_set_active (ghost_pad, TRUE);
78 gst_element_add_pad (bin, ghost_pad);
79 gst_object_unref (pad);
81 /* Configure the equalizer */
82 g_object_set (G_OBJECT (equalizer), "band1", (gdouble)-24.0, NULL);
83 g_object_set (G_OBJECT (equalizer), "band2", (gdouble)-24.0, NULL);
85 /* Set playbin's audio sink to be our sink bin */
86 g_object_set (GST_OBJECT (pipeline), "audio-sink", bin, NULL);
89 gst_element_set_state (pipeline, GST_STATE_PLAYING);
91 /* Wait until error or EOS */
92 bus = gst_element_get_bus (pipeline);
93 msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_ERROR | GST_MESSAGE_EOS);
97 gst_message_unref (msg);
98 gst_object_unref (bus);
99 gst_element_set_state (pipeline, GST_STATE_NULL);
100 gst_object_unref (pipeline);
105 > ![information] If you need help to compile this code, refer to the
106 > **Building the tutorials** section for your platform: [Mac] or
107 > [Windows] or use this specific command on Linux:
109 > `` gcc playback-tutorial-7.c -o playback-tutorial-7 `pkg-config --cflags --libs gstreamer-1.0` ``
111 > If you need help to run this code, refer to the **Running the
112 > tutorials** section for your platform: [Mac OS X], [Windows][1], for
113 > [iOS] or for [android].
115 > This tutorial opens a window and displays a movie, with accompanying audio. The media is fetched from the Internet, so the window might take a few seconds to appear, depending on your connection speed. The higher frequency bands have been attenuated, so the movie sound should have a more powerful bass component.<
117 > Required libraries: `gstreamer-1.0`
122 /* Create the elements inside the sink bin */
123 equalizer = gst_element_factory_make ("equalizer-3bands", "equalizer");
124 convert = gst_element_factory_make ("audioconvert", "convert");
125 sink = gst_element_factory_make ("autoaudiosink", "audio_sink");
126 if (!equalizer || !convert || !sink) {
127 g_printerr ("Not all elements could be created.\n");
132 All the Elements that compose our sink-bin are instantiated. We use an
133 `equalizer-3bands` and an `autoaudiosink`, with an `audioconvert` in
134 between, because we are not sure of the capabilities of the audio sink
135 (since they are hardware-dependant).
138 /* Create the sink bin, add the elements and link them */
139 bin = gst_bin_new ("audio_sink_bin");
140 gst_bin_add_many (GST_BIN (bin), equalizer, convert, sink, NULL);
141 gst_element_link_many (equalizer, convert, sink, NULL);
144 This adds the new Elements to the Bin and links them just as we would do
145 if this was a pipeline.
148 pad = gst_element_get_static_pad (equalizer, "sink");
149 ghost_pad = gst_ghost_pad_new ("sink", pad);
150 gst_pad_set_active (ghost_pad, TRUE);
151 gst_element_add_pad (bin, ghost_pad);
152 gst_object_unref (pad);
155 Now we need to create a Ghost Pad so this partial pipeline inside the
156 Bin can be connected to the outside. This Ghost Pad will be connected to
157 a Pad in one of the internal Elements (the sink pad of the equalizer),
158 so we retrieve this Pad with `gst_element_get_static_pad()`. Remember
159 from [](sdk-basic-tutorial-multithreading-and-pad-availability.md) that
160 if this was a Request Pad instead of an Always Pad, we would need to use
161 `gst_element_request_pad()`.
163 The Ghost Pad is created with `gst_ghost_pad_new()` (pointing to the
164 inner Pad we just acquired), and activated with `gst_pad_set_active()`.
165 It is then added to the Bin with `gst_element_add_pad()`, transferring
166 ownership of the Ghost Pad to the bin, so we do not have to worry about
169 Finally, the sink Pad we obtained from the equalizer needs to be release
170 with `gst_object_unref()`.
172 At this point, we have a functional sink-bin, which we can use as the
173 audio sink in `playbin`. We just need to instruct `playbin` to use it:
176 /* Set playbin's audio sink to be our sink bin */
177 g_object_set (GST_OBJECT (pipeline), "audio-sink", bin, NULL);
180 It is as simple as setting the `audio-sink` property on `playbin` to
181 the newly created sink.
184 /* Configure the equalizer */
185 g_object_set (G_OBJECT (equalizer), "band1", (gdouble)-24.0, NULL);
186 g_object_set (G_OBJECT (equalizer), "band2", (gdouble)-24.0, NULL);
189 The only bit remaining is to configure the equalizer. For this example,
190 the two higher frequency bands are set to the maximum attenuation so the
191 bass is boosted. Play a bit with the values to feel the difference (Look
192 at the documentation for the `equalizer-3bands` element for the allowed
197 Build a video bin instead of an audio bin, using one of the many
198 interesting video filters GStreamer offers, like `solarize`,
199 `vertigotv` or any of the Elements in the `effectv` plugin. Remember to
200 use the color space conversion element `videoconvert` if your
201 pipeline fails to link due to incompatible caps.
205 This tutorial has shown:
207 - How to set your own sinks to `playbin` using the audio-sink and
208 video-sink properties.
209 - How to wrap a piece of pipeline into a `GstBin` so it can be used as
210 a **sink-bin** by `playbin`.
212 It has been a pleasure having you here, and see you soon\!
214 [information]: images/icons/emoticons/information.png
215 [Mac]: sdk-installing-on-mac-osx.md
216 [Windows]: sdk-installing-on-windows.md
217 [Mac OS X]: sdk-installing-on-mac-osx.md#building-the-tutorials
218 [1]: sdk-installing-on-windows.md#running-the-tutorials
219 [iOS]: sdk-installing-for-ios-development.md#building-the-tutorials
220 [android]: sdk-installing-for-android-development.md#building-the-tutorials
221 [warning]: images/icons/emoticons/warning.png