mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-16 13:26:36 +00:00
66d7070ef1
Original commit message from CVS: * CHANGES-0.9: * docs/design/part-TODO.txt: * docs/design/part-events.txt: Some docs updates * gst/base/gstbasesink.c: (gst_base_sink_handle_object), (gst_base_sink_event), (gst_base_sink_do_sync), (gst_base_sink_activate_push), (gst_base_sink_activate_pull): * gst/base/gstbasesrc.c: (gst_base_src_send_discont), (gst_base_src_do_seek), (gst_base_src_event_handler), (gst_base_src_loop): * gst/base/gstbasetransform.c: (gst_base_transform_transform_caps), (gst_base_transform_configure_caps), (gst_base_transform_setcaps), (gst_base_transform_get_size), (gst_base_transform_buffer_alloc), (gst_base_transform_event), (gst_base_transform_handle_buffer), (gst_base_transform_set_passthrough), (gst_base_transform_is_passthrough): * gst/elements/gstfakesink.c: (gst_fake_sink_event): * gst/elements/gstfilesink.c: (gst_file_sink_event): Event updates. * gst/gstbuffer.h: Use faster casts. * gst/gstelement.c: (gst_element_seek): * gst/gstelement.h: Update gst_element_seek. * gst/gstevent.c: (gst_event_finalize), (_gst_event_copy), (gst_event_new), (gst_event_new_custom), (gst_event_get_structure), (gst_event_new_flush_start), (gst_event_new_flush_stop), (gst_event_new_eos), (gst_event_new_newsegment), (gst_event_parse_newsegment), (gst_event_new_tag), (gst_event_parse_tag), (gst_event_new_filler), (gst_event_new_qos), (gst_event_parse_qos), (gst_event_new_seek), (gst_event_parse_seek), (gst_event_new_navigation): * gst/gstevent.h: Make GstEvent use GstStructure. Add parsing code, make sure the API is sufficiently generic. Mark possible directions of events and serialization. * gst/gstmessage.c: (gst_message_init), (gst_message_finalize), (_gst_message_copy), (gst_message_new_segment_start), (gst_message_new_segment_done), (gst_message_new_custom), (gst_message_parse_segment_start), (gst_message_parse_segment_done): Small cleanups. * gst/gstpad.c: (gst_pad_get_caps_unlocked), (gst_pad_accept_caps), (gst_pad_set_caps), (gst_pad_send_event): Update for new events. Catch events sent in wrong directions. * gst/gstqueue.c: (gst_queue_link_src), (gst_queue_handle_sink_event), (gst_queue_chain), (gst_queue_loop), (gst_queue_handle_src_query): Event updates. * gst/gsttag.c: * gst/gsttag.h: Remove event code from this file. * libs/gst/dataprotocol/dataprotocol.c: (gst_dp_packet_from_event), (gst_dp_event_from_packet): Event updates.
195 lines
8 KiB
Text
195 lines
8 KiB
Text
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_FLUSH_START: data is to be discarded
|
|
GST_EVENT_FLUSH_STOP: data is allowed again
|
|
GST_EVENT_EOS: no more data is to be expected on a pad.
|
|
GST_EVENT_NEWSEGMENT: A new group of buffers with common start time
|
|
GST_EVENT_TAG: Stream metadata.
|
|
GST_EVENT_FILLER: Filler for sparse data streams
|
|
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_NAVIGATION: A navigation event.
|
|
|
|
|
|
FLUSH_START/STOP
|
|
----------------
|
|
|
|
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_START 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_STOP event 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 FLUSH_STOP 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.
|
|
|
|
|
|
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.
|
|
|
|
An EOS event sent on a srcpad returns GST_FLOW_UNEXPECTED.
|
|
|
|
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.
|
|
|
|
|
|
NEWSEGMENT
|
|
-------------
|
|
|
|
A newsegment event is sent downstream by an element to indicate that the following
|
|
group of buffers start and end at the specified positions. The newsegment 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 NEWSEGMENT event.
|
|
|
|
Before sending buffers, an element must send a NEWSEGMENT event. An element is
|
|
free to refuse buffers if they were not preceeded by a NEWSEGMENT event.
|
|
|
|
Elements that sync to the clock should store the NEWSEGMENT start and end values
|
|
and substract the start value from the buffer timestamp before comparing
|
|
it against the stream time (see part-clocks.txt).
|
|
|
|
An element is allowed to send out buffers with the NEWSEGMENT start time already
|
|
substracted from the timestamp. If it does so, it needs to send a corrected
|
|
NEWSEGMENT downstream, ie, one with start time 0.
|
|
|
|
A NEWSEGMENT event should be generated as soon as possible in the pipeline and
|
|
is usually generated by a demuxer or source. The event is generated before
|
|
pushing the first buffer and after a seek, right before pushing the new buffer.
|
|
|
|
The NEWSEGMENT event can be send from both the application and the streaming
|
|
thread and should be serialized with the buffers.
|
|
|
|
Buffers should be clipped within the range indicated by the newsegment event
|
|
start and stop values. Sinks are allowed to drop buffers with timestamps out
|
|
of the indicated newsegment range.
|
|
|
|
|
|
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. The seek event
|
|
also contains the new playback rate of the stream, 1.0 is normal playback,
|
|
2.0 double speed and negative values mean backwards playback.
|
|
|
|
A seek usually flushes the graph to minimize latency after the seek this
|
|
behaviour is triggered by using the SEEK_FLUSH flag.
|
|
|
|
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 with FLUSH is as follows:
|
|
|
|
1) unblock the streaming threads, they could be blocked in a chain
|
|
function. This is done by sending a FLUSH_START 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_STOP event to all peer elements to allow streaming again.
|
|
|
|
5) send a NEWSEGMENT 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.
|
|
|
|
More information about the different seek types can be found in
|
|
part-seeking.txt.
|
|
|
|
|
|
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.
|
|
|
|
|