We have seen that threads are created by elements but it is also possible to insert elements in the pipeline for the sole purpose of forcing a new thread in the pipeline.
There are several reasons to force the use of threads. However, for performance reasons, you never want to use one thread for every element out there, since that will create some overhead. Let's now list some situations where threads can be particularly useful:
Data buffering, for example when dealing with network streams or when recording data from a live stream such as a video or audio card. Short hickups elsewhere in the pipeline will not cause data loss. See also the section called “Stream buffering ” about network buffering with queue2.
Synchronizing output devices, e.g. when playing a stream containing both video and audio data. By using threads for both outputs, they will run independently and their synchronization will be better.
Above, we've mentioned the “queue” element several times
now. A queue is the thread boundary element through which you can
force the use of threads. It does so by using a classic
provider/consumer model as learned in threading classes at
universities all around the world. By doing this, it acts both as a
means to make data throughput between threads threadsafe, and it can
also act as a buffer. Queues have several GObject
properties to be configured for specific uses. For example, you can set
lower and upper thresholds for the element. If there's less data than
the lower threshold (default: disabled), it will block output. If
there's more data than the upper threshold, it will block input or
(if configured to do so) drop data.
To use a queue (and therefore force the use of two distinct threads in the pipeline), one can simply create a “queue” element and put this in as part of the pipeline. GStreamer will take care of all threading details internally.