From 08faf88f0d2acba4c6c9a0fed794429938df2c3e Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Tue, 29 Jan 2002 23:48:08 +0000 Subject: [PATCH] added event proposal - probably a bit long, you may shorten it, if you can. Original commit message from CVS: added event proposal - probably a bit long, you may shorten it, if you can. --- docs/random/events | 327 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 327 insertions(+) create mode 100644 docs/random/events diff --git a/docs/random/events b/docs/random/events new file mode 100644 index 0000000000..f609ad429a --- /dev/null +++ b/docs/random/events @@ -0,0 +1,327 @@ +EVENTS RFC +========== + + +Scope +----- +This document tries to describe a possible implementation of an event +system for GStreamer that is able to handle all known problems and works +better than the current (0.3.1) system which evolved over time. + + +Definition +---------- + +The event system is designed to be a mechanism for communication between +elements. They are used to get information to the right point when this +point cannot be known in advance. +Events can be generated by either an element or the application and are +processed by elements. + + +Event Handling +-------------- + +Events may be inserted into a pipeline in the PAUSED or PLAYING state. Some +events may travel during the PAUSED state, others may only travel when PLAYING. +The insertion of events during the NULL or READY state should be supported if +at all possible. Events may not be processed in those states though. +After an event is inserted into the pipeline, no assumption may be made on how +the event will be processed. It is eg wrong to assume that an event that is +inserted at the beginning of the pipeline may come out at the end. +There are 3 different directions an event can be processed. + +* downstream events + + Downstream events are inserted on source pads and travel along the pipeline. + They are handled like buffers and processed in order. If event x is inserted + into a pipeline after buffer y, they are guaranteed to travel in that order. + Downstream events therefore only travel when the pipeline is PLAYING. + Downstream events must be handled by the routines that handle buffers, too. + An example downstream event is the event signalling that the stream has ended. + Please keep in mind that downstream events take the same way as buffers. So a + ghost pad will never receive these events. + +* upstream events + + Upstream events are inserted on sink pads and travel backwards through the + pipeline. They travel as fast as possible. Source pads must have a handler + function in place to process events. A default handler is implemented. + An example upstream event is an event that seeks inside the stream. + Please keep in mind that upstream events take the same way as buffers in reverse + direction. This means that ghost pads will never receive them. + +* vertical events + + Vertical events travel from elements to their parents. They are targetted at + the application. Vertical events should be used for information that an + application cannot receive in an easy way by using callbacks or properties. + Vertical events are send to the application by the pipeline that collects those + events and supplies a callback for the application. Vertical events are also only + happening when the pipeline is in PAUSED or PLAZING state. + An example vertical event is the error event informing the application about + unexpected behaviour. + + +The GstEvent object +------------------- + +struct _GstEvent { + GstData data; + + GstEventType type; + guint64 timestamp; + GstObject *src; + + union { + ... + } event_data; +}; + +data: The parent object. +type: The type of the event. GStreamer aims to keep the number of different + plugin types as small as possible. +timestamp: The time when the event was created. This property is used to identify + duplicated events. If the application inserts an event, the timestamp + is set by the element receiving the event from the application. +src: The element that created the event. If an application inserts an event, + the element that received the event from the application sets itself as + the source. +event_data: data specific to the event type. + + +The different event types +------------------------- + +The following names in brackets correspong to the event's type property. + +GST_EVENT_DISCONTINUOUS +direction(s): downstream +event_data: struct { + GstDiscontType type; + } discontinuous; +This event is used to indicate that the current stream does not continue. Possible +indications are a new stream (type = GST_DISCONT_NEW), the happening of a seek +(type = GST_DISCONT_SEEK) or the end of the stream when no more data is available. +(type = GST_DISCONT_EOS) + +GST_EVENT_SEEK +direction(s): upstream +event_data: struct { + GstSeekType type; + gint64 offset; + gboolean flush; + } seek; +This event is used if a seek is needed. Uses include applications or the avi demuxer +element requesting the end of the stream first. The seek can happen absolute (SET), +relative to the current position (CUR) or relative to the end (END). It is possible +to seek by frames (FRAME), time in microseconds (TIME) or bytes (BYTE). This is +indicated by the type field, which takes the values +GST_SEEK_FRAME/TIME/BYTEOFFSET_SET/CUR/END. The offset field indicates how many units +should be seeked. Negative values indicate seeking backwards from the indicated position. +The flush field indicates if buffered data shuold be flushed or discarded. + +GST_EVENT_FLUSH +direction(s): upstream +event_data: none +This event indicates that all buffered data should be flushed out immediately. + +GST_EVENT_INFO +direction(s): downstream, vertical +event_data: struct { + GstProps *props; + } info; +The Info event is used to transport meta information like bitrate, author, title, +interpret or stream length. Most info events will be emitted vertical and downstream +at the same time. Vertical emission ensures that an application knows about those +properties and downstream emission ensures that elements can compute own information +from these infos. (eg converting stream length in bytes to song length in +microseconds). +Props consist of key / value pairs, where the key is a string identifier and the value +is a GstPropEntry. Many key strings are predefined to allow consistency between elements. +Elements should try to suppy any information they can as soon as possible. + +GST_EVENT_HAS_INFO +direction(s): upstream +void (*GstHasInfoCallback) (gchar *name, GstPropsEntry *info, gpointer data); +event_data: struct { + GList *info; + GstHasInfoCallback callback; + gpointer data; + } has_info; +The has_info event might be inserted by an application to find out if a pipeline can supply +the specified infos. the info list contains all information that the application is +interested in. If an element can supply information it calls the supplied callback with the +name of the information it can supply, the information if it is already available or NULL and +the data. If this event is destroyed, it will call the callback with name = NULL to indicate +that no more data will be received. +This event will for example be used by playlists when they generate information. + +GST_EVENT_ERROR +direction(s): vertical +event_data: struct { + gchar *message + } error; +An error event is emitted, whenever a recoverable error occurs that the application +should know about. The usage should be similar to GLibs GError. An example would be +"connection closed" for a host to host plugin. + + +Reference Counting +------------------ + +References to events are handled similar to buffers. An element receives an event with +a single reference. If it forwards the event, this reference is lost. +Events own a reference to the element that created them. They take care of all of all +data inside them too (strings, props). So elements and applications that want to keep +this informations need to copy or add a reference them. + + +Changing Events +--------------- +It is not allowed to change any data inside an event. Changing events can only be +accomplished by removing the reference to them and not forwarding the event and then +creating a new one. + + +Default Behaviour +----------------- + +* downstream events + + These are not handled by default, because they must be handled by the chain handler + of the sink pad. There is however a function called gst_pad_event_default(GstPad *, + GstData *) that will take care of events if your code doesn't want to handle them. + But your code must be aware that not everything that your chain function receives + is a buffer. It could be an event. + +* upstream events + + Upstream events are handled by a default handler function that is inserted on sink + pads when they are created. This function simply forwards the event to all connected + sink pads of the element. You are free to change this handler. + +* vertical events + + Vertical events can not be received by elements. Bins have a default handler function + that simply forwards the event to their parent. Pipelines offer callbacks for events. + You may change this handler for your custom bins. + + +Use Cases +--------- + +Following are some simple use cases describing how events are generated. The pipeline +decriptions use gst-launch syntax. "..." indicates that something follows there but is +not important for the example. + +* filesrc ! fakesink + + - When starting the pipeline, filesrc will emit a DISCONTINUOUS event of type NEW + indicating a new stream. + - Following that event will be an INFO event containing the length of the file/stream + in bytes. + - After the file was played, the filesrc emits a "DISCONTINUOUS" of type EOS. + +* filesrc ! mad ! ... + + - When starting, filesrc emits a DISCONTINUOUS event followed by an INFO event (see above). + The mad plugin remembers the length of the file and removes the INFO element as it + is no longer of use. The DISCONTINUOUS event has passed mad after making sure, that all + buffers are cleared. + - Mad will emit a SEEK event to BYTEOFFSET_END; offset = -sizeof(ID3_info) to read out the ID3 + information. + - Filesrc emits a DISCONTINUOUS event of type SEEK to indicate that it seeked to the end. + This event will not be passed on by mad. + - after receiving the ID 3 information, mad will issue an INFO event containing all data + it extracted. This event will probably only be passed vertical as ID3 information is of + no use to other elements. + - mad then ISSUES a SEEK event of type BYTEOFFSET_SET; offset = 0 to make the filesrc start + playing the file. + - The filesrc will reset its offset and issue a DISCONTINUOUS event of type SEEK. This event + will not be forwarded by mad. + - When playing starts, mad is able to compute bitrate and other information including playing + time with the help of the previous length information supplied by the filesrc. It will then + issue another INFO event with that informations. This one will be send downstream and vertical. + +* ... ! avimux ! disksink + + This example is showing a more exotic way of using events. The reader should be aware that AVI + files have a limited filesize. Only 4 GB are allowed. We now show what happens when the avimux + encoder hits that limit. + - When the internal counter of avimux shows that it is approaching the filesize limit, the + avimux element pushes a buffer containig the footer to the disksink. + - After that it issues a DISCONTINUOUS event of the type DISCONT_NEW indicating a new stream. + The disksink will close the file and reopen a new one. + - The avimux plugin resets its internal size counter and restarts sending data to the new file. + +* filesrc ! gunzip ! mikmod ! osssink + + (please note that this example is purely theoretical. It should just show ideas) + During playback, an application is interested in "interpret", "title", "length_time", + "length_size" and "URI" of the current stream. + - The appplication creates a HAS_INFO event and inserts it at the end of the pipeline into the + osssink. + - The osssink cannot supply any info so it forwards the event to the mikmod element. + - The mikmod element can supply "title" and "length_time". It calls the supplied callback twice + and gives these two options. It forwards the event to the gunzip element. + - The gunzip element has already decoded the whole data so it knows the size of the stream. It + calls the callback for "length_size" and forwards the event. + - The filesrc supplies the "URI" and the "length_size" for a second time. It is now up to the + application's callback function to handle this second occurence of "length_size" information. + The filesrc does not forward the event and dereferences it. + - During disposal of the event, the callback function is called again with name=NULL. The + application now knows that no "title" can be supplied. + + +Open Questions +-------------- + +Open questions are issues that should probably be solved by events but can not be solved +currently. + +* A disksink needs to be able to inform elements of a restricted file size. Simply closing + the file and opening a new one might not work because elements might need to supply a + footer. (eg avimux) + + + +Issues / changes (to be deleted in final version) +---------------- + +? Are the event directions distinct? Or is it possible that some type of event + can travel eg upstream _and_ vertical? +? How are upstream/vertical events supposed to be handled if they occur when + the element is READY or NULL? Buffer the event? How many events should be + buffered? Maybe a READY element is attached to a PLAYING/PAUSED one and + constantly receiving events, no? +! The EOS event was merged with the DISCONTINUOUS event. +? Does the DISCONTINUOUS event need a "flush" option? +? Should chain funcs be changed to expect GstData instead of GstBuffer? + It's a little bit misleading if events can arrive there. +! added information about timestamp. +? Should timestamps of "follow up" events (eg conversion of seek) keep the + timestamp? +? src = NULL, when app inserts event? +? How do elements handle events they cannot use? (eg filesrc getting timebased + seek request) +? Somebody fix the GST_EVENT_FLUSH part. +? GValue or GstProps for INFO events? First requires to open up the props headers + and writing some API to ease the retrieval of the elements, the second requires + a rewrite of GST_EVENT_INFO. +? GQuark/GValue possible in INFO events? +! Merged INFO and PROPS event. They are nearly the same. Added documentation. +? Need to work out the ERROR event. +! changed prototype for gst_pad_event_default to accept buffers so the function checks + if it is an event and not every chain handler has to. +! added HAS_INFO event. An alternative to the callback function could be another vertical + event. +? Should HAS_INFO callback supply the element calling the function? +? Use case one: start with discont event? +? Do we need a state change event? +? Should we make elements supply information as soon as possible or only upon HAS_INFO + request? +? should the second example be done with region requesting instead of events? +? "location" or "URI"? +? What about suggesting buffer sizes? +? What about QoS?