[vlc-devel] [RFC PATCH 2/2] decoder: interruptible mwait

Thomas Guillem thomas at gllm.fr
Mon Nov 30 17:59:08 CET 2015



On Mon, Nov 30, 2015, at 17:03, Rémi Denis-Courmont wrote:
> On Monday 30 November 2015 14:57:49 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.
> > 
> > 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 );
> 
> See below.
> 
> > 
> >      /* 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 );
> >  }
> 
> Are you sure that works if input_DecoderFlush() is called *before* 
> DecoderTimedWait()? I think it just gets stuck as without the patch.

Ah no, there is a problem indeed. I'll propose a new patch.

> 
> >  void input_DecoderIsCcPresent( decoder_t *p_dec, bool pb_present[4] )
> 
> -- 
> Rémi Denis-Courmont
> http://www.remlab.net/
> 
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel


More information about the vlc-devel mailing list