| 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 lenth; | |
| /* 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; | |
| } | |