18a6db7e958b078810fe211e96d86b9e7ebe8fe5
[platform/upstream/gstreamer.git] / docs / manual / advanced-threads.xml
1 <chapter id="chapter-threads">
2   <title>Threads</title>
3   <para> 
4     GStreamer has support for multithreading through the use of
5     the <ulink type="http" url="../../gstreamer/html/GstThread.html"><classname>
6     GstThread</classname></ulink> object. This object is in fact
7     a special <ulink type="http" url="../../gstreamer/html/GstBin.html"><classname>
8     GstBin</classname></ulink> that will become a thread when started.
9   </para>
10
11   <para> 
12     To construct a new thread you will perform something like:
13   </para>
14
15   <para>
16     <programlisting>
17   GstElement *my_thread;
18
19   /* create the thread object */
20   my_thread = gst_thread_new ("my_thread");
21   /* you could have used gst_element_factory_make ("thread", "my_thread"); */
22   g_return_if_fail (my_thread != NULL);
23
24   /* add some plugins */
25   gst_bin_add (GST_BIN (my_thread), GST_ELEMENT (funky_src));
26   gst_bin_add (GST_BIN (my_thread), GST_ELEMENT (cool_effect));
27
28   /* link the elements here... */
29   ...
30   
31   /* start playing */
32   gst_element_set_state (GST_ELEMENT (my_thread), GST_STATE_PLAYING);
33
34     </programlisting>
35   </para>
36   <para>
37     The above program will create a thread with two elements in it. As soon
38     as it is set to the PLAYING state, the thread will start to iterate
39     itself. You never need to explicitly iterate a thread.
40   </para>
41   
42   <sect1 id="section-threads-constraints">
43     <title>Constraints placed on the pipeline by the GstThread</title>
44     <para>
45       Within the pipeline, everything is the same as in any other bin. The
46       difference lies at the thread boundary, at the link between the
47       thread and the outside world (containing bin).  Since GStreamer is
48       fundamentally buffer-oriented rather than byte-oriented, the natural
49       solution to this problem is an element that can "buffer" the buffers
50       between the threads, in a thread-safe fashion. This element is the
51       queue, described more fully in <xref linkend="section-queue"/>. It doesn't
52       matter if the queue is placed in the containing bin or in the thread
53       itself, but it needs to be present on one side or the other to enable
54       inter-thread communication.
55     </para>
56   </sect1>
57   <sect1 id="section-threads-when">
58     <title>When would you want to use a thread?</title>
59     <para>
60       If you are writing a GUI application, making the top-level bin a thread will make your GUI
61       more responsive. If it were a pipeline instead, it would have to be iterated by your
62       application's event loop, which increases the latency between events (say, keyboard presses)
63       and responses from the GUI. In addition, any slight hang in the GUI would delay iteration of
64       the pipeline, which (for example) could cause pops in the output of the sound card, if it is
65       an audio pipeline.
66     </para>
67     <para> 
68     <xref linkend="section-threads-img"/> shows how a thread can be visualised.
69     </para>
70     <figure float="1" id="section-threads-img">
71       <title>A thread</title>
72       <mediaobject>
73         <imageobject>
74           <imagedata fileref="images/thread.&image;" format="&IMAGE;" />
75         </imageobject>
76       </mediaobject>  
77     </figure>
78
79     <para> 
80     As an example we show the helloworld program using a thread.
81     </para>
82   
83     <para>
84       <programlisting>
85 /* example-begin threads.c */
86 #include &lt;gst/gst.h&gt;
87
88 /* we set this to TRUE right before gst_main (), but there could still
89    be a race condition between setting it and entering the function */
90 gboolean can_quit = FALSE;
91
92 /* eos will be called when the src element has an end of stream */
93 void 
94 eos (GstElement *src, gpointer data) 
95 {
96   GstThread *thread = GST_THREAD (data);
97   g_print ("have eos, quitting\n");
98
99   /* stop the bin */
100   gst_element_set_state (GST_ELEMENT (thread), GST_STATE_NULL);
101
102   while (!can_quit) /* waste cycles */ ;
103   gst_main_quit ();
104 }
105
106 int 
107 main (int argc, char *argv[]) 
108 {
109   GstElement *filesrc, *demuxer, *decoder, *converter, *audiosink;
110   GstElement *thread;
111
112   if (argc &lt; 2) {
113     g_print ("usage: %s &lt;Ogg/Vorbis filename&gt;\n", argv[0]);
114     exit (-1);
115   }
116
117   gst_init (&amp;argc, &amp;argv);
118
119   /* create a new thread to hold the elements */
120   thread = gst_thread_new ("thread");
121   g_assert (thread != 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   g_signal_connect (G_OBJECT (filesrc), "eos",
128                      G_CALLBACK (eos), thread);
129
130   /* create an ogg demuxer */
131   demuxer = gst_element_factory_make ("oggdemux", "demuxer");
132   g_assert (demuxer != NULL);
133
134   /* create a vorbis decoder */
135   decoder = gst_element_factory_make ("vorbisdec", "decoder");
136   g_assert (decoder != NULL);
137
138   /* create an audio converter */
139   converter = gst_element_factory_make ("audioconvert", "converter");
140   g_assert (decoder != NULL);
141
142   /* and an audio sink */
143   audiosink = gst_element_factory_make ("osssink", "play_audio");
144   g_assert (audiosink != NULL);
145
146   /* add objects to the thread */
147   gst_bin_add_many (GST_BIN (thread), filesrc, demuxer, decoder, converter, audiosink, NULL);
148   /* link them in the logical order */
149   gst_element_link_many (filesrc, demuxer, decoder, converter, audiosink, NULL);
150
151   /* start playing */
152   gst_element_set_state (thread, GST_STATE_PLAYING);
153
154   /* do whatever you want here, the thread will be playing */
155   g_print ("thread is playing\n");
156   
157   can_quit = TRUE;
158   gst_main ();
159
160   gst_object_unref (GST_OBJECT (thread));
161
162   exit (0);
163 }
164 /* example-end threads.c */
165       </programlisting>
166     </para>
167   </sect1>
168
169   <sect1 id="section-queue">
170     <title>Queue</title>
171   <para> 
172     A queue is a filter element.
173     Queues can be used to link two elements in such way that the data can 
174     be buffered.
175   </para>
176   <para> 
177     A buffer that is sinked to a Queue will not automatically be pushed to the
178     next linked element but will be buffered. It will be pushed to the next
179     element as soon as a gst_pad_pull () is called on the queue's source pad.
180   </para>
181   <para> 
182     Queues are mostly used in conjunction with a thread bin to
183     provide an external link for the thread's elements. You could have one
184     thread feeding buffers into a queue and another
185     thread repeatedly pulling on the queue to feed its 
186     internal elements.
187   </para>
188
189   <para> 
190     Below is a figure of a two-threaded decoder. We have one thread (the main execution
191     thread) reading the data from a file, and another thread decoding the data.
192   </para>
193   <figure float="1" id="section-queues-img">
194     <title>a two-threaded decoder with a queue</title>
195     <mediaobject>
196       <imageobject>
197         <imagedata fileref="images/queue.&image;" format="&IMAGE;" />
198       </imageobject>
199     </mediaobject>  
200   </figure>
201
202   <para> 
203     The standard <application>GStreamer</application> queue implementation has some
204     properties that can be changed using the g_objet_set () method. To set the 
205     maximum number of buffers that can be queued to 30, do:
206   </para>
207   <programlisting>
208   g_object_set (G_OBJECT (queue), "max_level", 30, NULL);
209   </programlisting>
210
211   <para> 
212     The following MP3 player shows you how to create the above pipeline
213     using a thread and a queue.
214   </para>
215
216   <programlisting>
217 /* example-begin queue.c */
218 #include &lt;stdlib.h&gt;
219 #include &lt;gst/gst.h&gt;
220
221 gboolean playing;
222
223 /* eos will be called when the src element has an end of stream */
224 void 
225 eos (GstElement *element, gpointer data) 
226 {
227   g_print ("have eos, quitting\n");
228
229   playing = FALSE;
230 }
231
232 int 
233 main (int argc, char *argv[]) 
234 {
235   GstElement *filesrc, *audiosink, *queue, *decode;
236   GstElement *bin;
237   GstElement *thread;
238
239   gst_init (&amp;argc,&amp;argv);
240
241   if (argc != 2) {
242     g_print ("usage: %s &lt;mp3 filename&gt;\n", argv[0]);
243     exit (-1);
244   }
245
246   /* create a new thread to hold the elements */
247   thread = gst_thread_new ("thread");
248   g_assert (thread != NULL);
249
250   /* create a new bin to hold the elements */
251   bin = gst_bin_new ("bin");
252   g_assert (bin != NULL);
253
254   /* create a disk reader */
255   filesrc = gst_element_factory_make ("filesrc", "disk_source");
256   g_assert (filesrc != NULL);
257   g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL);
258   g_signal_connect (G_OBJECT (filesrc), "eos",
259                     G_CALLBACK (eos), thread);
260
261   queue = gst_element_factory_make ("queue", "queue");
262   g_assert (queue != NULL);
263
264   /* and an audio sink */
265   audiosink = gst_element_factory_make ("osssink", "play_audio");
266   g_assert (audiosink != NULL);
267
268   decode = gst_element_factory_make ("mad", "decode");
269
270   /* add objects to the main bin */
271   gst_bin_add_many (GST_BIN (thread), decode, audiosink, NULL);
272
273   gst_bin_add_many (GST_BIN (bin), filesrc, queue, thread, NULL);
274
275   
276   gst_element_link (filesrc, queue);
277   gst_element_link_many (queue, decode, audiosink, NULL);
278
279   /* start playing */
280   gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PLAYING);
281
282   playing = TRUE;
283
284   while (playing) {
285     gst_bin_iterate (GST_BIN (bin));
286   }
287
288   gst_element_set_state (GST_ELEMENT (bin), GST_STATE_NULL);
289
290   return 0;
291 }
292 /* example-end queue.c */
293   </programlisting>
294
295   </sect1>
296 </chapter>