[vlc-devel] [PATCH 01/10] avcodec: refactor video decoding DecodeVideo function

Rémi Denis-Courmont remi at remlab.net
Sun Sep 4 16:31:34 CEST 2016


Le dimanche 4 septembre 2016, 15:30:05 ileoo at videolan.org a écrit :
> From: Ilkka Ollakka <ileoo at videolan.org>
> 
> ---
>  modules/codec/avcodec/video.c | 133
> ++++++++++++++++++++++++++---------------- 1 file changed, 82
> insertions(+), 51 deletions(-)
> 
> diff --git a/modules/codec/avcodec/video.c b/modules/codec/avcodec/video.c
> index 05a4d61..027ebf2 100644
> --- a/modules/codec/avcodec/video.c
> +++ b/modules/codec/avcodec/video.c
> @@ -584,6 +584,83 @@ static void Flush( decoder_t *p_dec )
>      decoder_AbortPictures( p_dec, false );
>  }
> 
> +static bool check_block_validity( decoder_sys_t *p_sys, block_t *block )
> +{
> +    if( !block)
> +        return true;
> +
> +    if( block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
> +    {
> +        p_sys->i_pts = VLC_TS_INVALID; /* To make sure we recover properly
> */ +
> +        p_sys->i_late_frames = 0;
> +        if( block->i_flags & BLOCK_FLAG_CORRUPTED )
> +        {
> +            block_Release( block );
> +            return false;
> +        }
> +    }
> +    return true;
> +}
> +
> +static bool check_block_being_late( decoder_sys_t *p_sys, block_t *block )
> +{
> +    if( !block )
> +        return false;
> +    if( block->i_flags & BLOCK_FLAG_PREROLL )
> +    {
> +        /* Do not care about late frames when prerolling
> +         * TODO avoid decoding of non reference frame
> +         * (ie all B except for H264 where it depends only on nal_ref_idc)
> */ +        p_sys->i_late_frames = 0;
> +    }
> +
> +    if( p_sys->i_late_frames <= 0 )
> +        return false;
> +
> +    if( mdate() - p_sys->i_late_frames_start > INT64_C(5000000))
> +    {
> +        if( p_sys->i_pts > VLC_TS_INVALID )
> +        {
> +            p_sys->i_pts = VLC_TS_INVALID; /* To make sure we recover
> properly */ +        }
> +        if( block )
> +            block_Release( block );
> +        p_sys->i_late_frames--;
> +        return true;
> +    }
> +    return false;
> +}
> +
> +
> +static void interpolate_next_pts( decoder_t *p_dec, AVFrame *frame )
> +{
> +    decoder_sys_t *p_sys = p_dec->p_sys;
> +    AVCodecContext *p_context = p_sys->p_context;
> +
> +    if( p_sys->i_pts <= VLC_TS_INVALID )
> +        return;
> +
> +    /* interpolate the next PTS */
> +    if( p_dec->fmt_in.video.i_frame_rate > 0 &&
> +        p_dec->fmt_in.video.i_frame_rate_base > 0 )
> +    {
> +        p_sys->i_pts += CLOCK_FREQ * (2 + frame->repeat_pict) *
> +            p_dec->fmt_in.video.i_frame_rate_base /
> +            (2 * p_dec->fmt_in.video.i_frame_rate);
> +    }
> +    else if( p_context->time_base.den > 0 )
> +    {
> +        int i_tick = p_context->ticks_per_frame;
> +        if( i_tick <= 0 )
> +            i_tick = 1;
> +
> +        p_sys->i_pts += CLOCK_FREQ * (2 + frame->repeat_pict) *
> +            i_tick * p_context->time_base.num /
> +            (2 * p_context->time_base.den);
> +    }
> +}
> +
>  /**************************************************************************
> *** * DecodeVideo: Called to decode one or more frames
>  
> ***************************************************************************
> **/ @@ -612,44 +689,17 @@ static picture_t *DecodeVideo( decoder_t *p_dec,
> block_t **pp_block ) return NULL;
>      }
> 
> -    if( p_block)
> -    {
> -        if( p_block->i_flags &
> (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) ) -        {
> -            p_sys->i_pts = VLC_TS_INVALID; /* To make sure we recover
> properly */ -
> -            p_sys->i_late_frames = 0;
> -            if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
> -            {
> -                block_Release( p_block );
> -                return NULL;
> -            }
> -        }
> -
> -        if( p_block->i_flags & BLOCK_FLAG_PREROLL )
> -        {
> -            /* Do not care about late frames when prerolling
> -             * TODO avoid decoding of non reference frame
> -             * (ie all B except for H264 where it depends only on
> nal_ref_idc) */ -            p_sys->i_late_frames = 0;
> -        }
> -    }
> +    if( !check_block_validity( p_sys, p_block ) )
> +        return NULL;
> 
> -    if( p_dec->b_frame_drop_allowed && (p_sys->i_late_frames > 0) &&
> -        (mdate() - p_sys->i_late_frames_start > INT64_C(5000000)) )

5*CLOCK_FREQ

> +    if( p_dec->b_frame_drop_allowed &&  check_block_being_late( p_sys,
> p_block) ) {
> -        if( p_sys->i_pts > VLC_TS_INVALID )
> -        {
> -            p_sys->i_pts = VLC_TS_INVALID; /* To make sure we recover
> properly */ -        }
> -        if( p_block )
> -            block_Release( p_block );
> -        p_sys->i_late_frames--;
>          msg_Err( p_dec, "more than 5 seconds of late video -> "
>                   "dropping frame (computer too slow ?)" );
>          return NULL;
>      }
> 
> +
>      /* A good idea could be to decode all I pictures and see for the other
> */ if( p_dec->b_frame_drop_allowed &&
>          p_sys->b_hurry_up &&
> @@ -815,27 +865,8 @@ static picture_t *DecodeVideo( decoder_t *p_dec,
> block_t **pp_block ) /* Interpolate the next PTS */
>          if( i_pts > VLC_TS_INVALID )
>              p_sys->i_pts = i_pts;
> -        if( p_sys->i_pts > VLC_TS_INVALID )
> -        {
> -            /* interpolate the next PTS */
> -            if( p_dec->fmt_in.video.i_frame_rate > 0 &&
> -                p_dec->fmt_in.video.i_frame_rate_base > 0 )
> -            {
> -                p_sys->i_pts += CLOCK_FREQ * (2 + frame->repeat_pict) *
> -                    p_dec->fmt_in.video.i_frame_rate_base /
> -                    (2 * p_dec->fmt_in.video.i_frame_rate);
> -            }
> -            else if( p_context->time_base.den > 0 )
> -            {
> -                int i_tick = p_context->ticks_per_frame;
> -                if( i_tick <= 0 )
> -                    i_tick = 1;
> 
> -                p_sys->i_pts += CLOCK_FREQ * (2 + frame->repeat_pict) *
> -                    i_tick * p_context->time_base.num /
> -                    (2 * p_context->time_base.den);
> -            }
> -        }
> +        interpolate_next_pts( p_dec, frame );
> 
>          /* Update frame late count (except when doing preroll) */
>          mtime_t i_display_date = 0;

-- 
Rémi Denis-Courmont
http://www.remlab.net/



More information about the vlc-devel mailing list