1 <chapter id="chapter-dataaccess">
2 <title>Pipeline manipulation</title>
4 This chapter will discuss how you can manipulate your pipeline in several
5 ways from your application on. Parts of this chapter are downright
6 hackish, so be assured that you'll need some programming knowledge
7 before you start reading this.
10 Topics that will be discussed here include how you can insert data into
11 a pipeline from your application, how to read data from a pipeline,
12 how to manipulate the pipeline's speed, length, starting point and how
13 to listen to a pipeline's data processing.
16 <sect1 id="section-data-probe">
17 <title>Data probing</title>
19 Probing is best envisioned as a pad listener. Technically, a probe is
20 nothing more than a signal callback that can be attached to a pad.
21 Those signals are by default not fired at all (since that may have a
22 negative impact on performance), but can be enabled by attaching a
23 probe using <function>gst_pad_add_data_probe ()</function> or one of
24 the similar functions. Those functions attach the signal handler and
25 enable the actual signal emission. Similarly, one can use the
26 <function>gst_pad_remove_data_probe ()</function> or related functions
27 to remove the signal handlers again. It is also possible to only listen
28 to events or only to buffers (and ignore the other).
31 Probes run in pipeline threading context, so callbacks should try to
32 not block and generally not do any weird stuff, since this could
33 have a negative impact on pipeline performance or, in case of bugs,
34 cause deadlocks or crashes. However, most common buffer operations
35 that elements can do in <function>_chain ()</function> functions, can
36 be done in probe callbacks as well. The example below gives a short
37 impression on how to use them.
39 <programlisting><!-- example-begin probe.c -->
40 #include <gst/gst.h>
43 cb_have_data (GstPad *pad,
48 guint16 *data = (guint16 *) GST_BUFFER_DATA (buffer), t;
51 for (y = 0; y < 288; y++) {
52 for (x = 0; x < 384 / 2; x++) {
53 t = data[384 - 1 - x];
54 data[384 - 1 - x] = data[x];
68 GstElement *pipeline, *src, *sink, *filter, *csp;
72 gst_init (&argc, &argv);
73 loop = g_main_loop_new (NULL, FALSE);
76 pipeline = gst_pipeline_new ("my-pipeline");
77 src = gst_element_factory_make ("videotestsrc", "src");
78 filter = gst_element_factory_make ("capsfilter", "filter");
79 csp = gst_element_factory_make ("ffmpegcolorspace", "csp");
80 sink = gst_element_factory_make ("xvimagesink", "sink");
81 gst_bin_add_many (GST_BIN (pipeline), src, filter, csp, sink, NULL);
82 gst_element_link_many (src, filter, csp, sink, NULL);
83 g_object_set (G_OBJECT (filter), "caps",
84 gst_caps_new_simple ("video/x-raw-rgb",
85 "width", G_TYPE_INT, 384,
86 "height", G_TYPE_INT, 288,
87 "framerate", G_TYPE_DOUBLE, (gdouble) 25.0,
88 "bpp", G_TYPE_INT, 16,
89 "depth", G_TYPE_INT, 16,
90 "endianness", G_TYPE_INT, G_BYTE_ORDER,
92 pad = gst_element_get_pad (src, "src");
93 gst_pad_add_buffer_probe (pad, G_CALLBACK (cb_have_data), NULL);
94 gst_object_unref (pad);
97 gst_element_set_state (pipeline, GST_STATE_PLAYING);
98 g_main_loop_run (loop);
101 gst_element_set_state (pipeline, GST_STATE_NULL);
102 gst_object_unref (pipeline);
106 <!-- example-end probe.c --></programlisting>
108 Compare that output with the output of <quote>gst-launch-0.9
109 videotestsrc ! xvimagesink</quote>, just so you know what you're
114 <sect1 id="section-data-spoof">
115 <title>Manually adding or removing data from/to a pipeline</title>
117 Many people have expressed the wish to use their own sources to inject
118 data into a pipeline. Some people have also expressed the wish to grab
119 the output in a pipeline and take care of the actual output inside
120 their application. While either of these methods are stongly
121 discouraged, &GStreamer; offers hacks to do this. <emphasis>However,
122 there is no support for those methods.</emphasis> If it doesn't work,
123 you're on your own. Also, synchronization, thread-safety and other
124 things that you've been able to take for granted so far are no longer
125 guanranteed if you use any of those methods. It's always better to
126 simply write a plugin and have the pipeline schedule and manage it.
127 See the Plugin Writer's Guide for more information on this topic. Also
128 see the next section, which will explain how to embed plugins statically
132 After all those disclaimers, let's start. There's three possible
133 elements that you can use for the above-mentioned purposes. Those are
134 called <quote>fakesrc</quote> (an imaginary source),
135 <quote>fakesink</quote> (an imaginary sink) and <quote>identity</quote>
136 (an imaginary filter). The same method applies to each of those
137 elements. Here, we will discuss how to use those elements to insert
138 (using fakesrc) or grab (using fakesink or identity) data from a
139 pipeline, and how to set negotiation.
142 Those who're paying close attention, will notice that the purpose
143 of identity is almost identical to that of probes. Indeed, this is
144 true. Probes allow for the same purpose, and a bunch more, and
145 with less overhead plus dynamic removing/adding of handlers, but
146 apart from those, probes and identity have the same purpose, just
147 in a completely different implementation type.
150 <sect2 id="section-spoof-handoff">
151 <title>Inserting or grabbing data</title>
153 The three before-mentioned elements (fakesrc, fakesink and identity)
154 each have a <quote>handoff</quote> signal that will be called in
155 the <function>_get ()</function>- (fakesrc) or <function>_chain
156 ()</function>-function (identity, fakesink). In the signal handler,
157 you can set (fakesrc) or get (identity, fakesink) data to/from the
158 provided buffer. Note that in the case of fakesrc, you have to set
159 the size of the provided buffer using the <quote>sizemax</quote>
160 property. For both fakesrc and fakesink, you also have to set the
161 <quote>signal-handoffs</quote> property for this method to work.
164 Note that your handoff function should <emphasis>not</emphasis>
165 block, since this will block pipeline iteration. Also, do not try
166 to use all sort of weird hacks in such functions to accomplish
167 something that looks like synchronization or so; it's not the right
168 way and will lead to issues elsewhere. If you're doing any of this,
169 you're basically misunderstanding the &GStreamer; design.
173 <sect2 id="section-spoof-format">
174 <title>Forcing a format</title>
176 Sometimes, when using fakesrc as a source in your pipeline, you'll
177 want to set a specific format, for example a video size and format
178 or an audio bitsize and number of channels. You can do this by
179 forcing a specific <classname>GstCaps</classname> on the pipeline,
180 which is possible by using <emphasis>filtered caps</emphasis>. You
181 can set a filtered caps on a link by using the
182 <quote>capsfilter</quote> element in between the two elements, and
183 specifying a <classname>GstCaps</classname> as
184 <quote>caps</quote> property on this element. It will then
185 only allow types matching that specified capability set for
190 <sect2 id="section-spoof-example">
191 <title>Example application</title>
193 This example application will generate black/white (it switches
194 every second) video to an X-window output by using fakesrc as a
195 source and using filtered caps to force a format. Since the depth
196 of the image depends on your X-server settings, we use a colorspace
197 conversion element to make sure that the output to your X server
198 will have the correct bitdepth. You can also set timestamps on the
199 provided buffers to override the fixed framerate.
201 <programlisting><!-- example-begin fakesrc.c -->
202 #include <string.h> /* for memset () */
203 #include <gst/gst.h>
206 cb_handoff (GstElement *fakesrc,
211 static gboolean white = FALSE;
213 /* this makes the image black/white */
214 memset (GST_BUFFER_DATA (buffer), white ? 0xff : 0x0,
215 GST_BUFFER_SIZE (buffer));
223 GstElement *pipeline, *fakesrc, *flt, *conv, *videosink;
227 gst_init (&argc, &argv);
228 loop = g_main_loop_new (NULL, FALSE);
231 pipeline = gst_pipeline_new ("pipeline");
232 fakesrc = gst_element_factory_make ("fakesrc", "source");
233 flt = gst_element_factory_make ("capsfilter", "flt");
234 conv = gst_element_factory_make ("ffmpegcolorspace", "conv");
235 videosink = gst_element_factory_make ("xvimagesink", "videosink");
238 g_object_set (G_OBJECT (flt), "caps",
239 gst_caps_new_simple ("video/x-raw-rgb",
240 "width", G_TYPE_INT, 384,
241 "height", G_TYPE_INT, 288,
242 "framerate", G_TYPE_DOUBLE, (gdouble) 1.0,
243 "bpp", G_TYPE_INT, 16,
244 "depth", G_TYPE_INT, 16,
245 "endianness", G_TYPE_INT, G_BYTE_ORDER,
247 gst_bin_add_many (GST_BIN (pipeline), fakesrc, flt, conv, videosink, NULL);
248 gst_element_link_many (fakesrc, flt, conv, videosink, NULL);
250 /* setup fake source */
251 g_object_set (G_OBJECT (fakesrc),
252 "signal-handoffs", TRUE,
253 "sizemax", 384 * 288 * 2,
254 "sizetype", 2, NULL);
255 g_signal_connect (fakesrc, "handoff", G_CALLBACK (cb_handoff), NULL);
258 gst_element_set_state (pipeline, GST_STATE_PLAYING);
259 g_main_loop_run (loop);
262 gst_element_set_state (pipeline, GST_STATE_NULL);
263 gst_object_unref (GST_OBJECT (pipeline));
267 <!-- example-end fakesrc.c --></programlisting>
271 <sect1 id="section-data-manager">
272 <title>Embedding static elements in your application</title>
274 The <ulink type="http"
275 url="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/pwg/html/index.html">Plugin
276 Writer's Guide</ulink> describes in great detail how to write elements
277 for the &GStreamer; framework. In this section, we will solely discuss
278 how to embed such elements statically in your application. This can be
279 useful for application-specific elements that have no use elsewhere in
283 Dynamically loaded plugins contain a structure that's defined using
284 <function>GST_PLUGIN_DEFINE ()</function>. This structure is loaded
285 when the plugin is loaded by the &GStreamer; core. The structure
286 contains an initialization function (usually called
287 <function>plugin_init</function>) that will be called right after that.
288 It's purpose is to register the elements provided by the plugin with
289 the &GStreamer; framework. If you want to embed elements directly in
290 your application, the only thing you need to do is to manually run
291 this structure using <function>_gst_plugin_register_static
292 ()</function>. The initialization will then be called, and the elements
293 will from then on be available like any other element, without
294 them having to be dynamically loadable libraries. In the example below,
295 you would be able to call <function>gst_element_factory_make
296 ("my-element-name", "some-name")</function> to create an instance
301 * Here, you would write the actual plugin code.
307 register_elements (GstPlugin *plugin)
309 return gst_element_register (plugin, "my-element-name",
310 GST_RANK_NONE, MY_PLUGIN_TYPE);
313 static GstPluginDesc plugin_desc = {
316 "my-private-plugins",
317 "Private elements of my application",
323 "http://www.my-application.net/",
328 * Call this function right after calling gst_init ().
332 my_elements_init (void)
334 _gst_plugin_register_static (&plugin_desc);