This is the current implementation of events, based on an earlier document, in this same directory, called "events". 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 arbitrary pad or element 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 appropriately. 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 is 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. Plugin generated events ----------------------- We cover the range of events a plugin can generate and how they are supposed to handle them. * EOS when the plugin has no more data to push, it pushes an EOS event and calls gst_element_set_eos. _get based plugins should call gst_element_set_eos() before returning the EOS event. gst_element_set_eos() will put an element into the PAUSED state and will emit the eos signal to the app. Elements receiving the EOS event on a pad should not pull anymore data from that pad (in case of a loop based element). If the plugin cannot operate when it doesn't receive data on that pad, the element should go to EOS too. It does this by pushing any data it might still have, to the srcpad after which it pushes an EOS event on thet pad and calls gst_element_set_eos(). The EOS event will typically originate from a source element, it will eventually put all elements into the PAUSED state so that the pipeline stops. The EOS event is strictly a downstream event. * DISCONTINUOUS The discontinuous event is used to indicate a discontinuity in the stream to downstream elements. A disctontinuity happens for the following reasons: - a source element is sending the first buffers of a stream. - an element has performed a seek operation resulting in a discontinuity in the data. elements that receive a discontinuity event should flush any state they might have and treat the new data as the start of new data. Before sending out the new data the element must send a discont event to the downstream element with at least a GST_FORMAT_TIME or GST_FORMAT_BYTES as the format/value pair (see below). a DISCONTINUOUS event has a flush flag. If that flag is set, the element should also remove any buffered data it might have. In addition to the flush flag, a DISCONTINUOUS event also caries up to GST_DISCONTINUOUS_MAX_FORMATS format/value pairs. These values might be used by the receiver of the event to resynchronize itself. elements that are using a clock must take special actions upon receiving the DISCONTINUOUS event: they must call gst_clock_handle_discont() with the GST_FORMAT_TIME value of the discont event. The DISCONTINUOUS event is strictly a downstream event. * SEEK The seek event is used to reposition the upstream elements to a new position in the media stream. The seek event caries a bitwise-or of a GstFormat and a GstSeekType. An element receiving the seek event on its srcpad should try to reposition itself as closely to the requested location as possible. if the ACCURATE flag is set and it cannot reposition itself with absolute certainty, it should reposition itself well before the requested position. If the ACCURATE flag is not set, the element is free to choose a suitable position in the stream before or after the requested time. If the flush flag is set it should make sure that it pushes the DISCONTINUOUS event the next time it is scheduled, clearing any data it might have buffered. The element is free to set the ACCURACY field in the event to notify the originator of the event of the result. If no accuracy is set, it defaults to FUZZY. The SEEK event is stricly an upstream event. * QOS QoS is sent to indicate Quality of Service to the upstream element(s). The QOS event is stricly an upstream event. * FLUSH A plugin can send a flush event to its src or sink peer to clear the buffered contents in the pipeline. application generated events ---------------------------- The application can insert events into the pipeline at arbitrary places. This is done by calling gst_pad_send_event() on a pad. An application can also insert events on any element. The element can implement its own handler for these events or it can use the default handler, which simply forwards the event to the first connected sinkpad of the element. Events to an element are send using gst_element_send_event(). This first implementation only covers inserting events on src pads since inserting events on sinkpads needs changes to the scheduler. * FLUSH A flush event is used to clear any buffered data an element might have. It is a downstream and upstream event. Flush events are typically inserted into the pipeline by the app. Elements that buffer data should implement an event handler on both the sink and src pads it might have and respond to the flush event by clearing all data they have buffered. * SEEK The application can insert the seek event into the pipeline on a srcpad with gst_pad_send_event () or on an element with gst_element_send_event(). The semantics of the seek parameters are described above. Thread safety ------------- All upstream events can occur outside the element's thread context. It is not required to protect the element's data structures with mutexes because in principal we don't support sending events to a running threaded pipeline. GstQueue in its current form will refuse to pass events upstream if it is in the PLAYING state. Future versions might pass the event on as soon as the element is scheduled again on the sinkpad. An application cannot insert an event on an element that is PLAYING in another thread context. It is therefore strongly recommended to PAUSE the threaded pipeline before inserting an event. use cases --------- 1) filesrc ! fakesink << explain EOS >> 2) filesrc ! fakesink The app wants to perform a seek on filesrc. It'll call the gst_pad_send_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..