docs/manual/advanced-autoplugging.xml: Fix autoplugging example.
[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 <!-- 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
189   /* init GStreamer */
190   gst_init (&amp;argc, &amp;argv);
191   loop = g_main_loop_new (NULL, FALSE);
192
193   /* check args */
194   if (argc != 2) {
195     g_print ("Usage: %s &lt;filename&gt;\n", argv[0]);
196     return -1;
197   }
198
199   /* create a new pipeline to hold the elements */
200   pipeline = gst_pipeline_new ("pipe");
201   gst_bus_add_watch (gst_pipeline_get_bus (GST_PIPELINE (pipeline)),
202                      my_bus_callback, NULL);
203
204   /* create file source and typefind element */
205   filesrc = gst_element_factory_make ("filesrc", "source");
206   g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL);
207   typefind = gst_element_factory_make ("typefind", "typefinder");
208   g_signal_connect (typefind, "have-type", G_CALLBACK (cb_typefound), loop);
209
210   /* setup */
211   gst_bin_add_many (GST_BIN (pipeline), filesrc, typefind, NULL);
212   gst_element_link (filesrc, typefind);
213   gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
214   g_main_loop_run (loop);
215
216   /* unset */
217   gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
218   gst_object_unref (GST_OBJECT (pipeline));
219
220   return 0;
221 }
222     <!-- example-end typefind.c c --></programlisting>
223     <para>
224       Once a media type has been detected, you can plug an element (e.g. a
225       demuxer or decoder) to the source pad of the typefind element, and
226       decoding of the media stream will start right after.
227     </para>
228   </sect1>
229
230   <sect1 id="section-dynamic">
231     <title>Plugging together dynamic pipelines</title>
232     <para> 
233       In this chapter we will see how you can create a dynamic pipeline. A
234       dynamic pipeline is a pipeline that is updated or created while data
235      is flowing through it. We will create a partial pipeline first and add
236       more elements while the pipeline is playing. The basis of this player
237       will be the application that we wrote in the previous section (<xref
238       linkend="section-typefinding"/>) to identify unknown media streams.
239     </para>
240     <!-- example-begin dynamic.c a --><!--
241 #include &lt;gst/gst.h&gt;
242
243 GstElement *pipeline;
244     --><!-- example-end dynamic.c a -->
245     <para>
246       Once the type of the media has been found, we will find elements in
247       the registry that can decode this streamtype. For this, we will get
248       all element factories (which we've seen before in <xref
249       linkend="section-elements-create"/>) and find the ones with the
250       given MIME-type and capabilities on their sinkpad. Note that we will
251       only use parsers, demuxers and decoders. We will not use factories for
252       any other element types, or we might get into a loop of encoders and
253       decoders. For this, we will want to build a list of <quote>allowed</quote>
254       factories right after initializing &GStreamer;.
255     </para>
256     <programlisting><!-- example-begin dynamic.c b -->
257 static GList *factories;
258
259 /*
260  * This function is called by the registry loader. Its return value
261  * (TRUE or FALSE) decides whether the given feature will be included
262  * in the list that we're generating further down.
263  */
264
265 static gboolean
266 cb_feature_filter (GstPluginFeature *feature,
267                    gpointer          data)
268 {
269   const gchar *klass;
270   guint rank;
271
272   /* we only care about element factories */
273   if (!GST_IS_ELEMENT_FACTORY (feature))
274     return FALSE;
275
276   /* only parsers, demuxers and decoders */
277   klass = gst_element_factory_get_klass (GST_ELEMENT_FACTORY (feature));
278   if (g_strrstr (klass, "Demux") == NULL &amp;&amp;
279       g_strrstr (klass, "Decoder") == NULL &amp;&amp;
280       g_strrstr (klass, "Parse") == NULL)
281     return FALSE;
282
283   /* only select elements with autoplugging rank */
284   rank = gst_plugin_feature_get_rank (feature);
285   if (rank &lt; GST_RANK_MARGINAL)
286     return FALSE;
287
288   return TRUE;
289 }
290
291 /*
292  * This function is called to sort features by rank.
293  */
294
295 static gint
296 cb_compare_ranks (GstPluginFeature *f1,
297                   GstPluginFeature *f2)
298 {
299   return gst_plugin_feature_get_rank (f2) - gst_plugin_feature_get_rank (f1);
300 }
301
302 static void
303 init_factories (void)
304 {
305   /* first filter out the interesting element factories */
306   factories = gst_registry_pool_feature_filter (
307       (GstPluginFeatureFilter) cb_feature_filter, FALSE, NULL);
308
309   /* sort them according to their ranks */
310   factories = g_list_sort (factories, (GCompareFunc) cb_compare_ranks);
311 }
312     <!-- example-end dynamic.c b --></programlisting>
313     <para>
314       From this list of element factories, we will select the one that most
315       likely will help us decoding a media stream to a given output type.
316       For each newly created element, we will again try to autoplug new
317       elements to its source pad(s). Also, if the element has dynamic pads
318       (which we've seen before in <xref linkend="section-pads-dynamic"/>),
319       we will listen for newly created source pads and handle those, too.
320       The following code replaces the <function>cb_type_found</function>
321       from the previous section with a function to initiate autoplugging,
322       which will continue with the above approach.
323     </para>
324     <programlisting><!-- example-begin dynamic.c c -->
325 static void try_to_plug (GstPad *pad, const GstCaps *caps);
326
327 static GstElement *audiosink;
328
329 static void
330 cb_newpad (GstElement *element,
331            GstPad     *pad,
332            gpointer    data)
333 {
334   GstCaps *caps;
335
336   caps = gst_pad_get_caps (pad);
337   try_to_plug (pad, caps);
338   gst_caps_unref (caps);
339 }
340
341 static void
342 close_link (GstPad      *srcpad,
343             GstElement  *sinkelement,
344             const gchar *padname,
345             const GList *templlist)
346 {
347   GstPad *pad;
348   gboolean has_dynamic_pads = FALSE;
349
350   g_print ("Plugging pad %s:%s to newly created %s:%s\n",
351            gst_object_get_name (GST_OBJECT (gst_pad_get_parent (srcpad))),
352            gst_pad_get_name (srcpad),
353            gst_object_get_name (GST_OBJECT (sinkelement)), padname);
354
355   /* add the element to the pipeline and set correct state */
356   if (sinkelement != audiosink) {
357     gst_bin_add (GST_BIN (pipeline), sinkelement);
358     gst_element_set_state (sinkelement, GST_STATE_READY);
359   }
360   pad = gst_element_get_pad (sinkelement, padname);
361   gst_pad_link (srcpad, pad);
362   if (sinkelement != audiosink) {
363     gst_element_set_state (sinkelement, GST_STATE_PAUSED);
364   }
365   gst_object_unref (GST_OBJECT (pad));
366
367   /* if we have static source pads, link those. If we have dynamic
368    * source pads, listen for new-pad signals on the element */
369   for ( ; templlist != NULL; templlist = templlist->next) {
370     GstStaticPadTemplate *templ = templlist->data;
371
372     /* only sourcepads, no request pads */
373     if (templ->direction != GST_PAD_SRC ||
374         templ->presence == GST_PAD_REQUEST) {
375       continue;
376     }
377
378     switch (templ->presence) {
379       case GST_PAD_ALWAYS: {
380         GstPad *pad = gst_element_get_pad (sinkelement, templ->name_template);
381         GstCaps *caps = gst_pad_get_caps (pad);
382
383         /* link */
384         try_to_plug (pad, caps);
385         gst_object_unref (GST_OBJECT (pad));
386         gst_caps_unref (caps);
387         break;
388       }
389       case GST_PAD_SOMETIMES:
390         has_dynamic_pads = TRUE;
391         break;
392       default:
393         break;
394     }
395   }
396
397   /* listen for newly created pads if this element supports that */
398   if (has_dynamic_pads) {
399     g_signal_connect (sinkelement, "new-pad", G_CALLBACK (cb_newpad), NULL);
400   }
401 }
402
403 static void
404 try_to_plug (GstPad        *pad,
405              const GstCaps *caps)
406 {
407   GstObject *parent = GST_OBJECT (GST_OBJECT_PARENT (pad));
408   const gchar *mime;
409   const GList *item;
410   GstCaps *res, *audiocaps;
411
412   /* don't plug if we're already plugged - FIXME: memleak for pad */
413   if (GST_PAD_IS_LINKED (gst_element_get_pad (audiosink, "sink"))) {
414     g_print ("Omitting link for pad %s:%s because we're already linked\n",
415              GST_OBJECT_NAME (parent), GST_OBJECT_NAME (pad));
416     return;
417   }
418
419   /* as said above, we only try to plug audio... Omit video */
420   mime = gst_structure_get_name (gst_caps_get_structure (caps, 0));
421   if (g_strrstr (mime, "video")) {
422     g_print ("Omitting link for pad %s:%s because mimetype %s is non-audio\n",
423              GST_OBJECT_NAME (parent), GST_OBJECT_NAME (pad), mime);
424     return;
425   }
426
427   /* can it link to the audiopad? */
428   audiocaps = gst_pad_get_caps (gst_element_get_pad (audiosink, "sink"));
429   res = gst_caps_intersect (caps, audiocaps);
430   if (res &amp;&amp; !gst_caps_is_empty (res)) {
431     g_print ("Found pad to link to audiosink - plugging is now done\n");
432     close_link (pad, audiosink, "sink", NULL);
433     gst_caps_unref (audiocaps);
434     gst_caps_unref (res);
435     return;
436   }
437   gst_caps_unref (audiocaps);
438   gst_caps_unref (res);
439
440   /* try to plug from our list */
441   for (item = factories; item != NULL; item = item->next) {
442     GstElementFactory *factory = GST_ELEMENT_FACTORY (item->data);
443     const GList *pads;
444
445     for (pads = gst_element_factory_get_static_pad_templates (factory);
446          pads != NULL; pads = pads->next) {
447       GstStaticPadTemplate *templ = pads->data;
448
449       /* find the sink template - need an always pad*/
450       if (templ->direction != GST_PAD_SINK ||
451           templ->presence != GST_PAD_ALWAYS) {
452         continue;
453       }
454
455       /* can it link? */
456       res = gst_caps_intersect (caps,
457           gst_static_caps_get (&amp;templ->static_caps));
458       if (res &amp;&amp; !gst_caps_is_empty (res)) {
459         GstElement *element;
460         gchar *name_template = g_strdup (templ->name_template);
461
462         /* close link and return */
463         gst_caps_unref (res);
464         element = gst_element_factory_create (factory, NULL);
465         close_link (pad, element, name_template,
466                     gst_element_factory_get_static_pad_templates (factory));
467         g_free (name_template);
468         return;
469       }
470       gst_caps_unref (res);
471
472       /* we only check one sink template per factory, so move on to the
473        * next factory now */
474       break;
475     }
476   }
477
478   /* if we get here, no item was found */
479   g_print ("No compatible pad found to decode %s on %s:%s\n",
480            mime, GST_OBJECT_NAME (parent), GST_OBJECT_NAME (pad));
481 }
482
483 static void
484 cb_typefound (GstElement *typefind,
485               guint       probability,
486               GstCaps    *caps,
487               gpointer    data)
488 {
489   gchar *s;
490   GstPad *pad;
491
492   s = gst_caps_to_string (caps);
493   g_print ("Detected media type %s\n", s);
494   g_free (s);
495
496   /* actually plug now */
497   pad = gst_element_get_pad (typefind, "src");
498   try_to_plug (pad, caps);
499   gst_object_unref (GST_OBJECT (pad));
500 }
501     <!-- example-end dynamic.c c --></programlisting>
502     <para>
503       By doing all this, we will be able to make a simple autoplugger that
504       can automatically setup a pipeline for any media type. In the example
505       below, we will do this for audio only. However, we can also do this
506       for video to create a player that plays both audio and video.
507     </para>
508     <!-- example-begin dynamic.c d --><!--
509 static gboolean
510 my_bus_callback (GstBus     *bus,
511                  GstMessage *message,
512                  gpointer    data)
513 {
514   GMainLoop *loop = data;
515
516   switch (GST_MESSAGE_TYPE (message)) {
517     case GST_MESSAGE_ERROR: {
518       GError *err;
519       gchar *debug;
520
521       gst_message_parse_error (message, &amp;err, &amp;debug);
522       g_print ("Error: %s\n", err-&gt;message);
523       g_error_free (err);
524       g_free (debug);
525
526       g_main_loop_quit (loop);
527       break;
528     }
529     case GST_MESSAGE_EOS:
530       /* end-of-stream */
531       g_main_loop_quit (loop);
532       break;
533     default:
534       break;
535   }
536
537   /* remove from queue */
538   return TRUE;
539 }
540
541 gint
542 main (gint   argc,
543       gchar *argv[])
544 {
545   GMainLoop *loop;
546   GstElement *typefind, *realsink;
547   gchar *p;
548
549   /* init GStreamer and ourselves */
550   gst_init (&amp;argc, &amp;argv);
551   loop = g_main_loop_new (NULL, FALSE);
552   init_factories ();
553
554   /* args */
555   if (argc != 2) {
556     g_print ("Usage: %s &lt;filename&gt;\n", argv[0]);
557     return -1;
558   }
559
560   /* pipeline */
561   p = g_strdup_printf ("filesrc location=\"%s\" ! typefind name=tf", argv[1]);
562   pipeline = gst_parse_launch (p, NULL);
563   gst_bus_add_watch (gst_pipeline_get_bus (GST_PIPELINE (pipeline)),
564                      my_bus_callback, NULL);
565   g_free (p);
566   typefind = gst_bin_get_by_name (GST_BIN (pipeline), "tf");
567   g_signal_connect (typefind, "have-type", G_CALLBACK (cb_typefound), NULL);
568   gst_object_unref (GST_OBJECT (typefind));
569   audiosink = gst_element_factory_make ("audioconvert", "aconv");
570   realsink = gst_element_factory_make ("alsasink", "audiosink");
571   gst_bin_add_many (GST_BIN (pipeline), audiosink, realsink, NULL);
572   gst_element_link (audiosink, realsink);
573   gst_element_set_state (pipeline, GST_STATE_PLAYING);
574
575   /* run */
576   g_main_loop_run (loop);
577
578   /* exit */
579   gst_element_set_state (pipeline, GST_STATE_NULL);
580   gst_object_unref (GST_OBJECT (pipeline));
581
582   return 0;
583 }
584     --><!-- example-end dynamic.c d -->
585     <para>
586       The example above is a good first try for an autoplugger. Next steps
587       would be to listen for <quote>pad-removed</quote> signals, so we
588       can dynamically change the plugged pipeline if the stream changes
589       (this happens for DVB or Ogg radio). Also, you might want special-case
590       code for input with known content (such as a DVD or an audio-CD),
591       and much, much more. Moreover, you'll want many checks to prevent
592       infinite loops during autoplugging, maybe you'll want to implement
593       shortest-path-finding to make sure the most optimal pipeline is chosen,
594       and so on. Basically, the features that you implement in an autoplugger
595       depend on what you want to use it for. For full-blown implementations,
596       see the <quote>playbin</quote> and <quote>decodebin</quote> elements.
597     </para>
598   </sect1>
599 </chapter>