docs/: Small docs updates.
[platform/upstream/gstreamer.git] / docs / design / part-states.txt
1 States
2 ======
3
4 Both elements and pads can be in different states. The states of the pads are 
5 linked to the state of the element so the design of the states is mainly
6 focused around the element states.
7
8 An element can be in 4 states. NULL, READY, PAUSED and PLAYING. When an element
9 is initially instantiated, it is in the NULL state.
10
11
12 State definitions
13 -----------------
14
15  - NULL:    This is the initial state of an element. 
16  - READY:   The element should be prepared to go to PAUSED.
17  - PAUSED:  The element should be ready to accept and process data. Sink
18             elements however only accept one buffer and then block.
19  - PLAYING: The same as PAUSED except for sinks, who are now accepting
20             and rendering data.
21
22 We call the sequence NULL->PLAYING an upwards state change and PLAYING->NULL
23 a downwards state change.
24
25
26 State transitions
27 -----------------
28
29 the following state changes are possible:
30
31  NULL -> READY
32    - The element must check if the resources it needs are available. 
33      Audiosinks typically try to probe the device.
34
35  READY -> PAUSED
36    - The element opens the device and prepares itself for PLAYING.
37    - the element pads are activated in order to receive data in PAUSED. 
38      streaming threads are started.
39    - some elements might need to return ASYNC and complete the state change
40      when they have enough information. It is a requirement for sinks to
41      return ASYNC and complete the state change when they receive the first
42      buffer or EOS event (prerol). Sinks also block the dataflow when in PAUSED.
43    - a pipeline resets the stream time to 0.
44    - live sources return NO_PREROLL and don't generate data.
45  
46  PAUSED -> PLAYING
47    - most elements ignore this state change.
48    - The pipeline selects a clock and distributes this to all the children
49      before setting them to PLAYING. This means that it is only alowed to
50      synchronize on the clock in the PLAYING state.
51    - The pipeline uses the clock and the stream time to calculate the base time.
52      The base time is distributed to all children when performing the state
53      change.
54    - sink elements stop blocking on the preroll buffer or event and start
55      rendering the data. 
56    - sinks can post the EOS message in the PLAYING state. It is not allowed to
57      post EOS when not in the PLAYING state.
58    - while streaming in PAUSED or PLAYING elements can create and remove 
59      dynamic pads.
60    - live sources start generating data and return SUCCESS.
61
62  PLAYING -> PAUSED
63    - most elements ignore this state change.
64    - The pipeline calculates the stream time based on the last selected clock
65      and the base time. It stores this information to continue playback when
66      going back to the PLAYING state.
67    - sinks unblock any clock wait calls.
68    - sinks return ASYNC from this state change and complete the state change
69      when they receive a buffer or an EOS event.
70    - any queued EOS messages are removed since they will be reposted when going
71      back to the PLAYING state.
72    - live sources stop generating data and return NO_PREROLL.
73
74  PAUSED -> READY
75    - sinks unblock any waits in the preroll.
76    - elements unblock any waits on devices
77    - the element pads are deactivated so that streaming becomes impossible and
78      all streaming threads are stopped. 
79  
80  READY -> NULL
81    - element removes any dynamically created pads
82
83
84 State variables
85 ---------------
86
87 An element has 4 state variables that are protected with the object LOCK:
88
89   - STATE
90   - STATE_NEXT
91   - STATE_PENDING 
92   - STATE_RETURN
93
94 The STATE always reflects the current state of the element. 
95 The STATE_NEXT reflects the next state the element will go to.
96 The STATE_PENDING always reflects the required state of the element. 
97 The STATE_RETURN reflects the last return value of a state change.
98
99 The STATE_NEXT and STATE_PENDING can be VOID_PENDING if the element is in 
100 the right state. 
101
102 An element has a special lock to protect against concurrent invocations of
103 _set_state(), called the STATE_LOCK. 
104
105
106 Setting state on elements
107 -------------------------
108
109 The state of an element can be changed with _element_set_state(). When chaning
110 the state of an element all intermediate states will also be set on the element
111 until the final desired state is set.
112
113 The _set_state() function can return 3 possible values:
114
115   GST_STATE_FAILURE: The state change failed for some reason. The plugin should
116                      have posted an error message on the bus with information.
117   
118   GST_STATE_SUCCESS: The state change is completed successfully.
119
120   GST_STATE_ASYNC:   The state change will complete later on. This can happen 
121                      When the element needs a long time to perform the state
122                      change or for sinks that need to receive the first buffer
123                      before they can complete the state change (preroll).
124
125   GST_STATE_NO_PREROLL: The state change is completed successfully but the element
126                      will not be able to produce data in the PAUSED state.
127
128 In the case of an async state change, it is possible to proceed to the next
129 state before the current state change completed, however, the element will only
130 get to this next state before completing the previous ASYNC state change. 
131 After receiving an ASYNC return value, you can use _element_get_state() to poll 
132 the status of the element. If the polling returns SUCCESS, the element completed
133 the state change to the last requested state with _set_state().
134
135 When setting the state of an element, the STATE_PENDING is set to the required 
136 state. Then the state change function of the element is called and the result of 
137 that function is used to update the STATE and STATE_RETURN fields, STATE_NEXT,
138 STATE_PENDING and STATE_RETURN fields. If the function returned ASYNC, this result
139 is immediatly returned to the caller.
140
141
142 Getting state of elements
143 -------------------------
144
145 The _get_state() function takes 3 arguments, two pointers that will hold the
146 current and pending state and one GstClockTime that holds a timeout value. The 
147 function returns a GstElementStateReturn.
148
149  - If the element returned SUCCESS to the previous _set_state() function, this
150    function will return the last state set on the element and VOID_PENDING in
151    the pending state value. The function returns GST_STATE_SUCCESS.
152
153  - If the element returned NO_PREROLL to the previous _set_state() function, this
154    function will return the last state set on the element and VOID_PENDING in
155    the pending state value. The function returns GST_STATE_NO_PREROLL.
156
157  - If the element returned FAILURE to the previous _set_state() call, this 
158    funciton will return FAILURE with the state set to the current state of
159    the element and the pending state set to the value used in the last call
160    of _set_state().
161
162  - If the element returned ASYNC to the previous _set_state() call, this function
163    will wait for the element to complete its state change up to the amount of time
164    specified in the GstClockTime. 
165
166    * If the element does not complete the state change in the specified amount of 
167      time, this function will return ASYNC with the state set to the current state
168      and the pending state set to the pending state.
169
170    * If the element completes the state change within the specified timeout, this 
171      function returns the updated state and VOID_PENDING as the pending state.
172
173    * If the element aborts the ASYNC state change due to an error within the 
174      specified timeout, this function returns FAILURE with the state set to last
175      successfull state and pending set to the last attempt. The element should 
176      also post an error message on the bus with more information about the problem.
177
178
179 States in GstBin
180 ----------------
181
182 A GstBin manages the state of its children. It does this by propagating the state
183 changes performed on it to all of its children.  The _set_state() function on a 
184 bin will call the _set_state() function on all of its children. 
185
186 The children are iterated from the sink elements to the source elements. This makes
187 sure that when changing the state of an element, the downstream elements are in
188 the correct state to process the eventual buffers. In the case of a downwards
189 state change, the sink elements will shut down first which makes the upstream
190 elements shut down as well since the _push() function returns a GST_FLOW_WRONG_STATE
191 error.
192
193 If all the children return SUCCESS, the function returns SUCCESS as well. 
194
195 If one of the children returns FAILURE, the function returns FAILURE as well. In
196 this state it is possible that some elements successfuly changed state. The 
197 application can check which elements have a changed state, which were in error
198 and which were not affected by iterating the elements and calling _get_state()
199 on the elements.
200
201 If after calling the state function on all children, one of the children returned
202 ASYNC, the function returns ASYNC as well. 
203
204 If after calling the state function on all children, one of the children returned
205 NO_PREROLL, the function returns NO_PREROLL as well. 
206
207 The current state of the bin can be retrieved with _get_state(). 
208
209 If the bin is performing an ASYNC state change, it will automatically update its
210 current state fields when it receives state messages from the children.
211
212
213 Implementing states in elements
214 -------------------------------
215
216 READY
217 -----
218
219
220
221 upward state change
222 -------------------
223
224 Upward state changes always return ASYNC either if the STATE_PENDING is
225 reached or not.
226
227 Element:
228
229   A -> B => SUCCESS 
230     - commit state
231
232   A -> B => ASYNC 
233     - no commit state
234     - element commits state ASYNC
235
236   A -> B while ASYNC
237     - update STATE_PENDING state
238     - no commit state
239     - no change_state called on element
240
241 Bin:
242
243   A->B: all elements SUCCESS
244     - commit state
245
246   A->B: some elements ASYNC
247     - no commit state
248     - listen for commit messages on bus
249     - for each commit message, poll elements
250     - if no ASYNC elements, commit state, continue state change 
251       to STATE_PENDING
252
253 downward state change
254 ----------------------
255
256 Downward state changes only return ASYNC if the final state is ASYNC.
257 This is to make sure that it's not needed to wait for an element to
258 complete the preroll or other ASYNC state changes when one only wants to
259 shut down an element.
260
261 Element:
262
263   A -> B => SUCCESS 
264     - commit state
265
266   A -> B => ASYNC not final state
267     - commit state on behalf of element
268
269   A -> B => ASYNC final state
270     - element will commit ASYNC 
271
272 Bin:
273   
274   A -> B -> SUCCESS
275     - commit state
276
277   A -> B -> ASYNC not final state
278     - commit state on behalf of element, continue state change
279
280   A -> B => ASYNC final state
281     - no commit state
282     - listen for commit messages on bus
283     - for each commit message, poll elements
284     - if no ASYNC elements, commit state
285
286
287 Locking overview (element)
288 --------------------------
289
290 * Element commiting SUCCESS
291
292  - STATE_LOCK is taken in set_state
293  - change state is called if SUCCESS, commit state is called
294  - commit state calls change_state to next state change.
295  - if final state is reached, stack unwinds and result is returned to 
296    set_state and caller.
297
298
299  set_state(element)       change_state (element)   commit_state
300
301       |                         |                       |
302       |                         |                       |
303   STATE_LOCK                    |                       |
304       |                         |                       |
305       |------------------------>|                       | 
306       |                         |                       | 
307       |                         |                       | 
308       |                         | (do state change)     |
309       |                         |                       |
310       |                         |                       |
311       |                         | if SUCCESS            |
312       |                         |---------------------->|
313       |                         |                       | post message
314       |                         |                       |
315       |                         |<----------------------| if (!final) change_state (next)
316       |                         |                       | else SIGNAL
317       |                         |                       |
318       |                         |                       |
319       |                         |                       |
320       |<------------------------|                       |
321       |     SUCCESS               
322       | 
323   STATE_UNLOCK
324       |      
325     SUCCESS   
326            
327
328
329 * Element commiting ASYNC
330
331  - STATE_LOCK is taken in set_state
332  - change state is called and returns ASYNC
333  - ASYNC returned to the caller.
334  - element takes STATE_LOCK in streaming thread.
335  - element calls commit_state in streaming thread.
336  - commit state calls change_state to next state change.
337
338
339  set_state(element)       change_state (element)     stream_thread      commit_state (element)
340
341       |                         |                          |                  |
342       |                         |                          |                  |
343   STATE_LOCK                    |                          |                  |
344       |                         |                          |                  |
345       |------------------------>|                          |                  |
346       |                         |                          |                  |
347       |                         |                          |                  |
348       |                         | (start_task)             |                  |
349       |                         |                          |                  |
350       |                         |                     STREAM_LOCK             |
351       |                         |                          |...               |
352       |<------------------------|                          |                  |
353       |     ASYNC                                     STREAM_UNLOCK           |
354   STATE_UNLOCK                                             |                  |       
355       |                .....sync........               STATE_LOCK             |               
356     ASYNC                                                  |----------------->|
357                                                            |                  |
358                                                            |                  |---> post_message()
359                                                            |                  |---> if (!final) change_state (next)
360                                                            |                  |     else SIGNAL
361                                                            |<-----------------|
362                                                        STATE_UNLOCK
363                                                            |
364                                                       STREAM_LOCK
365                                                            | ...
366                                                       STREAM_UNLOCK
367
368 *********************************************
369 *********************************************
370
371 set_state cannot be called from multiple threads at the same time. The STATE_LOCK
372 prevents this.
373
374 state variables are protected with the LOCK.
375
376 calling set_state while gst_state is called should unlock the get_state with
377 an error. The cookie will do that.
378
379
380  set_state(element)
381
382   STATE_LOCK
383
384   LOCK
385   update current, next, pending state
386   cookie++
387   UNLOCK
388
389   change_state
390
391   STATE_UNLOCK
392  
393    
394
395