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

Thomas Guillem thomas at gllm.fr
Wed Dec 2 10:10:49 CET 2015


Can I push 1/2 and 2/2 (2nd version) ?

On Tue, Dec 1, 2015, at 11:44, Thomas Guillem wrote:
> 
> On Tue, Dec 1, 2015, at 11:43, 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 | 39 ++++++++++++++++++++++++++++++++++-----
> >  1 file changed, 34 insertions(+), 5 deletions(-)
> > 
> > diff --git a/src/input/decoder.c b/src/input/decoder.c
> > index c4fb6a1..aa36aec 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>
> >  
> > @@ -91,6 +92,7 @@ struct decoder_owner_sys_t
> >      vlc_cond_t  wait_request;
> >      vlc_cond_t  wait_acknowledge;
> >      vlc_cond_t  wait_fifo; /* TODO: merge with wait_acknowledge */
> > +    vlc_cond_t  wait_timed;
> 
> I don't like adding a new cond...
> But it's either adding a new cond or adding a new boolean that is owned
> by the owner->lock (and then, you have to lock, reset the boolean,
> unlock from the DecoderThread when flushing is done).
> 
> >  
> >      /* -- These variables need locking on write(only) -- */
> >      audio_output_t *p_aout;
> > @@ -619,6 +621,25 @@ 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;
> > +
> > +    if (deadline - mdate() <= 0)
> > +        return VLC_SUCCESS;
> 
> I also added a deadline check in order to don't lock and wait for
> nothing.
> 
> > +
> > +    vlc_fifo_Lock( p_owner->p_fifo );
> > +    int ret = 0;
> > +    while( !p_owner->flushing && ret != ETIMEDOUT )
> > +        ret = vlc_fifo_TimedWaitCond( p_owner->p_fifo,
> > &p_owner->wait_timed,
> > +                                      deadline );
> > +    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 +1043,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 +1052,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 +1176,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 );
> >  }
> >  
> > @@ -1499,6 +1519,7 @@ static decoder_t * CreateDecoder( vlc_object_t
> > *p_parent,
> >      vlc_cond_init( &p_owner->wait_request );
> >      vlc_cond_init( &p_owner->wait_acknowledge );
> >      vlc_cond_init( &p_owner->wait_fifo );
> > +    vlc_cond_init( &p_owner->wait_timed );
> >  
> >      /* Set buffers allocation callbacks for the decoders */
> >      p_dec->pf_aout_format_update = aout_update_format;
> > @@ -1642,6 +1663,7 @@ static void DeleteDecoder( decoder_t * p_dec )
> >          vlc_object_release( p_owner->p_packetizer );
> >      }
> >  
> > +    vlc_cond_destroy( &p_owner->wait_timed );
> >      vlc_cond_destroy( &p_owner->wait_fifo );
> >      vlc_cond_destroy( &p_owner->wait_acknowledge );
> >      vlc_cond_destroy( &p_owner->wait_request );
> > @@ -1757,6 +1779,12 @@ void input_DecoderDelete( decoder_t *p_dec )
> >  
> >      vlc_cancel( p_owner->thread );
> >  
> > +    vlc_fifo_Lock( p_owner->p_fifo );
> > +    /* Signal DecoderTimedWait */
> > +    p_owner->flushing = true;
> > +    vlc_cond_signal( &p_owner->wait_timed );
> > +    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;
> > @@ -1891,6 +1919,7 @@ void input_DecoderFlush( decoder_t *p_dec )
> >          p_owner->frames_countdown++;
> >  
> >      vlc_fifo_Signal( p_owner->p_fifo );
> > +    vlc_cond_signal( &p_owner->wait_timed );
> >  
> >      vlc_fifo_Unlock( p_owner->p_fifo );
> >  }
> > -- 
> > 2.1.4
> > 


More information about the vlc-devel mailing list