Separate I4X4_PRED coding from macroblock modules
authorJingning Han <jingning@google.com>
Mon, 29 Apr 2013 19:43:38 +0000 (12:43 -0700)
committerJingning Han <jingning@google.com>
Tue, 30 Apr 2013 01:59:36 +0000 (18:59 -0700)
Separate the functionality of I4X4_PRED from decode_mb. Use
decode_atom_intra instead, to enable recursive partition of superblock
down to 8x8.

Change-Id: Ifc89a3be82225398954169d0a839abdbbfd8ca3b

vp9/common/vp9_blockd.h
vp9/common/vp9_enums.h
vp9/decoder/vp9_decodframe.c
vp9/encoder/vp9_encodeframe.c
vp9/encoder/vp9_encodeintra.c
vp9/encoder/vp9_encodeintra.h

index 8bb5a69..aebf4a1 100644 (file)
@@ -200,49 +200,62 @@ typedef enum {
   MAX_REF_FRAMES = 4
 } MV_REFERENCE_FRAME;
 
-static INLINE int mi_width_log2(BLOCK_SIZE_TYPE sb_type) {
+static INLINE int b_width_log2(BLOCK_SIZE_TYPE sb_type) {
   switch (sb_type) {
+    case BLOCK_SIZE_AB4X4: return 0;
 #if CONFIG_SB8X8
-    case BLOCK_SIZE_SB8X16:
-    case BLOCK_SIZE_SB8X8: return 0;
+    case BLOCK_SIZE_SB8X8:
+    case BLOCK_SIZE_SB8X16: return 1;
     case BLOCK_SIZE_SB16X8:
 #endif
     case BLOCK_SIZE_MB16X16:
-    case BLOCK_SIZE_SB16X32: return 0 + CONFIG_SB8X8;
+    case BLOCK_SIZE_SB16X32: return 2;
     case BLOCK_SIZE_SB32X16:
-    case BLOCK_SIZE_SB32X64:
-    case BLOCK_SIZE_SB32X32: return 1 + CONFIG_SB8X8;
+    case BLOCK_SIZE_SB32X32:
+    case BLOCK_SIZE_SB32X64: return 3;
     case BLOCK_SIZE_SB64X32:
-    case BLOCK_SIZE_SB64X64: return 2 + CONFIG_SB8X8;
+    case BLOCK_SIZE_SB64X64: return 4;
     default: assert(0);
   }
 }
 
-static INLINE int mi_height_log2(BLOCK_SIZE_TYPE sb_type) {
+static INLINE int b_height_log2(BLOCK_SIZE_TYPE sb_type) {
   switch (sb_type) {
+    case BLOCK_SIZE_AB4X4: return 0;
 #if CONFIG_SB8X8
-    case BLOCK_SIZE_SB16X8:
-    case BLOCK_SIZE_SB8X8: return 0;
+    case BLOCK_SIZE_SB8X8:
+    case BLOCK_SIZE_SB16X8: return 1;
     case BLOCK_SIZE_SB8X16:
 #endif
     case BLOCK_SIZE_MB16X16:
-    case BLOCK_SIZE_SB32X16: return 0 + CONFIG_SB8X8;
+    case BLOCK_SIZE_SB32X16: return 2;
     case BLOCK_SIZE_SB16X32:
-    case BLOCK_SIZE_SB64X32:
-    case BLOCK_SIZE_SB32X32: return 1 + CONFIG_SB8X8;
+    case BLOCK_SIZE_SB32X32:
+    case BLOCK_SIZE_SB64X32: return 3;
     case BLOCK_SIZE_SB32X64:
-    case BLOCK_SIZE_SB64X64: return 2 + CONFIG_SB8X8;
+    case BLOCK_SIZE_SB64X64: return 4;
     default: assert(0);
   }
 }
 
-// parse block dimension in the unit of 4x4 blocks
-static INLINE int b_width_log2(BLOCK_SIZE_TYPE sb_type) {
-  return mi_width_log2(sb_type) + 2 - CONFIG_SB8X8;
+static INLINE int mi_width_log2(BLOCK_SIZE_TYPE sb_type) {
+#if CONFIG_SB8X8
+  int a = b_width_log2(sb_type) - 1;
+#else
+  int a = b_width_log2(sb_type) - 2;
+#endif
+  assert(a >= 0);
+  return a;
 }
 
-static INLINE int b_height_log2(BLOCK_SIZE_TYPE sb_type) {
-  return mi_height_log2(sb_type) + 2 - CONFIG_SB8X8;
+static INLINE int mi_height_log2(BLOCK_SIZE_TYPE sb_type) {
+#if CONFIG_SB8X8
+  int a = b_height_log2(sb_type) - 1;
+#else
+  int a = b_height_log2(sb_type) - 2;
+#endif
+  assert(a >= 0);
+  return a;
 }
 
 typedef struct {
index fddbb55..b72b41e 100644 (file)
@@ -23,6 +23,7 @@
 #define MI_UV_SIZE (1 << (LOG2_MI_SIZE - 1))
 
 typedef enum BLOCK_SIZE_TYPE {
+  BLOCK_SIZE_AB4X4,
 #if CONFIG_SB8X8
   BLOCK_SIZE_SB8X8,
   BLOCK_SIZE_SB8X16,
index 9e5c341..27eb4b1 100644 (file)
@@ -300,7 +300,6 @@ static INLINE void dequant_add_y(MACROBLOCKD *xd, TX_TYPE tx_type, int idx) {
   }
 }
 
-
 static void decode_4x4(VP9D_COMP *pbi, MACROBLOCKD *xd, vp9_reader *r) {
   TX_TYPE tx_type;
   int i = 0;
@@ -338,32 +337,6 @@ static void decode_4x4(VP9D_COMP *pbi, MACROBLOCKD *xd, vp9_reader *r) {
                    dst, xd->plane[1].dst.stride,
                    xd->plane[2].eobs[i]);
     }
-  } else if (mode == I4X4_PRED) {
-    for (i = 0; i < 16; i++) {
-      int b_mode = xd->mode_info_context->bmi[i].as_mode.first;
-      uint8_t* dst;
-      dst = raster_block_offset_uint8(xd, BLOCK_SIZE_MB16X16, 0, i,
-                                      xd->plane[0].dst.buf,
-                                      xd->plane[0].dst.stride);
-#if CONFIG_NEWBINTRAMODES
-      xd->mode_info_context->bmi[i].as_mode.context =
-          vp9_find_bpred_context(xd, i, dst, xd->plane[0].dst.stride);
-      if (!xd->mode_info_context->mbmi.mb_skip_coeff)
-        vp9_decode_coefs_4x4(pbi, xd, r, PLANE_TYPE_Y_WITH_DC, i);
-#endif
-      vp9_intra4x4_predict(xd, i, b_mode, dst, xd->plane[0].dst.stride);
-      tx_type = get_tx_type_4x4(xd, i);
-      dequant_add_y(xd, tx_type, i);
-    }
-#if CONFIG_NEWBINTRAMODES
-    if (!xd->mode_info_context->mbmi.mb_skip_coeff)
-      vp9_decode_mb_tokens_4x4_uv(pbi, xd, r);
-#endif
-    vp9_build_intra_predictors_sbuv_s(xd, BLOCK_SIZE_MB16X16);
-    xd->itxm_add_uv_block(xd->plane[1].qcoeff, xd->plane[1].dst.buf,
-        xd->plane[1].dst.stride, xd->plane[1].eobs);
-    xd->itxm_add_uv_block(xd->plane[2].qcoeff, xd->plane[2].dst.buf,
-        xd->plane[1].dst.stride, xd->plane[2].eobs);
   } else if (mode == SPLITMV || get_tx_type_4x4(xd, 0) == DCT_DCT) {
     xd->itxm_add_y_block(xd->plane[0].qcoeff, xd->plane[0].dst.buf,
         xd->plane[0].dst.stride, xd);
@@ -437,6 +410,38 @@ static void decode_block(int plane, int block, BLOCK_SIZE_TYPE bsize,
   }
 }
 
+static void decode_atom_intra(VP9D_COMP *pbi, MACROBLOCKD *xd,
+                              vp9_reader *r,
+                              BLOCK_SIZE_TYPE bsize) {
+  int i = 0;
+  int bwl = b_width_log2(bsize), bhl = b_height_log2(bsize);
+  int bc = 1 << (bwl + bhl);
+  int tx_type;
+
+  for (i = 0; i < bc; i++) {
+    int b_mode = xd->mode_info_context->bmi[i].as_mode.first;
+    uint8_t* dst;
+    dst = raster_block_offset_uint8(xd, bsize, 0, i,
+                                    xd->plane[0].dst.buf,
+                                    xd->plane[0].dst.stride);
+#if CONFIG_NEWBINTRAMODES
+    xd->mode_info_context->bmi[i].as_mode.context =
+        vp9_find_bpred_context(xd, i, dst, xd->plane[0].dst.stride);
+    if (!xd->mode_info_context->mbmi.mb_skip_coeff)
+      vp9_decode_coefs_4x4(pbi, xd, r, PLANE_TYPE_Y_WITH_DC, i);
+#endif
+    vp9_intra4x4_predict(xd, i, b_mode, dst, xd->plane[0].dst.stride);
+    // TODO(jingning): refactor to use foreach_transformed_block_in_plane_
+    tx_type = get_tx_type_4x4(xd, i);
+    dequant_add_y(xd, tx_type, i);
+  }
+#if CONFIG_NEWBINTRAMODES
+  if (!xd->mode_info_context->mbmi.mb_skip_coeff)
+    vp9_decode_mb_tokens_4x4_uv(pbi, xd, r);
+#endif
+  foreach_transformed_block_uv(xd, bsize, decode_block, xd);
+}
+
 static void decode_sb(VP9D_COMP *pbi, MACROBLOCKD *xd, int mi_row, int mi_col,
                       vp9_reader *r, BLOCK_SIZE_TYPE bsize) {
   const int bwl = mi_width_log2(bsize), bhl = mi_height_log2(bsize);
@@ -545,7 +550,12 @@ static void decode_mb(VP9D_COMP *pbi, MACROBLOCKD *xd,
     } else if (tx_size == TX_8X8) {
       decode_8x8(xd);
     } else {
-      decode_4x4(pbi, xd, r);
+      if (mbmi->mode == I4X4_PRED)
+        // TODO(jingning): we need to move this to decode_atom later and
+        // deprecate decode_mb, when SB8X8 is on.
+        decode_atom_intra(pbi, xd, r, BLOCK_SIZE_MB16X16);
+      else
+        decode_4x4(pbi, xd, r);
     }
   }
 
@@ -671,10 +681,11 @@ static void decode_modes_b(VP9D_COMP *pbi, int mi_row, int mi_col,
   set_refs(pbi, mi_row, mi_col);
 
   // TODO(jingning): merge decode_sb_ and decode_mb_
-  if (bsize > BLOCK_SIZE_MB16X16)
+  if (bsize > BLOCK_SIZE_MB16X16) {
     decode_sb(pbi, xd, mi_row, mi_col, r, bsize);
-  else
+  } else {
     decode_mb(pbi, xd, mi_row, mi_col, r);
+  }
 
   xd->corrupted |= vp9_reader_has_error(r);
 }
index 3877391..d40c604 100644 (file)
@@ -1946,7 +1946,7 @@ static void encode_macroblock(VP9_COMP *cpi, TOKENEXTRA **t,
 #endif
     if (mbmi->mode == I4X4_PRED) {
       vp9_encode_intra16x16mbuv(cm, x);
-      vp9_encode_intra4x4mby(x);
+      vp9_encode_intra4x4mby(x, BLOCK_SIZE_MB16X16);
     } else if (mbmi->mode == I8X8_PRED) {
       vp9_encode_intra8x8mby(x);
       vp9_encode_intra8x8mbuv(x);
index 54c4f36..f6ddca8 100644 (file)
@@ -16,7 +16,7 @@
 #include "vp9/common/vp9_invtrans.h"
 #include "vp9/encoder/vp9_encodeintra.h"
 
-static void encode_intra4x4block(MACROBLOCK *x, int ib);
+static void encode_intra4x4block(MACROBLOCK *x, int ib, BLOCK_SIZE_TYPE bs);
 
 int vp9_encode_intra(VP9_COMP *cpi, MACROBLOCK *x, int use_16x16_pred) {
   MB_MODE_INFO * mbmi = &x->e_mbd.mode_info_context->mbmi;
@@ -33,27 +33,28 @@ int vp9_encode_intra(VP9_COMP *cpi, MACROBLOCK *x, int use_16x16_pred) {
 
     for (i = 0; i < 16; i++) {
       x->e_mbd.mode_info_context->bmi[i].as_mode.first = B_DC_PRED;
-      encode_intra4x4block(x, i);
+      encode_intra4x4block(x, i, BLOCK_SIZE_MB16X16);
     }
   }
 
   return vp9_get_mb_ss(x->plane[0].src_diff);
 }
 
-static void encode_intra4x4block(MACROBLOCK *x, int ib) {
+static void encode_intra4x4block(MACROBLOCK *x, int ib,
+                                 BLOCK_SIZE_TYPE bsize) {
   MACROBLOCKD * const xd = &x->e_mbd;
   TX_TYPE tx_type;
   uint8_t* const src =
-      raster_block_offset_uint8(xd, BLOCK_SIZE_MB16X16, 0, ib,
+      raster_block_offset_uint8(xd, bsize, 0, ib,
                                 x->plane[0].src.buf, x->plane[0].src.stride);
   uint8_t* const dst =
-      raster_block_offset_uint8(xd, BLOCK_SIZE_MB16X16, 0, ib,
+      raster_block_offset_uint8(xd, bsize, 0, ib,
                                 xd->plane[0].dst.buf, xd->plane[0].dst.stride);
   int16_t* const src_diff =
-      raster_block_offset_int16(xd, BLOCK_SIZE_MB16X16, 0, ib,
+      raster_block_offset_int16(xd, bsize, 0, ib,
                                 x->plane[0].src_diff);
   int16_t* const diff =
-      raster_block_offset_int16(xd, BLOCK_SIZE_MB16X16, 0, ib,
+      raster_block_offset_int16(xd, bsize, 0, ib,
                                 xd->plane[0].diff);
   int16_t* const coeff = BLOCK_OFFSET(x->plane[0].coeff, ib, 16);
 
@@ -88,11 +89,13 @@ static void encode_intra4x4block(MACROBLOCK *x, int ib) {
   vp9_recon_b(dst, diff, dst, xd->plane[0].dst.stride);
 }
 
-void vp9_encode_intra4x4mby(MACROBLOCK *mb) {
+void vp9_encode_intra4x4mby(MACROBLOCK *mb, BLOCK_SIZE_TYPE bsize) {
   int i;
+  int bwl = b_width_log2(bsize), bhl = b_height_log2(bsize);
+  int bc = 1 << (bwl + bhl);
 
-  for (i = 0; i < 16; i++)
-    encode_intra4x4block(mb, i);
+  for (i = 0; i < bc; i++)
+    encode_intra4x4block(mb, i, bsize);
 }
 
 void vp9_encode_intra16x16mby(VP9_COMMON *const cm, MACROBLOCK *x) {
index 6576c94..7ec2f11 100644 (file)
@@ -16,7 +16,7 @@
 int vp9_encode_intra(VP9_COMP *cpi, MACROBLOCK *x, int use_16x16_pred);
 void vp9_encode_intra16x16mby(VP9_COMMON *const cm, MACROBLOCK *x);
 void vp9_encode_intra16x16mbuv(VP9_COMMON *const cm, MACROBLOCK *x);
-void vp9_encode_intra4x4mby(MACROBLOCK *mb);
+void vp9_encode_intra4x4mby(MACROBLOCK *mb, BLOCK_SIZE_TYPE bs);
 void vp9_encode_intra8x8mby(MACROBLOCK *x);
 void vp9_encode_intra8x8mbuv(MACROBLOCK *x);
 void vp9_encode_intra8x8(MACROBLOCK *x, int ib);