mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 18:21:04 +00:00
242 lines
7.9 KiB
Text
242 lines
7.9 KiB
Text
Scheduling
|
|
----------
|
|
|
|
The scheduling in GStreamer is based on pads actively pushing (producing) data or
|
|
pad pulling in data (consuming) from other pads.
|
|
|
|
Pushing
|
|
~~~~~~~
|
|
|
|
A pad can produce data and push it to the next pad. A pad that behaves this way
|
|
exposes a loop function that will be called repeatedly until it returns false.
|
|
The loop function is allowed to block whenever it wants. When the pad is deactivated
|
|
the loop function should unblock though.
|
|
|
|
A pad operating in the push mode can only produce data to a pad that exposes a
|
|
chain function. This chain function will be called with the buffer produced by
|
|
the pushing pad.
|
|
|
|
This method of producing data is called the streaming mode since the producer
|
|
produces a constant stream of data.
|
|
|
|
Pulling
|
|
~~~~~~~
|
|
|
|
Pads that operate in pulling mode can only pull data from a pad that exposes the
|
|
pull_range function. In this case, the sink pad exposes a loop function that will be
|
|
called repeatedly until the task is stopped.
|
|
|
|
After pulling data from the peer pad, the loop function will typically call the
|
|
push function to push the result to the peer sinkpad.
|
|
|
|
|
|
Deciding the scheduling mode
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
When a pad is activated, the _activate() function is called. The pad can then
|
|
choose to activate itself in push or pull mode depending on upstream
|
|
capabilities.
|
|
|
|
The GStreamer core will by default activate pads in push mode when there is no
|
|
activate function for the pad.
|
|
|
|
The chain function
|
|
~~~~~~~~~~~~~~~~~~
|
|
|
|
The chain function will be called when a upstream element performs a _push() on the pad.
|
|
The upstream element can be another chain based element or a pushing source.
|
|
|
|
The getrange function
|
|
~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
The getrange function is called when a peer pad performs a _pull_range() on the pad. This
|
|
downstream pad can be a pulling element or another _pull_range() based element.
|
|
|
|
|
|
Scheduling Query
|
|
~~~~~~~~~~~~~~~~
|
|
|
|
A sinkpad can ask the upstream srcpad for its scheduling attributes. It does
|
|
this with the SCHEDULING query.
|
|
|
|
|
|
(out) "modes", G_TYPE_ARRAY (default NULL)
|
|
- an array of GST_TYPE_PAD_MODE enums. Contains all the supported
|
|
scheduling modes.
|
|
|
|
(out) "flags", GST_TYPE_SCHEDULING_FLAGS (default 0)
|
|
|
|
typedef enum {
|
|
GST_SCHEDULING_FLAG_SEEKABLE = (1 << 0),
|
|
GST_SCHEDULING_FLAG_SEQUENTIAL = (1 << 1)
|
|
} GstSchedulingFlags;
|
|
|
|
_SEEKABLE:
|
|
- the offset of a pull operation can be specified, if this flag is false,
|
|
the offset should be -1,
|
|
|
|
_SEQUENTIAL:
|
|
- suggest sequential access to the data. If _SEEKABLE is specified,
|
|
seeks are allowed but should be avoided. This is common for network
|
|
streams.
|
|
|
|
(out) "minsize", G_TYPE_INT (default 1)
|
|
- the suggested minimum size of pull requests
|
|
|
|
(out) "maxsize", G_TYPE_INT (default -1, unlimited)
|
|
- the suggested maximum size of pull requests
|
|
|
|
(out) "align", G_TYPE_INT (default 0)
|
|
- the suggested alignment for the pull requests.
|
|
|
|
|
|
|
|
Plug-in techniques
|
|
~~~~~~~~~~~~~~~~~~
|
|
|
|
Multi-sink elements
|
|
^^^^^^^^^^^^^^^^^^^
|
|
|
|
Elements with multiple sinks can either expose a loop function on each of the pads to
|
|
actively pull_range data or they can expose a chain function on each pad.
|
|
|
|
Implementing a chain function is usually easy and allows for all possible scheduling
|
|
methods.
|
|
|
|
Pad select
|
|
----------
|
|
|
|
If the chain based sink wants to wait for one of the pads to receive a buffer, just
|
|
implement the action to perform in the chain function. Be aware that the action could
|
|
be performed in different threads and possibly simultaneously so grab the STREAM_LOCK.
|
|
|
|
Collect pads
|
|
------------
|
|
|
|
If the chain based sink pads all require one buffer before the element can operate on
|
|
the data, collect all the buffers in the chain function and perform the action when
|
|
all chainpads received the buffer.
|
|
|
|
In this case you probably also don't want to accept more data on a pad that has a buffer
|
|
queued. This can easily be done with the following code snippet:
|
|
|
|
static GstFlowReturn _chain (GstPad *pad, GstBuffer *buffer)
|
|
{
|
|
LOCK (mylock);
|
|
while (pad->store != NULL) {
|
|
WAIT (mycond, mylock);
|
|
}
|
|
pad->store = buffer;
|
|
SIGNAL (mycond);
|
|
UNLOCK (mylock);
|
|
|
|
return GST_FLOW_OK;
|
|
}
|
|
|
|
static void _pull (GstPad *pad, GstBuffer **buffer)
|
|
{
|
|
LOCK (mylock);
|
|
while (pad->store == NULL) {
|
|
WAIT (mycond, mylock);
|
|
}
|
|
**buffer = pad->store;
|
|
pad->store = NULL;
|
|
SIGNAL (mycond);
|
|
UNLOCK (mylock);
|
|
}
|
|
|
|
|
|
Cases
|
|
~~~~~
|
|
|
|
Inside the braces below the pads is stated what function the
|
|
pad support:
|
|
|
|
l: exposes a loop function, so it can act as a pushing source.
|
|
g: exposes a getrange function
|
|
c: exposes a chain function
|
|
|
|
following scheduling decisions are made based on the scheduling
|
|
methods exposed by the pads:
|
|
|
|
(g) - (l): sinkpad will pull data from src
|
|
(l) - (c): srcpad actively pushes data to sinkpad
|
|
() - (c): srcpad will push data to sinkpad.
|
|
|
|
() - () : not schedulable.
|
|
() - (l): not schedulable.
|
|
(g) - () : not schedulable.
|
|
(g) - (c): not schedulable.
|
|
(l) - () : not schedulable.
|
|
(l) - (l): not schedulable
|
|
|
|
() - (g): impossible
|
|
(g) - (g): impossible.
|
|
(l) - (g): impossible
|
|
(c) - () : impossible
|
|
(c) - (g): impossible
|
|
(c) - (l): impossible
|
|
(c) - (c): impossible
|
|
|
|
+---------+ +------------+ +-----------+
|
|
| filesrc | | mp3decoder | | audiosink |
|
|
| src--sink src--sink |
|
|
+---------+ +------------+ +-----------+
|
|
(l-g) (c) () (c)
|
|
|
|
When activating the pads:
|
|
|
|
* audiosink has a chain function and the peer pad has no
|
|
loop function, no scheduling is done.
|
|
* mp3decoder and filesrc expose an (l) - (c) connection,
|
|
a thread is created to call the srcpad loop function.
|
|
|
|
+---------+ +------------+ +----------+
|
|
| filesrc | | avidemuxer | | fakesink |
|
|
| src--sink src--sink |
|
|
+---------+ +------------+ +----------+
|
|
(l-g) (l) () (c)
|
|
|
|
* fakesink has a chain function and the peer pad has no
|
|
loop function, no scheduling is done.
|
|
* avidemuxer and filesrc expose an (g) - (l) connection,
|
|
a thread is created to call the sinkpad loop function.
|
|
|
|
+---------+ +----------+ +------------+ +----------+
|
|
| filesrc | | identity | | avidemuxer | | fakesink |
|
|
| src--sink src--sink src--sink |
|
|
+---------+ +----------+ +------------+ +----------+
|
|
(l-g) (c) () (l) () (c)
|
|
|
|
* fakesink has a chain function and the peer pad has no
|
|
loop function, no scheduling is done.
|
|
* avidemuxer and identity expose no schedulable connection so
|
|
this pipeline is not schedulable.
|
|
|
|
+---------+ +----------+ +------------+ +----------+
|
|
| filesrc | | identity | | avidemuxer | | fakesink |
|
|
| src--sink src--sink src--sink |
|
|
+---------+ +----------+ +------------+ +----------+
|
|
(l-g) (c-l) (g) (l) () (c)
|
|
|
|
* fakesink has a chain function and the peer pad has no
|
|
loop function, no scheduling is done.
|
|
* avidemuxer and identity expose an (g) - (l) connection,
|
|
a thread is created to call the sinkpad loop function.
|
|
* identity knows the srcpad is getrange based and uses the
|
|
thread from avidemux to getrange data from filesrc.
|
|
|
|
+---------+ +----------+ +------------+ +----------+
|
|
| filesrc | | identity | | oggdemuxer | | fakesink |
|
|
| src--sink src--sink src--sink |
|
|
+---------+ +----------+ +------------+ +----------+
|
|
(l-g) (c) () (l-c) () (c)
|
|
|
|
* fakesink has a chain function and the peer pad has no
|
|
loop function, no scheduling is done.
|
|
* oggdemuxer and identity expose an () - (l-c) connection,
|
|
oggdemux has to operate in chain mode.
|
|
* identity chan only work chain based and so filesrc creates
|
|
a thread to push data to identity.
|
|
|
|
|