[vlc-devel] [RFC PATCH 2/2] decoder: interruptible mwait
Thomas Guillem
thomas at gllm.fr
Mon Nov 30 15:49:50 CET 2015
On Mon, Nov 30, 2015, at 14:57, Thomas Guillem wrote:
> A recent error in srt parsing lead the SPU DecoderThread to wait for
> 160000sec
> before displaying an spu. Therefore, you had to wait for that time when
> closing
> or flushing this decoder.
I confused deadline and duration, there is no subsdec error. With the
sample I tested, you have to wait for 130 seconds for the first
subtitle. This commit is still needed because you don't want to for 130
seconds when closing.
>
> mwait (called from Audio and SPU DecoderThread) can now be interrupted
> when
> flushing or closing.
>
> There is no check for this deadline. Maybe we should also test it in
> order to
> not exceed a certain value (more than 3seconds ?).
> ---
> src/input/decoder.c | 40 +++++++++++++++++++++++++++++++++-------
> 1 file changed, 33 insertions(+), 7 deletions(-)
>
> diff --git a/src/input/decoder.c b/src/input/decoder.c
> index 0f08198..f7f9d0c 100644
> --- a/src/input/decoder.c
> +++ b/src/input/decoder.c
> @@ -107,6 +107,7 @@ struct decoder_owner_sys_t
> bool b_waiting;
> bool b_first;
> bool b_has_data;
> + mtime_t wait_deadline;
>
> /* Flushing */
> bool flushing;
> @@ -619,6 +620,23 @@ static void DecoderWaitUnblock( decoder_t *p_dec )
> }
> }
>
> +/* DecoderTimedWait: Interruptible wait
> + * Returns VLC_SUCCESS if wait was not interrupted, and VLC_EGENERIC
> otherwise */
> +static int DecoderTimedWait( decoder_t *p_dec, mtime_t deadline )
> +{
> + decoder_owner_sys_t *p_owner = p_dec->p_owner;
> +
> + vlc_assert_locked( &p_owner->lock );
> + p_owner->wait_deadline = deadline;
> +
> + int ret = 0;
> + while( p_owner->wait_deadline > 0 && ret != ETIMEDOUT )
> + ret = vlc_cond_timedwait( &p_owner->wait_request,
> &p_owner->lock,
> + p_owner->wait_deadline );
> +
> + return ret == ETIMEDOUT ? VLC_SUCCESS : VLC_EGENERIC;
> +}
> +
> static inline void DecoderUpdatePreroll( int64_t *pi_preroll, const
> block_t *p )
> {
> if( p->i_flags & (BLOCK_FLAG_PREROLL|BLOCK_FLAG_DISCONTINUITY) )
> @@ -1016,21 +1034,21 @@ static void DecoderPlayAudio( decoder_t *p_dec,
> block_t *p_audio,
> DecoderWaitUnblock( p_dec );
> DecoderFixTs( p_dec, &p_audio->i_pts, NULL, &p_audio->i_length,
> &i_rate, AOUT_MAX_ADVANCE_TIME );
> - vlc_mutex_unlock( &p_owner->lock );
>
> audio_output_t *p_aout = p_owner->p_aout;
>
> if( p_aout == NULL || 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
> + || DecoderTimedWait( p_dec, p_audio->i_pts - AOUT_MAX_PREPARE_TIME
> ) )
> {
> + vlc_mutex_unlock( &p_owner->lock );
> msg_Dbg( p_dec, "discarded audio buffer" );
> *pi_lost_sum += 1;
> block_Release( p_audio );
> return;
> }
> -
> - mwait( p_audio->i_pts - AOUT_MAX_PREPARE_TIME );
> + vlc_mutex_unlock( &p_owner->lock );
>
> if( aout_DecPlay( p_aout, p_audio, i_rate ) == 0 )
> *pi_played_sum += 1;
> @@ -1154,15 +1172,16 @@ static void DecoderPlaySpu( decoder_t *p_dec,
> subpicture_t *p_subpic )
> DecoderWaitUnblock( p_dec );
> DecoderFixTs( p_dec, &p_subpic->i_start, &p_subpic->i_stop, NULL,
> NULL, INT64_MAX );
> - vlc_mutex_unlock( &p_owner->lock );
>
> - if( p_subpic->i_start <= VLC_TS_INVALID )
> + if( p_subpic->i_start <= VLC_TS_INVALID
> + || DecoderTimedWait( p_dec, p_subpic->i_start -
> SPU_MAX_PREPARE_TIME ) )
> {
> + vlc_mutex_unlock( &p_owner->lock );
> subpicture_Delete( p_subpic );
> return;
> }
> + vlc_mutex_unlock( &p_owner->lock );
>
> - mwait( p_subpic->i_start - SPU_MAX_PREPARE_TIME );
> vout_PutSubpicture( p_vout, p_subpic );
> }
>
> @@ -1483,6 +1502,7 @@ static decoder_t * CreateDecoder( vlc_object_t
> *p_parent,
> p_owner->b_draining = false;
> atomic_init( &p_owner->drained, false );
> p_owner->b_idle = false;
> + p_owner->wait_deadline = 0;
>
> es_format_Init( &p_owner->fmt, UNKNOWN_ES, 0 );
>
> @@ -1760,6 +1780,7 @@ void input_DecoderDelete( decoder_t *p_dec )
> /* Make sure we aren't waiting/decoding anymore */
> vlc_mutex_lock( &p_owner->lock );
> p_owner->b_waiting = false;
> + p_owner->wait_deadline = 0;
> vlc_cond_signal( &p_owner->wait_request );
>
> /* If the video output is paused or too slow, the decoded picture
> FIFO may
> @@ -1891,6 +1912,11 @@ void input_DecoderFlush( decoder_t *p_dec )
> vlc_fifo_Signal( p_owner->p_fifo );
>
> vlc_fifo_Unlock( p_owner->p_fifo );
> +
> + vlc_mutex_lock( &p_owner->lock );
> + p_owner->wait_deadline = 0;
> + vlc_cond_signal( &p_owner->wait_request );
> + vlc_mutex_unlock( &p_owner->lock );
> }
>
> void input_DecoderIsCcPresent( decoder_t *p_dec, bool pb_present[4] )
> --
> 2.1.4
>
More information about the vlc-devel
mailing list