[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