mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-16 21:36:35 +00:00
88 lines
4.5 KiB
Markdown
88 lines
4.5 KiB
Markdown
# Pad (de)activation
|
||
|
||
## Activation
|
||
|
||
When changing states, a bin will set the state on all of its children in
|
||
sink-to-source order. As elements undergo the READY→PAUSED transition,
|
||
their pads are activated so as to prepare for data flow. Some pads will
|
||
start tasks to drive the data flow.
|
||
|
||
An element activates its pads from sourcepads to sinkpads. This to make
|
||
sure that when the sinkpads are activated and ready to accept data, the
|
||
sourcepads are already active to pass the data downstream.
|
||
|
||
Pads can be activated in one of two modes, PUSH and PULL. PUSH pads are
|
||
the normal case, where the source pad in a link sends data to the sink
|
||
pad via `gst_pad_push()`. PULL pads instead have sink pads request data
|
||
from the source pads via `gst_pad_pull_range()`.
|
||
|
||
To activate a pad, the core will call `gst_pad_set_active()` with a
|
||
TRUE argument, indicating that the pad should be active. If the pad is
|
||
already active, be it in a PUSH or PULL mode, `gst_pad_set_active()`
|
||
will return without doing anything. Otherwise it will call the
|
||
activation function of the pad.
|
||
|
||
Because the core does not know in which mode to activate a pad (PUSH or
|
||
PULL), it delegates that choice to a method on the pad, `activate()`. The
|
||
`activate()` function of a pad should choose whether to operate in PUSH or
|
||
PULL mode. Once the choice is made, it should call `activate_mode()` with
|
||
the selected activation mode. The default `activate()` function will call
|
||
`activate_mode()` with `#GST_PAD_MODE_PUSH`, as it is the default
|
||
mechanism for data flow. A sink pad that supports either mode of
|
||
operation might call `activate_mode(PULL)` if the SCHEDULING query
|
||
upstream contains the `#GST_PAD_MODE_PULL` scheduling mode, and
|
||
`activate_mode(PUSH)` otherwise.
|
||
|
||
Consider the case `fakesrc ! fakesink`, where fakesink is configured to
|
||
operate in PULL mode. State changes in the pipeline will start with
|
||
fakesink, which is the most downstream element. The core will call
|
||
`activate()` on fakesink’s sink pad. For fakesink to go into PULL mode, it
|
||
needs to implement a custom `activate()` function that will call
|
||
`activate_mode(PULL)` on its sink pad (because the default is to use PUSH
|
||
mode). `activate_mode(PULL)` is then responsible for starting the task
|
||
that pulls from fakesrc:src. Clearly, fakesrc needs to be notified that
|
||
fakesrc is about to pull on its src pad, even though the pipeline has
|
||
not yet changed fakesrc’s state. For this reason, GStreamer will first
|
||
call `activate_mode(PULL)` on fakesink:sink’s peer before calling
|
||
`activate_mode(PULL)` on fakesink:sinks.
|
||
|
||
In short, upstream elements operating in PULL mode must be ready to
|
||
produce data in READY, after having `activate_mode(PULL)` called on their
|
||
source pad. Also, a call to `activate_mode(PULL)` needs to propagate
|
||
through the pipeline to every pad that a `gst_pad_pull()` will reach. In
|
||
the case `fakesrc ! identity ! fakesink`, calling `activate_mode(PULL)`
|
||
on identity’s source pad would need to activate its sink pad in pull
|
||
mode as well, which should propagate all the way to fakesrc.
|
||
|
||
If, on the other hand, `fakesrc ! fakesink` is operating in PUSH mode,
|
||
the activation sequence is different. First, `activate()` on fakesink:sink
|
||
calls `activate_mode(PUSH)` on fakesink:sink. Then fakesrc’s pads are
|
||
activated: sources first, then sinks (of which fakesrc has none).
|
||
fakesrc:src’s activation function is then called.
|
||
|
||
Note that it does not make sense to set an activation function on a
|
||
source pad. The peer of a source pad is downstream, meaning it should
|
||
have been activated first. If it was activated in PULL mode, the source
|
||
pad should have already had `activate_mode(PULL)` called on it, and thus
|
||
needs no further activation. Otherwise it should be in PUSH mode, which
|
||
is the choice of the default activation function.
|
||
|
||
So, in the PUSH case, the default activation function chooses PUSH mode,
|
||
which calls `activate_mode(PUSH)`, which will then start a task on the
|
||
source pad and begin pushing. In this way PUSH scheduling is a bit
|
||
easier, because it follows the order of state changes in a pipeline.
|
||
fakesink is already in PAUSED with an active sink pad by the time
|
||
fakesrc starts pushing data.
|
||
|
||
## Deactivation
|
||
|
||
Pad deactivation occurs when its parent goes into the READY state or
|
||
when the pad is deactivated explicitly by the application or element.
|
||
`gst_pad_set_active()` is called with a FALSE argument, which then
|
||
calls `activate_mode(PUSH)` or `activate_mode(PULL)` with a FALSE
|
||
argument, depending on the current activation mode of the pad.
|
||
|
||
## Mode switching
|
||
|
||
Changing from push to pull modes needs a bit of thought. This is
|
||
actually possible and implemented but not yet documented here.
|