Heavily refactor the sitemap
[platform/upstream/gstreamer.git] / markdown / additional / design / scheduling.md
1 # Scheduling
2
3 The scheduling in GStreamer is based on pads actively pushing
4 (producing) data or pulling (consuming) data from other pads.
5
6 ## Pushing
7
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.
12
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.
16
17 This method of producing data is called the streaming mode since the
18 producer produces a constant stream of data.
19
20 ## Pulling
21
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.
25
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.
28
29 ## Deciding the scheduling mode
30
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.
34
35 The GStreamer core will by default activate pads in push mode when there
36 is no activate function for the pad.
37
38 ## The chain function
39
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.
43
44 ## The getrange function
45
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.
49
50 ## Scheduling Query
51
52 A sinkpad can ask the upstream srcpad for its scheduling attributes. It
53 does this with the `SCHEDULING` query.
54
55 * (out) **`modes`**: `G_TYPE_ARRAY` (default NULL): an array of `GST_TYPE_PAD_MODE` enums. Contains all the supported scheduling modes.
56
57 * (out) **`flags`**, `GST_TYPE_SCHEDULING_FLAGS` (default 0):
58
59 ```c
60 typedef enum {
61   GST_SCHEDULING_FLAG_SEEKABLE           = (1 << 0),
62   GST_SCHEDULING_FLAG_SEQUENTIAL         = (1 << 1),
63   GST_SCHEDULING_FLAG_BANDWIDTH_LIMITED  = (1 << 2)
64 } GstSchedulingFlags;
65 ```
66
67 *
68     * **`_SEEKABLE`**: the offset of a pull operation can be specified, if this
69     flag is false, the offset should be -1.
70
71     * **`_SEQUENTIAL`**: suggest sequential access to the data. If `_SEEKABLE`
72     is specified, seeks are allowed but should be avoided. This is common for
73     network streams.
74
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.
81
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.
85
86 ## Plug-in techniques
87
88 ### Multi-sink elements
89
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
92 function on each pad.
93
94 Implementing a chain function is usually easy and allows for all
95 possible scheduling methods.
96
97 # Pad select
98
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`.
102
103 # Collect pads
104
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.
108
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:
111
112 ``` c
113 static GstFlowReturn _chain (GstPad *pad, GstBuffer *buffer)
114 {
115   LOCK (mylock);
116   while (pad->store != NULL) {
117     WAIT (mycond, mylock);
118   }
119   pad->store = buffer;
120   SIGNAL (mycond);
121   UNLOCK (mylock);
122
123   return GST_FLOW_OK;
124 }
125
126 static void _pull (GstPad *pad, GstBuffer **buffer)
127 {
128   LOCK (mylock);
129   while (pad->store == NULL) {
130     WAIT (mycond, mylock);
131   }
132   **buffer = pad->store;
133   pad->store = NULL;
134   SIGNAL (mycond);
135   UNLOCK (mylock);
136 }
137 ```
138
139 ## Cases
140
141 Inside the braces below the pads is stated what function the pad
142 support:
143
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
147
148 Following scheduling decisions are made based on the scheduling methods exposed
149 by the pads:
150
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.
154
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
161
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
169
170 ```
171 +---------+    +------------+    +-----------+
172 | filesrc |    | mp3decoder |    | audiosink |
173 |        src--sink         src--sink         |
174 +---------+    +------------+    +-----------+
175         (l-g) (c)           ()   (c)
176 ```
177
178 When activating the pads:
179
180   - audiosink has a chain function and the peer pad has no loop
181     function, no scheduling is done.
182
183   - mp3decoder and filesrc expose an (l) - (c) connection, a thread is
184     created to call the srcpad loop function.
185
186 ```
187 +---------+    +------------+    +----------+
188 | filesrc |    | avidemuxer |    | fakesink |
189 |        src--sink         src--sink        |
190 +---------+    +------------+    +----------+
191         (l-g) (l)          ()   (c)
192 ```
193
194   - fakesink has a chain function and the peer pad has no loop function,
195     no scheduling is done.
196
197   - avidemuxer and filesrc expose an (g) - (l) connection, a thread is
198     created to call the sinkpad loop function.
199
200 ```
201 +---------+    +----------+    +------------+    +----------+
202 | filesrc |    | identity |    | avidemuxer |    | fakesink |
203 |        src--sink       src--sink         src--sink        |
204 +---------+    +----------+    +------------+    +----------+
205         (l-g) (c)        ()   (l)          ()   (c)
206 ```
207
208   - fakesink has a chain function and the peer pad has no loop function,
209     no scheduling is done.
210
211   - avidemuxer and identity expose no schedulable connection so this
212     pipeline is not schedulable.
213
214 ```
215 +---------+    +----------+    +------------+    +----------+
216 | filesrc |    | identity |    | avidemuxer |    | fakesink |
217 |        src--sink       src--sink         src--sink        |
218 +---------+    +----------+    +------------+    +----------+
219         (l-g) (c-l)      (g)  (l)          ()   (c)
220 ```
221
222   - fakesink has a chain function and the peer pad has no loop function,
223     no scheduling is done.
224
225   - avidemuxer and identity expose an (g) - (l) connection, a thread is
226     created to call the sinkpad loop function.
227
228   - identity knows the srcpad is getrange based and uses the thread from
229     avidemux to getrange data from filesrc.
230
231 ```
232 +---------+    +----------+    +------------+    +----------+
233 | filesrc |    | identity |    | oggdemuxer |    | fakesink |
234 |        src--sink       src--sink         src--sink        |
235 +---------+    +----------+    +------------+    +----------+
236         (l-g) (c)        ()   (l-c)        ()   (c)
237 ```
238
239   - fakesink has a chain function and the peer pad has no loop function,
240     no scheduling is done.
241
242   - oggdemuxer and identity expose an () - (l-c) connection, oggdemux
243     has to operate in chain mode.
244
245   - identity chan only work chain based and so filesrc creates a thread
246     to push data to it.