docs/manual/advanced-autoplugging.xml: Prefix section with broken code with a warning...
[platform/upstream/gstreamer.git] / docs / manual / advanced-autoplugging.xml
1 <chapter id="chapter-autoplugging">
2   <title>Autoplugging</title>
3   <para>
4     In <xref linkend="chapter-helloworld"/>, you've learned to build a
5     simple media player for Ogg/Vorbis files. By using alternative elements,
6     you are able to build media players for other media types, such as
7     Ogg/Speex, MP3 or even video formats. However, you would rather want
8     to build an application that can automatically detect the media type
9     of a stream and automatically generate the best possible pipeline
10     by looking at all available elements in a system. This process is called
11     autoplugging, and &GStreamer; contains high-quality autopluggers. If
12     you're looking for an autoplugger, don't read any further and go to
13     <xref linkend="chapter-components"/>. This chapter will explain the
14     <emphasis>concept</emphasis> of autoplugging and typefinding. It will
15     explain what systems &GStreamer; includes to dynamically detect the
16     type of a media stream, and how to generate a pipeline of decoder
17     elements to playback this media. The same principles can also be used
18     for transcoding. Because of the full dynamicity of this concept,
19     &GStreamer; can be automatically extended to support new media types
20     without needing any adaptations to its autopluggers.
21   </para>
22   <para>
23     We will first introduce the concept of MIME types as a dynamic and
24     extendible way of identifying media streams. After that, we will introduce
25     the concept of typefinding to find the type of a media stream. Lastly,
26     we will explain how autoplugging and the &GStreamer; registry can be
27     used to setup a pipeline that will convert media from one mimetype to
28     another, for example for media decoding.
29   </para>
30
31   <sect1 id="section-mime">
32     <title>MIME-types as a way to identity streams</title>
33     <para>
34       We have previously introduced the concept of capabilities as a way
35       for elements (or, rather, pads) to agree on a media type when
36       streaming data from one element to the next (see <xref
37       linkend="section-caps"/>). We have explained that a capability is
38       a combination of a mimetype and a set of properties. For most
39       container formats (those are the files that you will find on your
40       hard disk; Ogg, for example, is a container format), no properties
41       are needed to describe the stream. Only a MIME-type is needed. A
42       full list of MIME-types and accompanying properties can be found
43       in <ulink type="http"
44       url="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/pwg/html/section-types-definitions.html">the
45       Plugin Writer's Guide</ulink>.
46     </para> 
47     <para>
48       An element must associate a MIME-type to its source and sink pads
49       when it is loaded into the system. &GStreamer; knows about the
50       different elements and what type of data they expect and emit through
51       the &GStreamer; registry. This allows for very dynamic and extensible
52       element creation as we will see.
53     </para> 
54
55     <para>
56       In <xref linkend="chapter-helloworld"/>, we've learned to build a
57       music player for Ogg/Vorbis files. Let's look at the MIME-types
58       associated with each pad in this pipeline. <xref
59       linkend="section-mime-img"/> shows what MIME-type belongs to each
60       pad in this pipeline.
61     </para>
62     <!-- FIXME: update for ogg/vorbis rather than mp3 -->
63     <figure float="1" id="section-mime-img">
64       <title>The Hello world pipeline with MIME types</title>
65       <mediaobject>
66         <imageobject>
67           <imagedata fileref="images/mime-world.&image;" format="&IMAGE;"/>
68         </imageobject>
69       </mediaobject>
70     </figure>
71     <para>
72       Now that we have an idea how &GStreamer; identifies known media
73       streams, we can look at methods &GStreamer; uses to setup pipelines
74       for media handling and for media type detection.
75     </para>
76   </sect1>
77
78   <sect1 id="section-typefinding">
79     <title>Media stream type detection</title>
80     <para>
81       Usually, when loading a media stream, the type of the stream is not
82       known. This means that before we can choose a pipeline to decode the
83       stream, we first need to detect the stream type. &GStreamer; uses the
84       concept of typefinding for this. Typefinding is a normal part of a
85       pipeline, it will read data for as long as the type of a stream is
86       unknown. During this period, it will provide data to all plugins
87       that implement a typefinder. when one of the typefinders recognizes
88       the stream, the typefind element will emit a signal and act as a
89       passthrough module from that point on. If no type was found, it will
90       emit an error and further media processing will stop.
91     </para>
92     <para>
93       Once the typefind element has found a type, the application can
94       use this to plug together a pipeline to decode the media stream.
95       This will be discussed in the next section.
96     </para>
97     <para>
98       Plugins in &GStreamer; can, as mentioned before, implement typefinder
99       functionality. A plugin implementing this functionality will submit
100       a mimetype, optionally a set of file extensions commonly used for this
101       media type, and a typefind function. Once this typefind function inside
102       the plugin is called, the plugin will see if the data in this media
103       stream matches a specific pattern that marks the media type identified
104       by that mimetype. If it does, it will notify the typefind element of
105       this fact, telling which mediatype was recognized and how certain we
106       are that this stream is indeed that mediatype. Once this run has been
107       completed for all plugins implementing a typefind functionality, the
108       typefind element will tell the application what kind of media stream
109       it thinks to have recognized.
110     </para>
111     <para>
112       The following code should explain how to use the typefind element.
113       It will print the detected media type, or tell that the media type
114       was not found. The next section will introduce more useful behaviours,
115       such as plugging together a decoding pipeline.
116     </para>
117     <programlisting><!-- example-begin typefind.c a -->
118 #include &lt;gst/gst.h&gt;
119 <!-- example-end typefind.c a -->
120 [.. my_bus_callback goes here ..]<!-- example-begin typefind.c b --><!--
121 static gboolean
122 my_bus_callback (GstBus     *bus,
123                  GstMessage *message,
124                  gpointer    data)
125 {
126   GMainLoop *loop = data;
127
128   switch (GST_MESSAGE_TYPE (message)) {
129     case GST_MESSAGE_ERROR: {
130       GError *err;
131       gchar *debug;
132
133       gst_message_parse_error (message, &amp;err, &amp;debug);
134       g_print ("Error: %s\n", err-&gt;message);
135       g_error_free (err);
136       g_free (debug);
137
138       g_main_loop_quit (loop);
139       break;
140     }
141     case GST_MESSAGE_EOS:
142       /* end-of-stream */
143       g_main_loop_quit (loop);
144       break;
145     default:
146       break;
147   }
148
149   /* remove from queue */
150   return TRUE;
151 }
152 --><!-- example-end typefind.c b -->
153 <!-- example-begin typefind.c c -->
154 static gboolean
155 idle_exit_loop (gpointer data)
156 {
157   g_main_loop_quit ((GMainLoop *) data);
158
159   /* once */
160   return FALSE;
161 }
162
163 static void
164 cb_typefound (GstElement *typefind,
165               guint       probability,
166               GstCaps    *caps,
167               gpointer    data)
168 {
169   GMainLoop *loop = data;
170   gchar *type;
171
172   type = gst_caps_to_string (caps);
173   g_print ("Media type %s found, probability %d%%\n", type, probability);
174   g_free (type);
175
176   /* since we connect to a signal in the pipeline thread context, we need
177    * to set an idle handler to exit the main loop in the mainloop context.
178    * Normally, your app should not need to worry about such things. */
179   g_idle_add (idle_exit_loop, loop);
180 }
181
182 gint 
183 main (gint   argc,
184       gchar *argv[])
185 {
186   GMainLoop *loop;
187   GstElement *pipeline, *filesrc, *typefind;
188   GstBus *bus;
189
190   /* init GStreamer */
191   gst_init (&amp;argc, &amp;argv);
192   loop = g_main_loop_new (NULL, FALSE);
193
194   /* check args */
195   if (argc != 2) {
196     g_print ("Usage: %s &lt;filename&gt;\n", argv[0]);
197     return -1;
198   }
199
200   /* create a new pipeline to hold the elements */
201   pipeline = gst_pipeline_new ("pipe");
202
203   bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
204   gst_bus_add_watch (bus, my_bus_callback, NULL);
205   gst_object_unref (bus);
206
207   /* create file source and typefind element */
208   filesrc = gst_element_factory_make ("filesrc", "source");
209   g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL);
210   typefind = gst_element_factory_make ("typefind", "typefinder");
211   g_signal_connect (typefind, "have-type", G_CALLBACK (cb_typefound), loop);
212
213   /* setup */
214   gst_bin_add_many (GST_BIN (pipeline), filesrc, typefind, NULL);
215   gst_element_link (filesrc, typefind);
216   gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
217   g_main_loop_run (loop);
218
219   /* unset */
220   gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
221   gst_object_unref (GST_OBJECT (pipeline));
222
223   return 0;
224 }
225     <!-- example-end typefind.c c --></programlisting>
226     <para>
227       Once a media type has been detected, you can plug an element (e.g. a
228       demuxer or decoder) to the source pad of the typefind element, and
229       decoding of the media stream will start right after.
230     </para>
231   </sect1>
232
233   <sect1 id="section-dynamic">
234     <title>Plugging together dynamic pipelines</title>
235     <warning><para>
236       The code in this section is broken, outdated and overly complicated.
237       Also, you should use decodebin, playbin or uridecodebin to get
238       decoders plugged automatically.
239     </para></warning>
240     <para> 
241       In this chapter we will see how you can create a dynamic pipeline. A
242       dynamic pipeline is a pipeline that is updated or created while data
243      is flowing through it. We will create a partial pipeline first and add
244       more elements while the pipeline is playing. The basis of this player
245       will be the application that we wrote in the previous section (<xref
246       linkend="section-typefinding"/>) to identify unknown media streams.
247     </para>
248     <!-- example-begin dynamic.c a --><!--
249 #include &lt;gst/gst.h&gt;
250
251 GstElement *pipeline;
252     --><!-- example-end dynamic.c a -->
253     <para>
254       Once the type of the media has been found, we will find elements in
255       the registry that can decode this streamtype. For this, we will get
256       all element factories (which we've seen before in <xref
257       linkend="section-elements-create"/>) and find the ones with the
258       given MIME-type and capabilities on their sinkpad. Note that we will
259       only use parsers, demuxers and decoders. We will not use factories for
260       any other element types, or we might get into a loop of encoders and
261       decoders. For this, we will want to build a list of <quote>allowed</quote>
262       factories right after initializing &GStreamer;.
263     </para>
264     <programlisting><!-- example-begin dynamic.c b -->
265 static GList *factories;
266
267 /*
268  * This function is called by the registry loader. Its return value
269  * (TRUE or FALSE) decides whether the given feature will be included
270  * in the list that we're generating further down.
271  */
272
273 static gboolean
274 cb_feature_filter (GstPluginFeature *feature,
275                    gpointer          data)
276 {
277   const gchar *klass;
278   guint rank;
279
280   /* we only care about element factories */
281   if (!GST_IS_ELEMENT_FACTORY (feature))
282     return FALSE;
283
284   /* only parsers, demuxers and decoders */
285   klass = gst_element_factory_get_klass (GST_ELEMENT_FACTORY (feature));
286   if (g_strrstr (klass, "Demux") == NULL &amp;&amp;
287       g_strrstr (klass, "Decoder") == NULL &amp;&amp;
288       g_strrstr (klass, "Parse") == NULL)
289     return FALSE;
290
291   /* only select elements with autoplugging rank */
292   rank = gst_plugin_feature_get_rank (feature);
293   if (rank &lt; GST_RANK_MARGINAL)
294     return FALSE;
295
296   return TRUE;
297 }
298
299 /*
300  * This function is called to sort features by rank.
301  */
302
303 static gint
304 cb_compare_ranks (GstPluginFeature *f1,
305                   GstPluginFeature *f2)
306 {
307   return gst_plugin_feature_get_rank (f2) - gst_plugin_feature_get_rank (f1);
308 }
309
310 static void
311 init_factories (void)
312 {
313   /* first filter out the interesting element factories */
314   factories = gst_registry_feature_filter (
315       gst_registry_get_default (),
316       (GstPluginFeatureFilter) cb_feature_filter, FALSE, NULL);
317
318   /* sort them according to their ranks */
319   factories = g_list_sort (factories, (GCompareFunc) cb_compare_ranks);
320 }
321     <!-- example-end dynamic.c b --></programlisting>
322     <para>
323       From this list of element factories, we will select the one that most
324       likely will help us decoding a media stream to a given output type.
325       For each newly created element, we will again try to autoplug new
326       elements to its source pad(s). Also, if the element has dynamic pads
327       (which we've seen before in <xref linkend="section-pads-dynamic"/>),
328       we will listen for newly created source pads and handle those, too.
329       The following code replaces the <function>cb_type_found</function>
330       from the previous section with a function to initiate autoplugging,
331       which will continue with the above approach.
332     </para>
333     <programlisting><!-- example-begin dynamic.c c -->
334 static void try_to_plug (GstPad *pad, const GstCaps *caps);
335
336 static GstElement *audiosink;
337
338 static void
339 cb_newpad (GstElement *element,
340            GstPad     *pad,
341            gpointer    data)
342 {
343   GstCaps *caps;
344
345   caps = gst_pad_get_caps (pad);
346   try_to_plug (pad, caps);
347   gst_caps_unref (caps);
348 }
349
350 static void
351 close_link (GstPad      *srcpad,
352             GstElement  *sinkelement,
353             const gchar *padname,
354             const GList *templlist)
355 {
356   GstPad *pad;
357   gboolean has_dynamic_pads = FALSE;
358
359   g_print ("Plugging pad %s:%s to newly created %s:%s\n",
360            gst_object_get_name (GST_OBJECT (gst_pad_get_parent (srcpad))),
361            gst_pad_get_name (srcpad),
362            gst_object_get_name (GST_OBJECT (sinkelement)), padname);
363
364   /* add the element to the pipeline and set correct state */
365   if (sinkelement != audiosink) {
366     gst_bin_add (GST_BIN (pipeline), sinkelement);
367     gst_element_set_state (sinkelement, GST_STATE_READY);
368   }
369   pad = gst_element_get_pad (sinkelement, padname);
370   gst_pad_link (srcpad, pad);
371   if (sinkelement != audiosink) {
372     gst_element_set_state (sinkelement, GST_STATE_PAUSED);
373   }
374   gst_object_unref (GST_OBJECT (pad));
375
376   /* if we have static source pads, link those. If we have dynamic
377    * source pads, listen for pad-added signals on the element */
378   for ( ; templlist != NULL; templlist = templlist->next) {
379     GstStaticPadTemplate *templ = templlist->data;
380
381     /* only sourcepads, no request pads */
382     if (templ->direction != GST_PAD_SRC ||
383         templ->presence == GST_PAD_REQUEST) {
384       continue;
385     }
386
387     switch (templ->presence) {
388       case GST_PAD_ALWAYS: {
389         GstPad *pad = gst_element_get_pad (sinkelement, templ->name_template);
390         GstCaps *caps = gst_pad_get_caps (pad);
391
392         /* link */
393         try_to_plug (pad, caps);
394         gst_object_unref (GST_OBJECT (pad));
395         gst_caps_unref (caps);
396         break;
397       }
398       case GST_PAD_SOMETIMES:
399         has_dynamic_pads = TRUE;
400         break;
401       default:
402         break;
403     }
404   }
405
406   /* listen for newly created pads if this element supports that */
407   if (has_dynamic_pads) {
408     g_signal_connect (sinkelement, "pad-added", G_CALLBACK (cb_newpad), NULL);
409   }
410 }
411
412 static void
413 try_to_plug (GstPad        *pad,
414              const GstCaps *caps)
415 {
416   GstObject *parent = GST_OBJECT (GST_OBJECT_PARENT (pad));
417   const gchar *mime;
418   const GList *item;
419   GstCaps *res, *audiocaps;
420
421   /* don't plug if we're already plugged - FIXME: memleak for pad */
422   if (GST_PAD_IS_LINKED (gst_element_get_pad (audiosink, "sink"))) {
423     g_print ("Omitting link for pad %s:%s because we're already linked\n",
424              GST_OBJECT_NAME (parent), GST_OBJECT_NAME (pad));
425     return;
426   }
427
428   /* as said above, we only try to plug audio... Omit video */
429   mime = gst_structure_get_name (gst_caps_get_structure (caps, 0));
430   if (g_strrstr (mime, "video")) {
431     g_print ("Omitting link for pad %s:%s because mimetype %s is non-audio\n",
432              GST_OBJECT_NAME (parent), GST_OBJECT_NAME (pad), mime);
433     return;
434   }
435
436   /* can it link to the audiopad? */
437   audiocaps = gst_pad_get_caps (gst_element_get_pad (audiosink, "sink"));
438   res = gst_caps_intersect (caps, audiocaps);
439   if (res &amp;&amp; !gst_caps_is_empty (res)) {
440     g_print ("Found pad to link to audiosink - plugging is now done\n");
441     close_link (pad, audiosink, "sink", NULL);
442     gst_caps_unref (audiocaps);
443     gst_caps_unref (res);
444     return;
445   }
446   gst_caps_unref (audiocaps);
447   gst_caps_unref (res);
448
449   /* try to plug from our list */
450   for (item = factories; item != NULL; item = item->next) {
451     GstElementFactory *factory = GST_ELEMENT_FACTORY (item->data);
452     const GList *pads;
453
454     for (pads = gst_element_factory_get_static_pad_templates (factory);
455          pads != NULL; pads = pads->next) {
456       GstStaticPadTemplate *templ = pads->data;
457
458       /* find the sink template - need an always pad*/
459       if (templ->direction != GST_PAD_SINK ||
460           templ->presence != GST_PAD_ALWAYS) {
461         continue;
462       }
463
464       /* can it link? */
465       res = gst_caps_intersect (caps,
466           gst_static_caps_get (&amp;templ->static_caps));
467       if (res &amp;&amp; !gst_caps_is_empty (res)) {
468         GstElement *element;
469         gchar *name_template = g_strdup (templ->name_template);
470
471         /* close link and return */
472         gst_caps_unref (res);
473         element = gst_element_factory_create (factory, NULL);
474         close_link (pad, element, name_template,
475                     gst_element_factory_get_static_pad_templates (factory));
476         g_free (name_template);
477         return;
478       }
479       gst_caps_unref (res);
480
481       /* we only check one sink template per factory, so move on to the
482        * next factory now */
483       break;
484     }
485   }
486
487   /* if we get here, no item was found */
488   g_print ("No compatible pad found to decode %s on %s:%s\n",
489            mime, GST_OBJECT_NAME (parent), GST_OBJECT_NAME (pad));
490 }
491
492 static void
493 cb_typefound (GstElement *typefind,
494               guint       probability,
495               GstCaps    *caps,
496               gpointer    data)
497 {
498   gchar *s;
499   GstPad *pad;
500
501   s = gst_caps_to_string (caps);
502   g_print ("Detected media type %s\n", s);
503   g_free (s);
504
505   /* actually plug now */
506   pad = gst_element_get_pad (typefind, "src");
507   try_to_plug (pad, caps);
508   gst_object_unref (GST_OBJECT (pad));
509 }
510     <!-- example-end dynamic.c c --></programlisting>
511     <para>
512       By doing all this, we will be able to make a simple autoplugger that
513       can automatically setup a pipeline for any media type. In the example
514       below, we will do this for audio only. However, we can also do this
515       for video to create a player that plays both audio and video.
516     </para>
517     <!-- example-begin dynamic.c d --><!--
518 static gboolean
519 my_bus_callback (GstBus     *bus,
520                  GstMessage *message,
521                  gpointer    data)
522 {
523   GMainLoop *loop = data;
524
525   switch (GST_MESSAGE_TYPE (message)) {
526     case GST_MESSAGE_ERROR: {
527       GError *err;
528       gchar *debug;
529
530       gst_message_parse_error (message, &amp;err, &amp;debug);
531       g_print ("Error: %s\n", err-&gt;message);
532       g_error_free (err);
533       g_free (debug);
534
535       g_main_loop_quit (loop);
536       break;
537     }
538     case GST_MESSAGE_EOS:
539       /* end-of-stream */
540       g_main_loop_quit (loop);
541       break;
542     default:
543       break;
544   }
545
546   /* remove from queue */
547   return TRUE;
548 }
549
550 gint
551 main (gint   argc,
552       gchar *argv[])
553 {
554   GMainLoop *loop;
555   GstElement *typefind, *realsink;
556   GstBus *bus;
557   GError *err = NULL;
558   gchar *p;
559
560   /* init GStreamer and ourselves */
561   gst_init (&amp;argc, &amp;argv);
562   loop = g_main_loop_new (NULL, FALSE);
563   init_factories ();
564
565   /* args */
566   if (argc != 2) {
567     g_print ("Usage: %s &lt;filename&gt;\n", argv[0]);
568     return -1;
569   }
570
571   /* pipeline */
572   p = g_strdup_printf ("filesrc location=\"%s\" ! typefind name=tf", argv[1]);
573   pipeline = gst_parse_launch (p, &amp;err);
574   g_free (p);
575
576   if (err) {
577     g_error ("Could not construct pipeline: %s", err-&gt;message);
578     g_error_free (err);
579     return -1;
580   }
581
582   bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
583   gst_bus_add_watch (bus, my_bus_callback, NULL);
584   gst_object_unref (bus);
585
586   typefind = gst_bin_get_by_name (GST_BIN (pipeline), "tf");
587   g_signal_connect (typefind, "have-type", G_CALLBACK (cb_typefound), NULL);
588   gst_object_unref (GST_OBJECT (typefind));
589   audiosink = gst_element_factory_make ("audioconvert", "aconv");
590   realsink = gst_element_factory_make ("alsasink", "audiosink");
591   gst_bin_add_many (GST_BIN (pipeline), audiosink, realsink, NULL);
592   gst_element_link (audiosink, realsink);
593   gst_element_set_state (pipeline, GST_STATE_PLAYING);
594
595   /* run */
596   g_main_loop_run (loop);
597
598   /* exit */
599   gst_element_set_state (pipeline, GST_STATE_NULL);
600   gst_object_unref (GST_OBJECT (pipeline));
601
602   return 0;
603 }
604     --><!-- example-end dynamic.c d -->
605     <para>
606       The example above is a good first try for an autoplugger. Next steps
607       would be to listen for <quote>pad-removed</quote> signals, so we
608       can dynamically change the plugged pipeline if the stream changes
609       (this happens for DVB or Ogg radio). Also, you might want special-case
610       code for input with known content (such as a DVD or an audio-CD),
611       and much, much more. Moreover, you'll want many checks to prevent
612       infinite loops during autoplugging, maybe you'll want to implement
613       shortest-path-finding to make sure the most optimal pipeline is chosen,
614       and so on. Basically, the features that you implement in an autoplugger
615       depend on what you want to use it for. For full-blown implementations,
616       see the <quote>playbin</quote> and <quote>decodebin</quote> elements.
617     </para>
618   </sect1>
619 </chapter>