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.
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.
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
22 We call the sequence NULL->PLAYING an upwards state change and PLAYING->NULL
23 a downwards state change.
29 An element has a special lock to manage the state changes. This lock is called
32 The STATE_LOCK protects 3 element variables:
38 The STATE always reflects the current state of the element. The PENDING_STATE
39 always reflects the required state of the element. The PENDING_STATE can be
40 VOID_PENDING if the element is in the right state. The STATE_ERROR flag
41 indicates that an error occured while doing the last state change.
44 Setting state on elements
45 -------------------------
47 The state of an element can be changed with _element_set_state(). When chaning
48 the state of an element all intermediate states will also be set on the element
49 until the final desired state is set.
51 The _set_state() function can return 3 possible values:
53 GST_STATE_FAILURE: The state change failed for some reason. The plugin should
54 have posted an error message on the bus with information.
56 GST_STATE_SUCCESS: The state change is completed successfully.
58 GST_STATE_ASYNC: The state change will complete later on. This can happen
59 When the element needs a long time to perform the state
60 change or for sinks that need to receive the first buffer
61 before they can complete the state change (preroll).
63 In the case of an async state change, it is not possible to proceed to the next
64 state until the current state change completed. After receiving an ASYNC return
65 value, you can use _element_get_state() to poll the status of the element.
67 When setting the state of an element, the PENDING_STATE is set to the required
68 state and the STATE_ERROR flag is cleared. Then the state change function of the
69 element is called and the result of that function is used to update the STATE,
70 PENDING_STATE and STATE_ERROR flags. If the function returned ASYNC, this result
71 is immediatly returned to the caller.
74 Getting state of elements
75 -------------------------
77 The _get_state() function takes 3 arguments, two pointers that will hold the
78 current and pending state and one GTimeVal that holds a timeout value. The
79 function returns a GstElementStateReturn.
81 - If the element returned SUCCESS to the previous _set_state() function, this
82 function will return the last state set on the element and VOID_PENDING in
83 the pending state value.
85 - If the element returned FAILURE to the previous _set_state() call, this
86 funciton will return FAILURE with the state set to the current state of
87 the element and the pending state set to the value used in the last call
90 - If the element returned ASYNC to the previous _set_state() call, this function
91 will wait for the element to complete its state change up to the amount of time
92 specified in the GTimeVal.
94 * If the element does not complete the state change in the specified amount of
95 time, this function will return ASYNC with the state set to the current state
96 and the pending state set to the pending state.
98 * If the element completes the state change within the specified timeout, this
99 function returns the updated state and VOID_PENDING as the pending state.
101 * If the element aborts the ASYNC state change due to an error within the
102 specified timeout, this function returns FAILURE with the state set to last
103 successfull state and pending set to the last attempt. The element should
104 also post an error message on the bus with more information about the problem.
110 A GstBin manages the state of its children. It does this by propagating the state
111 changes performed on it to all of its children. The _set_state() function on a
112 bin will call the _set_state() function on all of its children.
114 The children are iterated from the sink elements to the source elements. This makes
115 sure that when changing the state of an element, the downstream elements are in
116 the correct state to process the eventual buffers. In the case of a downwards
117 state change, the sink elements will shut down first which makes the upstream
118 elements shut down as well since the _push() function returns a GST_FLOW_WRONG_STATE
121 If all the children return SUCCESS, the function returns SUCCESS as well.
123 If one of the children returns FAILURE, the function returns FAILURE as well. In
124 this state it is possible that some elements successfuly changed state. The
125 application can check which elements have a changed state, which were in error
126 and which were not affected by iterating the elements and calling _get_state()
129 If after calling the state function on all children, one of the children returned
130 ASYNC, the function returns ASYNC as well.
132 The current state of the bin can be retrieved with _get_state(). This function will
133 call the _get_state() function on all the elements. If one of the children returns
134 FAILURE or ASYNC, the bin reports FAILURE or ASYNC respectively. The bin also
135 updates its state variables after polling its children, this means that the state
136 variables of the bin are only updated after calling _get_state() on the bin.
138 The _get_state() function will be called on the children with the same timout value
139 so the function can potentially block timeout*num_children.
142 Implementing states in elements
143 -------------------------------