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