[vlc-commits] aout_OutputNextBuffer: move both FIFOs atomically and clean up

Rémi Denis-Courmont git at videolan.org
Thu Jun 9 22:48:47 CEST 2011


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Thu Jun  9 23:44:48 2011 +0300| [cbb3e10972ab558bc0020aa3d448da2517916560] | committer: Rémi Denis-Courmont

aout_OutputNextBuffer: move both FIFOs atomically and clean up

This avoids racing with decoder thread (audio input & mixer) w.r.t. the
FIFO timestamps.

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

 src/audio_output/output.c |   55 +++++++++++++++-----------------------------
 1 files changed, 19 insertions(+), 36 deletions(-)

diff --git a/src/audio_output/output.c b/src/audio_output/output.c
index eecd3e5..d2626c3 100644
--- a/src/audio_output/output.c
+++ b/src/audio_output/output.c
@@ -251,31 +251,26 @@ aout_buffer_t * aout_OutputNextBuffer( aout_instance_t * p_aout,
                                        mtime_t start_date,
                                        bool b_can_sleek )
 {
+    aout_fifo_t *p_fifo = &p_aout->output.fifo;
     aout_buffer_t * p_buffer;
     mtime_t now = mdate();
 
     aout_lock_output_fifo( p_aout );
 
-    p_buffer = p_aout->output.fifo.p_first;
-
     /* Drop the audio sample if the audio output is really late.
      * 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_buffer->i_pts <
-            (b_can_sleek ? start_date : now) - AOUT_PTS_TOLERANCE )
+    while( ((p_buffer = p_fifo->p_first) != NULL)
+     && p_buffer->i_pts < (b_can_sleek ? start_date : now) - AOUT_PTS_TOLERANCE )
     {
         msg_Dbg( p_aout, "audio output is too slow (%"PRId64"), "
                  "trashing %"PRId64"us", now - p_buffer->i_pts,
                  p_buffer->i_length );
-        p_buffer = p_buffer->p_next;
-        aout_BufferFree( p_aout->output.fifo.p_first );
-        p_aout->output.fifo.p_first = p_buffer;
+        aout_BufferFree( aout_FifoPop( p_fifo ) );
     }
 
-    if ( p_buffer == NULL )
+    if( p_buffer == NULL )
     {
-        p_aout->output.fifo.pp_last = &p_aout->output.fifo.p_first;
-
 #if 0 /* This is bad because the audio output might just be trying to fill
        * in its internal buffers. And anyway, it's up to the audio output
        * to deal with this kind of starvation. */
@@ -285,17 +280,17 @@ aout_buffer_t * aout_OutputNextBuffer( aout_instance_t * p_aout,
         if ( !p_aout->output.b_starving )
             msg_Dbg( p_aout,
                  "audio output is starving (no input), playing silence" );
-        p_aout->output.b_starving = 1;
+        p_aout->output.b_starving = true;
 #endif
-
         aout_unlock_output_fifo( p_aout );
         return NULL;
     }
 
+    mtime_t delta = start_date - p_buffer->i_pts;
     /* Here we suppose that all buffers have the same duration - this is
      * generally true, and anyway if it's wrong it won't be a disaster.
      */
-    if ( p_buffer->i_pts > start_date + p_buffer->i_length )
+    if ( 0 > delta + p_buffer->i_length )
     /*
      *                   + AOUT_PTS_TOLERANCE )
      * There is no reason to want that, it just worsen the scheduling of
@@ -303,43 +298,31 @@ aout_buffer_t * aout_OutputNextBuffer( aout_instance_t * p_aout,
      * --Gibalou
      */
     {
-        const mtime_t i_delta = p_buffer->i_pts - start_date;
-        aout_unlock_output_fifo( p_aout );
-
         if ( !p_aout->output.b_starving )
             msg_Dbg( p_aout, "audio output is starving (%"PRId64"), "
-                     "playing silence", i_delta );
-        p_aout->output.b_starving = 1;
+                     "playing silence", -delta );
+        p_aout->output.b_starving = true;
+        aout_unlock_output_fifo( p_aout );
         return NULL;
     }
 
-    p_aout->output.b_starving = 0;
-
-    p_aout->output.fifo.p_first = p_buffer->p_next;
-    if ( p_buffer->p_next == NULL )
-    {
-        p_aout->output.fifo.pp_last = &p_aout->output.fifo.p_first;
-    }
+    p_aout->output.b_starving = false;
+    p_buffer = aout_FifoPop( p_fifo );
 
     if( !b_can_sleek )
     {
-        mtime_t difference = start_date - p_buffer->i_pts;
-
-        if( difference > AOUT_PTS_TOLERANCE
-         || difference < -AOUT_PTS_TOLERANCE )
+        if( delta > AOUT_PTS_TOLERANCE || delta < -AOUT_PTS_TOLERANCE )
         {
+            aout_unlock_output_fifo( p_aout );
             /* Try to compensate the drift by doing some resampling. */
             msg_Warn( p_aout, "output date isn't PTS date, requesting "
-                      "resampling (%"PRId64")", difference );
-
-            aout_FifoMoveDates( &p_aout->output.fifo, difference );
-            aout_unlock_output_fifo( p_aout );
+                      "resampling (%"PRId64")", delta );
 
             aout_lock_input_fifos( p_aout );
-            aout_fifo_t *p_fifo = &p_aout->p_input->mixer.fifo;
-            aout_FifoMoveDates( p_fifo, difference );
+            aout_lock_output_fifo( p_aout );
+            aout_FifoMoveDates( &p_aout->p_input->mixer.fifo, delta );
+            aout_FifoMoveDates( p_fifo, delta );
             aout_unlock_input_fifos( p_aout );
-            return p_buffer;
         }
     }
     aout_unlock_output_fifo( p_aout );



More information about the vlc-commits mailing list