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