Commit 1d8de367 authored by Rémi Denis-Courmont's avatar 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.
parent 483871eb
...@@ -1188,13 +1188,14 @@ static void DecoderPlayAudio( decoder_t *p_dec, aout_buffer_t *p_audio, ...@@ -1188,13 +1188,14 @@ static void DecoderPlayAudio( decoder_t *p_dec, aout_buffer_t *p_audio,
for( ;; ) for( ;; )
{ {
bool b_has_more = false; bool b_has_more = false, b_paused, b_reject;
bool b_reject;
DecoderWaitUnblock( p_dec, &b_reject );
DecoderWaitUnblock( p_dec, &b_reject );
if( p_owner->b_buffering ) if( p_owner->b_buffering )
break; break;
b_paused = p_owner->b_paused;
/* */ /* */
if( p_owner->buffer.p_audio ) if( p_owner->buffer.p_audio )
{ {
...@@ -1214,15 +1215,19 @@ static void DecoderPlayAudio( decoder_t *p_dec, aout_buffer_t *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, DecoderFixTs( p_dec, &p_audio->i_pts, NULL, &p_audio->i_length,
&i_rate, AOUT_MAX_ADVANCE_TIME ); &i_rate, AOUT_MAX_ADVANCE_TIME );
if( !p_aout || if( p_audio->i_pts <= VLC_TS_INVALID
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 || || i_rate > INPUT_RATE_DEFAULT*AOUT_MAX_INPUT_RATE )
i_rate > INPUT_RATE_DEFAULT*AOUT_MAX_INPUT_RATE )
b_reject = true; b_reject = true;
DecoderWaitDate( p_dec, &b_reject, DecoderWaitDate( p_dec, &b_reject,
p_audio->i_pts - AOUT_MAX_PREPARE_TIME ); 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 ) if( !b_reject )
{ {
assert( !p_owner->b_paused ); assert( !p_owner->b_paused );
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment