Since the plan generation only happens as a result of the state mechanism, I'll describe that first. It's supposed to be recursive, such that setting the state on a Bin recursively sets all the children. However, this needs to be rethought somewhat, in light of some recent ideas on the actual definition of some of the states. The mechanism is thus: When you call gst_element_set_state(element,state), it calls the change_state() class method. The basic Element-provided version just sets or unsets the state. A more complex element like the audiosink will switch on the state and do certain things like open or close the sound card on transition to/from various states. The success or failure of these actions can determine whether or not the state gets [un]set as requested. GtkObject signals enter in here, as whenever a state is successfully changed, the STATE_CHANGE signal is fired, which gives higher-level code the ability to do something based on the change. The Bin's change_state function walks through all its children and sets their state. This is where things get interesting, and where things are going to need to be changed. The issue is what the states are and mean. Currently the states are as follows (from gstelement.h): typedef enum { GST_STATE_COMPLETE = (1 << 0), GST_STATE_RUNNING = (1 << 1), GST_STATE_DISCOVERY = (1 << 2), GST_STATE_PREROLL = (1 << 3), GST_STATE_PLAYING = (1 << 4), GST_STATE_PAUSED = (1 << 5), GST_STATE_MAX = (1 << 15), } GstElementState; COMPLETE means all the necesary information is available to run, i.e. the filename for the disksrc, etc. RUNNING means that it's actually doing something, but that's fuzzy. PLAYING means there really is data flowing through the graph, where PAUSED temporary stops the flow. PLAYING && PAUSED is the same idea as !PLAYING, but there are probably going to be many cases where there really is a distinction. DISCOVERY is intended for the autoconnect case, in those instances where the only way to determine the input or output type of some pad is for an element to actually process some data. The idea in that case is that the source element would be responsible for sending the data non-destructively (in the case of a network client, it would have to save it all up, unless it has seek capabilities over the network), and all downstream elements process it in such a way as to not hose their own state. Or rather, when they cease to do discovery, they completely wipe their state as if nothing ever happened. PREROLL is a local state, used for things like sending the first half of an MPEG GOP through the decoder in order to start playback at a frame somewhere in the middle of said GOP. Not sure how that will work, exactly. The issue is that these states aren't layered, and it most certainly isn't the case that a container isn't able to be of a certain state unless all of its children are. I guess I should explain the idea of reconfigurable pipelines: Build an MP3 player, give it the ability to use audio effects plugins. Since you don't want to have to start the stream over again (especially if it's a network stream) every time you change the effect. This means you need to be able to freeze the pipeline in place to change it, without taking too much time. This matters when you consider that certain state changes should render various state bits invalid. In the FROZEN state these won't happen, because the assumption is that they're temporary. If you haven't noticed by now, the state system isn't entirely self-consistent yet. It needs work, and it needs discussion.