diff h264.c @ 2597:b5b09255f7c3 libavcodec

CABAC support for MBAFF I frames patch by (Lo«Ác Le Loarer < lll+ffmpeg m4x org) This patch corrects the support for I slice in CABAC and MBAFF mode. This decodes correctly 6 more frames of the conformance suite.
author michael
date Tue, 05 Apr 2005 18:29:26 +0000
parents 5357b214eda0
children aaf8e94bce00
line wrap: on
line diff
--- a/h264.c	Tue Apr 05 17:59:05 2005 +0000
+++ b/h264.c	Tue Apr 05 18:29:26 2005 +0000
@@ -4658,9 +4658,8 @@
     
     if(intra_slice){
         MpegEncContext * const s = &h->s;
-        const int mb_xy= s->mb_x + s->mb_y*s->mb_stride;
-        const int mba_xy = mb_xy - 1;
-        const int mbb_xy = mb_xy - s->mb_stride;
+        const int mba_xy = h->left_mb_xy[0];
+        const int mbb_xy = h->top_mb_xy;
         int ctx=0;
         if( h->slice_table[mba_xy] == h->slice_num && !IS_INTRA4x4( s->current_picture.mb_type[mba_xy] ) )
             ctx++;
@@ -4717,9 +4716,8 @@
             return decode_cabac_intra_mb_type(h, 17, 0) + 5;
         }
     } else if( h->slice_type == B_TYPE ) {
-        const int mb_xy= s->mb_x + s->mb_y*s->mb_stride;
-        const int mba_xy = mb_xy - 1;
-        const int mbb_xy = mb_xy - s->mb_stride;
+        const int mba_xy = h->left_mb_xy[0];
+        const int mbb_xy = h->top_mb_xy;
         int ctx = 0;
         int bits;
 
@@ -5152,6 +5150,32 @@
     return 0;
 }
 
+void inline compute_mb_neighboors(H264Context *h)
+{
+    MpegEncContext * const s = &h->s;
+    const int mb_xy  = s->mb_x + s->mb_y*s->mb_stride;
+    h->top_mb_xy     = mb_xy - s->mb_stride;
+    h->left_mb_xy[0] = mb_xy - 1;
+    if(h->mb_aff_frame){
+        const int pair_xy          = s->mb_x     + (s->mb_y & ~1)*s->mb_stride;
+        const int top_pair_xy      = pair_xy     - s->mb_stride;
+        const int top_mb_frame_flag      = !IS_INTERLACED(s->current_picture.mb_type[top_pair_xy]);
+        const int left_mb_frame_flag = !IS_INTERLACED(s->current_picture.mb_type[pair_xy-1]);
+        const int curr_mb_frame_flag = !h->mb_field_decoding_flag;
+        const int bottom = (s->mb_y & 1);
+        if (bottom
+                ? !curr_mb_frame_flag // bottom macroblock
+                : (!curr_mb_frame_flag && !top_mb_frame_flag) // top macroblock
+                ) {
+            h->top_mb_xy -= s->mb_stride;
+        }
+        if (left_mb_frame_flag != curr_mb_frame_flag) {
+            h->left_mb_xy[0] = pair_xy - 1;
+        }
+    }
+    return;
+}
+
 /**
  * decodes a macroblock
  * @returns 0 if ok, AC_ERROR / DC_ERROR / MV_ERROR if an error is noticed
@@ -5185,6 +5209,7 @@
 
     h->prev_mb_skiped = 0;
 
+    compute_mb_neighboors(h);
     if( ( mb_type = decode_cabac_mb_type( h ) ) < 0 ) {
         av_log( h->s.avctx, AV_LOG_ERROR, "decode_cabac_mb_type failed\n" );
         return -1;