[vlc-commits] decoder: add decoder_RequestReload
Thomas Guillem
git at videolan.org
Thu Jul 28 09:04:35 CEST 2016
vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | 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
More information about the vlc-commits
mailing list