[vlc-devel] [PATCH 01/10] avcodec: refactor video decoding DecodeVideo function
ileoo at videolan.org
ileoo at videolan.org
Sun Sep 4 14:30:05 CEST 2016
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)) )
+ 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;
--
2.6.6
More information about the vlc-devel
mailing list