[vlc-devel] [PATCH] decoder: reload module if aout restart and fails during playback
Thomas Guillem
thomas at gllm.fr
Tue Jul 26 18:19:33 CEST 2016
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" );
+
+ 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
More information about the vlc-devel
mailing list