OUTDATED
--------

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.
