added event proposal - probably a bit long, you may shorten it, if you can.
authorBenjamin Otte <otte@gnome.org>
Tue, 29 Jan 2002 23:48:08 +0000 (23:48 +0000)
committerBenjamin Otte <otte@gnome.org>
Tue, 29 Jan 2002 23:48:08 +0000 (23:48 +0000)
Original commit message from CVS:
added event proposal - probably a bit long, you may shorten it, if you can.

docs/random/events [new file with mode: 0644]

diff --git a/docs/random/events b/docs/random/events
new file mode 100644 (file)
index 0000000..f609ad4
--- /dev/null
@@ -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?