2004-12-15 07:30:55 +00:00
|
|
|
<chapter id="chapter-scheduler">
|
2004-12-15 17:32:49 +00:00
|
|
|
<title>Scheduling</title>
|
2004-12-15 07:30:55 +00:00
|
|
|
<para>
|
|
|
|
The scheduler is responsible for managing the plugins at runtime. Its
|
|
|
|
main responsibilities are:
|
|
|
|
<itemizedlist>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
Preparing the plugins so they can be scheduled.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
Monitoring state changes and enabling/disabling the element in the
|
|
|
|
chain.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
Choosing an element as the entry point for the pipeline.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
Selecting and distributing the global clock.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
</itemizedlist>
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
The scheduler is a pluggable component; this means that alternative
|
|
|
|
schedulers can be written and plugged into GStreamer. The default scheduler
|
|
|
|
uses cothreads to schedule the plugins in a pipeline. Cothreads are fast
|
|
|
|
and lightweight user-space threads.
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
There is usually no need to interact with the scheduler directly, however
|
|
|
|
in some cases it is feasible to set a specific clock or force a specific
|
|
|
|
plugin as the entry point in the pipeline.
|
|
|
|
</para>
|
|
|
|
|
2004-12-15 17:32:49 +00:00
|
|
|
<sect1 id="section-chain-based">
|
|
|
|
<title>Chain-based elements</title>
|
|
|
|
<para>
|
|
|
|
Chain based elements receive a buffer of data and are supposed
|
|
|
|
to handle the data and perform a gst_pad_push.
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
The basic main function of a chain-based element is like:
|
|
|
|
</para>
|
|
|
|
<programlisting>
|
|
|
|
static void
|
|
|
|
chain_function (GstPad *pad, GstBuffer *buffer)
|
|
|
|
{
|
|
|
|
GstBuffer *outbuffer;
|
|
|
|
|
|
|
|
....
|
|
|
|
// process the buffer, create a new outbuffer
|
|
|
|
...
|
|
|
|
|
|
|
|
gst_pad_push (srcpad, outbuffer);
|
|
|
|
}
|
|
|
|
</programlisting>
|
|
|
|
<para>
|
|
|
|
Chain based function are mainly used for elements that have a one to one
|
|
|
|
relation between their input and output behaviour. An example of such an
|
|
|
|
element can be a simple video blur filter. The filter takes a buffer in, performs
|
|
|
|
the blur operation on it and sends out the resulting buffer.
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
Another element, for example, is a volume filter. The filter takes audio samples as
|
|
|
|
input, performs the volume effect and sends out the resulting buffer.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
</sect1>
|
|
|
|
|
|
|
|
<sect1 id="section-loop-based">
|
|
|
|
<title>Loop-based elements</title>
|
|
|
|
<para>
|
|
|
|
As opposed to chain-based elements, loop-based elements enter an
|
|
|
|
infinite loop that looks like this:
|
|
|
|
|
|
|
|
<programlisting>
|
|
|
|
GstBuffer *buffer, *outbuffer;
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
buffer = gst_pad_pull (sinkpad);
|
|
|
|
...
|
|
|
|
// process buffer, create outbuffer
|
|
|
|
while (!done) {
|
|
|
|
....
|
|
|
|
// optionally request another buffer
|
|
|
|
buffer = gst_pad_pull (sinkpad);
|
|
|
|
....
|
|
|
|
}
|
|
|
|
...
|
|
|
|
gst_pad_push (srcpad, outbuffer);
|
|
|
|
}
|
|
|
|
</programlisting>
|
|
|
|
|
|
|
|
The loop-based elements request a buffer whenever they need one.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
When the request for a buffer cannot be immediately satisfied, the control
|
|
|
|
will be given to the source element of the loop-based element until it
|
|
|
|
performs a push on its source pad. At that time the control is handed
|
|
|
|
back to the loop-based element, etc... The execution trace can get
|
|
|
|
fairly complex using cothreads when there are multiple input/output
|
|
|
|
pads for the loop-based element. Cothread switches are performed within
|
|
|
|
the call to gst_pad_pull and gst_pad_push; from the perspective of
|
|
|
|
the loop-based element, it just "appears" that gst_pad_push (or _pull)
|
|
|
|
might take a long time to return.
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
Loop based elements are mainly used for the more complex elements
|
|
|
|
that need a specific amount of data before they can start to produce
|
|
|
|
output. An example of such an element is the MPEG video decoder. The
|
|
|
|
element will pull a buffer, perform some decoding on it and optionally
|
|
|
|
request more buffers to decode, and when a complete video frame has
|
|
|
|
been decoded, a buffer is sent out. For example, any plugin using the
|
|
|
|
bytestream library will need to be loop-based.
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
There is no problem in putting cothreaded elements into a <ulink
|
|
|
|
type="http" url="../../gstreamer/html/GstThread.html"><classname>GstThread
|
|
|
|
</classname></ulink> to
|
|
|
|
create even more complex pipelines with both user and kernel space threads.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
</sect1>
|
|
|
|
|
|
|
|
<sect1 id="section-opt">
|
|
|
|
<title>The optimal scheduler</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Explain opt a bit, chains, groups, and how it affects execution.
|
|
|
|
</para>
|
|
|
|
</sect1>
|
2004-12-15 07:30:55 +00:00
|
|
|
</chapter>
|