mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-03 16:09:39 +00:00
99a3a0a6c0
Original commit message from CVS: * docs/design/part-clocks.txt: * docs/design/part-events.txt: * gst/base/gstbasesrc.c: (gst_base_src_do_seek): Small docs updates. Only update the seeking values when we are not busy streaming.
129 lines
5.1 KiB
Text
129 lines
5.1 KiB
Text
Clocks
|
|
------
|
|
|
|
To synchronize the different elements, the GstPipeline is responsible for
|
|
selecting and distributing a global GstClock for all the elements in it.
|
|
|
|
This selection happens whenever an element is added or removed from the
|
|
pipeline. Whever the clock changes in a pipeline, a message is posted on
|
|
the bus signaling the new clock to the application.
|
|
|
|
The GstClock returns a monotonically increasing time with the method
|
|
_get_time(). Its accuracy and base time depends on the specific clock
|
|
implementation but time is always expessed in nanoseconds. Since the
|
|
baseline of the clock is undefined, the clock time returned is not
|
|
meaningfull in itself, what matters are the deltas between two clock
|
|
times.
|
|
The time reported by the clock is called the absolute time.
|
|
|
|
|
|
Time in GStreamer
|
|
-----------------
|
|
|
|
The absolute time is used to calculate the stream time. The stream time
|
|
is defined as follows:
|
|
|
|
- If the pipeline is NULL/READY, the stream time is undefined.
|
|
- In PAUSED, the stream time remains at the time when it was last
|
|
PAUSED. When the stream is PAUSED for the first time, the stream time
|
|
is 0.
|
|
- In PLAYING, the stream time is the delta between the absolute time
|
|
and the base time. The base time is defined as the absolute time minus
|
|
the stream time at the time when the pipeline is set to PLAYING.
|
|
- after a seek, the stream time is set to 0 (see part-seeking.txt)
|
|
|
|
The stream time is completely managed by the GstPipeline object using the
|
|
GstClock absolute time.
|
|
|
|
|
|
Timestamps
|
|
----------
|
|
|
|
The combination of the last DISCONT event and the buffer timestamps
|
|
express the presentation stream time of the buffer. The stream time
|
|
of a buffer is calculated as follows:
|
|
|
|
ST = TS - DT where: TS = buffer timestamp
|
|
DT = DISCONT timestamp
|
|
ST = buffer stream time
|
|
|
|
The reason for not making the buffer times express the stream time directly
|
|
is for the following reasons:
|
|
|
|
- demuxers are easier if they can just copy the timestamps as encoded in
|
|
the file. The initial discont event would contain the lowest timestamp in
|
|
the stream which makes the stream time start from 0.
|
|
- pipelines requiring retimestamping of buffers can efficiently adjust
|
|
the timestamp in the discont events and have all buffers retimestamped
|
|
automatically.
|
|
- resync after different kinds of seeks is easier.
|
|
|
|
If an element wants to synchronize a buffer to the clock it needs to first
|
|
calculate the buffer stream time and then bring the stream time to the
|
|
absolute clock time.
|
|
|
|
Converting a timestamp (in stream time) to absolute time is performed using
|
|
the following formula:
|
|
|
|
AT = BT + ST where: AT = absolute time
|
|
BT = base time
|
|
ST = stream time
|
|
|
|
The pipeline base time is propagated to all the element during the PAUSED
|
|
to PLAYING state change. All elements are therefore able to convert the
|
|
stream time to the absolute time. It is possible to specify an aditional
|
|
delay to the base time to compensate for the delay it takes to perform
|
|
the state change using the GstPipeline "delay" property.
|
|
|
|
|
|
Clock features
|
|
--------------
|
|
|
|
The clock supports periodic and single shot clock notifications both
|
|
synchronous and asynchronous.
|
|
|
|
One first needs to create a GstClockID for the periodic or single shot
|
|
notification using _clock_new_single_shot_id() or _clock_new_periodic_id().
|
|
|
|
To perform a blocking wait for the specific time of the GstClockID use the
|
|
gst_clock_id_wait(). To receive a callback when the specific time is reached
|
|
in the clock use gst_clock_id_wait_async(). Both these calls can be interrupted
|
|
with the gst_clock_id_unschedule() call. If the blocking wait is unscheduled
|
|
a return value of GST_CLOCK_UNSCHEDULED is returned.
|
|
|
|
The async callbacks can happen from any thread, either provided by the
|
|
core or from a streaming thread. The application should be prepared for this.
|
|
|
|
A GstClockID that has been unscheduled cannot be used again for any wait
|
|
operation.
|
|
|
|
It is possible to perform a blocking wait on the same ID from multiple
|
|
threads. However, registering the same ID for multiple async notifications is
|
|
not possible, the callback will only be called once.
|
|
|
|
None of the wait operations unref the GstClockID, the owner is
|
|
responsible for unreffing the ids itself. This holds for both periodic and
|
|
single shot notifications. The reason being that the owner of the ClockID
|
|
has to keep a handle to the ID to unblock the wait on FLUSHING events
|
|
or state changes and if we unref it automatically, the handle might be
|
|
invalid.
|
|
|
|
These clock operations do not operate on the stream time, so the callbacks
|
|
will also occur when not in PLAYING state as if the clock just keeps on
|
|
running.
|
|
|
|
|
|
Clock implementations
|
|
---------------------
|
|
|
|
The GStreamer core provides a GstSystemClock based on the system time.
|
|
Asynchronous callbacks are scheduled from an internal thread.
|
|
|
|
Clock implementors are encouraged to subclass this systemclock as it
|
|
implements the async notification.
|
|
|
|
Subclasses can however override all of the important methods for sync and
|
|
async notifications to implement their own callback methods or blocking
|
|
wait operations.
|
|
|
|
|