Merge branch 'master' into 0.11
[platform/upstream/gstreamer.git] / docs / manual / advanced-dataaccess.xml
1 <chapter id="chapter-dataaccess">
2   <title>Pipeline manipulation</title>
3   <para>
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.
8   </para>
9   <para>
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.
14   </para>
15
16   <sect1 id="section-data-probe">
17     <title>Data probing</title>
18     <para>
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_buffer_probe ()</function>,
24       <function>gst_pad_add_event_probe ()</function>, or
25       <function>gst_pad_add_data_probe ()</function>.
26       Those functions attach the signal handler and
27       enable the actual signal emission. Similarly, one can use the
28       <function>gst_pad_remove_buffer_probe ()</function>,
29       <function>gst_pad_remove_event_probe ()</function>, or
30       <function>gst_pad_remove_data_probe ()</function>
31       to remove the signal handlers again.
32     </para>
33     <para>
34       Probes run in pipeline threading context, so callbacks should try to
35       not block and generally not do any weird stuff, since this could
36       have a negative impact on pipeline performance or, in case of bugs,
37       cause deadlocks or crashes. More precisely, one should usually not
38       call any GUI-related functions from within a probe callback, nor try
39       to change the state of the pipeline.  An application may post custom
40       messages on the pipeline's bus though to communicate with the main
41       application thread and have it do things like stop the pipeline.
42     </para>
43     <para>
44       In any case, most common buffer operations
45       that elements can do in <function>_chain ()</function> functions, can
46       be done in probe callbacks as well. The example below gives a short
47       impression on how to use them (even if this usage is not entirely
48       correct, but more on that below):
49     </para>
50     <programlisting><!-- example-begin probe.c -->
51 #include &lt;gst/gst.h&gt;
52
53 static gboolean
54 cb_have_data (GstPad    *pad,
55               GstBuffer *buffer,
56               gpointer   u_data)
57 {
58   gint x, y;
59   guint16 *data, *ptr, t;
60   gsize size;
61   
62   data = gst_buffer_map (buffer, &amp;size, NULL, GST_MAP_WRITE);
63
64   ptr = data;
65   /* invert data */
66   for (y = 0; y &lt; 288; y++) {
67     for (x = 0; x &lt; 384 / 2; x++) {
68       t = ptr[384 - 1 - x];
69       ptr[384 - 1 - x] = ptr[x];
70       ptr[x] = t;
71     }
72     ptr += 384;
73   }
74   gst_buffer_unmap (buffer, data, size);
75
76
77   return TRUE;
78 }
79
80 gint
81 main (gint   argc,
82       gchar *argv[])
83 {
84   GMainLoop *loop;
85   GstElement *pipeline, *src, *sink, *filter, *csp;
86   GstCaps *filtercaps;
87   GstPad *pad;
88
89   /* init GStreamer */
90   gst_init (&amp;argc, &amp;argv);
91   loop = g_main_loop_new (NULL, FALSE);
92
93   /* build */
94   pipeline = gst_pipeline_new ("my-pipeline");
95   src = gst_element_factory_make ("videotestsrc", "src");
96   if (src == NULL)
97     g_error ("Could not create 'videotestsrc' element");
98
99   filter = gst_element_factory_make ("capsfilter", "filter");
100   g_assert (filter != NULL); /* should always exist */
101
102   csp = gst_element_factory_make ("ffmpegcolorspace", "csp");
103   if (csp == NULL)
104     g_error ("Could not create 'ffmpegcolorspace' element");
105
106   sink = gst_element_factory_make ("xvimagesink", "sink");
107   if (sink == NULL) {
108     sink = gst_element_factory_make ("ximagesink", "sink");
109     if (sink == NULL)
110       g_error ("Could not create neither 'xvimagesink' nor 'ximagesink' element");
111   }
112
113   gst_bin_add_many (GST_BIN (pipeline), src, filter, csp, sink, NULL);
114   gst_element_link_many (src, filter, csp, sink, NULL);
115   filtercaps = gst_caps_new_simple ("video/x-raw-rgb",
116                            "width", G_TYPE_INT, 384,
117                            "height", G_TYPE_INT, 288,
118                            "framerate", GST_TYPE_FRACTION, 25, 1,
119                            "bpp", G_TYPE_INT, 16,
120                            "depth", G_TYPE_INT, 16,
121                            "endianness", G_TYPE_INT, G_BYTE_ORDER,
122                            NULL);
123   g_object_set (G_OBJECT (filter), "caps", filtercaps, NULL);
124   gst_caps_unref (filtercaps);
125
126   pad = gst_element_get_pad (src, "src");
127   gst_pad_add_buffer_probe (pad, G_CALLBACK (cb_have_data), NULL);
128   gst_object_unref (pad);
129
130   /* run */
131   gst_element_set_state (pipeline, GST_STATE_PLAYING);
132
133   /* wait until it's up and running or failed */
134   if (gst_element_get_state (pipeline, NULL, NULL, -1) == GST_STATE_CHANGE_FAILURE) {
135     g_error ("Failed to go into PLAYING state");
136   }
137
138   g_print ("Running ...\n");
139   g_main_loop_run (loop);
140
141   /* exit */
142   gst_element_set_state (pipeline, GST_STATE_NULL);
143   gst_object_unref (pipeline);
144
145   return 0;
146 }
147     <!-- example-end probe.c --></programlisting>
148     <para>
149       Compare that output with the output of <quote>gst-launch-0.10
150       videotestsrc ! xvimagesink</quote>, just so you know what you're
151       looking for.
152     </para>
153     <para>
154       The above example is not really correct though.  Strictly speaking, a
155       pad probe callback is only allowed to modify the buffer content if the
156       buffer is writable, and it is only allowed to modify buffer metadata like
157       timestamps, caps, etc. if the buffer metadata is writable.  Whether this
158       is the case or not depends a lot on the pipeline and the elements
159       involved.  Often enough, this is the case, but sometimes it is not,
160       and if it is not then unexpected modification of the data or metadata
161       can introduce bugs that are very hard to debug and track down. You can
162       check if a buffer and its metadata are writable with
163       <function>gst_buffer_is_writable ()</function> and
164       <function>gst_buffer_is_metadata_writable ()</function>.  Since you
165       can't pass back a different buffer than the one passed in, there is no
166       point of making a buffer writable in the callback function.
167     </para>
168     <para>
169       Pad probes are suited best for looking at data as it passes through
170       the pipeline. If you need to modify data, you should write your own
171       GStreamer element. Base classes like GstAudioFilter, GstVideoFilter or
172       GstBaseTransform make this fairly easy.
173     </para>
174     <para>
175       If you just want to inspect buffers as they pass through the pipeline,
176       you don't even need to set up pad probes. You could also just insert
177       an identity element into the pipeline and connect to its "handoff"
178       signal. The identity element also provides a few useful debugging tools
179       like the "dump" property or the "last-message" property (the latter is
180       enabled by passing the '-v' switch to gst-launch).
181     </para>
182   </sect1>
183
184   <sect1 id="section-data-spoof">
185     <title>Manually adding or removing data from/to a pipeline</title>
186     <para>
187       Many people have expressed the wish to use their own sources to inject
188       data into a pipeline. Some people have also expressed the wish to grab
189       the output in a pipeline and take care of the actual output inside
190       their application. While either of these methods are stongly
191       discouraged, &GStreamer; offers hacks to do this. <emphasis>However,
192       there is no support for those methods.</emphasis> If it doesn't work,
193       you're on your own. Also, synchronization, thread-safety and other
194       things that you've been able to take for granted so far are no longer
195       guaranteed if you use any of those methods. It's always better to
196       simply write a plugin and have the pipeline schedule and manage it.
197       See the Plugin Writer's Guide for more information on this topic. Also
198       see the next section, which will explain how to embed plugins statically
199       in your application.
200     </para>
201     <note><para>
202         <ulink type="http"
203           url="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gstreamer-app.html">New
204           API</ulink> was developed to make data insertion and extraction easy
205         for applications. It can be found as GstAppSrc and GstAppSink in the
206         <ulink type="http"
207           url="http://gstreamer.freedesktop.org/modules/gst-plugins-base.html">
208           gst-plugins-base</ulink> module.
209     </para></note>
210     <para>
211       After all those disclaimers, let's start. There's three possible
212       elements that you can use for the above-mentioned purposes. Those are
213       called <quote>fakesrc</quote> (an imaginary source),
214       <quote>fakesink</quote> (an imaginary sink) and <quote>identity</quote>
215       (an imaginary filter). The same method applies to each of those
216       elements. Here, we will discuss how to use those elements to insert
217       (using fakesrc) or grab (using fakesink or identity) data from a
218       pipeline, and how to set negotiation.
219     </para>
220     <para>
221       Those who're paying close attention will notice that the purpose
222       of identity is almost identical to that of probes. Indeed, this is
223       true. Probes allow for the same purpose, and a bunch more, and
224       with less overhead plus dynamic removing/adding of handlers, but
225       apart from those, probes and identity have the same purpose, just
226       in a completely different implementation type.
227     </para>
228
229     <sect2 id="section-spoof-handoff">
230       <title>Inserting or grabbing data</title>
231       <para>
232         The three before-mentioned elements (fakesrc, fakesink and identity)
233         each have a <quote>handoff</quote> signal that will be called in
234         the <function>_get ()</function>- (fakesrc) or <function>_chain
235         ()</function>-function (identity, fakesink). In the signal handler,
236         you can set (fakesrc) or get (identity, fakesink) data to/from the
237         provided buffer. Note that in the case of fakesrc, you have to set
238         the size of the provided buffer using the <quote>sizemax</quote>
239         property. For both fakesrc and fakesink, you also have to set the
240         <quote>signal-handoffs</quote> property for this method to work.
241       </para>
242       <para>
243         Note that your handoff function should <emphasis>not</emphasis>
244         block, since this will block pipeline iteration. Also, do not try
245         to use all sort of weird hacks in such functions to accomplish
246         something that looks like synchronization or so; it's not the right
247         way and will lead to issues elsewhere. If you're doing any of this,
248         you're basically misunderstanding the &GStreamer; design.
249       </para>
250     </sect2>
251
252     <sect2 id="section-spoof-format">
253       <title>Forcing a format</title>
254       <para>
255         Sometimes, when using fakesrc as a source in your pipeline, you'll
256         want to set a specific format, for example a video size and format
257         or an audio bitsize and number of channels. You can do this by
258         forcing a specific <classname>GstCaps</classname> on the pipeline,
259         which is possible by using <emphasis>filtered caps</emphasis>. You
260         can set a filtered caps on a link by using the
261         <quote>capsfilter</quote> element in between the two elements, and
262         specifying a <classname>GstCaps</classname> as
263         <quote>caps</quote> property on this element. It will then
264         only allow types matching that specified capability set for
265         negotiation.  See also <xref linkend="section-caps-filter"/>.
266       </para>
267     </sect2>
268
269     <sect2 id="section-spoof-example">
270       <title>Example application</title>
271       <para>
272         This example application will generate black/white (it switches
273         every second) video to an X-window output by using fakesrc as a
274         source and using filtered caps to force a format. Since the depth
275         of the image depends on your X-server settings, we use a colorspace
276         conversion element to make sure that the output to your X server
277         will have the correct bitdepth. You can also set timestamps on the
278         provided buffers to override the fixed framerate.
279       </para>
280       <programlisting><!-- example-begin fakesrc.c -->
281 #include &lt;string.h&gt; /* for memset () */
282 #include &lt;gst/gst.h&gt;
283
284 static void
285 cb_handoff (GstElement *fakesrc,
286             GstBuffer  *buffer,
287             GstPad     *pad,
288             gpointer    user_data)
289 {
290   static gboolean white = FALSE;
291   gpointer data;
292   gsize size;
293   
294   data = gst_buffer_map (buffer, &amp;size, NULL, GST_MAP_WRITE);
295
296   /* this makes the image black/white */
297   memset (data, white ? 0xff : 0x0, size);
298   white = !white;
299
300   gst_buffer_unmap (buffer, data, size);
301 }
302
303 gint
304 main (gint   argc,
305       gchar *argv[])
306 {
307   GstElement *pipeline, *fakesrc, *flt, *conv, *videosink;
308   GMainLoop *loop;
309
310   /* init GStreamer */
311   gst_init (&amp;argc, &amp;argv);
312   loop = g_main_loop_new (NULL, FALSE);
313
314   /* setup pipeline */
315   pipeline = gst_pipeline_new ("pipeline");
316   fakesrc = gst_element_factory_make ("fakesrc", "source");
317   flt = gst_element_factory_make ("capsfilter", "flt");
318   conv = gst_element_factory_make ("ffmpegcolorspace", "conv");
319   videosink = gst_element_factory_make ("xvimagesink", "videosink");
320
321   /* setup */
322   g_object_set (G_OBJECT (flt), "caps",
323                 gst_caps_new_simple ("video/x-raw-rgb",
324                                      "width", G_TYPE_INT, 384,
325                                      "height", G_TYPE_INT, 288,
326                                      "framerate", GST_TYPE_FRACTION, 1, 1,
327                                      "bpp", G_TYPE_INT, 16,
328                                      "depth", G_TYPE_INT, 16,
329                                      "endianness", G_TYPE_INT, G_BYTE_ORDER,
330                                      NULL), NULL);
331   gst_bin_add_many (GST_BIN (pipeline), fakesrc, flt, conv, videosink, NULL);
332   gst_element_link_many (fakesrc, flt, conv, videosink, NULL);
333
334   /* setup fake source */
335   g_object_set (G_OBJECT (fakesrc),
336                 "signal-handoffs", TRUE,
337                 "sizemax", 384 * 288 * 2,
338                 "sizetype", 2, NULL);
339   g_signal_connect (fakesrc, "handoff", G_CALLBACK (cb_handoff), NULL);
340
341   /* play */
342   gst_element_set_state (pipeline, GST_STATE_PLAYING);
343   g_main_loop_run (loop);
344
345   /* clean up */
346   gst_element_set_state (pipeline, GST_STATE_NULL);
347   gst_object_unref (GST_OBJECT (pipeline));
348
349   return 0;
350 }
351       <!-- example-end fakesrc.c --></programlisting>
352     </sect2>
353   </sect1>
354
355   <sect1 id="section-data-manager">
356     <title>Embedding static elements in your application</title>
357     <para>
358       The <ulink type="http"
359       url="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/pwg/html/index.html">Plugin
360       Writer's Guide</ulink> describes in great detail how to write elements
361       for the &GStreamer; framework. In this section, we will solely discuss
362       how to embed such elements statically in your application. This can be
363       useful for application-specific elements that have no use elsewhere in
364       &GStreamer;.
365     </para>
366     <para>
367       Dynamically loaded plugins contain a structure that's defined using
368       <function>GST_PLUGIN_DEFINE ()</function>. This structure is loaded
369       when the plugin is loaded by the &GStreamer; core. The structure
370       contains an initialization function (usually called
371       <function>plugin_init</function>) that will be called right after that.
372       It's purpose is to register the elements provided by the plugin with
373       the &GStreamer; framework. If you want to embed elements directly in
374       your application, the only thing you need to do is to replace
375           <function>GST_PLUGIN_DEFINE ()</function> with
376           <function>GST_PLUGIN_DEFINE_STATIC ()</function>. This will cause the
377       elements to be registered when your application loads, and the elements
378       will from then on be available like any other element, without them
379       having to be dynamically loadable libraries. In the example below, you
380       would be able to call <function>gst_element_factory_make
381       ("my-element-name", "some-name")</function> to create an instance of the
382       element.
383     </para>
384
385     <programlisting>
386 /*
387  * Here, you would write the actual plugin code.
388  */
389
390 [..]
391
392 static gboolean
393 register_elements (GstPlugin *plugin)
394 {
395   return gst_element_register (plugin, "my-element-name",
396                                GST_RANK_NONE, MY_PLUGIN_TYPE);
397 }
398
399 GST_PLUGIN_DEFINE_STATIC (
400   GST_VERSION_MAJOR,
401   GST_VERSION_MINOR,
402   "my-private-plugins",
403   "Private elements of my application",
404   register_elements,
405   VERSION,
406   "LGPL",
407   "my-application",
408   "http://www.my-application.net/"
409 )
410     </programlisting>
411   </sect1>
412 </chapter>