[vlc-devel] [RFC PATCH 05/12] decoder: handle module fallback
Thomas Guillem
thomas at gllm.fr
Tue Jul 19 19:36:27 CEST 2016
---
include/vlc_codec.h | 5 +++++
src/input/decoder.c | 44 +++++++++++++++++++++++++++++++++-----------
2 files changed, 38 insertions(+), 11 deletions(-)
diff --git a/include/vlc_codec.h b/include/vlc_codec.h
index 2d01d26..98b9bdc 100644
--- a/include/vlc_codec.h
+++ b/include/vlc_codec.h
@@ -159,6 +159,11 @@ struct decoder_t
decoder_owner_sys_t *p_owner;
bool b_error;
+
+ /* Can be set to true by the module from pf_decode_* callbacks. This will
+ * tell the core to try a next module. The current module will be unloaded
+ * when the pf_decode callback ends. */
+ bool b_fallback;
};
/**
diff --git a/src/input/decoder.c b/src/input/decoder.c
index 6a847d7..c04de09 100644
--- a/src/input/decoder.c
+++ b/src/input/decoder.c
@@ -68,6 +68,7 @@ struct decoder_owner_sys_t
sout_instance_t *p_sout;
sout_packetizer_input_t *p_sout_input;
+ void *p_module_savectx;
vlc_thread_t thread;
/* Some decoders require already packetized data (ie. not truncated) */
@@ -138,7 +139,8 @@ struct decoder_owner_sys_t
* Load a decoder module
*/
static int LoadDecoder( decoder_t *p_dec, bool b_packetizer,
- const es_format_t *restrict p_fmt )
+ const es_format_t *restrict p_fmt,
+ void **pp_module_savectx )
{
p_dec->b_frame_drop_allowed = true;
p_dec->i_extra_picture_buffers = 0;
@@ -155,9 +157,11 @@ static int LoadDecoder( decoder_t *p_dec, bool b_packetizer,
/* Find a suitable decoder/packetizer module */
if( !b_packetizer )
- p_dec->p_module = module_need( p_dec, "decoder", "$codec", false );
+ p_dec->p_module = module_need_next( p_dec, "decoder", "$codec",
+ false, pp_module_savectx );
else
- p_dec->p_module = module_need( p_dec, "packetizer", "$packetizer", false );
+ p_dec->p_module = module_need_next( p_dec, "packetizer", "$packetizer",
+ false, pp_module_savectx );
if( !p_dec->p_module )
{
@@ -188,10 +192,12 @@ static void UnloadDecoder( decoder_t *p_dec )
es_format_Clean( &p_dec->fmt_in );
es_format_Clean( &p_dec->fmt_out );
p_dec->b_error = false;
+ p_dec->b_fallback = false;
}
static int ReloadDecoder( decoder_t *p_dec, bool b_packetizer,
- const es_format_t *restrict p_fmt )
+ const es_format_t *restrict p_fmt,
+ void **pp_module_savectx )
{
/* Copy p_fmt since it can be destroyed by UnloadDecoder */
es_format_t fmt_in;
@@ -200,7 +206,7 @@ static int ReloadDecoder( decoder_t *p_dec, bool b_packetizer,
/* Restart the decoder module */
UnloadDecoder( p_dec );
- if( LoadDecoder( p_dec, b_packetizer, &fmt_in ) )
+ if( LoadDecoder( p_dec, b_packetizer, &fmt_in, pp_module_savectx ) )
{
p_dec->b_error = true;
es_format_Clean( &fmt_in );
@@ -1027,8 +1033,11 @@ static void DecoderProcessVideo( decoder_t *p_dec, block_t *p_block )
/* Drain the decoder module */
DecoderDecodeVideo( p_dec, NULL );
+ free( p_owner->p_module_savectx );
+ p_owner->p_module_savectx = NULL;
if( ReloadDecoder( p_dec, false,
- &p_packetizer->fmt_out ) != VLC_SUCCESS )
+ &p_packetizer->fmt_out,
+ &p_owner->p_module_savectx ) != VLC_SUCCESS )
{
block_ChainRelease( p_packetized_block );
return;
@@ -1044,7 +1053,7 @@ static void DecoderProcessVideo( decoder_t *p_dec, block_t *p_block )
p_packetized_block->p_next = NULL;
DecoderDecodeVideo( p_dec, p_packetized_block );
- if( p_dec->b_error )
+ if( p_dec->b_error || p_dec->b_fallback )
{
block_ChainRelease( p_next );
return;
@@ -1209,8 +1218,11 @@ static void DecoderProcessAudio( decoder_t *p_dec, block_t *p_block )
/* Drain the decoder module */
DecoderDecodeAudio( p_dec, NULL );
+ free( p_owner->p_module_savectx );
+ p_owner->p_module_savectx = NULL;
if( ReloadDecoder( p_dec, false,
- &p_packetizer->fmt_out ) != VLC_SUCCESS )
+ &p_packetizer->fmt_out,
+ &p_owner->p_module_savectx ) != VLC_SUCCESS )
{
block_ChainRelease( p_packetized_block );
return;
@@ -1223,7 +1235,7 @@ static void DecoderProcessAudio( decoder_t *p_dec, block_t *p_block )
p_packetized_block->p_next = NULL;
DecoderDecodeAudio( p_dec, p_packetized_block );
- if( p_dec->b_error )
+ if( p_dec->b_error || p_dec->b_fallback )
{
block_ChainRelease( p_next );
return;
@@ -1342,6 +1354,12 @@ static void DecoderProcess( decoder_t *p_dec, block_t *p_block )
{
decoder_owner_sys_t *p_owner = p_dec->p_owner;
+ if( p_dec->b_fallback )
+ {
+ if( ReloadDecoder( p_dec, false, &p_dec->fmt_in,
+ &p_owner->p_module_savectx ) != VLC_SUCCESS )
+ goto error;
+ }
if( p_dec->b_error )
goto error;
@@ -1577,6 +1595,7 @@ static decoder_t * CreateDecoder( vlc_object_t *p_parent,
p_owner->i_spu_order = 0;
p_owner->p_sout = p_sout;
p_owner->p_sout_input = NULL;
+ p_owner->p_module_savectx = NULL;
p_owner->p_packetizer = NULL;
p_owner->b_fmt_description = false;
@@ -1632,7 +1651,7 @@ static decoder_t * CreateDecoder( vlc_object_t *p_parent,
vlc_custom_create( p_parent, sizeof( decoder_t ), "packetizer" );
if( p_owner->p_packetizer )
{
- if( LoadDecoder( p_owner->p_packetizer, true, fmt ) )
+ if( LoadDecoder( p_owner->p_packetizer, true, fmt, NULL ) )
{
vlc_object_release( p_owner->p_packetizer );
p_owner->p_packetizer = NULL;
@@ -1646,7 +1665,8 @@ static decoder_t * CreateDecoder( vlc_object_t *p_parent,
}
/* Find a suitable decoder/packetizer module */
- if( LoadDecoder( p_dec, p_sout != NULL, fmt ) )
+ if( LoadDecoder( p_dec, p_sout != NULL, fmt,
+ p_sout == NULL ? &p_owner->p_module_savectx : NULL ) )
return p_dec;
/* Copy ourself the input replay gain */
@@ -1757,6 +1777,8 @@ static void DeleteDecoder( decoder_t * p_dec )
vlc_object_release( p_owner->p_packetizer );
}
+ free( p_owner->p_module_savectx );
+
vlc_cond_destroy( &p_owner->wait_timed );
vlc_cond_destroy( &p_owner->wait_fifo );
vlc_cond_destroy( &p_owner->wait_acknowledge );
--
2.8.1
More information about the vlc-devel
mailing list