[gst-devel] concept of state (was: of bins)
in7y118 at public.uni-hamburg.de
in7y118 at public.uni-hamburg.de
Mon Oct 6 06:58:07 CEST 2003
I'm in the mood of writing everything I know and how I think it should work
about states. Not everything currently works like that, I would call that bugs.
If you disagree with anything I say, well that's why I post it: Let's discuss.
Someone might even put this into the docs later on, I'm in such a mood.
GStreamer elements know 4 states: GST_STATE_NULL, GST_STATE_READY,
GST_STATE_PAUSED and GST_STATE_PLAYING. To understand what each of these states
mean, you must understand what is done when the state changes. State changes
are handled stepwise inside an element. Each element class has a change_state
handler that takes care of this.
Let's have a look at the different states and state changes.
This is a "naked" element. A newly created element will be in this state.
Creation of an element will always succeed given enough memory. In this state
you can't really do much more but query information about supported media
types, püroperties or pads.
GST_STATE_NULL <=> GST_STATE_READY
Here the element is supposed to initalize or finalize everything it needs
external to GStreamer. Examples for this are input/output elements
opening/closing their devices or files or the Xvideo output connecting
to/disconnecting from the X server.
The only difference to GST_STATE_NULL is that you can now query a bit more
information, because external information is available. The Xvideo output
luginb will now be able to tell you the formats Xvideo supports. And sound
outputs will tell you what formats the sound card supports. Note however that
devices are opened in this state. The sound card will be blocked if an output
plugin accesses it directly.
GST_STATE_READY <=> GST_STATE_PAUSED
Now connections to other elements are (de)initialized. The most notable thing
going on is caps negotiation. Note that going back to READY resets the stream
to the beginning as it destroys all inter-element information.
An element in this state is fully initialized but not actively processing
anything. Everything it needs is completely set up, it may even be in the
middle of some data crunching, but the active processing is stopped.
GST_STATE_PAUSED <=> GST_STATE_PLAYING
This sets up the element itself for data processing. This includes making sure
the scheduler is aware of scheduling this element and so on.
The element is now actively processing data and may at any time be scheduled by
the scheduler to output buffers.
Element states can be set by calling gst_element_set_state().
gst_element_set_state() is threadsafe (FIXME, it isn't!) and can be used to set
any possible state. It will take care of making these changes step-by-step. It
returns one of 3 return values: GST_STATE_SUCCESS indicates that everything
worked as expected, GST_STATE_LOCKED indicates that no error occured, but the
element did not change state (examples for this can be found below) and
GST_STATE_FAILURE indicates an error. In the case of GST_STATE_FAILURE the
current state of the element is undefined and should be queried using
gst_elment_get_state() when it is needed.
A special attention should be given to container elements (like bins, threads
or pipelines). The state of a container element always equals the highest state
of all contained elements or GST_STATE_NULL if the element contains no children.
If you call gst_element_set_state() on a container, the container will try to
set all of its children to this state regardless of its own state or the state
of its children. If one of the children returns GST_STATE_FAILURE, it will then
abort with GST_STATE_FAILURE, cleanup is then up to the application. If no
child reports an error, it will return GST_STATE_SUCCESS if its state matches
the requested state and GST_STATE_LOCKED if not.
Note that this allows some funny incidents:
- Changing an empty container element to any state but GST_STATE_NULL will
always make that bin return GST_STATE_LOCKED.
- Changing a bin in GST_STATE_PLAYING to the same state might result in
GST_STATE_FAILURE even though the bin's state did not change. This will happen
when a child element, that previously was not in this state failed to change
Another possibility is locking the state of elements. You can use the function
gst_element_set_locked_state() to lock or unlock elements. Locked elements will
not change state when calling gstt_element_set_state() on them. Instead they
will keep their state and always return GST_STATE_LOCKED, even when you want to
set their state to the state they currently are in.
Quoting Thomas Vander Stichele <thomas at apestaart.org>:
> What do you think ?
More information about the gstreamer-devel