[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