2005-03-28 14:54:33 +00:00
|
|
|
States
|
|
|
|
======
|
|
|
|
|
|
|
|
Both elements and pads can be in different states. The states of the pads are
|
|
|
|
linked to the state of the element so the design of the states is mainly
|
|
|
|
focused around the element states.
|
|
|
|
|
|
|
|
An element can be in 4 states. NULL, READY, PAUSED and PLAYING. When an element
|
|
|
|
is initially instantiated, it is in the NULL state.
|
|
|
|
|
|
|
|
|
|
|
|
State definitions
|
|
|
|
-----------------
|
|
|
|
|
|
|
|
- NULL: This is the initial state of an element.
|
|
|
|
- READY: The element should be prepared to go to PAUSED.
|
|
|
|
- PAUSED: The element should be ready to accept and process data. Sink
|
|
|
|
elements however only accept one buffer and then block.
|
|
|
|
- PLAYING: The same as PAUSED except for sinks, who are now accepting
|
|
|
|
and rendering data.
|
|
|
|
|
|
|
|
We call the sequence NULL->PLAYING an upwards state change and PLAYING->NULL
|
|
|
|
a downwards state change.
|
|
|
|
|
|
|
|
|
|
|
|
State variables
|
|
|
|
---------------
|
|
|
|
|
|
|
|
An element has a special lock to manage the state changes. This lock is called
|
|
|
|
the STATE_LOCK.
|
|
|
|
|
|
|
|
The STATE_LOCK protects 3 element variables:
|
|
|
|
|
|
|
|
- STATE
|
|
|
|
- PENDING_STATE
|
|
|
|
- STATE_ERROR flag
|
2005-06-30 09:33:45 +00:00
|
|
|
- NO_PREROLL flag
|
2005-03-28 14:54:33 +00:00
|
|
|
|
|
|
|
The STATE always reflects the current state of the element. The PENDING_STATE
|
|
|
|
always reflects the required state of the element. The PENDING_STATE can be
|
|
|
|
VOID_PENDING if the element is in the right state. The STATE_ERROR flag
|
|
|
|
indicates that an error occured while doing the last state change.
|
|
|
|
|
2005-06-30 09:33:45 +00:00
|
|
|
The NO_PREROLL flag indicates that the element said it was not able to preroll
|
|
|
|
in its last state change. This flag is used in live sources.
|
|
|
|
|
2005-03-28 14:54:33 +00:00
|
|
|
|
|
|
|
Setting state on elements
|
|
|
|
-------------------------
|
|
|
|
|
|
|
|
The state of an element can be changed with _element_set_state(). When chaning
|
|
|
|
the state of an element all intermediate states will also be set on the element
|
|
|
|
until the final desired state is set.
|
|
|
|
|
|
|
|
The _set_state() function can return 3 possible values:
|
|
|
|
|
|
|
|
GST_STATE_FAILURE: The state change failed for some reason. The plugin should
|
|
|
|
have posted an error message on the bus with information.
|
|
|
|
|
|
|
|
GST_STATE_SUCCESS: The state change is completed successfully.
|
|
|
|
|
|
|
|
GST_STATE_ASYNC: The state change will complete later on. This can happen
|
|
|
|
When the element needs a long time to perform the state
|
|
|
|
change or for sinks that need to receive the first buffer
|
|
|
|
before they can complete the state change (preroll).
|
|
|
|
|
2005-06-23 10:37:09 +00:00
|
|
|
GST_STATE_NO_PREROLL: The state change is completed successfully but the element
|
|
|
|
will not be able to produce data in the PAUSED state.
|
|
|
|
|
|
|
|
In the case of an async state change, it is possible to proceed to the next
|
|
|
|
state before the current state change completed. After receiving an ASYNC return
|
2005-03-28 14:54:33 +00:00
|
|
|
value, you can use _element_get_state() to poll the status of the element.
|
|
|
|
|
|
|
|
When setting the state of an element, the PENDING_STATE is set to the required
|
|
|
|
state and the STATE_ERROR flag is cleared. Then the state change function of the
|
|
|
|
element is called and the result of that function is used to update the STATE,
|
|
|
|
PENDING_STATE and STATE_ERROR flags. If the function returned ASYNC, this result
|
|
|
|
is immediatly returned to the caller.
|
|
|
|
|
|
|
|
|
|
|
|
Getting state of elements
|
|
|
|
-------------------------
|
|
|
|
|
|
|
|
The _get_state() function takes 3 arguments, two pointers that will hold the
|
|
|
|
current and pending state and one GTimeVal that holds a timeout value. The
|
|
|
|
function returns a GstElementStateReturn.
|
|
|
|
|
|
|
|
- If the element returned SUCCESS to the previous _set_state() function, this
|
|
|
|
function will return the last state set on the element and VOID_PENDING in
|
2005-06-30 09:33:45 +00:00
|
|
|
the pending state value. The function returns GST_STATE_SUCCESS.
|
|
|
|
|
|
|
|
- If the element returned NO_PREROLL to the previous _set_state() function, this
|
|
|
|
function will return the last state set on the element and VOID_PENDING in
|
|
|
|
the pending state value. The function returns GST_STATE_NO_PREROLL.
|
2005-03-28 14:54:33 +00:00
|
|
|
|
|
|
|
- If the element returned FAILURE to the previous _set_state() call, this
|
|
|
|
funciton will return FAILURE with the state set to the current state of
|
|
|
|
the element and the pending state set to the value used in the last call
|
|
|
|
of _set_state().
|
|
|
|
|
|
|
|
- If the element returned ASYNC to the previous _set_state() call, this function
|
|
|
|
will wait for the element to complete its state change up to the amount of time
|
|
|
|
specified in the GTimeVal.
|
|
|
|
|
|
|
|
* If the element does not complete the state change in the specified amount of
|
|
|
|
time, this function will return ASYNC with the state set to the current state
|
|
|
|
and the pending state set to the pending state.
|
|
|
|
|
|
|
|
* If the element completes the state change within the specified timeout, this
|
|
|
|
function returns the updated state and VOID_PENDING as the pending state.
|
|
|
|
|
|
|
|
* If the element aborts the ASYNC state change due to an error within the
|
|
|
|
specified timeout, this function returns FAILURE with the state set to last
|
|
|
|
successfull state and pending set to the last attempt. The element should
|
|
|
|
also post an error message on the bus with more information about the problem.
|
|
|
|
|
|
|
|
|
|
|
|
States in GstBin
|
|
|
|
----------------
|
|
|
|
|
|
|
|
A GstBin manages the state of its children. It does this by propagating the state
|
|
|
|
changes performed on it to all of its children. The _set_state() function on a
|
|
|
|
bin will call the _set_state() function on all of its children.
|
|
|
|
|
|
|
|
The children are iterated from the sink elements to the source elements. This makes
|
|
|
|
sure that when changing the state of an element, the downstream elements are in
|
|
|
|
the correct state to process the eventual buffers. In the case of a downwards
|
|
|
|
state change, the sink elements will shut down first which makes the upstream
|
|
|
|
elements shut down as well since the _push() function returns a GST_FLOW_WRONG_STATE
|
|
|
|
error.
|
|
|
|
|
|
|
|
If all the children return SUCCESS, the function returns SUCCESS as well.
|
|
|
|
|
|
|
|
If one of the children returns FAILURE, the function returns FAILURE as well. In
|
|
|
|
this state it is possible that some elements successfuly changed state. The
|
|
|
|
application can check which elements have a changed state, which were in error
|
|
|
|
and which were not affected by iterating the elements and calling _get_state()
|
|
|
|
on the elements.
|
|
|
|
|
|
|
|
If after calling the state function on all children, one of the children returned
|
|
|
|
ASYNC, the function returns ASYNC as well.
|
|
|
|
|
2005-06-23 10:37:09 +00:00
|
|
|
If after calling the state function on all children, one of the children returned
|
|
|
|
NO_PREROLL, the function returns NO_PREROLL as well.
|
|
|
|
|
2005-03-28 14:54:33 +00:00
|
|
|
The current state of the bin can be retrieved with _get_state(). This function will
|
2005-06-23 10:37:09 +00:00
|
|
|
call the _get_state() function on all the elements.
|
|
|
|
|
|
|
|
First the bin will perform a _get_state() on all children with a 0 timeout. This
|
2005-06-30 09:33:45 +00:00
|
|
|
is to find any children with an ERROR/NO_PREROLL result value.
|
2005-06-23 10:37:09 +00:00
|
|
|
|
|
|
|
Then the bin performs the _get_state() with the requested timeout. The reason for
|
|
|
|
the 2 phases is that when an ERROR or NO_PREROLL result is found, a blocking
|
|
|
|
wait on the sinks might never return.
|
2005-03-28 14:54:33 +00:00
|
|
|
|
|
|
|
The _get_state() function will be called on the children with the same timout value
|
|
|
|
so the function can potentially block timeout*num_children.
|
|
|
|
|
2005-06-23 10:37:09 +00:00
|
|
|
The bin also updates its state variables after polling its children, this means that
|
|
|
|
the state variables of the bin are only updated after calling _get_state() on the bin.
|
|
|
|
|
2005-03-28 14:54:33 +00:00
|
|
|
|
|
|
|
Implementing states in elements
|
|
|
|
-------------------------------
|
|
|
|
|
|
|
|
READY
|
|
|
|
-----
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|