mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 19:51:11 +00:00
docs/design/draft-latency.txt: Slight redesign to allow for dynamic latency adjustments.
Original commit message from CVS: * docs/design/draft-latency.txt: Slight redesign to allow for dynamic latency adjustments. * docs/design/part-negotiation.txt: Fix some typos.
This commit is contained in:
parent
b3c3d335cf
commit
94e66c5da0
3 changed files with 45 additions and 25 deletions
|
@ -1,3 +1,11 @@
|
|||
2007-02-02 Wim Taymans,,, <wim@fluendo.com>
|
||||
|
||||
* docs/design/draft-latency.txt:
|
||||
Slight redesign to allow for dynamic latency adjustments.
|
||||
|
||||
* docs/design/part-negotiation.txt:
|
||||
Fix some typos.
|
||||
|
||||
2007-02-02 Sebastian Dröge <slomo@circular-chaos.org>
|
||||
|
||||
reviewed by: Wim Taymans <wim@fluendo.com>
|
||||
|
|
|
@ -12,7 +12,7 @@ first sample at time 0. If the source pushes buffers with 44100 samples at a
|
|||
time at 44100Hz it will have collected the buffer at second 1.
|
||||
Since the timestamp of the buffer is 0 and the time of the clock is now >= 1
|
||||
second, the sink will drop this buffer because it is too late.
|
||||
Without an latency compensation in the sink, all buffers will be dropped.
|
||||
Without any latency compensation in the sink, all buffers will be dropped.
|
||||
|
||||
The situation becomes more complex in the presence of:
|
||||
|
||||
|
@ -225,7 +225,8 @@ PAUSED->PLAYING in a non-live pipeline).
|
|||
implications:
|
||||
|
||||
- the current async_play vmethod in basesink can be deprecated since we now
|
||||
always call the state change function when going from PAUSED->PLAYING
|
||||
always call the state change function when going from PAUSED->PLAYING. We
|
||||
keep this method however to remain backward compatible.
|
||||
|
||||
|
||||
Latency compensation
|
||||
|
@ -234,28 +235,18 @@ Latency compensation
|
|||
As an extension to the revised state changes we can perform latency calculation
|
||||
and compensation before we proceed to the PLAYING state.
|
||||
|
||||
To the PREROLLED message posted by the sinks when then go to PAUSED we add the
|
||||
following fields:
|
||||
|
||||
- (boolean) live
|
||||
- (boolean) upstream-live
|
||||
- (int_range) latency (min and max latency in microseconds, could also be
|
||||
expressed as int_list or min/max fields)
|
||||
|
||||
When the pipeline collected all PREROLLED messages it can calculate the global
|
||||
latency as follows:
|
||||
|
||||
- if no message has live, latency = 0 (no sink syncs against the clock)
|
||||
- if no message has upstream-live, latency = 0 (no live source)
|
||||
|
||||
- latency = MAX (MIN (all latencies))
|
||||
- if MIN (MAX (all latencies) < latency we have an impossible situation.
|
||||
- perform a latency query on all sinks.
|
||||
- latency = MAX (all min latencies)
|
||||
- if MIN (all max latencies) < latency we have an impossible situation and we
|
||||
must generate an error indicating that this pipeline cannot be played.
|
||||
|
||||
The sinks gather this information with a LATENCY query upstream. Intermediate
|
||||
elements pass the query upstream and add the amount of latency they add to the
|
||||
result.
|
||||
|
||||
|
||||
ex1:
|
||||
sink1: [20 - 20]
|
||||
sink2: [33 - 40]
|
||||
|
@ -270,16 +261,17 @@ ex2:
|
|||
MAX (20, 33) = 33
|
||||
MIN (50, 40) = 40 >= 33 -> latency = 33
|
||||
|
||||
The latency is set on the pipeline by sending a SET_LATENCY event to the sinks
|
||||
The latency is set on the pipeline by sending a LATENCY event to the sinks
|
||||
that posted the PREROLLED message. This event configures the total latency on
|
||||
the sinks. The sink forwards this SET_LATENCY event upstream so that
|
||||
the sinks. The sink forwards this LATENCY event upstream so that
|
||||
intermediate elements can configure themselves as well.
|
||||
|
||||
After this step, the pipeline continues setting the pending state on the sinks.
|
||||
|
||||
A sink adds the latency value, received in the SET_LATENCY event, to
|
||||
A sink adds the latency value, received in the LATENCY event, to
|
||||
the times used for synchronizing against the clock. This will effectively
|
||||
delay the rendering of the buffer with the required latency.
|
||||
delay the rendering of the buffer with the required latency. Since this delay is
|
||||
the same for all sinks, all sinks will render data relatively synchronised.
|
||||
|
||||
|
||||
Flushing a playing pipeline
|
||||
|
@ -306,12 +298,32 @@ prerolls, it posts a PREROLLED message.
|
|||
|
||||
When all LOST_PREROLL messages are matched with a PREROLLED message, the bin
|
||||
will capture a new base time from the clock and will bring all the prerolled
|
||||
sinks back to playing (their pending state) after setting the new base time on
|
||||
them. It's also possible to perform additional latency calculations and
|
||||
adjustments before doing this.
|
||||
sinks back to PLAYING (or whatever their state was when they posted the
|
||||
LOST_PREROLL message) after setting the new base time on them. It's also possible
|
||||
to perform additional latency calculations and adjustments before doing this.
|
||||
|
||||
The difference with the NEED_PREROLL/PREROLLED and LOST_PREROLL/PREROLLED
|
||||
message pair is that the latter makes the pipeline acquire a new base time for
|
||||
the PREROLLED elements.
|
||||
|
||||
|
||||
Dynamically adjusting latency
|
||||
-----------------------------
|
||||
|
||||
An element that want to change the latency in the pipeline can do this by
|
||||
posting a LATENCY message on the bus. This message instructs the pipeline to:
|
||||
|
||||
- query the latency in the pipeline (which might now have changed)
|
||||
- redistribute a new global latency to all elements with a LATENCY event.
|
||||
|
||||
A use case where the latency in a pipeline can change could be a network element
|
||||
that observes an increased inter packet arrival jitter or excessive packet loss
|
||||
and decides to increase its internal buffering (and thus the latency). The
|
||||
element must post a LATENCY message and perform the additional latency
|
||||
adjustments when it receives the LATENCY event from the downstream peer element.
|
||||
|
||||
In a similar way can the latency be decreased when network conditions are
|
||||
improving again.
|
||||
|
||||
Latency adjustments will introduce glitches in playback in the sinks and must
|
||||
only be performed in special conditions.
|
||||
|
|
|
@ -9,13 +9,13 @@ flexible, constrained by those parts of the pipeline that are not
|
|||
flexible.
|
||||
|
||||
GStreamer's two scheduling modes, push mode and pull mode, lend
|
||||
themselves to different mechanisms to acheive this goal. As it is more
|
||||
themselves to different mechanisms to achieve this goal. As it is more
|
||||
common we describe push mode negotiation first.
|
||||
|
||||
Push-mode negotiation
|
||||
---------------------
|
||||
|
||||
Pussh-mode negotiation happens when elements want to push buffers and
|
||||
Push-mode negotiation happens when elements want to push buffers and
|
||||
need to decide on the format. This is called downstream negotiation
|
||||
because the upstream element decides the format for the downstream
|
||||
element. This is the most common case.
|
||||
|
|
Loading…
Reference in a new issue