3 The scheduling in GStreamer is based on pads actively pushing
4 (producing) data or pulling (consuming) data from other pads.
8 A pad can produce data and push it to the next pad. A pad that behaves
9 this way exposes a loop function that will be repeatedly called until it
10 returns false. This loop function is allowed to block whenever it wants.
11 When the pad is deactivated the loop function should unblock though.
13 A pad operating in the push mode can only produce data to a pad that
14 exposes a chain function. This chain function will be called with the
15 buffer produced by the pushing pad.
17 This method of producing data is called the streaming mode since the
18 producer produces a constant stream of data.
22 Pads that operate in pulling mode can only pull data from a pad that
23 exposes the `pull_range()` function. In this case, the sink pad exposes a
24 loop function that will be called repeatedly until the task is stopped.
26 After pulling data from the peer pad, the loop function will typically
27 call the push function to push the result to the peer sinkpad.
29 ## Deciding the scheduling mode
31 When a pad is activated, the `_activate()` function is called. The pad
32 can then choose to activate itself in push or pull mode depending on
33 upstream capabilities.
35 The GStreamer core will by default activate pads in push mode when there
36 is no activate function for the pad.
40 The chain function will be called when a upstream element performs a
41 `_push()` on the pad. The upstream element can be another chain based
42 element or a pushing source.
44 ## The getrange function
46 The getrange function is called when a peer pad performs a
47 `_pull_range()` on the pad. This downstream pad can be a pulling element
48 or another `_pull_range()` based element.
52 A sinkpad can ask the upstream srcpad for its scheduling attributes. It
53 does this with the `SCHEDULING` query.
55 * (out) **`modes`**: `G_TYPE_ARRAY` (default NULL): an array of `GST_TYPE_PAD_MODE` enums. Contains all the supported scheduling modes.
57 * (out) **`flags`**, `GST_TYPE_SCHEDULING_FLAGS` (default 0):
61 GST_SCHEDULING_FLAG_SEEKABLE = (1 << 0),
62 GST_SCHEDULING_FLAG_SEQUENTIAL = (1 << 1),
63 GST_SCHEDULING_FLAG_BANDWIDTH_LIMITED = (1 << 2)
68 * **`_SEEKABLE`**: the offset of a pull operation can be specified, if this
69 flag is false, the offset should be -1.
71 * **`_SEQUENTIAL`**: suggest sequential access to the data. If `_SEEKABLE`
72 is specified, seeks are allowed but should be avoided. This is common for
75 * **`_BANDWIDTH_LIMITED`**: suggest the element supports buffering data for
76 downstream to cope with bandwidth limitations. If this flag is on, the
77 downstream element might ask for more data than necessary for normal
78 playback. This use-case is interesting for on-disk buffering scenarios for
79 instance. Seek operations might be slow as well so downstream elements
80 should take this into consideration.
82 * (out) **`minsize`**: `G_TYPE_INT` (default 1): the suggested minimum size of pull requests
83 * (out) **`maxsize`**: `G_TYPE_INT` (default -1, unlimited): the suggested maximum size of pull requests
84 * (out) **`align`**: `G_TYPE_INT` (default 0): the suggested alignment for the pull requests.
88 ### Multi-sink elements
90 Elements with multiple sinks can either expose a loop function on each
91 of the pads to actively `pull_range` data or they can expose a chain
94 Implementing a chain function is usually easy and allows for all
95 possible scheduling methods.
99 If the chain based sink wants to wait for one of the pads to receive a buffer, just
100 implement the action to perform in the chain function. Be aware that the action could
101 be performed in different threads and possibly simultaneously so grab the `STREAM_LOCK`.
105 If the chain based sink pads all require one buffer before the element can operate on
106 the data, collect all the buffers in the chain function and perform the action when
107 all chainpads received the buffer.
109 In this case you probably also don't want to accept more data on a pad that has a buffer
110 queued. This can easily be done with the following code snippet:
113 static GstFlowReturn _chain (GstPad *pad, GstBuffer *buffer)
116 while (pad->store != NULL) {
117 WAIT (mycond, mylock);
126 static void _pull (GstPad *pad, GstBuffer **buffer)
129 while (pad->store == NULL) {
130 WAIT (mycond, mylock);
132 **buffer = pad->store;
141 Inside the braces below the pads is stated what function the pad
144 * l: exposes a loop function, so it can act as a pushing source.
145 * g: exposes a getrange function
146 * c: exposes a chain function
148 Following scheduling decisions are made based on the scheduling methods exposed
151 * (g) - (l): sinkpad will pull data from src
152 * (l) - (c): srcpad actively pushes data to sinkpad
153 * () - (c): srcpad will push data to sinkpad.
155 * () - () : not schedulable.
156 * () - (l): not schedulable.
157 * (g) - () : not schedulable.
158 * (g) - (c): not schedulable.
159 * (l) - () : not schedulable.
160 * (l) - (l): not schedulable
162 * () - (g): impossible
163 * (g) - (g): impossible.
164 * (l) - (g): impossible
165 * (c) - () : impossible
166 * (c) - (g): impossible
167 * (c) - (l): impossible
168 * (c) - (c): impossible
171 +---------+ +------------+ +-----------+
172 | filesrc | | mp3decoder | | audiosink |
173 | src--sink src--sink |
174 +---------+ +------------+ +-----------+
178 When activating the pads:
180 - audiosink has a chain function and the peer pad has no loop
181 function, no scheduling is done.
183 - mp3decoder and filesrc expose an (l) - (c) connection, a thread is
184 created to call the srcpad loop function.
187 +---------+ +------------+ +----------+
188 | filesrc | | avidemuxer | | fakesink |
189 | src--sink src--sink |
190 +---------+ +------------+ +----------+
194 - fakesink has a chain function and the peer pad has no loop function,
195 no scheduling is done.
197 - avidemuxer and filesrc expose an (g) - (l) connection, a thread is
198 created to call the sinkpad loop function.
201 +---------+ +----------+ +------------+ +----------+
202 | filesrc | | identity | | avidemuxer | | fakesink |
203 | src--sink src--sink src--sink |
204 +---------+ +----------+ +------------+ +----------+
205 (l-g) (c) () (l) () (c)
208 - fakesink has a chain function and the peer pad has no loop function,
209 no scheduling is done.
211 - avidemuxer and identity expose no schedulable connection so this
212 pipeline is not schedulable.
215 +---------+ +----------+ +------------+ +----------+
216 | filesrc | | identity | | avidemuxer | | fakesink |
217 | src--sink src--sink src--sink |
218 +---------+ +----------+ +------------+ +----------+
219 (l-g) (c-l) (g) (l) () (c)
222 - fakesink has a chain function and the peer pad has no loop function,
223 no scheduling is done.
225 - avidemuxer and identity expose an (g) - (l) connection, a thread is
226 created to call the sinkpad loop function.
228 - identity knows the srcpad is getrange based and uses the thread from
229 avidemux to getrange data from filesrc.
232 +---------+ +----------+ +------------+ +----------+
233 | filesrc | | identity | | oggdemuxer | | fakesink |
234 | src--sink src--sink src--sink |
235 +---------+ +----------+ +------------+ +----------+
236 (l-g) (c) () (l-c) () (c)
239 - fakesink has a chain function and the peer pad has no loop function,
240 no scheduling is done.
242 - oggdemuxer and identity expose an () - (l-c) connection, oggdemux
243 has to operate in chain mode.
245 - identity chan only work chain based and so filesrc creates a thread