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

Thomas Guillem thomas at gllm.fr
Mon Nov 30 18:15:49 CET 2015



On Mon, Nov 30, 2015, at 18:10, Rémi Denis-Courmont wrote:
> On Monday 30 November 2015 18:00:48 Thomas Guillem wrote:
> > mwait (called from Audio and SPU DecoderThread) can now be interrupted when
> > flushing or closing.
> > 
> > This fixes a too long closing/flushing time when the next spu or audio block
> > is too distant.
> > ---
> >  src/input/decoder.c | 34 +++++++++++++++++++++++++++++-----
> >  1 file changed, 29 insertions(+), 5 deletions(-)
> > 
> > diff --git a/src/input/decoder.c b/src/input/decoder.c
> > index 0f08198..314b00f 100644
> > --- a/src/input/decoder.c
> > +++ b/src/input/decoder.c
> > @@ -30,6 +30,7 @@
> >  # include "config.h"
> >  #endif
> >  #include <assert.h>
> > +#include <errno.h>
> > 
> >  #include <vlc_common.h>
> > 
> > @@ -107,6 +108,7 @@ struct decoder_owner_sys_t
> >      bool b_waiting;
> >      bool b_first;
> >      bool b_has_data;
> > +    bool b_abort_timedwait;
> > 
> >      /* Flushing */
> >      bool flushing;
> > @@ -619,6 +621,21 @@ 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_fifo_Lock( p_owner->p_fifo );
> > +    int ret = 0;
> > +    while( !p_owner->b_abort_timedwait && ret != ETIMEDOUT )
> > +        ret = vlc_fifo_TimedWait( p_owner->p_fifo, deadline );
> 
> Err, won´t that pointlessly wake up each and every time the decoder owner 
> queues new data?

Yes, didn't thought about it. So, do we add an other cond ?
Is it possible to use wait_request cond with the fifo mutex ?

> 
> (IMHO, this mwait() should be removed completely, but that might be
> easier 
> written than implemented.)
> 
> > +    vlc_fifo_Unlock( p_owner->p_fifo );
> > +
> > +    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) )
> > @@ -1022,7 +1039,8 @@ static void DecoderPlayAudio( decoder_t *p_dec,
> > block_t *p_audio,
> > 
> >      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 ) )
> > {
> >          msg_Dbg( p_dec, "discarded audio buffer" );
> >          *pi_lost_sum += 1;
> > @@ -1030,8 +1048,6 @@ static void DecoderPlayAudio( decoder_t *p_dec,
> > block_t *p_audio, return;
> >      }
> > 
> > -    mwait( p_audio->i_pts - AOUT_MAX_PREPARE_TIME );
> > -
> >      if( aout_DecPlay( p_aout, p_audio, i_rate ) == 0 )
> >          *pi_played_sum += 1;
> > 
> > @@ -1156,13 +1172,13 @@ static void DecoderPlaySpu( decoder_t *p_dec,
> > subpicture_t *p_subpic ) 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 )
> > ) {
> >          subpicture_Delete( p_subpic );
> >          return;
> >      }
> > 
> > -    mwait( p_subpic->i_start - SPU_MAX_PREPARE_TIME );
> >      vout_PutSubpicture( p_vout, p_subpic );
> >  }
> > 
> > @@ -1351,6 +1367,7 @@ static void *DecoderThread( void *p_data )
> >               * is called again. This will avoid a second useless flush (but
> > * harmless). */
> >              p_owner->flushing = false;
> > +            p_owner->b_abort_timedwait = false;
> > 
> >              continue;
> >          }
> > @@ -1483,6 +1500,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->b_abort_timedwait = false;
> > 
> >      es_format_Init( &p_owner->fmt, UNKNOWN_ES, 0 );
> > 
> > @@ -1757,6 +1775,11 @@ void input_DecoderDelete( decoder_t *p_dec )
> > 
> >      vlc_cancel( p_owner->thread );
> > 
> > +    vlc_fifo_Lock( p_owner->p_fifo );
> > +    p_owner->b_abort_timedwait = true;
> > +    vlc_fifo_Signal( p_owner->p_fifo );
> > +    vlc_fifo_Unlock( p_owner->p_fifo );
> > +
> >      /* Make sure we aren't waiting/decoding anymore */
> >      vlc_mutex_lock( &p_owner->lock );
> >      p_owner->b_waiting = false;
> > @@ -1881,6 +1904,7 @@ void input_DecoderFlush( decoder_t *p_dec )
> >       * dequeued by DecoderThread and there is no need to flush a second
> > time in * a row. */
> >      p_owner->flushing = true;
> > +    p_owner->b_abort_timedwait = true;
> > 
> >      /* Flushing video decoder when paused: increment frames_countdown in
> > order * to display one frame */
> 
> -- 
> 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