| Events |
| ------ |
| |
| Events are objects passed around in parallel to the buffer dataflow to |
| notify elements of various events. |
| |
| Events are received on pads using the event function. Some events should |
| be interleaved with the data stream so they require taking the STREAM_LOCK, |
| others don't. |
| |
| Different types of events exist to implement various functionalities. |
| |
| GST_EVENT_EOS: no more data is to be expected on a pad. |
| GST_EVENT_FLUSH: data is to be discarded or allowed again |
| GST_EVENT_DISCONTINUOUS: A new group of buffers with common start time |
| GST_EVENT_QOS: A notification of the quality of service of the stream |
| GST_EVENT_SEEK: A seek should be performed to a new position in the stream |
| GST_EVENT_SIZE: Notification of suggested buffer size. |
| GST_EVENT_RATE: Notification to change the processing speed of a stream |
| GST_EVENT_NAVIGATION: A navigation event. |
| GST_EVENT_TAG: Stream metadata. |
| |
| |
| EOS |
| --- |
| |
| The EOS event can only be sent on a sinkpad. It is typically emited by the |
| source element when it has finished sending data. This event is mainly sent |
| in the streaming thread but can also be sent from the application thread. |
| |
| The downstream element should forward the EOS event to its downstream peer |
| elements. This way the event will eventually reach the renderers which should |
| then post an EOS message on the bus. |
| |
| For elements with multiple sink pads it might be possible to wait for EOS on |
| all the pads before forwarding the event. |
| |
| The EOS event should always be interleaved with the data flow, therefore the |
| STREAM_LOCK should be taken. |
| |
| Sometimes the EOS event is generated by another element than the source, for |
| example a demuxer element can generate an EOS event before the source element. |
| This is not a problem, the demuxer does not send an EOS event to the upstream |
| element but returns GST_FLOW_UNEXPECTED, causing the source element to stop |
| sending data. |
| |
| An element that sends EOS on a pad should stop sending data on that pad. Source |
| elements typically pause() their task for that purpose. |
| |
| By default, the pipeline collects all EOS events from all the sinks before |
| passing the EOS message to the application. |
| |
| The EOS is only posted on the bus by the sink elements in the PLAYING state. If |
| the EOS event is received in the PAUSED state, it is queued until the element |
| goes to PLAYING. |
| |
| |
| FLUSH |
| ----- |
| |
| A flush event is sent both downstream and upstream to clear any pending data |
| from the pipeline. This might be needed to make the graph more responsive |
| when the normal dataflow gets interrupted by for example a seek event. |
| |
| Flushing happens in two stages. |
| |
| 1) a source filter sends the flush event to the downstream peer element. The |
| downstream element starts rejecting buffers from the upstream elements. It |
| sends the flush event further downstream and discards any buffers it is |
| holding as well as return from the chain function as soon as possible. |
| This makes sure that all upstream elements get unblocked. |
| This event is not synchronized with the STREAM_LOCK and can be done in the |
| application thread. |
| |
| 2) a source filter sends the flush event with the done flag set to indicate |
| that the downstream element can accept buffers again. The downstream |
| element sends the flush event to its peer elements. After this step dataflow |
| continues. The endflush call is synchronized with the STREAM_LOCK so any |
| data used by the chain function can safely freed here if needed. Any |
| pending EOS events should be discarded too. |
| |
| After the flush completes the second stage, data is flowing again in the pipeline |
| and all buffers are more recent than those before the flush. |
| |
| For elements that use the pullregion function, they send both flush events to |
| the upstream pads in the same way top make sure that the pullregion function |
| unlocks and any pending buffers are cleared in the upstream elements. |
| |
| |
| DISCONTINUOUS |
| ------------- |
| |
| A discont event is sent downstream by an element to indicate that the following |
| group of buffers start and end at the specified time. The discont event |
| also contains the playback speed of the stream. |
| |
| Since the stream time is always set to 0 at start and after a seek, a 0 |
| point for all next buffer's timestamps has to be propagated through the |
| pipeline using the DISCONT event. |
| |
| Elements that sync to the clock should store the DISCONT start and end values |
| and substract the start value from the buffer timestamp before comparing |
| it against the stream time. |
| |
| An element is allowed to send out buffers with the DISCONT start time already |
| substracted from the timestamp. If it does so, it needs to send a corrected |
| DISCONT downstream, ie, one with start time 0. |
| |
| A DISCONT event should be generated as soon as possible in the pipeline and |
| is usually generated by a demuxer. The event is generated before pushing the |
| first buffer and after a seek, right before pushing the new buffer. |
| |
| The DISCONT event can be send from both the application and the streaming |
| thread. |
| |
| |
| |
| SEEK |
| ---- |
| |
| A seek event is issued by the application to start playback of a new |
| position in the stream. It is called form the application thread and |
| travels upstream. |
| |
| The seek event contains the new start and end position of playback |
| after the seek is performed. Optionally the end position can be left |
| at -1 to continue playback to the end of the stream. |
| |
| A seek usually flushes the graph to minimize latency after the seek. |
| |
| The seek event is passed along from element to element until it reaches |
| an element that can perform the seek. No intermediate element is allowed |
| to assume that a seek to this location will happen. It is allowed to |
| modify the start and stop times if it needs to do so. this is typically |
| the case if a seek is requested for a non-time position. |
| |
| The actual seek is performed in the application thread so that success |
| or failure can be reported as a return value of the seek event. It is |
| therefore important that before executing the seek, the element acquires |
| the STREAM_LOCK so that the streaming thread and the seek gets serialized. |
| |
| The general flow of executing the seek is as follows: |
| |
| 1) unblock the streaming threads, they could be blocked in a chain |
| function. This is done by sending a flush on all srcpads. |
| The flush will make sure that all downstream elements unlock and |
| that control will return to this element chain/loop function. |
| We cannot lock the STREAM_LOCK before doing this since it might |
| cause a deadlock. |
| |
| 2) lock the STREAM_LOCK. This will work since the chain/loop function |
| was unlocked in step 1). |
| |
| 3) perform the seek. since the STREAM_LOCK is held, the streaming thread |
| will wait for the seek to complete. Most likely, the stream thread |
| will pause because the peer elements are flushing. |
| |
| 4) send a flush event with the done flag set to allow streaming again. |
| |
| 5) send a DISCONT event to signal the new buffer timestamp base time. |
| |
| 6) start stopped tasks and unlock the STREAM_LOCK, dataflow will continue |
| now from the new position. |
| |
| |
| SIZE |
| ---- |
| |
| Some demuxers know an optimal size for any downstream buffers. They can |
| use this event to signal this fact. Similary an element can signal an |
| upstream element for a prefered buffer size. |
| |
| |
| RATE |
| ---- |
| |
| When the application wants to change the playback rate of the stream, it |
| issues a rate event on the sinks. A rate of 1.0 is the normal playback rate, |
| 2.0 plays at twice the speed and negative values play backwards. |
| |
| The rate event travels upstream. After the rate event reaches an element |
| that can handle the rate event, it issues a flush and generates a new |
| DISCONT event with the updated rate. |
| |
| Note that the clock speed does not change. More specific information about |
| changing the playback rate are to be thought out and written down. |
| |
| |
| NAVIGATION |
| ---------- |
| |
| A navigation event is generated by a sink element to signal the elements |
| of a navigation event such as a mouse movement or button click. |
| Navigation events travel upstream. |
| |
| |
| TAG |
| --- |
| |
| The tag event is sent downstream when an element has discovered metadata |
| tags in a media file. Encoders can use this event to adjust their tagging |
| system. A tag is serialized with buffers. |
| |
| |