INITIAL RAMBLINGS
-----------------

some random ramblings about the event system:

Possible candidates for events
------------------------------

  - QoS
  - EOS
  - Seek
  - caps nego??
  - bufferpool get??
  - ...

Assumptions for events
----------------------

- They are tied to a pad.
- get rid of gst_pad_set_*_function (except for the chain/get ones)
- occur async to dataflow. (need locking?)
- fixed set of events only for core features. (elements cannot abuse
     events for doing dataflow)

Questions
---------

limit the valid directions an event can travel in? ie. Can EOS only 
travel downstream (left to right)? 

eg. Seek travels upstream, but it makes sense to also make it travel 
    downstream (the case of a filesink, where we overwrite the header)


Setting an event function
-------------------------

void gst_pad_set_event_function (GstPad *pad, gint event_mask,
				 GstEventFunction *function);


event masks:

typedef enum {
  GST_EVENT_EOS 		= (1 << 0),
  GST_EVENT_QOS			= (1 << 1),
  GST_EVENT_SEEK		= (1 << 2),
  GST_EVENT_CAPS		= (1 << 3),
} GstEventType;

Event structure
---------------

typedef struct {
  GstEventType type;
  GstEventMinorType minor;
  guint64 timestamp;  /* also sequence number ?? */

  union {
    /* EOS stuff */
    /* QoS stuff */
    /* Seek stuff */
    GstSeekType type; /* time, bytes, ... */
    gint64 offset;
    gint64 length;
    /* Caps stuff */
    GstCaps *caps;
  } data;
} GstEvent;


typedef enum {
  GST_EVENT_MINOR_NONE,
  /* EOS stuff */

  /* QoS stuff */
  /* Seek stuff */
  GST_EVENT_MINOR_OFFSET,
  GST_EVENT_MINOR_TIME,

  /* caps nego stuff */
  GST_EVENT_MINOR_CAPS_TRY,
  GST_EVENT_MINOR_CAPS_START,
  GST_EVENT_MINOR_CAPS_FINAL,
} GstEventMinorType;  


Receiving events
----------------

a sample GstEventFunction, the event functions returns TRUE if the event is handled, 
FALSE otherwise.

gboolean
gst_anelement_handle_event (GstPad *pad, GstEvent *event)
{
  if (event->type == GST_EVENT_EOS) {
    /* do something */
    return TRUE;
  }
  else if (event->type == GST_EVENT_CAPS) {
    if (event->minor == GST_EVENT_CAPS_TRY) {
      /* try using this caps structure */
      return TRUE; /* return FALSE to proxy ???*/
    }
  }
  return FALSE;
}


Default event handler for pads
------------------------------

gboolean
gst_pad_handle_event (GstPad *pad, GstEvent *event)
{
  GstElement *element;
  GList *pads;
  GstPad *srcpad;
  gboolean result = TRUE;
  GstPadDirection dir = GST_PAD_DIRECTION (pad);

  g_return_val_if_fail (pad != NULL, FALSE);
  g_return_val_if_fail (GST_IS_REAL_PAD(pad), FALSE);   // NOTE the restriction

  element = GST_ELEMENT (gst_object_get_parent (GST_OBJECT (pad)));

  /* send out the events to all pad with opposite direction */
  pads = gst_element_get_pad_list(element);
  while (pads) {
    otherpad = GST_PAD(pads->data);
    pads = g_list_next(pads);

    if (gst_pad_get_direction(otherpad) != dir) {
      result &= gst_pad_send_event (GST_REAL_PAD(otherpad), event);
    }
  }

  /* result is combined result of all handlers? */
  return result;
}

  
