What are states?
A state describes whether the element instance is initialized, whether it
is ready to transfer data and whether it is currently handling data. There
are four states defined in &GStreamer;: GST_STATE_NULL,
GST_STATE_READY, GST_STATE_PAUSED
and GST_STATE_PLAYING.
GST_STATE_NULL (from now on referred to as
NULL
) is the default state of an element. In this state, it
has not allocated any runtime resources, it has not loaded any runtime
libraries and it can obviously not handle data.
GST_STATE_READY (from now on referred to as
READY
) is the next state that an element can be in. In the
READY state, an element has all default resources (runtime-libraries,
runtime-memory) allocated. However, it has not yet allocated or defined
anything that is stream-specific. When going from NULL to READY state
(GST_STATE_NULL_TO_READY), an element should
allocate any non-stream-specific resources and should load runtime-loadable
libraries (if any). When going the other way around (from READY to NULL,
GST_STATE_READY_TO_NULL), an element should unload
these libraries and free all allocated resources. Examples of such
resources are hardware devices. Note that files are generally streams,
and these should thus be considered as stream-specific resources; therefore,
they should not be allocated in this state.
GST_STATE_PAUSED (from now on referred to as
PAUSED
) is a state in which an element is by all means able
to handle data; the only 'but' here is that it doesn't actually handle
any data. When going from the READY state into the PAUSED state
(GST_STATE_READY_TO_PAUSED), the element will
usually not do anything at all: all stream-specific info is generally
handled in the _link (), which is called during caps
negotiation. Exceptions to this rule are, for example, files: these are
considered stream-specific data (since one file is one stream), and should
thus be opened in this state change. When going from the PAUSED back to
READY (GST_STATE_PAUSED_TO_READY), all
stream-specific data should be discarded.
GST_STATE_PLAYING (from now on referred to as
PLAYING
) is the highest state that an element can be in. It
is similar to PAUSED, except that now, data is actually passing over the
pipeline. The transition from PAUSED to PLAYING
(GST_STATE_PAUSED_TO_PLAYING) should be as small
as possible and would ideally cause no delay at all. The same goes for the
reverse transition (GST_STATE_PLAYING_TO_PAUSED).
Managing filter state
An element can be notified of state changes through a virtual function
pointer. Inside this function, the element can initialize any sort of
specific data needed by the element, and it can optionally fail to
go from one state to another.
Do not g_assert for unhandled state changes; this is taken care of by
the GstElement base class.
static GstElementStateReturn
gst_my_filter_change_state (GstElement *element);
static void
gst_my_filter_class_init (GstMyFilterClass *klass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
element_class->change_state = gst_my_filter_change_state;
}
static GstElementStateReturn
gst_my_filter_change_state (GstElement *element)
{
GstMyFilter *filter = GST_MY_FILTER (element);
switch (GST_STATE_TRANSITION (element)) {
case GST_STATE_NULL_TO_READY:
if (!gst_my_filter_allocate_memory (filter))
return GST_STATE_FAILURE;
break;
case GST_STATE_READY_TO_NULL:
gst_my_filter_free_memory (filter);
break;
default:
break;
}
if (GST_ELEMENT_CLASS (parent_class)->change_state)
return GST_ELEMENT_CLASS (parent_class)->change_state (element);
return GST_STATE_SUCCESS;
}