new proggy I never checked in
[platform/upstream/gstreamer.git] / docs / manual / helloworld2.xml
1 <chapter id="cha-hello2">
2   <title>Your second application</title>
3   <para>
4     FIXME: delete this section, talk more about the spider. In a previous chapter we created a first
5     version of the helloworld application. We then explained a better way of creating the elements
6     using factories identified by MIME types and the autoplugger.
7   </para>
8
9   <sect1>
10     <title>Autoplugging helloworld </title>
11     <para> 
12       We will create a second version of the helloworld application using
13       autoplugging. Its source code is a bit more complicated but 
14       it can handle many more data types.  It can even play the audio track
15       of a video file.
16     </para>
17     <para> 
18       Here is the full program listing.  Start by looking at the main ()
19       function.
20     </para>
21
22     <programlisting>
23 /* example-begin helloworld2.c */
24 #include &lt;gst/gst.h&gt;
25
26 static void     gst_play_have_type      (GstElement *typefind, GstCaps *caps, GstElement *pipeline);
27 static void     gst_play_cache_empty    (GstElement *element, GstElement *pipeline);
28
29 static void
30 gst_play_have_type (GstElement *typefind, GstCaps *caps, GstElement *pipeline)
31 {
32   GstElement *osssink;
33   GstElement *new_element;
34   GstAutoplug *autoplug;
35   GstElement *autobin;
36   GstElement *filesrc;
37   GstElement *cache;
38
39   g_print ("GstPipeline: play have type\n");
40
41   gst_element_set_state (pipeline, GST_STATE_PAUSED);
42
43   filesrc = gst_bin_get_by_name (GST_BIN (pipeline), "disk_source");
44   autobin = gst_bin_get_by_name (GST_BIN (pipeline), "autobin");
45   cache = gst_bin_get_by_name (GST_BIN (autobin), "cache");
46
47   /* unlink the typefind from the pipeline and remove it */
48   gst_element_unlink (cache, typefind);
49   gst_bin_remove (GST_BIN (autobin), typefind);
50       
51   /* and an audio sink */
52   osssink = gst_element_factory_make ("osssink", "play_audio");
53   g_assert (osssink != NULL);
54
55   autoplug = gst_autoplug_factory_make ("staticrender");
56   g_assert (autoplug != NULL);
57
58   new_element = gst_autoplug_to_renderers (autoplug, caps, osssink, NULL);
59
60   if (!new_element) {
61     g_print ("could not autoplug, no suitable codecs found...\n");
62     exit (-1);
63   }
64
65   gst_element_set_name (new_element, "new_element");
66
67   gst_bin_add (GST_BIN (autobin), new_element);
68
69   g_object_set (G_OBJECT (cache), "reset", TRUE, NULL);
70
71   gst_element_link (cache, new_element);
72
73   gst_element_set_state (pipeline, GST_STATE_PLAYING);
74 }
75
76 static void
77 gst_play_cache_empty (GstElement *element, GstElement *pipeline)
78 {
79   GstElement *autobin;
80   GstElement *filesrc;
81   GstElement *cache;
82   GstElement *new_element;
83
84   g_print ("have cache empty\n");
85
86   gst_element_set_state (pipeline, GST_STATE_PAUSED);
87
88   filesrc = gst_bin_get_by_name (GST_BIN (pipeline), "disk_source");
89   autobin = gst_bin_get_by_name (GST_BIN (pipeline), "autobin");
90   cache = gst_bin_get_by_name (GST_BIN (autobin), "cache");
91   new_element = gst_bin_get_by_name (GST_BIN (autobin), "new_element");
92
93   gst_element_unlink (filesrc, cache);
94   gst_element_unlink (cache, new_element);
95   gst_bin_remove (GST_BIN (autobin), cache);
96   gst_element_link (filesrc, new_element);
97
98   gst_element_set_state (pipeline, GST_STATE_PLAYING);
99
100   g_print ("done with cache_empty\n");
101 }
102
103 int 
104 main (int argc, char *argv[]) 
105 {
106   GstElement *filesrc;
107   GstElement *pipeline;
108   GstElement *autobin;
109   GstElement *typefind;
110   GstElement *cache;
111
112   gst_init (&amp;argc, &amp;argv);
113
114   if (argc != 2) {
115     g_print ("usage: %s &lt;filename with audio&gt;\n", argv[0]);
116     exit (-1);
117   }
118
119   /* create a new pipeline to hold the elements */
120   pipeline = gst_pipeline_new ("pipeline");
121   g_assert (pipeline != NULL);
122
123   /* create a disk reader */
124   filesrc = gst_element_factory_make ("filesrc", "disk_source");
125   g_assert (filesrc != NULL);
126   g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL);
127   gst_bin_add (GST_BIN (pipeline), filesrc);
128
129   autobin = gst_bin_new ("autobin");
130   cache = gst_element_factory_make ("autoplugcache", "cache");
131   g_signal_connect (G_OBJECT (cache), "cache_empty", 
132                      G_CALLBACK (gst_play_cache_empty), pipeline);
133
134   typefind = gst_element_factory_make ("typefind", "typefind");
135   g_signal_connect (G_OBJECT (typefind), "have_type", 
136                      G_CALLBACK (gst_play_have_type), pipeline);
137   gst_bin_add (GST_BIN (autobin), cache);
138   gst_bin_add (GST_BIN (autobin), typefind);
139
140   gst_element_link (cache, typefind);
141   gst_element_add_ghost_pad (autobin, 
142                              gst_element_get_pad (cache, "sink"), "sink");
143
144   gst_bin_add (GST_BIN( pipeline), autobin);
145   gst_element_link (filesrc, autobin);
146
147   /* start playing */
148   gst_element_set_state( GST_ELEMENT (pipeline), GST_STATE_PLAYING);
149
150   while (gst_bin_iterate (GST_BIN (pipeline)));
151
152   /* stop the pipeline */
153   gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
154
155   gst_object_unref (GST_OBJECT (pipeline));
156
157   exit(0);
158 }
159 /* example-end helloworld2.c */
160     </programlisting>
161     <para>
162       We start by constructing a 'filesrc' element and an 'autobin' element that
163       holds the autoplugcache and the typefind element.
164     </para>
165     <para>
166       We attach the "cache_empty" signal to gst_play_cache_empty and the 
167       "have_type" to our gst_play_have_type function.
168     </para>
169
170     <para>
171       The _have_type function first sets the pipeline to the PAUSED state
172       so that it can safely modify the pipeline. It then finds the elements 
173       it is going to manipulate in the pipeline with:
174     </para>
175     <programlisting>
176   filesrc = gst_bin_get_by_name (GST_BIN (pipeline), "disk_source");
177   autobin = gst_bin_get_by_name (GST_BIN (pipeline), "autobin");
178   cache = gst_bin_get_by_name (GST_BIN (autobin), "cache");
179     </programlisting>
180
181     <para>
182       Now we have a handle to the elements we are going to manipulate in
183       the next step.
184     </para>
185     <para>
186       We don't need the typefind element anymore so we remove it from 
187       the pipeline: 
188     </para>
189     <programlisting>
190   /* unlink the typefind from the pipeline and remove it */
191   gst_element_unlink (cache, "src", typefind, "sink");
192   gst_bin_remove (GST_BIN (autobin), typefind);
193     </programlisting>
194
195     <para>
196       Our next step is to construct an element that can play the type we just
197       detected. We are going to use the autoplugger to create an element that
198       links the type to an osssink. We add the new element to our 
199       autobin.
200     </para>
201
202     <programlisting>
203   /* and an audio sink */
204   osssink = gst_element_factory_make("osssink", "play_audio");
205   g_assert(osssink != NULL);
206
207   autoplug = gst_autoplug_factory_make ("staticrender");
208   g_assert (autoplug != NULL);
209
210   new_element = gst_autoplug_to_renderers (autoplug,
211            caps,
212            osssink,
213            NULL);
214
215   if (!new_element) {
216     g_print ("could not autoplug, no suitable codecs found...\n");
217     exit (-1);
218   }
219
220   gst_element_set_name (new_element, "new_element");
221
222   gst_bin_add (GST_BIN (autobin), new_element);
223     </programlisting>
224
225     <para>
226       Our next step is to reset the cache so that the buffers used by the
227       typefind element are fed into the new element we just created. We reset
228       the cache by setting the "reset" property of the cache element to TRUE.
229     </para>
230     <programlisting>
231   g_object_set (G_OBJECT (cache), "reset", TRUE, NULL);
232
233   gst_element_link (cache, "src", new_element, "sink");
234     </programlisting>
235     <para>
236      Finally we set the pipeline back to the playing state. At this point the
237      cache will replay the buffers. We will be notified when the cache is empty 
238      by the gst_play_cache_empty callback function.
239     </para>
240
241     <para>
242       The cache empty function simply removes the autoplugcache element from
243       the pipeline and relinks the filesrc to the autoplugged element.
244     </para>
245
246     <para>
247       To compile the helloworld2 example, use: 
248     </para>
249     <programlisting>
250        gcc -Wall `pkg-config gstreamer-0.7 --cflags --libs` helloworld2.c \
251              -o helloworld2 
252     </programlisting>
253     <para>
254       You can run the example with 
255       (substitute helloworld.mp3 with you favorite audio file):
256     </para>
257     <programlisting>
258       ./helloworld2 helloworld.mp3
259     </programlisting>
260     <para>
261       You can also try to use an AVI or MPEG file as its input. 
262       Using autoplugging,
263       <application>GStreamer</application> 
264       will automatically figure out how to 
265       handle the stream. 
266       Remember that only the audio part will be played because 
267       we have only added an osssink to the pipeline.
268     </para>
269     <programlisting>
270       ./helloworld2 mymovie.mpeg
271     </programlisting>
272
273   </sect1>
274 </chapter>