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