h264dec: Dont display trash before a keyframe.
authorMichael Niedermayer <michaelni@gmx.at>
Sat, 17 Sep 2011 17:59:48 +0000 (19:59 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Sat, 17 Sep 2011 19:20:44 +0000 (21:20 +0200)
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 <michaelni@gmx.at>
libavcodec/h264.c
libavcodec/h264.h
libavcodec/mpegvideo.h

index 3b24b6a..33f70fe 100644 (file)
@@ -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;
+            }
         }
     }
 
index 374cd16..ed4afdd 100644 (file)
@@ -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;
 
 
index e130a93..39efc1e 100644 (file)
@@ -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