diff --git a/docs/random/wtay/events b/docs/random/wtay/events index 2e9b7c5a50..788d154eda 100644 --- a/docs/random/wtay/events +++ b/docs/random/wtay/events @@ -1,140 +1,135 @@ -some random ramblings about the event system: +This is a round up from our IRC session on events. It's open for +discussion of course. + +Definition +---------- + +The event system is designed to be a mechanism for _inter_plugin_ +communication. Their scope is therefore limited in a way that they do +not serve as a way to communicate between plugins and the app (signals +and properties are still used for plugin-app communication). + +Events will be generated by either a plugin or the app. It should be +possible for a plugin to generate an event on one of its pads and it +should be possible for an app to insert an event on an abitrary pad +in the pipeline. + + +Event handling +-------------- + +Events can both travel upstream or downstream. Some events, by nature, only +travel in one direction. + +* downstream events + + - Travel in the same way buffers do. This includes that they are handled + by the scheduler. The rationale is that the events should be kept as close + to the buffers are possible. + + - plugins should check the type of the GstData passed in the _chain or _loop + function and act appropriatly. This can be done by either doing their own + stuff or by calling the default handler. + + - are handled on the sink pad. + +* upstream events + + - are handled with an event handler attached to the srcpad. A default handler + will be implemented for pads that don't implement their own handler. + + - travel as fast as possible. the rationale is that a seek event should get to + the src element ASAP. + Possible candidates for events ------------------------------ - - QoS + - QoS + quality of service. Plugins can notify other plugins about the quality + of the pipeline. A video element can for example say that it receives + too much frames and that plugins connected to it need to slow down. + - EOS + A plugin can notify other plugins that it has run out-of-data. + - Seek + Used to notify plugins that they need to seek to a certain byte offset + or timestamp. + + - discontinuous + A plugin has detected a discontinuity in the stream. Other plugins might + need to resync. + + - flush + Plugins need to get rid of any buffered data ASAP. + - 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) +application generated events +---------------------------- -Questions +The application can insert events into the pipeline at arbirary places. This +will be done by calling gst_pad_event() on a pad. + +A first implementation will only cover inserting events on src pads since +inserting events on sinkpads needs changes to the scheduler. + + +Effects of events on plugins +---------------------------- + +some events are going to change the state of an element. The EOS event will +for example change the state of an element to the PAUSED state. Not sure when +or how this will happen. + + +use cases --------- -limit the valid directions an event can travel in? ie. Can EOS only -travel downstream (left to right)? +1) filesrc ! fakesink -eg. Seek travels upstream, but it makes sense to also make it travel - downstream (the case of a disksink, where we overwrite the header) +filesrc will read until it reaches EOF. It will then create a GstEvent of type +EOS and return it in the _get function. The event will travel downstream and +will reach the fakesink element. Fakesink will detect the event in the _chain +function and will call the default handler. The default handler will set the +element to the paused state. filesrc will eventually change its state to PAUSED, +probably before sending out the event (TBD) + +2) filesrc ! fakesink + +The app wants to perform a seek on filesrc. It'll call the gst_pad_event() on +filesrcs src pad with the SEEK event type. The event handler will react and +change filesrcs internal status. filesrc will return a DISCONT event before +returning the buffer with the new offset. + +3) filesrc ! mpeg2parse video_0! queue ! { mpeg2dec ! xvideosink } + +lost of possibilities here: The app can choose to insert a seek event on the +filesrc element (byte offset), it can insert a byte/time offset seek on the +video_0 pad of mpeg2parse or it can insert a time seek event on mpeg2decs +src pad. + +the event will travel upstream using the handlers and the intermediate elements +can convert the event from a time to a byte offset (possibly using GstTimeCache +to speed up things). + +Filesrc will get a byte seek event on its src pad and will proceed as in case 2. + +As can be seen from this example the app will generate an event in another +context than those of the plugins, so this will need proper locking. + +The app can also choose to insert a flush event on one of the src pads. The +plugins would clear their cached data and forward the event to their upstream +peer pad(s). + +4)... + +Insert impossible case here.. -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; -} - - +