docs/design/: Some more tweeks and additions to the docs.
[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 variables
27 ---------------
28
29 An element has a special lock to manage the state changes. This lock is called
30 the STATE_LOCK. 
31
32 The STATE_LOCK protects 3 element variables:
33
34   - STATE
35   - PENDING_STATE 
36   - STATE_ERROR flag
37   - NO_PREROLL flag
38
39 The STATE always reflects the current state of the element. The PENDING_STATE
40 always reflects the required state of the element. The PENDING_STATE can be
41 VOID_PENDING if the element is in the right state. The STATE_ERROR flag 
42 indicates that an error occured while doing the last state change.
43
44 The NO_PREROLL flag indicates that the element said it was not able to preroll
45 in its last state change. This flag is used in live sources.
46
47
48 Setting state on elements
49 -------------------------
50
51 The state of an element can be changed with _element_set_state(). When chaning
52 the state of an element all intermediate states will also be set on the element
53 until the final desired state is set.
54
55 The _set_state() function can return 3 possible values:
56
57   GST_STATE_FAILURE: The state change failed for some reason. The plugin should
58                      have posted an error message on the bus with information.
59   
60   GST_STATE_SUCCESS: The state change is completed successfully.
61
62   GST_STATE_ASYNC:   The state change will complete later on. This can happen 
63                      When the element needs a long time to perform the state
64                      change or for sinks that need to receive the first buffer
65                      before they can complete the state change (preroll).
66
67   GST_STATE_NO_PREROLL: The state change is completed successfully but the element
68                      will not be able to produce data in the PAUSED state.
69
70 In the case of an async state change, it is possible to proceed to the next
71 state before the current state change completed. After receiving an ASYNC return
72 value, you can use _element_get_state() to poll the status of the element.
73
74 When setting the state of an element, the PENDING_STATE is set to the required 
75 state and the STATE_ERROR flag is cleared. Then the state change function of the
76 element is called and the result of that function is used to update the STATE,
77 PENDING_STATE and STATE_ERROR flags. If the function returned ASYNC, this result
78 is immediatly returned to the caller.
79
80
81 Getting state of elements
82 -------------------------
83
84 The _get_state() function takes 3 arguments, two pointers that will hold the
85 current and pending state and one GTimeVal that holds a timeout value. The 
86 function returns a GstElementStateReturn.
87
88  - If the element returned SUCCESS to the previous _set_state() function, this
89    function will return the last state set on the element and VOID_PENDING in
90    the pending state value. The function returns GST_STATE_SUCCESS.
91
92  - If the element returned NO_PREROLL to the previous _set_state() function, this
93    function will return the last state set on the element and VOID_PENDING in
94    the pending state value. The function returns GST_STATE_NO_PREROLL.
95
96  - If the element returned FAILURE to the previous _set_state() call, this 
97    funciton will return FAILURE with the state set to the current state of
98    the element and the pending state set to the value used in the last call
99    of _set_state().
100
101  - If the element returned ASYNC to the previous _set_state() call, this function
102    will wait for the element to complete its state change up to the amount of time
103    specified in the GTimeVal. 
104
105    * If the element does not complete the state change in the specified amount of 
106      time, this function will return ASYNC with the state set to the current state
107      and the pending state set to the pending state.
108
109    * If the element completes the state change within the specified timeout, this 
110      function returns the updated state and VOID_PENDING as the pending state.
111
112    * If the element aborts the ASYNC state change due to an error within the 
113      specified timeout, this function returns FAILURE with the state set to last
114      successfull state and pending set to the last attempt. The element should 
115      also post an error message on the bus with more information about the problem.
116
117
118 States in GstBin
119 ----------------
120
121 A GstBin manages the state of its children. It does this by propagating the state
122 changes performed on it to all of its children.  The _set_state() function on a 
123 bin will call the _set_state() function on all of its children. 
124
125 The children are iterated from the sink elements to the source elements. This makes
126 sure that when changing the state of an element, the downstream elements are in
127 the correct state to process the eventual buffers. In the case of a downwards
128 state change, the sink elements will shut down first which makes the upstream
129 elements shut down as well since the _push() function returns a GST_FLOW_WRONG_STATE
130 error.
131
132 If all the children return SUCCESS, the function returns SUCCESS as well. 
133
134 If one of the children returns FAILURE, the function returns FAILURE as well. In
135 this state it is possible that some elements successfuly changed state. The 
136 application can check which elements have a changed state, which were in error
137 and which were not affected by iterating the elements and calling _get_state()
138 on the elements.
139
140 If after calling the state function on all children, one of the children returned
141 ASYNC, the function returns ASYNC as well. 
142
143 If after calling the state function on all children, one of the children returned
144 NO_PREROLL, the function returns NO_PREROLL as well. 
145
146 The current state of the bin can be retrieved with _get_state(). This function will
147 call the _get_state() function on all the elements. 
148
149 First the bin will perform a _get_state() on all children with a 0 timeout. This
150 is to find any children with an ERROR/NO_PREROLL result value. 
151
152 Then the bin performs the _get_state() with the requested timeout. The reason for
153 the 2 phases is that when an ERROR or NO_PREROLL result is found, a blocking 
154 wait on the sinks might never return.
155
156 The _get_state() function will be called on the children with the same timout value
157 so the function can potentially block timeout*num_children.
158
159 The bin also updates its state variables after polling its children, this means that 
160 the state variables of the bin are only updated after calling _get_state() on the bin.
161
162
163 Implementing states in elements
164 -------------------------------
165
166 READY
167 -----
168
169
170    
171
172