Scheduling is, in short, a method for making sure that every element gets called once in a while to process data and prepare data for the next element. Likewise, a kernel has a scheduler for processes, and your brain is a very complex scheduler too in a way. Randomly calling elements' chain functions won't bring us far, however, so you'll understand that the schedulers in GStreamer are a bit more complex than this. However, as a start, it's a nice picture.
So far, we have only discussed _chain ()
-operating
elements, i.e. elements that have a chain-function set on their sink pad
and push buffers on their source pad(s). Pads (or elements) can also operate
in two other scheduling modes, however. In this chapter, we will discuss
what those scheduling modes are, how they can be enabled and in what
cases they are useful. The other two scheduling modes are random access
(_getrange ()
-based) or task-runner (which means
that this element is the driving force in the pipeline) mode.
The stage in which GStreamer decides in what scheduling mode the various elements will operate, is called the pad-activation stage. In this stage, GStreamer will query the scheduling capabilities (i.e. it will see in what modes each particular element/pad can operate) and decide on the optimal scheduling composition for the pipeline. Next, each pad will be notified of the scheduling mode that was assigned to it, and after that the pipeline will start running.
Pads can be assigned one of three modes, each mode putting several
prerequisites on the pads. Pads should implement a notification
function (gst_pad_set_activatepull_function ()
and
gst_pad_set_activatepush_function ()
) to be
notified of the scheduling mode assignment. Also, sinkpads assigned
to do pull-based scheduling mode should start and stop their task
in this function.
If all pads of an element are assigned to do
"push"-based scheduling, then this means that data
will be pushed by upstream elements to this element using the
sinkpads _chain ()
-function. Prerequisites
for this scheduling mode are that a chain-function was set for
each sinkpad usinggst_pad_set_chain_function ()
and that all downstream elements operate in the same mode. Pads are
assigned to do push-based scheduling in sink-to-source element
order, and within an element first sourcepads and then sinkpads.
Sink elements can operate in this mode if their sinkpad is activated
for push-based scheduling. Source elements cannot be chain-based.
Alternatively, sinkpads can be the driving force behind a pipeline
by operating in "pull"-based mode, while the sourcepads
of the element still operate in push-based mode. In order to be the
driving force, those pads start a GstTask
when their pads are being activated. This task is a thread, which
will call a function specified by the element. When called, this
function will have random data access (through
gst_pad_get_range ()
) over all sinkpads, and
can push data over the sourcepads, which effectively means that
this element controls dataflow in the pipeline. Prerequisites for
this mode are that all downstream elements can act in chain-based
mode, and that all upstream elements allow random access (see below).
Source elements can be told to act in this mode if their sourcepads
are activated in push-based fashion. Sink elements can be told to
act in this mode when their sinkpads are activated in pull-mode.
lastly, all pads in an element can be assigned to act in pull-mode.
too. However, contrary to the above, this does not mean that they
start a task on their own. Rather, it means that they are pull
slave for the downstream element, and have to provide random data
access to it from their _get_range ()
-function.
Requiremenents are that the a _get_range
()
-function was set on this pad using the function
gst_pad_set_getrange_function ()
. Also, if
the element has any sinkpads, all those pads (and thereby their
peers) need to operate in random access mode, too. Note that the
element is supposed to activate those elements itself! GStreamer
will not do that for you.
In the next two sections, we will go closer into pull-based scheduling (elements/pads driving the pipeline, and elements/pads providing random access), and some specific use cases will be given.