1 <chapter id="chapter-threads">
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.
12 To construct a new thread you will perform something like:
17 GstElement *my_thread;
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);
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));
28 /* link the elements here... */
32 gst_element_set_state (GST_ELEMENT (my_thread), GST_STATE_PLAYING);
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.
42 <sect1 id="section-threads-constraints">
43 <title>Constraints placed on the pipeline by the GstThread</title>
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.
57 <sect1 id="section-threads-when">
58 <title>When would you want to use a thread?</title>
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
68 <xref linkend="section-threads-img"/> shows how a thread can be visualised.
70 <figure float="1" id="section-threads-img">
71 <title>A thread</title>
74 <imagedata fileref="images/thread.ℑ" format="&IMAGE;" />
80 As an example we show the helloworld program using a thread.
85 /* example-begin threads.c */
86 #include <gst/gst.h>
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;
92 /* eos will be called when the src element has an end of stream */
94 eos (GstElement *src, gpointer data)
96 GstThread *thread = GST_THREAD (data);
97 g_print ("have eos, quitting\n");
100 gst_element_set_state (GST_ELEMENT (thread), GST_STATE_NULL);
102 while (!can_quit) /* waste cycles */ ;
107 main (int argc, char *argv[])
109 GstElement *filesrc, *demuxer, *decoder, *converter, *audiosink;
113 g_print ("usage: %s <Ogg/Vorbis filename>\n", argv[0]);
117 gst_init (&argc, &argv);
119 /* create a new thread to hold the elements */
120 thread = gst_thread_new ("thread");
121 g_assert (thread != NULL);
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);
130 /* create an ogg demuxer */
131 demuxer = gst_element_factory_make ("oggdemux", "demuxer");
132 g_assert (demuxer != NULL);
134 /* create a vorbis decoder */
135 decoder = gst_element_factory_make ("vorbisdec", "decoder");
136 g_assert (decoder != NULL);
138 /* create an audio converter */
139 converter = gst_element_factory_make ("audioconvert", "converter");
140 g_assert (decoder != NULL);
142 /* and an audio sink */
143 audiosink = gst_element_factory_make ("osssink", "play_audio");
144 g_assert (audiosink != NULL);
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);
152 gst_element_set_state (thread, GST_STATE_PLAYING);
154 /* do whatever you want here, the thread will be playing */
155 g_print ("thread is playing\n");
160 gst_object_unref (GST_OBJECT (thread));
164 /* example-end threads.c */
169 <sect1 id="section-queue">
172 A queue is a filter element.
173 Queues can be used to link two elements in such way that the data can
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.
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
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.
193 <figure float="1" id="section-queues-img">
194 <title>a two-threaded decoder with a queue</title>
197 <imagedata fileref="images/queue.ℑ" format="&IMAGE;" />
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:
208 g_object_set (G_OBJECT (queue), "max_level", 30, NULL);
212 The following MP3 player shows you how to create the above pipeline
213 using a thread and a queue.
217 /* example-begin queue.c */
218 #include <stdlib.h>
219 #include <gst/gst.h>
223 /* eos will be called when the src element has an end of stream */
225 eos (GstElement *element, gpointer data)
227 g_print ("have eos, quitting\n");
233 main (int argc, char *argv[])
235 GstElement *filesrc, *audiosink, *queue, *decode;
239 gst_init (&argc,&argv);
242 g_print ("usage: %s <mp3 filename>\n", argv[0]);
246 /* create a new thread to hold the elements */
247 thread = gst_thread_new ("thread");
248 g_assert (thread != NULL);
250 /* create a new bin to hold the elements */
251 bin = gst_bin_new ("bin");
252 g_assert (bin != NULL);
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);
261 queue = gst_element_factory_make ("queue", "queue");
262 g_assert (queue != NULL);
264 /* and an audio sink */
265 audiosink = gst_element_factory_make ("osssink", "play_audio");
266 g_assert (audiosink != NULL);
268 decode = gst_element_factory_make ("mad", "decode");
270 /* add objects to the main bin */
271 gst_bin_add_many (GST_BIN (thread), decode, audiosink, NULL);
273 gst_bin_add_many (GST_BIN (bin), filesrc, queue, thread, NULL);
276 gst_element_link (filesrc, queue);
277 gst_element_link_many (queue, decode, audiosink, NULL);
280 gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PLAYING);
285 gst_bin_iterate (GST_BIN (bin));
288 gst_element_set_state (GST_ELEMENT (bin), GST_STATE_NULL);
292 /* example-end queue.c */