[vlc-devel] [PATCH V3 2/2] aout: use original pts as play date

Thomas Guillem thomas at gllm.fr
Mon Mar 4 12:20:42 CET 2019


This will be needed if scaletempo/soxr patches are merged.

This will be also required by the new output clock. Indeed, in case of rate
change, only the filters are changed but not the aout. This means that
aout->time_get() timebase need to be the same than clock update points: the
orignal pts given by the decoder. In case the filters are outputting slightly
more or less data because of a ressampler imprecision, the delay will be
corrected via aout->time_get.
---
 src/audio_output/aout_internal.h |  1 +
 src/audio_output/dec.c           | 23 +++++++++++++++++++++--
 2 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/src/audio_output/aout_internal.h b/src/audio_output/aout_internal.h
index 32be61034f..5b302a5d93 100644
--- a/src/audio_output/aout_internal.h
+++ b/src/audio_output/aout_internal.h
@@ -67,6 +67,7 @@ typedef struct
         int resamp_type; /**< Resampler mode (FIXME: redundant / resampling) */
         bool discontinuity;
     } sync;
+    vlc_tick_t original_pts;
 
     int requested_stereo_mode; /**< Requested stereo mode set by the user */
 
diff --git a/src/audio_output/dec.c b/src/audio_output/dec.c
index 0898487668..ef08dd851e 100644
--- a/src/audio_output/dec.c
+++ b/src/audio_output/dec.c
@@ -99,6 +99,7 @@ error:
     owner->sync.rate = 1.f;
     owner->sync.resamp_type = AOUT_RESAMPLING_NONE;
     owner->sync.discontinuity = true;
+    owner->original_pts = VLC_TICK_INVALID;
 
     atomic_init (&owner->buffers_lost, 0);
     atomic_init (&owner->buffers_played, 0);
@@ -362,25 +363,42 @@ int aout_DecPlay(audio_output_t *aout, block_t *block)
         vlc_mutex_unlock (&owner->vp.lock);
     }
 
+    vlc_tick_t pts = block->i_pts;
+    if (owner->original_pts == VLC_TICK_INVALID)
+    {
+        /* Use the original PTS for synchronization and as a play date of the
+         * aout module. This PTS need to be saved here in order to use the PTS
+         * of the first block that has been filtered. Indeed, aout filters may
+         * need more than one block to output a new one. */
+        owner->original_pts = pts;
+    }
+
     block = aout_FiltersPlay(owner->filters, block, owner->sync.rate);
     if (block == NULL)
         return ret;
+    if (block->i_flags & BLOCK_FLAG_DISCONTINUITY)
+    {
+        /* Use the current PTS since previous blocks may have been dropped */
+        owner->original_pts = pts;
+    }
 
     /* Software volume */
     aout_volume_Amplify (owner->volume, block);
 
     /* Drift correction */
-    aout_DecSynchronize(aout, block->i_pts);
+    aout_DecSynchronize(aout, owner->original_pts);
 
     /* Output */
     owner->sync.discontinuity = false;
-    aout->play(aout, block, block->i_pts);
+    aout->play(aout, block, owner->original_pts);
+    owner->original_pts = VLC_TICK_INVALID;
     atomic_fetch_add_explicit(&owner->buffers_played, 1, memory_order_relaxed);
     return ret;
 drop:
     owner->sync.discontinuity = true;
     block_Release (block);
     atomic_fetch_add_explicit(&owner->buffers_lost, 1, memory_order_relaxed);
+    owner->original_pts = VLC_TICK_INVALID;
     return ret;
 }
 
@@ -428,4 +446,5 @@ void aout_DecFlush (audio_output_t *aout, bool wait)
         aout->flush(aout, wait);
     }
     owner->sync.discontinuity = true;
+    owner->original_pts = VLC_TICK_INVALID;
 }
-- 
2.20.1



More information about the vlc-devel mailing list