[vlc-devel] [PATCH] decoder: reload module if aout restart and fails during playback

Thomas Guillem thomas at gllm.fr
Wed Jul 27 10:35:42 CEST 2016



On Tue, Jul 26, 2016, at 18:19, Thomas Guillem wrote:
> In order to be able to change from S/PDIF to PCM since there is no S/PDIF
> converter anymore.
> 
> We can't reload directly from DecoderPlayAudio since this function may be
> called from a running asynchronous decoder.
> ---
>  src/audio_output/aout_internal.h |  2 +-
>  src/audio_output/dec.c           | 11 ++++++++---
>  src/input/decoder.c              | 15 ++++++++++++++-
>  3 files changed, 23 insertions(+), 5 deletions(-)
> 
> diff --git a/src/audio_output/aout_internal.h
> b/src/audio_output/aout_internal.h
> index 4990597..6e2134c 100644
> --- a/src/audio_output/aout_internal.h
> +++ b/src/audio_output/aout_internal.h
> @@ -137,7 +137,7 @@ bool aout_ChangeFilterString( vlc_object_t *manager,
> vlc_object_t *aout,
>  int aout_DecNew(audio_output_t *, const audio_sample_format_t *,
>                  const audio_replay_gain_t *, const aout_request_vout_t
>                  *);
>  void aout_DecDelete(audio_output_t *);
> -void aout_DecPlay(audio_output_t *, block_t *, int i_input_rate);
> +void aout_DecPlay(audio_output_t *, block_t *, int i_input_rate, bool
> *);
>  void aout_DecGetResetStats(audio_output_t *, unsigned *, unsigned *);
>  void aout_DecChangePause(audio_output_t *, bool b_paused, mtime_t
>  i_date);
>  void aout_DecFlush(audio_output_t *, bool wait);
> diff --git a/src/audio_output/dec.c b/src/audio_output/dec.c
> index 84c2f60..7731f83 100644
> --- a/src/audio_output/dec.c
> +++ b/src/audio_output/dec.c
> @@ -131,10 +131,11 @@ void aout_DecDelete (audio_output_t *aout)
>      var_Destroy (aout, "stereo-mode");
>  }
>  
> -static int aout_CheckReady (audio_output_t *aout)
> +static int aout_CheckReady (audio_output_t *aout, bool *reload_decoder)
>  {
>      aout_owner_t *owner = aout_owner (aout);
>  
> +    *reload_decoder = false;
>      int restart = atomic_exchange (&owner->restart, 0);
>      if (unlikely(restart))
>      {
> @@ -166,6 +167,9 @@ static int aout_CheckReady (audio_output_t *aout)
>              {
>                  aout_OutputDelete (aout);
>                  owner->mixer_format.i_format = 0;
> +                /* The aout restarted but there is no valid filters
> anymore:
> +                 * ask the decoder to restart */
> +                *reload_decoder = restart & AOUT_RESTART_OUTPUT;
>              }
>          }
>          /* TODO: This would be a good time to call clean up any video
>          output
> @@ -339,7 +343,8 @@ static void aout_DecSynchronize (audio_output_t
> *aout, mtime_t dec_pts,
>  /*****************************************************************************
>   * aout_DecPlay : filter & mix the decoded buffer
>   *****************************************************************************/
> -void aout_DecPlay (audio_output_t *aout, block_t *block, int input_rate)
> +void aout_DecPlay (audio_output_t *aout, block_t *block, int input_rate,
> +                   bool *reload_decoder)
>  {
>      aout_owner_t *owner = aout_owner (aout);
>  
> @@ -351,7 +356,7 @@ void aout_DecPlay (audio_output_t *aout, block_t
> *block, int input_rate)
>                                   / owner->input_format.i_rate;
>  
>      aout_OutputLock (aout);
> -    if (unlikely(aout_CheckReady (aout)))
> +    if (unlikely(aout_CheckReady (aout, reload_decoder)))
>          goto drop; /* Pipeline is unrecoverably broken :-( */
>  
>      const mtime_t now = mdate (), advance = block->i_pts - now;
> diff --git a/src/input/decoder.c b/src/input/decoder.c
> index 6a847d7..978e2f4 100644
> --- a/src/input/decoder.c
> +++ b/src/input/decoder.c
> @@ -80,6 +80,7 @@ struct decoder_owner_sys_t
>      /* */
>      bool           b_fmt_description;
>      vlc_meta_t     *p_description;
> +    atomic_bool    reload;
>  
>      /* fifo */
>      block_fifo_t *p_fifo;
> @@ -1123,7 +1124,10 @@ static int DecoderPlayAudio( decoder_t *p_dec,
> block_t *p_audio,
>       && i_rate <= INPUT_RATE_DEFAULT*AOUT_MAX_INPUT_RATE
>       && !DecoderTimedWait( p_dec, p_audio->i_pts - AOUT_MAX_PREPARE_TIME
>       ) )
>      {
> -        aout_DecPlay( p_aout, p_audio, i_rate );
> +        bool restart_decoder;
> +        aout_DecPlay( p_aout, p_audio, i_rate, &restart_decoder );
> +        if( restart_decoder )
> +            atomic_store( &p_owner->reload, true );
>      }
>      else
>      {
> @@ -1345,6 +1349,14 @@ static void DecoderProcess( decoder_t *p_dec,
> block_t *p_block )
>      if( p_dec->b_error )
>          goto error;
>  
> +    if( atomic_exchange( &p_owner->reload, false ) )
> +    {
> +        msg_Warn( p_dec, "Reloading the decoder module" );
> +

I'll also need to reset p_owner->fmt.audio, so that the next call to
aout_update_format() will create a new aout and not re-use the previous
one.

> +        if( ReloadDecoder( p_dec, NULL, &p_dec->fmt_in ) != VLC_SUCCESS
> )
> +            goto error;
> +    }
> +
>      if( p_block )
>      {
>          if( p_block->i_buffer <= 0 )
> @@ -1593,6 +1605,7 @@ static decoder_t * CreateDecoder( vlc_object_t
> *p_parent,
>      p_owner->flushing = false;
>      p_owner->b_draining = false;
>      atomic_init( &p_owner->drained, false );
> +    atomic_init( &p_owner->reload, false );
>      p_owner->b_idle = false;
>  
>      es_format_Init( &p_owner->fmt, UNKNOWN_ES, 0 );
> -- 
> 2.8.1
> 
> _______________________________________________
> 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