[vlc-commits] Change audio output tolerance times

Rémi Denis-Courmont git at videolan.org
Wed Jul 20 17:54:43 CEST 2011


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Wed Jul 20 18:19:40 2011 +0300| [ef4280c5ba23487eddaa62773a318032016cf6dc] | committer: Rémi Denis-Courmont

Change audio output tolerance times

Maximum buffering time (AOUT_MAX_PREPARE_TIME) is increased to 2
seconds, consistent with increases in audio hardware buffer sizes.
In practice however, this is bound to the input PTS delay.

Maximum advance time is updated accordingly (+ 1 second).

Lip desynchronization tolerance is segregated, following EBU R37:
 - 40 ms (as before) maximum audio advance
 - 60 ms maximum audio delay.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=ef4280c5ba23487eddaa62773a318032016cf6dc
---

 include/vlc_aout.h             |   17 +++++++++++------
 modules/audio_output/alsa.c    |    3 ++-
 modules/audio_output/directx.c |    2 +-
 modules/audio_output/oss.c     |    2 +-
 modules/audio_output/waveout.c |    6 +++---
 src/audio_output/input.c       |    9 ++++-----
 src/audio_output/output.c      |   24 ++++++++----------------
 7 files changed, 30 insertions(+), 33 deletions(-)

diff --git a/include/vlc_aout.h b/include/vlc_aout.h
index 5e8af52..bb64328 100644
--- a/include/vlc_aout.h
+++ b/include/vlc_aout.h
@@ -33,19 +33,24 @@
 
 /* Buffers which arrive in advance of more than AOUT_MAX_ADVANCE_TIME
  * will be considered as bogus and be trashed */
-#define AOUT_MAX_ADVANCE_TIME           (DEFAULT_PTS_DELAY * 5)
+#define AOUT_MAX_ADVANCE_TIME           (AOUT_MAX_PREPARE_TIME + CLOCK_FREQ)
 
 /* Buffers which arrive in advance of more than AOUT_MAX_PREPARE_TIME
  * will cause the calling thread to sleep */
-#define AOUT_MAX_PREPARE_TIME           (CLOCK_FREQ/2)
+#define AOUT_MAX_PREPARE_TIME           (2 * CLOCK_FREQ)
 
 /* Buffers which arrive after pts - AOUT_MIN_PREPARE_TIME will be trashed
  * to avoid too heavy resampling */
-#define AOUT_MIN_PREPARE_TIME           (CLOCK_FREQ/25)
+#define AOUT_MIN_PREPARE_TIME           AOUT_MAX_PTS_ADVANCE
 
-/* Max acceptable delay between the coded PTS and the actual presentation
- * time, without resampling */
-#define AOUT_PTS_TOLERANCE              (CLOCK_FREQ/25)
+/* Tolerance values from EBU Recommendation 37 */
+/** Maximum advance of actual audio playback time to coded PTS,
+ * above which downsampling will be performed */
+#define AOUT_MAX_PTS_ADVANCE            (CLOCK_FREQ / 25)
+
+/** Maximum delay of actual audio playback time from coded PTS,
+ * above which upsampling will be performed */
+#define AOUT_MAX_PTS_DELAY              (3 * CLOCK_FREQ / 50)
 
 /* Max acceptable resampling (in %) */
 #define AOUT_MAX_RESAMPLING             10
diff --git a/modules/audio_output/alsa.c b/modules/audio_output/alsa.c
index 2ea4b25..3f3804a 100644
--- a/modules/audio_output/alsa.c
+++ b/modules/audio_output/alsa.c
@@ -569,7 +569,8 @@ static void* ALSAThread( void *data )
 
     /* Wait for the exact time to start playing (avoids resampling) */
     vlc_sem_wait( &p_sys->wait );
-    mwait( p_sys->start_date - AOUT_PTS_TOLERANCE / 4 );
+    mwait( p_sys->start_date - AOUT_MAX_PTS_ADVANCE / 4 );
+#warning Should wait for buffer availability instead!
 
     for(;;)
         ALSAFill( p_aout );
diff --git a/modules/audio_output/directx.c b/modules/audio_output/directx.c
index d8f0a00..773bf86 100644
--- a/modules/audio_output/directx.c
+++ b/modules/audio_output/directx.c
@@ -1028,7 +1028,7 @@ static void* DirectSoundThread( void *data )
     if( !vlc_atomic_get( &p_notif->abort) )
     {
         HRESULT dsresult;
-        mwait( p_notif->start_date - AOUT_PTS_TOLERANCE / 2 );
+        mwait( p_notif->start_date - AOUT_MAX_PTS_ADVANCE / 2 );
 
         /* start playing the buffer */
         dsresult = IDirectSoundBuffer_Play( p_aout->output.p_sys->p_dsbuffer,
diff --git a/modules/audio_output/oss.c b/modules/audio_output/oss.c
index 03ef538..7037461 100644
--- a/modules/audio_output/oss.c
+++ b/modules/audio_output/oss.c
@@ -633,7 +633,7 @@ static void* OSSThread( void *obj )
             else
             {
                 mtime_t delay = next_date - mdate();
-                if( delay > AOUT_PTS_TOLERANCE )
+                if( delay > AOUT_MAX_PTS_ADVANCE )
                 {
                     msleep( delay / 2 );
                 }
diff --git a/modules/audio_output/waveout.c b/modules/audio_output/waveout.c
index 4e26e97..efcc7d9 100644
--- a/modules/audio_output/waveout.c
+++ b/modules/audio_output/waveout.c
@@ -887,10 +887,10 @@ static void* WaveOutThread( void *data )
         return NULL;
 
     msg_Dbg( p_aout, "will start to play in %"PRId64" us",
-             (p_sys->start_date - AOUT_PTS_TOLERANCE/4)-mdate());
+             (p_sys->start_date - AOUT_MAX_PTS_ADVANCE/4)-mdate());
 
     // than wait a short time... before grabbing first frames
-    mwait( p_sys->start_date - AOUT_PTS_TOLERANCE/4 );
+    mwait( p_sys->start_date - AOUT_MAX_PTS_ADVANCE/4 );
 
 #define waveout_warn(msg) msg_Warn( p_aout, "aout_OutputNextBuffer no buffer "\
                            "got next_date=%d ms, "\
@@ -937,7 +937,7 @@ static void* WaveOutThread( void *data )
                     // means we are too early to request a new buffer?
                     waveout_warn("waiting...")
                     next_date = aout_FifoFirstDate( &p_aout->output.fifo );
-                    mwait( next_date - AOUT_PTS_TOLERANCE/4 );
+                    mwait( next_date - AOUT_MAX_PTS_ADVANCE/4 );
                     next_date = mdate();
                     p_buffer = aout_OutputNextBuffer( p_aout, next_date,
                                                       b_sleek );
diff --git a/src/audio_output/input.c b/src/audio_output/input.c
index 9178c15..7283dff 100644
--- a/src/audio_output/input.c
+++ b/src/audio_output/input.c
@@ -573,11 +573,9 @@ void aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
     if( !start_date )
         start_date = p_buffer->i_pts;
 
-    mtime_t tolerance = 3 * AOUT_PTS_TOLERANCE
-                          * i_input_rate / INPUT_RATE_DEFAULT;
     mtime_t drift = start_date - p_buffer->i_pts;
 
-    if( drift < -tolerance )
+    if( drift < -i_input_rate * 3 * AOUT_MAX_PTS_ADVANCE / INPUT_RATE_DEFAULT )
     {
         msg_Warn( p_aout, "buffer way too early (%"PRId64"), clearing queue",
                   drift );
@@ -589,7 +587,8 @@ void aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
         start_date = p_buffer->i_pts;
         drift = 0;
     }
-    else if( drift > +tolerance )
+    else
+    if( drift > +i_input_rate * 3 * AOUT_MAX_PTS_DELAY / INPUT_RATE_DEFAULT )
     {
         msg_Warn( p_aout, "buffer way too late (%"PRId64"), dropping buffer",
                   drift );
@@ -607,7 +606,7 @@ void aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
     /* Run the resampler if needed.
      * We first need to calculate the output rate of this resampler. */
     if ( ( p_input->i_resampling_type == AOUT_RESAMPLING_NONE ) &&
-         ( drift < -AOUT_PTS_TOLERANCE || drift > +AOUT_PTS_TOLERANCE ) &&
+         ( drift < -AOUT_MAX_PTS_ADVANCE || drift > +AOUT_MAX_PTS_DELAY ) &&
          p_input->i_nb_resamplers > 0 )
     {
         /* Can happen in several circumstances :
diff --git a/src/audio_output/output.c b/src/audio_output/output.c
index 493ebda..c20362a 100644
--- a/src/audio_output/output.c
+++ b/src/audio_output/output.c
@@ -275,7 +275,7 @@ aout_buffer_t * aout_OutputNextBuffer( aout_instance_t * p_aout,
      * In the case of b_can_sleek, we don't use a resampler so we need to be
      * a lot more severe. */
     while( ((p_buffer = p_fifo->p_first) != NULL)
-     && p_buffer->i_pts < (b_can_sleek ? start_date : now) - AOUT_PTS_TOLERANCE )
+     && p_buffer->i_pts < (b_can_sleek ? start_date : now) - AOUT_MAX_PTS_DELAY )
     {
         msg_Dbg( p_aout, "audio output is too slow (%"PRId64"), "
                  "trashing %"PRId64"us", now - p_buffer->i_pts,
@@ -304,12 +304,6 @@ aout_buffer_t * aout_OutputNextBuffer( aout_instance_t * p_aout,
      * generally true, and anyway if it's wrong it won't be a disaster.
      */
     if ( 0 > delta + p_buffer->i_length )
-    /*
-     *                   + AOUT_PTS_TOLERANCE )
-     * There is no reason to want that, it just worsen the scheduling of
-     * an audio sample after an output starvation (ie. on start or on resume)
-     * --Gibalou
-     */
     {
         if ( !p_aout->output.b_starving )
             msg_Dbg( p_aout, "audio output is starving (%"PRId64"), "
@@ -322,17 +316,15 @@ aout_buffer_t * aout_OutputNextBuffer( aout_instance_t * p_aout,
     p_aout->output.b_starving = false;
     p_buffer = aout_FifoPop( p_fifo );
 
-    if( !b_can_sleek )
+    if( !b_can_sleek
+     && ( delta > AOUT_MAX_PTS_DELAY || delta < -AOUT_MAX_PTS_ADVANCE ) )
     {
-        if( delta > AOUT_PTS_TOLERANCE || delta < -AOUT_PTS_TOLERANCE )
-        {
-            /* Try to compensate the drift by doing some resampling. */
-            msg_Warn( p_aout, "output date isn't PTS date, requesting "
-                      "resampling (%"PRId64")", delta );
+        /* Try to compensate the drift by doing some resampling. */
+        msg_Warn( p_aout, "output date isn't PTS date, requesting "
+                  "resampling (%"PRId64")", delta );
 
-            aout_FifoMoveDates( &p_aout->p_input->mixer.fifo, delta );
-            aout_FifoMoveDates( p_fifo, delta );
-        }
+        aout_FifoMoveDates( &p_aout->p_input->mixer.fifo, delta );
+        aout_FifoMoveDates( p_fifo, delta );
     }
 out:
     aout_unlock( p_aout );



More information about the vlc-commits mailing list