[vlc-devel] [PATCH] [RFC] decoder: add a Flush callback to decoders/packetizers
Thomas Guillem
thomas at gllm.fr
Wed Nov 18 17:23:07 CET 2015
On Wed, Nov 18, 2015, at 09:33, Steve Lhomme wrote:
> The flush handling is not passed to the DecoderProcessXXX functions
> anymore
>
> All decoder & packetizer, aout/vout/spu flushing is done in one place.
> The sout flushing will be part of another patch.
> --
> deprecates https://patches.videolan.org/patch/10776/
> ---
> include/vlc_codec.h | 1 +
> src/input/decoder.c | 145
> ++++++++++++++++++++++++++++++----------------------
> 2 files changed, 85 insertions(+), 61 deletions(-)
>
> diff --git a/include/vlc_codec.h b/include/vlc_codec.h
> index 1a2baa2..1399d26 100644
> --- a/include/vlc_codec.h
> +++ b/include/vlc_codec.h
> @@ -70,6 +70,7 @@ struct decoder_t
> block_t * ( * pf_decode_audio )( decoder_t *, block_t **
> );
> subpicture_t * ( * pf_decode_sub) ( decoder_t *, block_t **
> );
> block_t * ( * pf_packetize ) ( decoder_t *, block_t **
> );
> + int ( * pf_flush ) ( decoder_t * );
>
> /* Closed Caption (CEA 608/708) extraction.
> * If set, it *may* be called after pf_decode_video/pf_packetize
> diff --git a/src/input/decoder.c b/src/input/decoder.c
> index cacf7f2..b1adac3 100644
> --- a/src/input/decoder.c
> +++ b/src/input/decoder.c
> @@ -134,6 +134,8 @@ struct decoder_owner_sys_t
> /* */
> #define DECODER_SPU_VOUT_WAIT_DURATION ((int)(0.200*CLOCK_FREQ))
>
> +static int DecoderFlush( decoder_t *p_dec );
> +
> /**
> * Load a decoder module
> */
> @@ -148,6 +150,7 @@ static int LoadDecoder( decoder_t *p_dec, bool
> b_packetizer,
> p_dec->pf_decode_sub = NULL;
> p_dec->pf_get_cc = NULL;
> p_dec->pf_packetize = NULL;
> + p_dec->pf_flush = DecoderFlush;
>
> es_format_Copy( &p_dec->fmt_in, p_fmt );
> es_format_Init( &p_dec->fmt_out, UNKNOWN_ES, 0 );
> @@ -224,6 +227,25 @@ static block_t *DecoderBlockFlushNew()
> return p_null;
> }
>
> +int DecoderFlush( decoder_t *p_dec )
> +{
> + block_t *p_flush = DecoderBlockFlushNew();
> + if( p_flush )
> + {
> + if (p_dec->pf_decode_video)
compare p_dec->fmt_out.i_cat to stay consistent ? (see if(
p_dec->fmt_out.i_cat == AUDIO_ES )...)
> + p_dec->pf_decode_video( p_dec, &p_flush );
> + else if (p_dec->pf_decode_audio)
> + p_dec->pf_decode_audio( p_dec, &p_flush );
> + else if (p_dec->pf_decode_sub)
> + p_dec->pf_decode_sub( p_dec, &p_flush );
> + else if (p_dec->pf_packetize)
> + p_dec->pf_packetize( p_dec, &p_flush );
> + else
> + block_Release( p_flush );
also return VLC_EGENERIC;
> + }
else return VLC_EGENERIC;
> + return VLC_SUCCESS;
> +}
> +
> /*****************************************************************************
> * Buffers allocation callbacks for the decoders
> *****************************************************************************/
> @@ -945,6 +967,13 @@ static void DecoderProcessVideo( decoder_t *p_dec,
> block_t *p_block, bool b_flus
Don't compile ? typo ? the b_flush arg should be gone for video too ?
> {
> decoder_owner_sys_t *p_owner = (decoder_owner_sys_t
> *)p_dec->p_owner;
>
> + if ( b_flush )
> + {
> + if( p_owner->p_vout )
> + vout_Flush( p_owner->p_vout, VLC_TS_0 );
> + return;
> + }
> +
> if( p_owner->p_packetizer )
> {
> block_t *p_packetized_block;
> @@ -982,22 +1011,11 @@ static void DecoderProcessVideo( decoder_t *p_dec,
> block_t *p_block, bool b_flus
> p_packetized_block = p_next;
> }
> }
> - /* The packetizer does not output a block that tell the decoder
> to flush
> - * do it ourself */
> - if( b_flush )
> - {
> - block_t *p_null = DecoderBlockFlushNew();
> - if( p_null )
> - DecoderDecodeVideo( p_dec, p_null );
> - }
> }
> else
> {
> DecoderDecodeVideo( p_dec, p_block );
> }
> -
> - if( b_flush && p_owner->p_vout )
> - vout_Flush( p_owner->p_vout, VLC_TS_INVALID+1 );
> }
>
> static void DecoderPlayAudio( decoder_t *p_dec, block_t *p_audio,
> @@ -1096,7 +1114,7 @@ static void DecoderDecodeAudio( decoder_t *p_dec,
> block_t *p_block )
>
> /* This function process a audio block
> */
> -static void DecoderProcessAudio( decoder_t *p_dec, block_t *p_block,
> bool b_flush )
> +static void DecoderProcessAudio( decoder_t *p_dec, block_t *p_block )
> {
> decoder_owner_sys_t *p_owner = (decoder_owner_sys_t
> *)p_dec->p_owner;
>
> @@ -1134,22 +1152,11 @@ static void DecoderProcessAudio( decoder_t
> *p_dec, block_t *p_block, bool b_flus
> p_packetized_block = p_next;
> }
> }
> - /* The packetizer does not output a block that tell the decoder
> to flush
> - * do it ourself */
> - if( b_flush )
> - {
> - block_t *p_null = DecoderBlockFlushNew();
> - if( p_null )
> - DecoderDecodeAudio( p_dec, p_null );
> - }
> }
> else
> {
> DecoderDecodeAudio( p_dec, p_block );
> }
> -
> - if( b_flush && p_owner->p_aout )
> - aout_DecFlush( p_owner->p_aout, false );
> }
>
> static void DecoderPlaySpu( decoder_t *p_dec, subpicture_t *p_subpic )
> @@ -1191,7 +1198,7 @@ static void DecoderPlaySpu( decoder_t *p_dec,
> subpicture_t *p_subpic )
>
> /* This function process a subtitle block
> */
> -static void DecoderProcessSpu( decoder_t *p_dec, block_t *p_block, bool
> b_flush )
> +static void DecoderProcessSpu( decoder_t *p_dec, block_t *p_block )
> {
> decoder_owner_sys_t *p_owner = p_dec->p_owner;
>
> @@ -1230,17 +1237,6 @@ static void DecoderProcessSpu( decoder_t *p_dec,
> block_t *p_block, bool b_flush
> if( p_vout )
> vlc_object_release( p_vout );
> }
> -
> - if( b_flush && p_owner->p_spu_vout )
> - {
> - p_vout = input_resource_HoldVout( p_owner->p_resource );
> -
> - if( p_vout && p_owner->p_spu_vout == p_vout )
> - vout_FlushSubpictureChannel( p_vout, p_owner->i_spu_channel
> );
> -
> - if( p_vout )
> - vlc_object_release( p_vout );
> - }
> }
>
> /**
> @@ -1269,45 +1265,72 @@ static void DecoderProcess( decoder_t *p_dec,
> block_t *p_block )
> return;
> }
>
> -#ifdef ENABLE_SOUT
> - if( p_owner->b_packetizer )
> - {
> - if( p_block )
> - p_block->i_flags &= ~BLOCK_FLAG_CORE_PRIVATE_MASK;
> + bool b_flush = false;
>
> - DecoderProcessSout( p_dec, p_block );
> - }
> - else
> -#endif
> + if( p_block )
> {
> - bool b_flush = false;
> -
> - if( p_block )
> - {
> - const bool b_flushing = p_owner->i_preroll_end == INT64_MAX;
> - DecoderUpdatePreroll( &p_owner->i_preroll_end, p_block );
> + const bool b_flushing = p_owner->i_preroll_end == INT64_MAX;
> + DecoderUpdatePreroll( &p_owner->i_preroll_end, p_block );
>
> - b_flush = !b_flushing && b_flush_request;
> + b_flush = !b_flushing && b_flush_request;
Here, b_flush_request comes from b_flush_request = p_block &&
(p_block->i_flags & BLOCK_FLAG_CORE_FLUSH);
It should not, you should pass the b_flush_request boolean directly to
DecoderProcess function. (see /* TODO: add a flush callback to
decoder... */)
You should also remove the BLOCK_FLAG_CORE_FLUSH internal flag.
>
> - p_block->i_flags &= ~BLOCK_FLAG_CORE_PRIVATE_MASK;
> - }
> + p_block->i_flags &= ~BLOCK_FLAG_CORE_PRIVATE_MASK;
> + }
>
> - if( p_dec->fmt_out.i_cat == AUDIO_ES )
> + if (b_flush)
> + {
> + if ( p_block )
> {
> - DecoderProcessAudio( p_dec, p_block, b_flush );
> + block_Release( p_block );
> + p_block = NULL;
> }
> - else if( p_dec->fmt_out.i_cat == VIDEO_ES )
> +
> + if ( p_owner->p_packetizer )
> + p_owner->p_packetizer->pf_flush( p_owner->p_packetizer );
> + p_dec->pf_flush( p_dec );
both returns not checked.
Maybe pf_flush shouldn't return anything to stay consistent with
vlc_filter.h ?
The question is: can decoder/packetizer modules flush fail ?
> +
> + if( p_owner->p_vout )
> + vout_Flush( p_owner->p_vout, VLC_TS_0 );
> + if( p_owner->p_aout )
> + aout_DecFlush( p_owner->p_aout, false );
> + if( p_owner->p_spu_vout )
> {
> - DecoderProcessVideo( p_dec, p_block, b_flush );
> + vout_thread_t *p_vout = input_resource_HoldVout(
> p_owner->p_resource );
> +
> + if( p_vout && p_owner->p_spu_vout == p_vout )
> + vout_FlushSubpictureChannel( p_vout,
> p_owner->i_spu_channel );
> +
> + if( p_vout )
> + vlc_object_release( p_vout );
> }
> - else if( p_dec->fmt_out.i_cat == SPU_ES )
> + }
> + else
> + {
> +#ifdef ENABLE_SOUT
> + if( p_owner->b_packetizer )
> {
> - DecoderProcessSpu( p_dec, p_block, b_flush );
> + DecoderProcessSout( p_dec, p_block );
> }
> else
> +#endif
> {
> - msg_Err( p_dec, "unknown ES format" );
> - p_dec->b_error = true;
> + if( p_dec->fmt_out.i_cat == AUDIO_ES )
> + {
> + DecoderProcessAudio( p_dec, p_block );
> + }
> + else if( p_dec->fmt_out.i_cat == VIDEO_ES )
> + {
> + DecoderProcessVideo( p_dec, p_block );
> + }
> + else if( p_dec->fmt_out.i_cat == SPU_ES )
> + {
> + DecoderProcessSpu( p_dec, p_block );
> + }
> + else
> + {
> + msg_Err( p_dec, "unknown ES format" );
> + p_dec->b_error = true;
> + }
> }
> }
> }
> --
> 2.6.2
>
> _______________________________________________
> 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