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="chapter-queues"/>. 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 a -->
89 /* we set this to TRUE right before gst_main (), but there could still
90 be a race condition between setting it and entering the function */
91 gboolean can_quit = FALSE;
93 /* eos will be called when the src element has an end of stream */
95 eos (GstElement *src, gpointer data)
97 GstThread *thread = GST_THREAD (data);
98 g_print ("have eos, quitting\n");
101 gst_element_set_state (GST_ELEMENT (thread), GST_STATE_NULL);
103 while (!can_quit) /* waste cycles */ ;
108 main (int argc, char *argv[])
110 GstElement *filesrc, *demuxer, *decoder, *converter, *audiosink;
114 g_print ("usage: %s <Ogg/Vorbis filename>\n", argv[0]);
118 gst_init (&argc, &argv);
120 /* create a new thread to hold the elements */
121 thread = gst_thread_new ("thread");
122 g_assert (thread != NULL);
124 /* create a disk reader */
125 filesrc = gst_element_factory_make ("filesrc", "disk_source");
126 g_assert (filesrc != NULL);
127 g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL);
128 g_signal_connect (G_OBJECT (filesrc), "eos",
129 G_CALLBACK (eos), thread);
131 /* create an ogg demuxer */
132 demuxer = gst_element_factory_make ("oggdemux", "demuxer");
133 g_assert (demuxer != NULL);
135 /* create a vorbis decoder */
136 decoder = gst_element_factory_make ("vorbisdec", "decoder");
137 g_assert (decoder != NULL);
139 /* create an audio converter */
140 converter = gst_element_factory_make ("audioconvert", "converter");
141 g_assert (decoder != NULL);
143 /* and an audio sink */
144 audiosink = gst_element_factory_make ("osssink", "play_audio");
145 g_assert (audiosink != NULL);
147 /* add objects to the thread */
148 gst_bin_add_many (GST_BIN (thread), filesrc, demuxer, decoder, converter, audiosink, NULL);
149 /* link them in the logical order */
150 gst_element_link_many (filesrc, demuxer, decoder, converter, audiosink, NULL);
153 gst_element_set_state (thread, GST_STATE_PLAYING);
155 /* do whatever you want here, the thread will be playing */
156 g_print ("thread is playing\n");
161 gst_object_unref (GST_OBJECT (thread));
166 <!-- example-end threads.c a -->