[vlc-commits] decoder: work around race whereby pause kicks during lip-sync

Rémi Denis-Courmont git at videolan.org
Mon Apr 23 21:47:38 CEST 2012


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Mon Apr 23 22:45:23 2012 +0300| [6ccfc4a3c1706d94b932e1154dfee71c232c5fbb] | committer: Rémi Denis-Courmont

decoder: work around race whereby pause kicks during lip-sync

DecoderWaitDate() releases the lock and thus state can change.
In particular, the aout can be destroyed, or paused or resumed.
So those checks must be done after DecoderWaitDate().

There may be a cleaner way to do this, but it will likely be more
invasive. This patch fixes #5825 and probably #6369 too.

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

 src/input/decoder.c |   19 ++++++++++++-------
 1 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/src/input/decoder.c b/src/input/decoder.c
index e043448..b68df6f 100644
--- a/src/input/decoder.c
+++ b/src/input/decoder.c
@@ -1188,13 +1188,14 @@ static void DecoderPlayAudio( decoder_t *p_dec, aout_buffer_t *p_audio,
 
     for( ;; )
     {
-        bool b_has_more = false;
-        bool b_reject;
-        DecoderWaitUnblock( p_dec, &b_reject );
+        bool b_has_more = false, b_paused, b_reject;
 
+        DecoderWaitUnblock( p_dec, &b_reject );
         if( p_owner->b_buffering )
             break;
 
+        b_paused = p_owner->b_paused;
+
         /* */
         if( p_owner->buffer.p_audio )
         {
@@ -1214,15 +1215,19 @@ static void DecoderPlayAudio( decoder_t *p_dec, aout_buffer_t *p_audio,
         DecoderFixTs( p_dec, &p_audio->i_pts, NULL, &p_audio->i_length,
                       &i_rate, AOUT_MAX_ADVANCE_TIME );
 
-        if( !p_aout ||
-            p_audio->i_pts <= VLC_TS_INVALID ||
-            i_rate < INPUT_RATE_DEFAULT/AOUT_MAX_INPUT_RATE ||
-            i_rate > INPUT_RATE_DEFAULT*AOUT_MAX_INPUT_RATE )
+        if( p_audio->i_pts <= VLC_TS_INVALID
+         || i_rate < INPUT_RATE_DEFAULT/AOUT_MAX_INPUT_RATE
+         || i_rate > INPUT_RATE_DEFAULT*AOUT_MAX_INPUT_RATE )
             b_reject = true;
 
         DecoderWaitDate( p_dec, &b_reject,
                          p_audio->i_pts - AOUT_MAX_PREPARE_TIME );
 
+        if( unlikely(p_owner->b_paused != b_paused) )
+            continue; /* race with input thread? retry... */
+        if( p_aout == NULL )
+            b_reject = true;
+
         if( !b_reject )
         {
             assert( !p_owner->b_paused );



More information about the vlc-commits mailing list