From a64b028aeb6579636e578ceb73f69b468bddb2f0 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 17 Sep 2011 19:59:48 +0200 Subject: [PATCH] h264dec: Dont display trash before a keyframe. Fixes Ticket472 This may (or may not) cause problems with files that have no keyframes. Plese open a bugreport or mail me if you have a file for which this fails. Signed-off-by: Michael Niedermayer --- libavcodec/h264.c | 17 ++++++++++------- libavcodec/h264.h | 2 ++ libavcodec/mpegvideo.h | 1 + 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/libavcodec/h264.c b/libavcodec/h264.c index 3b24b6ac55..33f70fe729 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -2262,6 +2262,7 @@ static void flush_dpb(AVCodecContext *avctx){ h->s.first_field= 0; ff_h264_reset_sei(h); ff_mpeg_flush(avctx); + h->sync= 0; } static int init_poc(H264Context *h){ @@ -3711,6 +3712,8 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){ s->current_picture_ptr->f.key_frame |= (hx->nal_unit_type == NAL_IDR_SLICE) || (h->sei_recovery_frame_cnt >= 0); + h->sync |= !!s->current_picture_ptr->f.key_frame; + s->current_picture_ptr->sync = h->sync; if (h->current_slice == 1) { if(!(s->flags2 & CODEC_FLAG2_CHUNKS)) { @@ -3914,13 +3917,13 @@ static int decode_frame(AVCodecContext *avctx, field_end(h, 0); - if (!h->next_output_pic) { - /* Wait for second field. */ - *data_size = 0; - - } else { - *data_size = sizeof(AVFrame); - *pict = *(AVFrame*)h->next_output_pic; + *data_size = 0; /* Wait for second field. */ + if (h->next_output_pic && h->next_output_pic->sync) { + h->sync |= 2*!!h->next_output_pic->f.key_frame; + if(h->sync>1 || h->next_output_pic->f.pict_type != AV_PICTURE_TYPE_B){ + *data_size = sizeof(AVFrame); + *pict = *(AVFrame*)h->next_output_pic; + } } } diff --git a/libavcodec/h264.h b/libavcodec/h264.h index 374cd163ec..ed4afdddfa 100644 --- a/libavcodec/h264.h +++ b/libavcodec/h264.h @@ -582,6 +582,8 @@ typedef struct H264Context{ int cur_chroma_format_idc; int16_t slice_row[MAX_SLICES]; ///< to detect when MAX_SLICES is too low + + int sync; ///< did we had a keyframe or recovery point }H264Context; diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h index e130a935ba..39efc1e3c1 100644 --- a/libavcodec/mpegvideo.h +++ b/libavcodec/mpegvideo.h @@ -129,6 +129,7 @@ typedef struct Picture{ int ref_count[2][2]; ///< number of entries in ref_poc (FIXME need per slice) int mbaff; ///< h264 1 -> MBAFF frame 0-> not MBAFF int field_picture; ///< whether or not the picture was encoded in seperate fields + int sync; ///< has been decoded after a keyframe int mb_var_sum; ///< sum of MB variance for current frame int mc_mb_var_sum; ///< motion compensated MB variance for current frame