[vlc-devel] [PATCH] RFC: output_clock: respect first pts delay (FIXUP)

Thomas Guillem thomas at gllm.fr
Wed Feb 13 13:23:59 CET 2019


Commit on top of the https://code.videolan.org/jbk/vlc/tree/clock-core/25
branch, will be fixup.

This commit fixes underrun when the first audio pts is too far in the future.
This happened with .ogg, .ts and live streams.

Without this commit, the first vlc_clock_ConvertToSystem() from aout/dec.c will
return a first play date that only take the jitter into account. So we ended
with an invalid first system date: likely to be vlc_tick_now() + clock->jitter,
ignoring the delay between the first audio pts and the PCR.
---
 src/clock/clock.c  | 15 ++++++++++++++-
 src/clock/clock.h  |  2 ++
 src/input/es_out.c |  4 ++++
 3 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/src/clock/clock.c b/src/clock/clock.c
index 8308c0ffc4..5bdc6c174e 100644
--- a/src/clock/clock.c
+++ b/src/clock/clock.c
@@ -47,6 +47,7 @@ struct vlc_clock_main_t
     vlc_tick_t delay;
 
     vlc_tick_t pause_date;
+    vlc_tick_t first_pts;
 
     clock_point_t wait_sync_ref; /* When the master */
     vlc_tick_t dejitter; /* Delay used to absorb the clock jitter */
@@ -276,8 +277,12 @@ static vlc_tick_t vlc_clock_main_to_system_locked(vlc_clock_main_t * main_clock,
         if (main_clock->wait_sync_ref.stream == VLC_TICK_INVALID ||
             main_clock->wait_sync_ref.system == VLC_TICK_INVALID)
         {
+            const vlc_tick_t initial_delay = pts - main_clock->first_pts;
+            const vlc_tick_t system_delay =
+                __MAX(main_clock->dejitter, initial_delay);
+
             main_clock->wait_sync_ref =
-                clock_point_Create(pts, now + main_clock->dejitter);
+                clock_point_Create(pts, now + system_delay);
         }
         system = (pts - main_clock->wait_sync_ref.stream) / main_clock->rate;
         system += main_clock->wait_sync_ref.system;
@@ -423,6 +428,14 @@ void vlc_clock_main_Reset(vlc_clock_main_t * main_clock)
 {
     vlc_mutex_lock(&main_clock->lock);
     vlc_clock_main_reset(main_clock);
+    main_clock->first_pts = VLC_TICK_INVALID;
+    vlc_mutex_unlock(&main_clock->lock);
+}
+
+void vlc_clock_main_SetFirstPts(vlc_clock_main_t * main_clock, vlc_tick_t pts)
+{
+    vlc_mutex_lock(&main_clock->lock);
+    main_clock->first_pts = pts;
     vlc_mutex_unlock(&main_clock->lock);
 }
 
diff --git a/src/clock/clock.h b/src/clock/clock.h
index e079440af6..8bd5adb40d 100644
--- a/src/clock/clock.h
+++ b/src/clock/clock.h
@@ -51,6 +51,8 @@ void vlc_clock_main_Abort(vlc_clock_main_t * main);
  */
 void vlc_clock_main_Reset(vlc_clock_main_t * main);
 
+void vlc_clock_main_SetFirstPts(vlc_clock_main_t * main, vlc_tick_t pts);
+
 /**
  * This function set the allocated interface as the master making the current
  * master if any a slave.
diff --git a/src/input/es_out.c b/src/input/es_out.c
index 5d8be99f9f..773c825a2d 100644
--- a/src/input/es_out.c
+++ b/src/input/es_out.c
@@ -798,6 +798,10 @@ static void EsOutDecodersStopBuffering( es_out_t *out, bool b_forced )
     p_sys->i_preroll_end = -1;
     p_sys->i_prev_stream_level = -1;
 
+    /* Send the first PCR to the output clock. This will be used as a reference
+     * point for the sync point. */
+    vlc_clock_main_SetFirstPts(p_sys->p_pgrm->p_main_clock, i_stream_start);
+
     if( p_sys->i_buffering_extra_initial > 0 )
     {
         /* FIXME wrong ? */
-- 
2.20.1



More information about the vlc-devel mailing list