54d0d99e3de6d223a24ffac5ea2897743ce37659
[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_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).
29     </para>
30     <para>
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.
38     </para>
39     <programlisting><!-- example-begin probe.c -->
40 #include &lt;gst/gst.h&gt;
41
42 static gboolean
43 cb_have_data (GstPad    *pad,
44               GstBuffer *buffer,
45               gpointer   u_data)
46 {
47   gint x, y;
48   guint16 *data = (guint16 *) GST_BUFFER_DATA (buffer), t;
49
50   /* invert data */
51   for (y = 0; y &lt; 288; y++) {
52     for (x = 0; x &lt; 384 / 2; x++) {
53       t = data[384 - 1 - x];
54       data[384 - 1 - x] = data[x];
55       data[x] = t;
56     }
57     data += 384;
58   }
59
60   return TRUE;
61 }
62
63 gint
64 main (gint   argc,
65       gchar *argv[])
66 {
67   GMainLoop *loop;
68   GstElement *pipeline, *src, *sink, *filter, *csp;
69   GstCaps *caps;
70   GstPad *pad;
71
72   /* init GStreamer */
73   gst_init (&amp;argc, &amp;argv);
74   loop = g_main_loop_new (NULL, FALSE);
75
76   /* build */
77   pipeline = gst_pipeline_new ("my-pipeline");
78   src = gst_element_factory_make ("videotestsrc", "src");
79   if (src == NULL)
80     g_error ("Could not create 'videotestsrc' element");
81
82   filter = gst_element_factory_make ("capsfilter", "filter");
83   g_assert (filer != NULL); /* should always exist */
84
85   csp = gst_element_factory_make ("ffmpegcolorspace", "csp");
86   if (csp == NULL)
87     g_error ("Could not create 'ffmpegcolorspace' element");
88
89   sink = gst_element_factory_make ("xvimagesink", "sink");
90   if (sink == NULL) {
91     sink = gst_element_factory_make ("ximagesink", "sink");
92     if (sink == NULL)
93       g_error ("Could not create neither 'xvimagesink' nor 'ximagesink' element");
94   }
95
96   gst_bin_add_many (GST_BIN (pipeline), src, filter, csp, sink, NULL);
97   gst_element_link_many (src, filter, csp, sink, NULL);
98   filtercaps = gst_caps_new_simple ("video/x-raw-rgb",
99                            "width", G_TYPE_INT, 384,
100                            "height", G_TYPE_INT, 288,
101                            "framerate", GST_TYPE_FRACTION, 25, 1,
102                            "bpp", G_TYPE_INT, 16,
103                            "depth", G_TYPE_INT, 16,
104                            "endianness", G_TYPE_INT, G_BYTE_ORDER,
105                            NULL);
106   g_object_set (G_OBJECT (filter), "caps", filtercaps, NULL);
107   gst_caps_unref (filtercaps);
108
109   pad = gst_element_get_pad (src, "src");
110   gst_pad_add_buffer_probe (pad, G_CALLBACK (cb_have_data), NULL);
111   gst_object_unref (pad);
112
113   /* run */
114   gst_element_set_state (pipeline, GST_STATE_PLAYING);
115
116   /* wait until it's up and running or failed */
117   if (gst_element_get_state (pipeline, NULL, NULL, -1) == GST_STATE_CHANGE_FAILURE) {
118     g_error ("Failed to go into PLAYING state");
119   }
120
121   g_print ("Running ...\n");
122   g_main_loop_run (loop);
123
124   /* exit */
125   gst_element_set_state (pipeline, GST_STATE_NULL);
126   gst_object_unref (pipeline);
127
128   return 0;
129 }
130     <!-- example-end probe.c --></programlisting>
131     <para>
132       Compare that output with the output of <quote>gst-launch-0.10
133       videotestsrc ! xvimagesink</quote>, just so you know what you're
134       looking for.
135     </para>
136   </sect1>
137
138   <sect1 id="section-data-spoof">
139     <title>Manually adding or removing data from/to a pipeline</title>
140     <para>
141       Many people have expressed the wish to use their own sources to inject
142       data into a pipeline. Some people have also expressed the wish to grab
143       the output in a pipeline and take care of the actual output inside
144       their application. While either of these methods are stongly
145       discouraged, &GStreamer; offers hacks to do this. <emphasis>However,
146       there is no support for those methods.</emphasis> If it doesn't work,
147       you're on your own. Also, synchronization, thread-safety and other
148       things that you've been able to take for granted so far are no longer
149       guanranteed if you use any of those methods. It's always better to
150       simply write a plugin and have the pipeline schedule and manage it.
151       See the Plugin Writer's Guide for more information on this topic. Also
152       see the next section, which will explain how to embed plugins statically
153       in your application.
154     </para>
155     <para>
156       After all those disclaimers, let's start. There's three possible
157       elements that you can use for the above-mentioned purposes. Those are
158       called <quote>fakesrc</quote> (an imaginary source),
159       <quote>fakesink</quote> (an imaginary sink) and <quote>identity</quote>
160       (an imaginary filter). The same method applies to each of those
161       elements. Here, we will discuss how to use those elements to insert
162       (using fakesrc) or grab (using fakesink or identity) data from a
163       pipeline, and how to set negotiation.
164     </para>
165     <para>
166       Those who're paying close attention, will notice that the purpose
167       of identity is almost identical to that of probes. Indeed, this is
168       true. Probes allow for the same purpose, and a bunch more, and
169       with less overhead plus dynamic removing/adding of handlers, but
170       apart from those, probes and identity have the same purpose, just
171       in a completely different implementation type.
172     </para>
173
174     <sect2 id="section-spoof-handoff">
175       <title>Inserting or grabbing data</title>
176       <para>
177         The three before-mentioned elements (fakesrc, fakesink and identity)
178         each have a <quote>handoff</quote> signal that will be called in
179         the <function>_get ()</function>- (fakesrc) or <function>_chain
180         ()</function>-function (identity, fakesink). In the signal handler,
181         you can set (fakesrc) or get (identity, fakesink) data to/from the
182         provided buffer. Note that in the case of fakesrc, you have to set
183         the size of the provided buffer using the <quote>sizemax</quote>
184         property. For both fakesrc and fakesink, you also have to set the
185         <quote>signal-handoffs</quote> property for this method to work.
186       </para>
187       <para>
188         Note that your handoff function should <emphasis>not</emphasis>
189         block, since this will block pipeline iteration. Also, do not try
190         to use all sort of weird hacks in such functions to accomplish
191         something that looks like synchronization or so; it's not the right
192         way and will lead to issues elsewhere. If you're doing any of this,
193         you're basically misunderstanding the &GStreamer; design.
194       </para>
195     </sect2>
196
197     <sect2 id="section-spoof-format">
198       <title>Forcing a format</title>
199       <para>
200         Sometimes, when using fakesrc as a source in your pipeline, you'll
201         want to set a specific format, for example a video size and format
202         or an audio bitsize and number of channels. You can do this by
203         forcing a specific <classname>GstCaps</classname> on the pipeline,
204         which is possible by using <emphasis>filtered caps</emphasis>. You
205         can set a filtered caps on a link by using the
206         <quote>capsfilter</quote> element in between the two elements, and
207         specifying a <classname>GstCaps</classname> as
208         <quote>caps</quote> property on this element. It will then
209         only allow types matching that specified capability set for
210         negotiation.
211       </para>
212     </sect2>
213
214     <sect2 id="section-spoof-example">
215       <title>Example application</title>
216       <para>
217         This example application will generate black/white (it switches
218         every second) video to an X-window output by using fakesrc as a
219         source and using filtered caps to force a format. Since the depth
220         of the image depends on your X-server settings, we use a colorspace
221         conversion element to make sure that the output to your X server
222         will have the correct bitdepth. You can also set timestamps on the
223         provided buffers to override the fixed framerate.
224       </para>
225       <programlisting><!-- example-begin fakesrc.c -->
226 #include &lt;string.h&gt; /* for memset () */
227 #include &lt;gst/gst.h&gt;
228
229 static void
230 cb_handoff (GstElement *fakesrc,
231             GstBuffer  *buffer,
232             GstPad     *pad,
233             gpointer    user_data)
234 {
235   static gboolean white = FALSE;
236
237   /* this makes the image black/white */
238   memset (GST_BUFFER_DATA (buffer), white ? 0xff : 0x0,
239           GST_BUFFER_SIZE (buffer));
240   white = !white;
241 }
242
243 gint
244 main (gint   argc,
245       gchar *argv[])
246 {
247   GstElement *pipeline, *fakesrc, *flt, *conv, *videosink;
248   GMainLoop *loop;
249
250   /* init GStreamer */
251   gst_init (&amp;argc, &amp;argv);
252   loop = g_main_loop_new (NULL, FALSE);
253
254   /* setup pipeline */
255   pipeline = gst_pipeline_new ("pipeline");
256   fakesrc = gst_element_factory_make ("fakesrc", "source");
257   flt = gst_element_factory_make ("capsfilter", "flt");
258   conv = gst_element_factory_make ("ffmpegcolorspace", "conv");
259   videosink = gst_element_factory_make ("xvimagesink", "videosink");
260
261   /* setup */
262   g_object_set (G_OBJECT (flt), "caps",
263                 gst_caps_new_simple ("video/x-raw-rgb",
264                                      "width", G_TYPE_INT, 384,
265                                      "height", G_TYPE_INT, 288,
266                                      "framerate", GST_TYPE_FRACTION, 1, 1,
267                                      "bpp", G_TYPE_INT, 16,
268                                      "depth", G_TYPE_INT, 16,
269                                      "endianness", G_TYPE_INT, G_BYTE_ORDER,
270                                      NULL), NULL);
271   gst_bin_add_many (GST_BIN (pipeline), fakesrc, flt, conv, videosink, NULL);
272   gst_element_link_many (fakesrc, flt, conv, videosink, NULL);
273
274   /* setup fake source */
275   g_object_set (G_OBJECT (fakesrc),
276                 "signal-handoffs", TRUE,
277                 "sizemax", 384 * 288 * 2,
278                 "sizetype", 2, NULL);
279   g_signal_connect (fakesrc, "handoff", G_CALLBACK (cb_handoff), NULL);
280
281   /* play */
282   gst_element_set_state (pipeline, GST_STATE_PLAYING);
283   g_main_loop_run (loop);
284
285   /* clean up */
286   gst_element_set_state (pipeline, GST_STATE_NULL);
287   gst_object_unref (GST_OBJECT (pipeline));
288
289   return 0;
290 }
291       <!-- example-end fakesrc.c --></programlisting>
292     </sect2>
293   </sect1>
294
295   <sect1 id="section-data-manager">
296     <title>Embedding static elements in your application</title>
297     <para>
298       The <ulink type="http"
299       url="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/pwg/html/index.html">Plugin
300       Writer's Guide</ulink> describes in great detail how to write elements
301       for the &GStreamer; framework. In this section, we will solely discuss
302       how to embed such elements statically in your application. This can be
303       useful for application-specific elements that have no use elsewhere in
304       &GStreamer;.
305     </para>
306     <para>
307       Dynamically loaded plugins contain a structure that's defined using
308       <function>GST_PLUGIN_DEFINE ()</function>. This structure is loaded
309       when the plugin is loaded by the &GStreamer; core. The structure
310       contains an initialization function (usually called
311       <function>plugin_init</function>) that will be called right after that.
312       It's purpose is to register the elements provided by the plugin with
313       the &GStreamer; framework. If you want to embed elements directly in
314       your application, the only thing you need to do is to replace
315           <function>GST_PLUGIN_DEFINE ()</function> with
316           <function>GST_PLUGIN_DEFINE_STATIC ()</function>. This will cause the
317       elements to be registered when your application loads, and the elements
318       will from then on be available like any other element, without them
319       having to be dynamically loadable libraries. In the example below, you
320       would be able to call <function>gst_element_factory_make
321       ("my-element-name", "some-name")</function> to create an instance of the
322       element.
323     </para>
324
325     <programlisting>
326 /*
327  * Here, you would write the actual plugin code.
328  */
329
330 [..]
331
332 static gboolean
333 register_elements (GstPlugin *plugin)
334 {
335   return gst_element_register (plugin, "my-element-name",
336                                GST_RANK_NONE, MY_PLUGIN_TYPE);
337 }
338
339 GST_PLUGIN_DEFINE_STATIC (
340   GST_VERSION_MAJOR,
341   GST_VERSION_MINOR,
342   "my-private-plugins",
343   "Private elements of my application",
344   register_elements,
345   VERSION,
346   "LGPL",
347   "my-application",
348   "http://www.my-application.net/"
349 )
350     </programlisting>
351   </sect1>
352 </chapter>