vlc | branch: master | Thomas Guillem <[email protected]> | Wed Jul 27 15:47:12 2016 +0200| [dcd9274c7aeb5c7d88e75e993750122917a919fd] | committer: Thomas Guillem
decoder: add decoder_RequestReload See next commit for RELOAD_DECODER_AOUT usage. > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=dcd9274c7aeb5c7d88e75e993750122917a919fd --- include/vlc_codec.h | 7 +++++++ src/input/decoder.c | 44 +++++++++++++++++++++++++++++++++++++++----- src/libvlccore.sym | 1 + 3 files changed, 47 insertions(+), 5 deletions(-) diff --git a/include/vlc_codec.h b/include/vlc_codec.h index 2d01d26..9c36643 100644 --- a/include/vlc_codec.h +++ b/include/vlc_codec.h @@ -367,6 +367,13 @@ VLC_API block_t * decoder_NewAudioBuffer( decoder_t *, int i_size ) VLC_USED; */ VLC_API subpicture_t * decoder_NewSubpicture( decoder_t *, const subpicture_updater_t * ) VLC_USED; +/* + * Request that the decoder should be reloaded. The current module will be + * unloaded. Reloading a module may cause a loss of frames. There is no + * warranty that pf_decode_* callbacks won't be called again after this call. + */ +VLC_API void decoder_RequestReload( decoder_t * ); + /** * This function gives all input attachments at once. * diff --git a/src/input/decoder.c b/src/input/decoder.c index 39c1c2d..21f822a 100644 --- a/src/input/decoder.c +++ b/src/input/decoder.c @@ -54,6 +54,16 @@ #include "../video_output/vout_control.h" +/* + * Possibles values set in p_owner->reload atomic + */ +enum reload +{ + RELOAD_NO_REQUEST, + RELOAD_DECODER, /* Reload the decoder module */ + RELOAD_DECODER_AOUT /* Stop the aout and reload the decoder module */ +}; + struct decoder_owner_sys_t { input_thread_t *p_input; @@ -80,6 +90,7 @@ struct decoder_owner_sys_t /* */ bool b_fmt_description; vlc_meta_t *p_description; + atomic_int reload; /* fifo */ block_fifo_t *p_fifo; @@ -191,7 +202,7 @@ static void UnloadDecoder( decoder_t *p_dec ) } static int ReloadDecoder( decoder_t *p_dec, bool b_packetizer, - const es_format_t *restrict p_fmt ) + const es_format_t *restrict p_fmt, enum reload reload ) { /* Copy p_fmt since it can be destroyed by UnloadDecoder */ es_format_t fmt_in; @@ -589,6 +600,14 @@ subpicture_t *decoder_NewSubpicture( decoder_t *p_decoder, return p_subpicture; } +void decoder_RequestReload( decoder_t * p_dec ) +{ + decoder_owner_sys_t *p_owner = p_dec->p_owner; + /* Don't override reload if it's RELOAD_DECODER_AOUT */ + int expected = RELOAD_NO_REQUEST; + atomic_compare_exchange_strong( &p_owner->reload, &expected, RELOAD_DECODER ); +} + /* decoder_GetInputAttachments: */ int decoder_GetInputAttachments( decoder_t *p_dec, @@ -1031,8 +1050,8 @@ static void DecoderProcessVideo( decoder_t *p_dec, block_t *p_block ) /* Drain the decoder module */ DecoderDecodeVideo( p_dec, NULL ); - if( ReloadDecoder( p_dec, false, - &p_packetizer->fmt_out ) != VLC_SUCCESS ) + if( ReloadDecoder( p_dec, false, &p_packetizer->fmt_out, + RELOAD_DECODER ) != VLC_SUCCESS ) { block_ChainRelease( p_packetized_block ); return; @@ -1213,8 +1232,8 @@ static void DecoderProcessAudio( decoder_t *p_dec, block_t *p_block ) /* Drain the decoder module */ DecoderDecodeAudio( p_dec, NULL ); - if( ReloadDecoder( p_dec, false, - &p_packetizer->fmt_out ) != VLC_SUCCESS ) + if( ReloadDecoder( p_dec, false, &p_packetizer->fmt_out, + RELOAD_DECODER ) != VLC_SUCCESS ) { block_ChainRelease( p_packetized_block ); return; @@ -1349,6 +1368,20 @@ static void DecoderProcess( decoder_t *p_dec, block_t *p_block ) if( p_dec->b_error ) goto error; + /* Here, the atomic doesn't prevent to miss a reload request. + * DecoderProcess*() can still be called after the decoder module or the + * audio output requested a reload. This will only result in a drop of an + * input block or an output buffer. */ + enum reload reload; + if( ( reload = atomic_exchange( &p_owner->reload, RELOAD_NO_REQUEST ) ) ) + { + msg_Warn( p_dec, "Reloading the decoder module%s", + reload == RELOAD_DECODER_AOUT ? " and the audio output" : "" ); + + if( ReloadDecoder( p_dec, false, &p_dec->fmt_in, reload ) != VLC_SUCCESS ) + goto error; + } + if( p_block ) { if( p_block->i_buffer <= 0 ) @@ -1597,6 +1630,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, RELOAD_NO_REQUEST ); p_owner->b_idle = false; es_format_Init( &p_owner->fmt, UNKNOWN_ES, 0 ); diff --git a/src/libvlccore.sym b/src/libvlccore.sym index b5193c5..ae86025 100644 --- a/src/libvlccore.sym +++ b/src/libvlccore.sym @@ -81,6 +81,7 @@ decoder_GetDisplayRate decoder_GetInputAttachments decoder_NewAudioBuffer decoder_NewSubpicture +decoder_RequestReload decoder_SynchroChoose decoder_SynchroDate decoder_SynchroDecode _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
