sb8x8 integration in rd loop.
authorRonald S. Bultje <rbultje@google.com>
Tue, 30 Apr 2013 23:13:20 +0000 (16:13 -0700)
committerRonald S. Bultje <rbultje@google.com>
Tue, 30 Apr 2013 23:13:20 +0000 (16:13 -0700)
Work-in-progress, not yet ready for review. TODO items:
- bitstream writing (encoder) and reading (decoder)
- decoder reconstruction

Change-Id: I5afb7284e7e0480847b47cd0097cb469433c9081

26 files changed:
vp9/common/vp9_blockd.h
vp9/common/vp9_entropymode.c
vp9/common/vp9_entropymode.h
vp9/common/vp9_enums.h
vp9/common/vp9_findnearmv.h
vp9/common/vp9_loopfilter.c
vp9/common/vp9_onyxc_int.h
vp9/common/vp9_reconinter.c
vp9/decoder/vp9_decodemv.c
vp9/decoder/vp9_decodframe.c
vp9/encoder/vp9_bitstream.c
vp9/encoder/vp9_block.h
vp9/encoder/vp9_encodeframe.c
vp9/encoder/vp9_encodeintra.c
vp9/encoder/vp9_encodeintra.h
vp9/encoder/vp9_encodemb.c
vp9/encoder/vp9_encodemb.h
vp9/encoder/vp9_modecosts.c
vp9/encoder/vp9_onyx_if.c
vp9/encoder/vp9_onyx_int.h
vp9/encoder/vp9_quantize.c
vp9/encoder/vp9_ratectrl.c
vp9/encoder/vp9_rdopt.c
vp9/encoder/vp9_rdopt.h
vp9/encoder/vp9_segmentation.c
vp9/encoder/vp9_tokenize.c

index aebf4a1..6c18387 100644 (file)
@@ -83,7 +83,9 @@ typedef enum {
   D27_PRED,           /* Directional 22 deg prediction  [anti-clockwise from 0 deg hor] */
   D63_PRED,           /* Directional 67 deg prediction  [anti-clockwise from 0 deg hor] */
   TM_PRED,            /* Truemotion prediction */
+#if !CONFIG_SB8X8
   I8X8_PRED,          /* 8x8 based prediction, each 8x8 has its own mode */
+#endif
   I4X4_PRED,          /* 4x4 based prediction, each 4x4 has its own mode */
   NEARESTMV,
   NEARMV,
@@ -126,7 +128,9 @@ typedef enum {
 
 #define VP9_YMODES  (I4X4_PRED + 1)
 #define VP9_UV_MODES (TM_PRED + 1)
+#if !CONFIG_SB8X8
 #define VP9_I8X8_MODES (TM_PRED + 1)
+#endif
 #define VP9_I32X32_MODES (TM_PRED + 1)
 
 #define VP9_MVREFS (1 + SPLITMV - NEARESTMV)
@@ -169,6 +173,7 @@ typedef enum {
 #define VP9_NKF_BINTRAMODES (VP9_BINTRAMODES)  /* 10 */
 #endif
 
+#if !CONFIG_SB8X8
 typedef enum {
   PARTITIONING_16X8 = 0,
   PARTITIONING_8X16,
@@ -176,6 +181,7 @@ typedef enum {
   PARTITIONING_4X4,
   NB_PARTITIONINGS,
 } SPLITMV_PARTITIONING_TYPE;
+#endif
 
 /* For keyframes, intra block modes are predicted by the (already decoded)
    modes for the Y blocks to the left and above us; for interframes, there
@@ -271,7 +277,9 @@ typedef struct {
 
   int mb_mode_context[MAX_REF_FRAMES];
 
+#if !CONFIG_SB8X8
   SPLITMV_PARTITIONING_TYPE partitioning;
+#endif
   unsigned char mb_skip_coeff;                                /* does this mb has coefficients at all, 1=no coefficients, 0=need decode tokens */
   unsigned char need_to_clamp_mvs;
   unsigned char need_to_clamp_secondmv;
@@ -293,7 +301,7 @@ typedef struct {
 
 typedef struct {
   MB_MODE_INFO mbmi;
-  union b_mode_info bmi[16];
+  union b_mode_info bmi[16 >> (CONFIG_SB8X8 * 2)];
 } MODE_INFO;
 
 struct scale_factors {
@@ -433,8 +441,11 @@ typedef struct macroblockd {
 
   int corrupted;
 
-  int sb_index;
-  int mb_index;   // Index of the MB in the SB (0..3)
+  int sb_index;   // index of 32x32 block inside the 64x64 block
+  int mb_index;   // index of 16x16 block inside the 32x32 block
+#if CONFIG_SB8X8
+  int b_index;    // index of 8x8 block inside the 16x16 block
+#endif
   int q_index;
 
 } MACROBLOCKD;
@@ -442,10 +453,10 @@ typedef struct macroblockd {
 static INLINE void update_partition_context(MACROBLOCKD *xd,
                                             BLOCK_SIZE_TYPE sb_type,
                                             BLOCK_SIZE_TYPE sb_size) {
-  int bsl = mi_width_log2(sb_size) - CONFIG_SB8X8, bs = 1 << bsl;
-  int bwl = mi_width_log2(sb_type) - CONFIG_SB8X8;
-  int bhl = mi_height_log2(sb_type) - CONFIG_SB8X8;
-  int boffset = mi_width_log2(BLOCK_SIZE_SB64X64) - CONFIG_SB8X8 - bsl;
+  int bsl = mi_width_log2(sb_size), bs = 1 << bsl;
+  int bwl = mi_width_log2(sb_type);
+  int bhl = mi_height_log2(sb_type);
+  int boffset = mi_width_log2(BLOCK_SIZE_SB64X64) - bsl;
   int i;
   // skip macroblock partition
   if (bsl == 0)
@@ -481,9 +492,9 @@ static INLINE void update_partition_context(MACROBLOCKD *xd,
 
 static INLINE int partition_plane_context(MACROBLOCKD *xd,
                                           BLOCK_SIZE_TYPE sb_type) {
-  int bsl = mi_width_log2(sb_type) - CONFIG_SB8X8, bs = 1 << bsl;
+  int bsl = mi_width_log2(sb_type), bs = 1 << bsl;
   int above = 0, left = 0, i;
-  int boffset = mi_width_log2(BLOCK_SIZE_SB64X64) - bsl - CONFIG_SB8X8;
+  int boffset = mi_width_log2(BLOCK_SIZE_SB64X64) - bsl;
 
   assert(mi_width_log2(sb_type) == mi_height_log2(sb_type));
   assert(bsl >= 0);
@@ -581,6 +592,7 @@ static TX_TYPE get_tx_type_4x4(const MACROBLOCKD *xd, int ib) {
           xd->mode_info_context->bmi[ib].as_mode.context :
 #endif
         xd->mode_info_context->bmi[ib].as_mode.first);
+#if !CONFIG_SB8X8
   } else if (xd->mode_info_context->mbmi.mode == I8X8_PRED &&
              xd->q_index < ACTIVE_HT) {
     const int ic = (ib & 10);
@@ -615,7 +627,8 @@ static TX_TYPE get_tx_type_4x4(const MACROBLOCKD *xd, int ib) {
     // Use 2D DCT
     tx_type = DCT_DCT;
 #endif
-  } else if (xd->mode_info_context->mbmi.mode < I8X8_PRED &&
+#endif  // !CONFIG_SB8X8
+  } else if (xd->mode_info_context->mbmi.mode <= TM_PRED &&
              xd->q_index < ACTIVE_HT) {
 #if USE_ADST_FOR_I16X16_4X4
 #if USE_ADST_PERIPHERY_ONLY
@@ -659,14 +672,17 @@ static TX_TYPE get_tx_type_8x8(const MACROBLOCKD *xd, int ib) {
 #endif
   if (ib >= (1 << (wb + hb)))  // no chroma adst
     return tx_type;
+#if !CONFIG_SB8X8
   if (xd->mode_info_context->mbmi.mode == I8X8_PRED &&
       xd->q_index < ACTIVE_HT8) {
     // TODO(rbultje): MB_PREDICTION_MODE / B_PREDICTION_MODE should be merged
     // or the relationship otherwise modified to address this type conversion.
     tx_type = txfm_map(pred_mode_conv(
            (MB_PREDICTION_MODE)xd->mode_info_context->bmi[ib].as_mode.first));
-  } else if (xd->mode_info_context->mbmi.mode < I8X8_PRED &&
-             xd->q_index < ACTIVE_HT8) {
+  } else
+#endif  // CONFIG_SB8X8
+  if (xd->mode_info_context->mbmi.mode <= TM_PRED &&
+      xd->q_index < ACTIVE_HT8) {
 #if USE_ADST_FOR_I16X16_8X8
 #if USE_ADST_PERIPHERY_ONLY
     const int hmax = 1 << wb;
@@ -707,7 +723,7 @@ static TX_TYPE get_tx_type_16x16(const MACROBLOCKD *xd, int ib) {
 #endif
   if (ib >= (1 << (wb + hb)))
     return tx_type;
-  if (xd->mode_info_context->mbmi.mode < I8X8_PRED &&
+  if (xd->mode_info_context->mbmi.mode <= TM_PRED &&
       xd->q_index < ACTIVE_HT16) {
     tx_type = txfm_map(pred_mode_conv(xd->mode_info_context->mbmi.mode));
 #if USE_ADST_PERIPHERY_ONLY
@@ -738,7 +754,9 @@ void vp9_setup_block_dptrs(MACROBLOCKD *xd);
 static TX_SIZE get_uv_tx_size(const MACROBLOCKD *xd) {
   MB_MODE_INFO *mbmi = &xd->mode_info_context->mbmi;
   const TX_SIZE size = mbmi->txfm_size;
+#if !CONFIG_SB8X8
   const MB_PREDICTION_MODE mode = mbmi->mode;
+#endif  // !CONFIG_SB8X8
 
   switch (mbmi->sb_type) {
     case BLOCK_SIZE_SB64X64:
@@ -750,6 +768,17 @@ static TX_SIZE get_uv_tx_size(const MACROBLOCKD *xd) {
         return TX_16X16;
       else
         return size;
+#if CONFIG_SB8X8
+    case BLOCK_SIZE_SB32X16:
+    case BLOCK_SIZE_SB16X32:
+    case BLOCK_SIZE_MB16X16:
+      if (size == TX_16X16)
+        return TX_8X8;
+      else
+        return size;
+    default:
+      return TX_4X4;
+#else  // CONFIG_SB8X8
     default:
       if (size == TX_16X16)
         return TX_8X8;
@@ -757,6 +786,7 @@ static TX_SIZE get_uv_tx_size(const MACROBLOCKD *xd) {
         return TX_4X4;
       else
         return size;
+#endif  // CONFIG_SB8X8
   }
 
   return size;
@@ -812,7 +842,10 @@ typedef void (*foreach_transformed_block_visitor)(int plane, int block,
                                                   void *arg);
 static INLINE void foreach_transformed_block_in_plane(
     const MACROBLOCKD* const xd, BLOCK_SIZE_TYPE bsize, int plane,
-    int is_split, foreach_transformed_block_visitor visit, void *arg) {
+#if !CONFIG_SB8X8
+    int is_split,
+#endif  // !CONFIG_SB8X8
+    foreach_transformed_block_visitor visit, void *arg) {
   const int bw = b_width_log2(bsize), bh = b_height_log2(bsize);
 
   // block and transform sizes, in number of 4x4 blocks log 2 ("*_b")
@@ -830,7 +863,10 @@ static INLINE void foreach_transformed_block_in_plane(
   // than the size of the subsampled data, or forced externally by the mb mode.
   const int ss_max = MAX(xd->plane[plane].subsampling_x,
                          xd->plane[plane].subsampling_y);
-  const int ss_txfrm_size = txfrm_size_b > ss_block_size || is_split
+  const int ss_txfrm_size = txfrm_size_b > ss_block_size
+#if !CONFIG_SB8X8
+                            || is_split
+#endif  // !CONFIG_SB8X8
                                 ? txfrm_size_b - ss_max * 2
                                 : txfrm_size_b;
   const int step = 1 << ss_txfrm_size;
@@ -847,17 +883,24 @@ static INLINE void foreach_transformed_block_in_plane(
 static INLINE void foreach_transformed_block(
     const MACROBLOCKD* const xd, BLOCK_SIZE_TYPE bsize,
     foreach_transformed_block_visitor visit, void *arg) {
+#if !CONFIG_SB8X8
   const MB_PREDICTION_MODE mode = xd->mode_info_context->mbmi.mode;
   const int is_split =
       xd->mode_info_context->mbmi.txfm_size == TX_8X8 &&
       (mode == I8X8_PRED || mode == SPLITMV);
+#endif  // !CONFIG_SB8X8
   int plane;
 
   for (plane = 0; plane < MAX_MB_PLANE; plane++) {
+#if !CONFIG_SB8X8
     const int is_split_chroma = is_split &&
          xd->plane[plane].plane_type == PLANE_TYPE_UV;
+#endif  // !CONFIG_SB8X8
 
-    foreach_transformed_block_in_plane(xd, bsize, plane, is_split_chroma,
+    foreach_transformed_block_in_plane(xd, bsize, plane,
+#if !CONFIG_SB8X8
+                                       is_split_chroma,
+#endif  // !CONFIG_SB8X8
                                        visit, arg);
   }
 }
@@ -865,14 +908,19 @@ static INLINE void foreach_transformed_block(
 static INLINE void foreach_transformed_block_uv(
     const MACROBLOCKD* const xd, BLOCK_SIZE_TYPE bsize,
     foreach_transformed_block_visitor visit, void *arg) {
+#if !CONFIG_SB8X8
   const MB_PREDICTION_MODE mode = xd->mode_info_context->mbmi.mode;
   const int is_split =
       xd->mode_info_context->mbmi.txfm_size == TX_8X8 &&
       (mode == I8X8_PRED || mode == SPLITMV);
+#endif  // !CONFIG_SB8X8
   int plane;
 
   for (plane = 1; plane < MAX_MB_PLANE; plane++) {
-    foreach_transformed_block_in_plane(xd, bsize, plane, is_split,
+    foreach_transformed_block_in_plane(xd, bsize, plane,
+#if !CONFIG_SB8X8
+                                       is_split,
+#endif  // !CONFIG_SB8X8
                                        visit, arg);
   }
 }
@@ -900,11 +948,16 @@ static INLINE void foreach_predicted_block_in_plane(
   int pred_w, pred_h;
 
   if (mode == SPLITMV) {
+#if CONFIG_SB8X8
+    pred_w = 0;
+    pred_h = 0;
+#else
     // 4x4 or 8x8
     const int is_4x4 =
         (xd->mode_info_context->mbmi.partitioning == PARTITIONING_4X4);
     pred_w = is_4x4 ? 0 : 1 >> xd->plane[plane].subsampling_x;
     pred_h = is_4x4 ? 0 : 1 >> xd->plane[plane].subsampling_y;
+#endif
   } else {
     pred_w = bw;
     pred_h = bh;
index 8d5577f..ed5441c 100644 (file)
 #include "vpx_mem/vpx_mem.h"
 
 static const unsigned int kf_y_mode_cts[8][VP9_YMODES] = {
+#if CONFIG_SB8X8
+  /* DC V   H  D45 135 117 153 D27 D63 TM i4X4 */
+  {12,  6,  5,  5,  5,  5,  5,  5,  5,  2, 200},
+  {25, 13, 13,  7,  7,  7,  7,  7,  7,  6, 160},
+  {31, 17, 18,  8,  8,  8,  8,  8,  8,  9, 139},
+  {40, 22, 23,  8,  8,  8,  8,  8,  8, 12, 116},
+  {53, 26, 28,  8,  8,  8,  8,  8,  8, 13,  94},
+  {68, 33, 35,  8,  8,  8,  8,  8,  8, 17,  68},
+  {78, 38, 38,  8,  8,  8,  8,  8,  8, 19,  52},
+  {89, 42, 42,  8,  8,  8,  8,  8,  8, 21,  34},
+#else
   /* DC V   H  D45 135 117 153 D27 D63 TM i8x8 i4X4 */
   {12,  6,  5,  5,  5,  5,  5,  5,  5,  2, 22, 200},
   {25, 13, 13,  7,  7,  7,  7,  7,  7,  6, 27, 160},
@@ -25,11 +36,17 @@ static const unsigned int kf_y_mode_cts[8][VP9_YMODES] = {
   {68, 33, 35,  8,  8,  8,  8,  8,  8, 17, 20,  68},
   {78, 38, 38,  8,  8,  8,  8,  8,  8, 19, 16,  52},
   {89, 42, 42,  8,  8,  8,  8,  8,  8, 21, 12,  34},
+#endif
 };
 
 static const unsigned int y_mode_cts  [VP9_YMODES] = {
+#if CONFIG_SB8X8
+  /* DC V   H  D45 135 117 153 D27 D63 TM i4X4 */
+  98, 19, 15, 14, 14, 14, 14, 12, 12, 13, 70
+#else
   /* DC V   H  D45 135 117 153 D27 D63 TM i8x8 i4X4 */
   98, 19, 15, 14, 14, 14, 14, 12, 12, 13, 16, 70
+#endif
 };
 
 static const unsigned int uv_mode_cts [VP9_YMODES] [VP9_UV_MODES] = {
@@ -44,14 +61,18 @@ static const unsigned int uv_mode_cts [VP9_YMODES] [VP9_UV_MODES] = {
   { 150, 15, 10, 10, 10, 10, 10, 75, 10,  6}, /* D27 */
   { 150, 15, 10, 10, 10, 10, 10, 10, 75,  6}, /* D63 */
   { 160, 30, 30, 10, 10, 10, 10, 10, 10, 16}, /* TM */
+#if !CONFIG_SB8X8
   { 132, 46, 40, 10, 10, 10, 10, 10, 10, 18}, /* i8x8 - never used */
+#endif
   { 150, 35, 41, 10, 10, 10, 10, 10, 10, 10}, /* i4X4 */
 };
 
+#if !CONFIG_SB8X8
 static const unsigned int i8x8_mode_cts  [VP9_I8X8_MODES] = {
   /* DC V  H D45 135 117 153 D27 D63  TM */
   73, 49, 61, 30, 30, 30, 30, 30, 30, 13
 };
+#endif
 
 static const unsigned int kf_uv_mode_cts [VP9_YMODES] [VP9_UV_MODES] = {
   // DC   V   H  D45 135 117 153 D27 D63 TM
@@ -65,7 +86,9 @@ static const unsigned int kf_uv_mode_cts [VP9_YMODES] [VP9_UV_MODES] = {
   { 102, 33, 20, 20, 20, 20, 20, 64, 20, 14}, /* D27 */
   { 102, 33, 20, 20, 20, 20, 20, 20, 64, 14}, /* D63 */
   { 132, 36, 30, 20, 20, 20, 20, 20, 20, 18}, /* TM */
+#if !CONFIG_SB8X8
   { 122, 41, 35, 20, 20, 20, 20, 20, 20, 18}, /* i8x8 - never used */
+#endif
   { 122, 41, 35, 20, 20, 20, 20, 20, 20, 18}, /* I4X4 */
 };
 
@@ -123,6 +146,7 @@ const vp9_prob vp9_sub_mv_ref_prob2 [SUBMVREF_COUNT][VP9_SUBMVREFS - 1] = {
   { 208, 1, 1  }
 };
 
+#if !CONFIG_SB8X8
 vp9_mbsplit vp9_mbsplits [VP9_NUMMBSPLITS] = {
   {
     0,  0,  0,  0,
@@ -150,9 +174,17 @@ vp9_mbsplit vp9_mbsplits [VP9_NUMMBSPLITS] = {
 const int vp9_mbsplit_count [VP9_NUMMBSPLITS] = { 2, 2, 4, 16};
 
 const vp9_prob vp9_mbsplit_probs [VP9_NUMMBSPLITS - 1] = { 110, 111, 150};
+#endif
 
 const vp9_prob vp9_partition_probs[NUM_PARTITION_CONTEXTS]
                                   [PARTITION_TYPES - 1] = {
+#if CONFIG_SB8X8
+  // FIXME(jingning,rbultje) put real probabilities here
+  {202, 162, 107},
+  {16,  2,   169},
+  {3,   246,  19},
+  {104, 90,  134},
+#endif
   {202, 162, 107},
   {16,  2,   169},
   {3,   246,  19},
@@ -228,8 +260,12 @@ const vp9_tree_index vp9_ymode_tree[VP9_YMODES * 2 - 2] = {
   -D27_PRED, -D63_PRED,
   16, 18,
   -V_PRED, -H_PRED,
+#if CONFIG_SB8X8
+  -TM_PRED, -I4X4_PRED
+#else
   -TM_PRED, 20,
   -I4X4_PRED, -I8X8_PRED
+#endif
 };
 
 const vp9_tree_index vp9_kf_ymode_tree[VP9_YMODES * 2 - 2] = {
@@ -242,10 +278,15 @@ const vp9_tree_index vp9_kf_ymode_tree[VP9_YMODES * 2 - 2] = {
   -D27_PRED, -D63_PRED,
   16, 18,
   -V_PRED, -H_PRED,
+#if CONFIG_SB8X8
+  -TM_PRED, -I4X4_PRED
+#else
   -TM_PRED, 20,
   -I4X4_PRED, -I8X8_PRED
+#endif
 };
 
+#if !CONFIG_SB8X8
 const vp9_tree_index vp9_i8x8_mode_tree[VP9_I8X8_MODES * 2 - 2] = {
   2, 14,
   -DC_PRED, 4,
@@ -257,6 +298,7 @@ const vp9_tree_index vp9_i8x8_mode_tree[VP9_I8X8_MODES * 2 - 2] = {
   -V_PRED, 16,
   -H_PRED, -TM_PRED
 };
+#endif
 
 const vp9_tree_index vp9_uv_mode_tree[VP9_UV_MODES * 2 - 2] = {
   2, 14,
@@ -270,11 +312,13 @@ const vp9_tree_index vp9_uv_mode_tree[VP9_UV_MODES * 2 - 2] = {
   -H_PRED, -TM_PRED
 };
 
+#if !CONFIG_SB8X8
 const vp9_tree_index vp9_mbsplit_tree[6] = {
   -PARTITIONING_4X4,   2,
   -PARTITIONING_8X8,   4,
   -PARTITIONING_16X8, -PARTITIONING_8X16,
 };
+#endif
 
 const vp9_tree_index vp9_mv_ref_tree[8] = {
   -ZEROMV, 2,
@@ -308,8 +352,10 @@ struct vp9_token vp9_sb_ymode_encodings[VP9_I32X32_MODES];
 struct vp9_token vp9_sb_kf_ymode_encodings[VP9_I32X32_MODES];
 struct vp9_token vp9_kf_ymode_encodings[VP9_YMODES];
 struct vp9_token vp9_uv_mode_encodings[VP9_UV_MODES];
+#if !CONFIG_SB8X8
 struct vp9_token vp9_i8x8_mode_encodings[VP9_I8X8_MODES];
 struct vp9_token vp9_mbsplit_encodings[VP9_NUMMBSPLITS];
+#endif
 
 struct vp9_token vp9_mv_ref_encoding_array[VP9_MVREFS];
 struct vp9_token vp9_sb_mv_ref_encoding_array[VP9_MVREFS];
@@ -340,12 +386,16 @@ void vp9_init_mbmode_probs(VP9_COMMON *x) {
                                      bct, uv_mode_cts[i], 0);
   }
 
+#if !CONFIG_SB8X8
   vp9_tree_probs_from_distribution(vp9_i8x8_mode_tree, x->fc.i8x8_mode_prob,
                                    bct, i8x8_mode_cts, 0);
+#endif
 
   vpx_memcpy(x->fc.sub_mv_ref_prob, vp9_sub_mv_ref_prob2,
              sizeof(vp9_sub_mv_ref_prob2));
+#if !CONFIG_SB8X8
   vpx_memcpy(x->fc.mbsplit_prob, vp9_mbsplit_probs, sizeof(vp9_mbsplit_probs));
+#endif
   vpx_memcpy(x->fc.switchable_interp_prob, vp9_switchable_interp_prob,
              sizeof(vp9_switchable_interp_prob));
 
@@ -449,8 +499,10 @@ void vp9_entropy_mode_init() {
   vp9_tokens_from_tree(vp9_sb_ymode_encodings, vp9_sb_ymode_tree);
   vp9_tokens_from_tree(vp9_sb_kf_ymode_encodings, vp9_sb_kf_ymode_tree);
   vp9_tokens_from_tree(vp9_uv_mode_encodings,  vp9_uv_mode_tree);
+#if !CONFIG_SB8X8
   vp9_tokens_from_tree(vp9_i8x8_mode_encodings,  vp9_i8x8_mode_tree);
   vp9_tokens_from_tree(vp9_mbsplit_encodings, vp9_mbsplit_tree);
+#endif
   vp9_tokens_from_tree(vp9_switchable_interp_encodings,
                        vp9_switchable_interp_tree);
   vp9_tokens_from_tree(vp9_partition_encodings, vp9_partition_tree);
@@ -629,9 +681,11 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) {
   update_mode_probs(VP9_NKF_BINTRAMODES, vp9_bmode_tree,
                     fc->bmode_counts, fc->pre_bmode_prob,
                     fc->bmode_prob, 0);
+#if !CONFIG_SB8X8
   update_mode_probs(VP9_I8X8_MODES,
                     vp9_i8x8_mode_tree, fc->i8x8_mode_counts,
                     fc->pre_i8x8_mode_prob, fc->i8x8_mode_prob, 0);
+#endif
 
   for (i = 0; i < SUBMVREF_COUNT; ++i)
     update_mode_probs(VP9_SUBMVREFS,
@@ -639,9 +693,11 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) {
                       fc->pre_sub_mv_ref_prob[i], fc->sub_mv_ref_prob[i],
                       LEFT4X4);
 
+#if !CONFIG_SB8X8
   update_mode_probs(VP9_NUMMBSPLITS, vp9_mbsplit_tree,
                     fc->mbsplit_counts, fc->pre_mbsplit_prob,
                     fc->mbsplit_prob, 0);
+#endif
 #if CONFIG_COMP_INTERINTRA_PRED
   if (cm->use_interintra) {
     int factor, interintra_prob, count;
index 6655695..24f988f 100644 (file)
@@ -15,7 +15,9 @@
 #include "vp9/common/vp9_treecoder.h"
 
 #define SUBMVREF_COUNT 5
+#if !CONFIG_SB8X8
 #define VP9_NUMMBSPLITS 4
+#endif
 
 #if CONFIG_COMP_INTERINTRA_PRED
 #define VP9_DEF_INTERINTRA_PROB 248
@@ -24,6 +26,7 @@
 #define SEPARATE_INTERINTRA_UV  0
 #endif
 
+#if !CONFIG_SB8X8
 typedef const int vp9_mbsplit[16];
 
 extern vp9_mbsplit vp9_mbsplits[VP9_NUMMBSPLITS];
@@ -31,6 +34,7 @@ extern vp9_mbsplit vp9_mbsplits[VP9_NUMMBSPLITS];
 extern const int vp9_mbsplit_count[VP9_NUMMBSPLITS];    /* # of subsets */
 
 extern const vp9_prob vp9_mbsplit_probs[VP9_NUMMBSPLITS - 1];
+#endif
 
 extern int vp9_mv_cont(const int_mv *l, const int_mv *a);
 
@@ -48,8 +52,10 @@ extern const vp9_tree_index  vp9_kf_ymode_tree[];
 extern const vp9_tree_index  vp9_uv_mode_tree[];
 #define vp9_sb_ymode_tree vp9_uv_mode_tree
 #define vp9_sb_kf_ymode_tree vp9_uv_mode_tree
+#if !CONFIG_SB8X8
 extern const vp9_tree_index  vp9_i8x8_mode_tree[];
 extern const vp9_tree_index  vp9_mbsplit_tree[];
+#endif
 extern const vp9_tree_index  vp9_mv_ref_tree[];
 extern const vp9_tree_index  vp9_sb_mv_ref_tree[];
 extern const vp9_tree_index  vp9_sub_mv_ref_tree[];
@@ -60,9 +66,11 @@ extern struct vp9_token vp9_ymode_encodings[VP9_YMODES];
 extern struct vp9_token vp9_sb_ymode_encodings[VP9_I32X32_MODES];
 extern struct vp9_token vp9_sb_kf_ymode_encodings[VP9_I32X32_MODES];
 extern struct vp9_token vp9_kf_ymode_encodings[VP9_YMODES];
-extern struct vp9_token vp9_i8x8_mode_encodings[VP9_I8X8_MODES];
 extern struct vp9_token vp9_uv_mode_encodings[VP9_UV_MODES];
+#if !CONFIG_SB8X8
+extern struct vp9_token vp9_i8x8_mode_encodings[VP9_I8X8_MODES];
 extern struct vp9_token vp9_mbsplit_encodings[VP9_NUMMBSPLITS];
+#endif
 
 /* Inter mode values do not start at zero */
 
index b72b41e..3f00ba4 100644 (file)
@@ -47,6 +47,6 @@ typedef enum PARTITION_TYPE {
 } PARTITION_TYPE;
 
 #define PARTITION_PLOFFSET   4  // number of probability models per block size
-#define NUM_PARTITION_CONTEXTS (2 * PARTITION_PLOFFSET)
+#define NUM_PARTITION_CONTEXTS ((2 + CONFIG_SB8X8) * PARTITION_PLOFFSET)
 
 #endif  // VP9_COMMON_VP9_ENUMS_H_
index 0854545..df1ab73 100644 (file)
@@ -74,11 +74,13 @@ vp9_prob *vp9_mv_ref_probs(VP9_COMMON *pc,
                            vp9_prob p[VP9_MVREFS - 1],
                            const int context);
 
+#if !CONFIG_SB8X8
 extern const uint8_t vp9_mbsplit_offset[4][16];
+#endif
 
 static int left_block_mv(const MACROBLOCKD *xd,
                          const MODE_INFO *cur_mb, int b) {
-  if (!(b & 3)) {
+  if (!(b & (3 >> CONFIG_SB8X8))) {
     if (!xd->left_available)
       return 0;
 
@@ -88,7 +90,7 @@ static int left_block_mv(const MACROBLOCKD *xd,
     if (cur_mb->mbmi.mode != SPLITMV)
       return cur_mb->mbmi.mv[0].as_int;
 
-    b += 4;
+    b += 4 >> CONFIG_SB8X8;
   }
 
   return (cur_mb->bmi + b - 1)->as_mv[0].as_int;
@@ -96,7 +98,7 @@ static int left_block_mv(const MACROBLOCKD *xd,
 
 static int left_block_second_mv(const MACROBLOCKD *xd,
                                 const MODE_INFO *cur_mb, int b) {
-  if (!(b & 3)) {
+  if (!(b & (3 >> CONFIG_SB8X8))) {
     if (!xd->left_available)
       return 0;
 
@@ -106,7 +108,7 @@ static int left_block_second_mv(const MACROBLOCKD *xd,
     if (cur_mb->mbmi.mode != SPLITMV)
       return cur_mb->mbmi.second_ref_frame > 0 ?
           cur_mb->mbmi.mv[1].as_int : cur_mb->mbmi.mv[0].as_int;
-    b += 4;
+    b += 4 >> CONFIG_SB8X8;
   }
 
   return cur_mb->mbmi.second_ref_frame > 0 ?
@@ -115,72 +117,85 @@ static int left_block_second_mv(const MACROBLOCKD *xd,
 }
 
 static int above_block_mv(const MODE_INFO *cur_mb, int b, int mi_stride) {
-  if (!(b >> 2)) {
+  if (!(b >> (2 >> CONFIG_SB8X8))) {
     /* On top edge, get from MB above us */
     cur_mb -= mi_stride;
 
     if (cur_mb->mbmi.mode != SPLITMV)
       return cur_mb->mbmi.mv[0].as_int;
-    b += 16;
+    b += 16 >> (2 * CONFIG_SB8X8);
   }
 
-  return (cur_mb->bmi + b - 4)->as_mv[0].as_int;
+  return (cur_mb->bmi + b - (4 >> CONFIG_SB8X8))->as_mv[0].as_int;
 }
 
 static int above_block_second_mv(const MODE_INFO *cur_mb, int b, int mi_stride) {
-  if (!(b >> 2)) {
+  if (!(b >> (2 >> CONFIG_SB8X8))) {
     /* On top edge, get from MB above us */
     cur_mb -= mi_stride;
 
     if (cur_mb->mbmi.mode != SPLITMV)
       return cur_mb->mbmi.second_ref_frame > 0 ?
           cur_mb->mbmi.mv[1].as_int : cur_mb->mbmi.mv[0].as_int;
-    b += 16;
+    b += 16 >> (2 * CONFIG_SB8X8);
   }
 
   return cur_mb->mbmi.second_ref_frame > 0 ?
-      (cur_mb->bmi + b - 4)->as_mv[1].as_int :
-      (cur_mb->bmi + b - 4)->as_mv[0].as_int;
+      (cur_mb->bmi + b - (4 >> CONFIG_SB8X8))->as_mv[1].as_int :
+      (cur_mb->bmi + b - (4 >> CONFIG_SB8X8))->as_mv[0].as_int;
 }
 
 static B_PREDICTION_MODE left_block_mode(const MODE_INFO *cur_mb, int b) {
-  if (!(b & 3)) {
+#if CONFIG_SB8X8
+  // FIXME(rbultje, jingning): temporary hack because jenkins doesn't
+  // understand this condition. This will go away soon.
+  if (b == 0 || b == 2) {
+#else
+  if (!(b & (3 >> CONFIG_SB8X8))) {
+#endif
     /* On L edge, get from MB to left of us */
     --cur_mb;
 
-    if (cur_mb->mbmi.mode < I8X8_PRED) {
+    if (cur_mb->mbmi.mode <= TM_PRED) {
       return pred_mode_conv(cur_mb->mbmi.mode);
+#if !CONFIG_SB8X8
     } else if (cur_mb->mbmi.mode == I8X8_PRED) {
       return pred_mode_conv(
           (MB_PREDICTION_MODE)(cur_mb->bmi + 3 + b)->as_mode.first);
+#endif  // !CONFIG_SB8X8
     } else if (cur_mb->mbmi.mode == I4X4_PRED) {
-      return ((cur_mb->bmi + 3 + b)->as_mode.first);
+      return ((cur_mb->bmi + (3 >> CONFIG_SB8X8) + b)->as_mode.first);
     } else {
       return B_DC_PRED;
     }
   }
+#if CONFIG_SB8X8
+  assert(b == 1 || b == 3);
+#endif
   return (cur_mb->bmi + b - 1)->as_mode.first;
 }
 
 static B_PREDICTION_MODE above_block_mode(const MODE_INFO *cur_mb,
                                           int b, int mi_stride) {
-  if (!(b >> 2)) {
+  if (!(b >> (2 >> CONFIG_SB8X8))) {
     /* On top edge, get from MB above us */
     cur_mb -= mi_stride;
 
-    if (cur_mb->mbmi.mode < I8X8_PRED) {
+    if (cur_mb->mbmi.mode <= TM_PRED) {
       return pred_mode_conv(cur_mb->mbmi.mode);
+#if !CONFIG_SB8X8
     } else if (cur_mb->mbmi.mode == I8X8_PRED) {
       return pred_mode_conv(
           (MB_PREDICTION_MODE)(cur_mb->bmi + 12 + b)->as_mode.first);
+#endif
     } else if (cur_mb->mbmi.mode == I4X4_PRED) {
-      return ((cur_mb->bmi + 12 + b)->as_mode.first);
+      return ((cur_mb->bmi + (CONFIG_SB8X8 ? 2 : 12) + b)->as_mode.first);
     } else {
       return B_DC_PRED;
     }
   }
 
-  return (cur_mb->bmi + b - 4)->as_mode.first;
+  return (cur_mb->bmi + b - (4 >> CONFIG_SB8X8))->as_mode.first;
 }
 
 #endif  // VP9_COMMON_VP9_FINDNEARMV_H_
index ed0c354..edb0c54 100644 (file)
@@ -27,7 +27,9 @@ static void lf_init_lut(loop_filter_info_n *lfi) {
   lfi->mode_lf_lut[H_PRED] = 1;
   lfi->mode_lf_lut[TM_PRED] = 1;
   lfi->mode_lf_lut[I4X4_PRED]  = 0;
+#if !CONFIG_SB8X8
   lfi->mode_lf_lut[I8X8_PRED] = 0;
+#endif
   lfi->mode_lf_lut[ZEROMV]  = 1;
   lfi->mode_lf_lut[NEARESTMV] = 2;
   lfi->mode_lf_lut[NEARMV] = 2;
@@ -165,10 +167,14 @@ void vp9_loop_filter_frame_init(VP9_COMMON *cm,
 // the MB uses a prediction size of 16x16 and either 16x16 transform
 // is used or there is no residue at all.
 static int mb_lf_skip(const MB_MODE_INFO *const mbmi) {
-  const MB_PREDICTION_MODE mode = mbmi->mode;
   const int skip_coef = mbmi->mb_skip_coeff;
   const int tx_size = mbmi->txfm_size;
+#if CONFIG_SB8X8
+  return mbmi->sb_type >= BLOCK_SIZE_MB16X16 &&
+#else
+  const MB_PREDICTION_MODE mode = mbmi->mode;
   return mode != I4X4_PRED && mode != I8X8_PRED && mode != SPLITMV &&
+#endif
          (tx_size >= TX_16X16 || skip_coef);
 }
 
@@ -220,7 +226,13 @@ static void lpf_mb(VP9_COMMON *cm, const MODE_INFO *mi,
 
       if (!skip_lf) {
         if (tx_size >= TX_8X8) {
-          if (tx_size == TX_8X8 && (mode == I8X8_PRED || mode == SPLITMV))
+          if (tx_size == TX_8X8 &&
+#if CONFIG_SB8X8
+              (mi->mbmi.sb_type < BLOCK_SIZE_MB16X16)
+#else
+              (mode == I8X8_PRED || mode == SPLITMV)
+#endif
+              )
             vp9_loop_filter_bh8x8(y_ptr, u_ptr, v_ptr,
                                   y_stride, uv_stride, &lfi);
           else
@@ -244,7 +256,13 @@ static void lpf_mb(VP9_COMMON *cm, const MODE_INFO *mi,
 
       if (!skip_lf) {
         if (tx_size >= TX_8X8) {
-          if (tx_size == TX_8X8 && (mode == I8X8_PRED || mode == SPLITMV))
+          if (tx_size == TX_8X8 &&
+#if CONFIG_SB8X8
+              (mi->mbmi.sb_type < BLOCK_SIZE_MB16X16)
+#else
+              (mode == I8X8_PRED || mode == SPLITMV)
+#endif
+              )
             vp9_loop_filter_bv8x8(y_ptr, u_ptr, v_ptr,
                                   y_stride, uv_stride, &lfi);
           else
index cbead80..96ceca2 100644 (file)
@@ -65,9 +65,13 @@ typedef struct frame_contexts {
   vp9_prob ymode_prob[VP9_YMODES - 1]; /* interframe intra mode probs */
   vp9_prob sb_ymode_prob[VP9_I32X32_MODES - 1];
   vp9_prob uv_mode_prob[VP9_YMODES][VP9_UV_MODES - 1];
+#if !CONFIG_SB8X8
   vp9_prob i8x8_mode_prob[VP9_I8X8_MODES - 1];
+#endif
   vp9_prob sub_mv_ref_prob[SUBMVREF_COUNT][VP9_SUBMVREFS - 1];
+#if !CONFIG_SB8X8
   vp9_prob mbsplit_prob[VP9_NUMMBSPLITS - 1];
+#endif
   vp9_prob partition_prob[NUM_PARTITION_CONTEXTS][PARTITION_TYPES - 1];
 
   vp9_coeff_probs coef_probs_4x4[BLOCK_TYPES];
@@ -87,17 +91,25 @@ typedef struct frame_contexts {
   vp9_prob pre_ymode_prob[VP9_YMODES - 1]; /* interframe intra mode probs */
   vp9_prob pre_sb_ymode_prob[VP9_I32X32_MODES - 1];
   vp9_prob pre_uv_mode_prob[VP9_YMODES][VP9_UV_MODES - 1];
+#if !CONFIG_SB8X8
   vp9_prob pre_i8x8_mode_prob[VP9_I8X8_MODES - 1];
+#endif
   vp9_prob pre_sub_mv_ref_prob[SUBMVREF_COUNT][VP9_SUBMVREFS - 1];
+#if !CONFIG_SB8X8
   vp9_prob pre_mbsplit_prob[VP9_NUMMBSPLITS - 1];
+#endif
   vp9_prob pre_partition_prob[NUM_PARTITION_CONTEXTS][PARTITION_TYPES - 1];
   unsigned int bmode_counts[VP9_NKF_BINTRAMODES];
   unsigned int ymode_counts[VP9_YMODES];   /* interframe intra mode probs */
   unsigned int sb_ymode_counts[VP9_I32X32_MODES];
   unsigned int uv_mode_counts[VP9_YMODES][VP9_UV_MODES];
+#if !CONFIG_SB8X8
   unsigned int i8x8_mode_counts[VP9_I8X8_MODES];   /* interframe intra probs */
+#endif
   unsigned int sub_mv_ref_counts[SUBMVREF_COUNT][VP9_SUBMVREFS];
+#if !CONFIG_SB8X8
   unsigned int mbsplit_counts[VP9_NUMMBSPLITS];
+#endif
   unsigned int partition_counts[NUM_PARTITION_CONTEXTS][PARTITION_TYPES];
 
   vp9_coeff_probs pre_coef_probs_4x4[BLOCK_TYPES];
index 6efe246..0420063 100644 (file)
@@ -265,19 +265,27 @@ static INLINE int round_mv_comp_q4(int value) {
   return (value < 0 ? value - 2 : value + 2) / 4;
 }
 
+#if CONFIG_SB8X8
+#define IDX1 2
+#define IDX2 3
+#else
+#define IDX1 4
+#define IDX2 5
+#endif
+
 static int mi_mv_pred_row_q4(MACROBLOCKD *mb, int off, int idx) {
   const int temp = mb->mode_info_context->bmi[off + 0].as_mv[idx].as_mv.row +
                    mb->mode_info_context->bmi[off + 1].as_mv[idx].as_mv.row +
-                   mb->mode_info_context->bmi[off + 4].as_mv[idx].as_mv.row +
-                   mb->mode_info_context->bmi[off + 5].as_mv[idx].as_mv.row;
+                   mb->mode_info_context->bmi[off + IDX1].as_mv[idx].as_mv.row +
+                   mb->mode_info_context->bmi[off + IDX2].as_mv[idx].as_mv.row;
   return round_mv_comp_q4(temp);
 }
 
 static int mi_mv_pred_col_q4(MACROBLOCKD *mb, int off, int idx) {
   const int temp = mb->mode_info_context->bmi[off + 0].as_mv[idx].as_mv.col +
                    mb->mode_info_context->bmi[off + 1].as_mv[idx].as_mv.col +
-                   mb->mode_info_context->bmi[off + 4].as_mv[idx].as_mv.col +
-                   mb->mode_info_context->bmi[off + 5].as_mv[idx].as_mv.col;
+                   mb->mode_info_context->bmi[off + IDX1].as_mv[idx].as_mv.col +
+                   mb->mode_info_context->bmi[off + IDX2].as_mv[idx].as_mv.col;
   return round_mv_comp_q4(temp);
 }
 
index c51d0b2..474250c 100644 (file)
@@ -65,9 +65,11 @@ static MB_PREDICTION_MODE read_kf_mb_ymode(vp9_reader *r, const vp9_prob *p) {
   return (MB_PREDICTION_MODE)treed_read(r, vp9_kf_ymode_tree, p);
 }
 
+#if !CONFIG_SB8X8
 static int read_i8x8_mode(vp9_reader *r, const vp9_prob *p) {
   return treed_read(r, vp9_i8x8_mode_tree, p);
 }
+#endif
 
 static MB_PREDICTION_MODE read_uv_mode(vp9_reader *r, const vp9_prob *p) {
   return (MB_PREDICTION_MODE)treed_read(r, vp9_uv_mode_tree, p);
@@ -161,6 +163,7 @@ static void kfread_modes(VP9D_COMP *pbi, MODE_INFO *m,
     }
   }
 
+#if !CONFIG_SB8X8
   if (m->mbmi.mode == I8X8_PRED) {
     int i;
     for (i = 0; i < 4; ++i) {
@@ -175,14 +178,25 @@ static void kfread_modes(VP9D_COMP *pbi, MODE_INFO *m,
   }
 
   // chroma mode
-  if (m->mbmi.mode != I8X8_PRED) {
+  if (m->mbmi.mode != I8X8_PRED)
+#endif
+  {
     m->mbmi.uv_mode = read_uv_mode(r, cm->kf_uv_mode_prob[m->mbmi.mode]);
   }
 
   if (cm->txfm_mode == TX_MODE_SELECT &&
       !m->mbmi.mb_skip_coeff &&
-      m->mbmi.mode <= I8X8_PRED) {
+#if CONFIG_SB8X8
+      m->mbmi.mode != I4X4_PRED
+#else
+      m->mbmi.mode <= I8X8_PRED
+#endif
+      ) {
+#if CONFIG_SB8X8
+    const int allow_16x16 = m->mbmi.sb_type >= BLOCK_SIZE_MB16X16;
+#else
     const int allow_16x16 = m->mbmi.mode != I8X8_PRED;
+#endif
     const int allow_32x32 = m->mbmi.sb_type >= BLOCK_SIZE_SB32X32;
     m->mbmi.txfm_size = select_txfm_size(cm, r, allow_16x16, allow_32x32);
   } else if (cm->txfm_mode >= ALLOW_32X32 &&
@@ -767,19 +781,29 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
     mbmi->uv_mode = DC_PRED;
     switch (mbmi->mode) {
       case SPLITMV: {
+#if CONFIG_SB8X8
+        const int num_p = 4;
+#else
         const int s = treed_read(r, vp9_mbsplit_tree, cm->fc.mbsplit_prob);
         const int num_p = vp9_mbsplit_count[s];
+#endif
         int j = 0;
 
+#if !CONFIG_SB8X8
         cm->fc.mbsplit_counts[s]++;
-        mbmi->need_to_clamp_mvs = 0;
         mbmi->partitioning = s;
+#endif
+        mbmi->need_to_clamp_mvs = 0;
         do {  // for each subset j
           int_mv leftmv, abovemv, second_leftmv, second_abovemv;
           int_mv blockmv, secondmv;
           int mv_contz;
           int blockmode;
+#if CONFIG_SB8X8
+          int k = j;
+#else
           int k = vp9_mbsplit_offset[s][j];  // first block in subset j
+#endif
 
           leftmv.as_int = left_block_mv(xd, mi, k);
           abovemv.as_int = above_block_mv(mi, k, mis);
@@ -851,6 +875,7 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
           }
           */
 
+#if !CONFIG_SB8X8
           {
             /* Fill (uniform) modes, mvs of jth subset.
              Must do it here because ensuing subsets can
@@ -866,12 +891,12 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
               fill_offset++;
             } while (--fill_count);
           }
-
+#endif
         } while (++j < num_p);
       }
 
-      mv0->as_int = mi->bmi[15].as_mv[0].as_int;
-      mv1->as_int = mi->bmi[15].as_mv[1].as_int;
+      mv0->as_int = mi->bmi[15 >> (2 * CONFIG_SB8X8)].as_mv[0].as_int;
+      mv1->as_int = mi->bmi[15 >> (2 * CONFIG_SB8X8)].as_mv[1].as_int;
 
       break;  /* done with SPLITMV */
 
@@ -957,6 +982,7 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
       } while (++j < 16);
     }
 
+#if !CONFIG_SB8X8
     if (mbmi->mode == I8X8_PRED) {
       int i;
       for (i = 0; i < 4; i++) {
@@ -969,7 +995,9 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
         mi->bmi[ib + 5].as_mode.first = mode8x8;
         cm->fc.i8x8_mode_counts[mode8x8]++;
       }
-    } else {
+    } else
+#endif
+    {
       mbmi->uv_mode = read_uv_mode(r, cm->fc.uv_mode_prob[mbmi->mode]);
       cm->fc.uv_mode_counts[mbmi->mode][mbmi->uv_mode]++;
     }
@@ -980,23 +1008,44 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
     */
 
   if (cm->txfm_mode == TX_MODE_SELECT && mbmi->mb_skip_coeff == 0 &&
-      ((mbmi->ref_frame == INTRA_FRAME && mbmi->mode <= I8X8_PRED) ||
-       (mbmi->ref_frame != INTRA_FRAME && !(mbmi->mode == SPLITMV &&
-                           mbmi->partitioning == PARTITIONING_4X4)))) {
+      ((mbmi->ref_frame == INTRA_FRAME &&
+#if CONFIG_SB8X8
+        mbmi->mode != I4X4_PRED
+#else
+        mbmi->mode <= I8X8_PRED
+#endif
+        ) ||
+       (mbmi->ref_frame != INTRA_FRAME &&
+#if CONFIG_SB8X8
+        mbmi->mode != SPLITMV
+#else
+        !(mbmi->mode == SPLITMV && mbmi->partitioning == PARTITIONING_4X4)
+#endif
+        ))) {
+#if CONFIG_SB8X8
+    const int allow_16x16 = mbmi->sb_type >= BLOCK_SIZE_MB16X16;
+#else
     const int allow_16x16 = mbmi->mode != I8X8_PRED && mbmi->mode != SPLITMV;
+#endif
     const int allow_32x32 = mbmi->sb_type >= BLOCK_SIZE_SB32X32;
     mbmi->txfm_size = select_txfm_size(cm, r, allow_16x16, allow_32x32);
   } else if (mbmi->sb_type >= BLOCK_SIZE_SB32X32 &&
              cm->txfm_mode >= ALLOW_32X32) {
     mbmi->txfm_size = TX_32X32;
   } else if (cm->txfm_mode >= ALLOW_16X16 &&
+#if CONFIG_SB8X8
+             mbmi->sb_type >= BLOCK_SIZE_MB16X16 &&
+#endif
       ((mbmi->ref_frame == INTRA_FRAME && mbmi->mode <= TM_PRED) ||
        (mbmi->ref_frame != INTRA_FRAME && mbmi->mode != SPLITMV))) {
     mbmi->txfm_size = TX_16X16;
   } else if (cm->txfm_mode >= ALLOW_8X8 &&
       (!(mbmi->ref_frame == INTRA_FRAME && mbmi->mode == I4X4_PRED) &&
-       !(mbmi->ref_frame != INTRA_FRAME && mbmi->mode == SPLITMV &&
-         mbmi->partitioning == PARTITIONING_4X4))) {
+       !(mbmi->ref_frame != INTRA_FRAME && mbmi->mode == SPLITMV
+#if !CONFIG_SB8X8
+         && mbmi->partitioning == PARTITIONING_4X4
+#endif
+         ))) {
     mbmi->txfm_size = TX_8X8;
   } else {
     mbmi->txfm_size = TX_4X4;
index 023bfcb..12f8948 100644 (file)
@@ -203,6 +203,7 @@ static void mb_init_dequantizer(VP9_COMMON *pc, MACROBLOCKD *xd) {
     xd->plane[i].dequant = pc->uv_dequant[xd->q_index];
 }
 
+#if !CONFIG_SB8X8
 static void decode_16x16(MACROBLOCKD *xd) {
   const TX_TYPE tx_type = get_tx_type_16x16(xd, 0);
 
@@ -283,6 +284,7 @@ static void decode_8x8(MACROBLOCKD *xd) {
                      xd->plane[1].dst.stride, xd->plane[2].eobs[0]);
   }
 }
+#endif
 
 static INLINE void dequant_add_y(MACROBLOCKD *xd, TX_TYPE tx_type, int idx) {
   struct macroblockd_plane *const y = &xd->plane[0];
@@ -298,6 +300,7 @@ static INLINE void dequant_add_y(MACROBLOCKD *xd, TX_TYPE tx_type, int idx) {
   }
 }
 
+#if !CONFIG_SB8X8
 static void decode_4x4(VP9D_COMP *pbi, MACROBLOCKD *xd, vp9_reader *r) {
   TX_TYPE tx_type;
   int i = 0;
@@ -353,6 +356,7 @@ static void decode_4x4(VP9D_COMP *pbi, MACROBLOCKD *xd, vp9_reader *r) {
                           xd->plane[1].dst.stride, xd->plane[2].eobs);
   }
 }
+#endif
 
 static int txfrm_block_to_raster_block(MACROBLOCKD *xd,
                                        BLOCK_SIZE_TYPE bsize,
@@ -520,6 +524,7 @@ static void decode_sb(VP9D_COMP *pbi, MACROBLOCKD *xd, int mi_row, int mi_col,
   }
 }
 
+#if !CONFIG_SB8X8
 // TODO(jingning): Need to merge SB and MB decoding. The MB decoding currently
 // couples special handles on I8x8, B_PRED, and splitmv modes.
 static void decode_mb(VP9D_COMP *pbi, MACROBLOCKD *xd,
@@ -622,6 +627,7 @@ static void decode_mb(VP9D_COMP *pbi, MACROBLOCKD *xd,
   }
 #endif
 }
+#endif
 
 static int get_delta_q(vp9_reader *r, int *dq) {
   const int old_value = *dq;
@@ -708,6 +714,9 @@ static void decode_modes_b(VP9D_COMP *pbi, int mi_row, int mi_col,
   vp9_decode_mb_mode_mv(pbi, xd, mi_row, mi_col, r);
   set_refs(pbi, mi_row, mi_col);
 
+#if CONFIG_SB8X8
+  decode_sb(pbi, xd, mi_row, mi_col, r, bsize);
+#else
   // TODO(jingning): merge decode_sb_ and decode_mb_
   if (bsize > BLOCK_SIZE_MB16X16) {
     decode_sb(pbi, xd, mi_row, mi_col, r, bsize);
@@ -724,6 +733,7 @@ static void decode_modes_b(VP9D_COMP *pbi, int mi_row, int mi_col,
       // and SPLITMV of 8x8, 16x8, and 8x16. To be migrated into decode_sb.
       decode_mb(pbi, xd, mi_row, mi_col, r);
   }
+#endif
 
   xd->corrupted |= vp9_reader_has_error(r);
 }
@@ -1142,9 +1152,13 @@ static void update_frame_context(FRAME_CONTEXT *fc) {
   vp9_copy(fc->pre_sb_ymode_prob, fc->sb_ymode_prob);
   vp9_copy(fc->pre_uv_mode_prob, fc->uv_mode_prob);
   vp9_copy(fc->pre_bmode_prob, fc->bmode_prob);
+#if !CONFIG_SB8X8
   vp9_copy(fc->pre_i8x8_mode_prob, fc->i8x8_mode_prob);
+#endif
   vp9_copy(fc->pre_sub_mv_ref_prob, fc->sub_mv_ref_prob);
+#if !CONFIG_SB8X8
   vp9_copy(fc->pre_mbsplit_prob, fc->mbsplit_prob);
+#endif
   vp9_copy(fc->pre_partition_prob, fc->partition_prob);
   fc->pre_nmvc = fc->nmvc;
 
@@ -1157,9 +1171,13 @@ static void update_frame_context(FRAME_CONTEXT *fc) {
   vp9_zero(fc->sb_ymode_counts);
   vp9_zero(fc->uv_mode_counts);
   vp9_zero(fc->bmode_counts);
+#if !CONFIG_SB8X8
   vp9_zero(fc->i8x8_mode_counts);
+#endif
   vp9_zero(fc->sub_mv_ref_counts);
+#if !CONFIG_SB8X8
   vp9_zero(fc->mbsplit_counts);
+#endif
   vp9_zero(fc->NMVcount);
   vp9_zero(fc->mv_ref_ct);
   vp9_zero(fc->partition_counts);
index 3ab67cd..c06a034 100644 (file)
@@ -281,9 +281,11 @@ static void sb_kfwrite_ymode(vp9_writer *bc, int m, const vp9_prob *p) {
   write_token(bc, vp9_uv_mode_tree, p, vp9_sb_kf_ymode_encodings + m);
 }
 
+#if !CONFIG_SB8X8
 static void write_i8x8_mode(vp9_writer *bc, int m, const vp9_prob *p) {
   write_token(bc, vp9_i8x8_mode_tree, p, vp9_i8x8_mode_encodings + m);
 }
+#endif
 
 static void write_uv_mode(vp9_writer *bc, int m, const vp9_prob *p) {
   write_token(bc, vp9_uv_mode_tree, p, vp9_uv_mode_encodings + m);
@@ -302,9 +304,11 @@ static void write_kf_bmode(vp9_writer *bc, int m, const vp9_prob *p) {
   write_token(bc, vp9_kf_bmode_tree, p, vp9_kf_bmode_encodings + m);
 }
 
+#if !CONFIG_SB8X8
 static void write_split(vp9_writer *bc, int x, const vp9_prob *p) {
   write_token(bc, vp9_mbsplit_tree, p, vp9_mbsplit_encodings + x);
 }
+#endif
 
 static int prob_update_savings(const unsigned int *ct,
                                const vp9_prob oldp, const vp9_prob newp,
@@ -728,8 +732,9 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m,
       do {
         write_bmode(bc, m->bmi[j].as_mode.first,
                     pc->fc.bmode_prob);
-      } while (++j < 16);
+      } while (++j < (16 >> (CONFIG_SB8X8 * 2)));
     }
+#if !CONFIG_SB8X8
     if (mode == I8X8_PRED) {
       write_i8x8_mode(bc, m->bmi[0].as_mode.first,
                       pc->fc.i8x8_mode_prob);
@@ -739,7 +744,9 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m,
                       pc->fc.i8x8_mode_prob);
       write_i8x8_mode(bc, m->bmi[10].as_mode.first,
                       pc->fc.i8x8_mode_prob);
-    } else {
+    } else
+#endif
+    {
       write_uv_mode(bc, mi->uv_mode,
                     pc->fc.uv_mode_prob[mode]);
     }
@@ -824,19 +831,26 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m,
         ++count_mb_seg[mi->partitioning];
 #endif
 
+#if !CONFIG_SB8X8
         write_split(bc, mi->partitioning, cpi->common.fc.mbsplit_prob);
         cpi->mbsplit_count[mi->partitioning]++;
+#endif
 
         do {
           B_PREDICTION_MODE blockmode;
           int_mv blockmv;
+#if !CONFIG_SB8X8
           const int *const  L = vp9_mbsplits[mi->partitioning];
+#endif
           int k = -1;  /* first block in subset j */
           int mv_contz;
           int_mv leftmv, abovemv;
 
           blockmode = cpi->mb.partition_info->bmi[j].mode;
           blockmv = cpi->mb.partition_info->bmi[j].mv;
+#if CONFIG_SB8X8
+          k = j;
+#else
 #if CONFIG_DEBUG
           while (j != L[++k])
             if (k >= 16)
@@ -844,6 +858,7 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m,
 #else
           while (j != L[++k]);
 #endif
+#endif
           leftmv.as_int = left_block_mv(xd, m, k);
           abovemv.as_int = above_block_mv(m, k, mis);
           mv_contz = vp9_mv_cont(&leftmv, &abovemv);
@@ -875,6 +890,22 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m,
     }
   }
 
+#if CONFIG_SB8X8
+  if (((rf == INTRA_FRAME && mode != I4X4_PRED) ||
+       (rf != INTRA_FRAME && mode != SPLITMV)) &&
+      pc->txfm_mode == TX_MODE_SELECT &&
+      !(skip_coeff || vp9_segfeature_active(xd, segment_id,
+                                            SEG_LVL_SKIP))) {
+    TX_SIZE sz = mi->txfm_size;
+    // FIXME(rbultje) code ternary symbol once all experiments are merged
+    vp9_write(bc, sz != TX_4X4, pc->prob_tx[0]);
+    if (mi->sb_type >= BLOCK_SIZE_MB16X16 && sz != TX_4X4) {
+      vp9_write(bc, sz != TX_8X8, pc->prob_tx[1]);
+      if (mi->sb_type >= BLOCK_SIZE_SB32X32 && sz != TX_8X8)
+        vp9_write(bc, sz != TX_16X16, pc->prob_tx[2]);
+    }
+  }
+#else
   if (((rf == INTRA_FRAME && mode <= I8X8_PRED) ||
        (rf != INTRA_FRAME && !(mode == SPLITMV &&
                                mi->partitioning == PARTITIONING_4X4))) &&
@@ -890,6 +921,7 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m,
         vp9_write(bc, sz != TX_16X16, pc->prob_tx[2]);
     }
   }
+#endif
 }
 
 static void write_mb_modes_kf(const VP9_COMP *cpi,
@@ -930,8 +962,9 @@ static void write_mb_modes_kf(const VP9_COMP *cpi,
 #endif
 
       write_kf_bmode(bc, bm, c->kf_bmode_prob[a][l]);
-    } while (++i < 16);
+    } while (++i < (16 >> (CONFIG_SB8X8 * 2)));
   }
+#if !CONFIG_SB8X8
   if (ym == I8X8_PRED) {
     write_i8x8_mode(bc, m->bmi[0].as_mode.first, c->fc.i8x8_mode_prob);
     // printf("    mode: %d\n", m->bmi[0].as_mode.first); fflush(stdout);
@@ -942,8 +975,22 @@ static void write_mb_modes_kf(const VP9_COMP *cpi,
     write_i8x8_mode(bc, m->bmi[10].as_mode.first, c->fc.i8x8_mode_prob);
     // printf("    mode: %d\n", m->bmi[10].as_mode.first); fflush(stdout);
   } else
+#endif
     write_uv_mode(bc, m->mbmi.uv_mode, c->kf_uv_mode_prob[ym]);
 
+#if CONFIG_SB8X8
+  if (ym != I4X4_PRED && c->txfm_mode == TX_MODE_SELECT &&
+      !(skip_coeff || vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP))) {
+    TX_SIZE sz = m->mbmi.txfm_size;
+    // FIXME(rbultje) code ternary symbol once all experiments are merged
+    vp9_write(bc, sz != TX_4X4, c->prob_tx[0]);
+    if (m->mbmi.sb_type >= BLOCK_SIZE_MB16X16 && sz != TX_4X4) {
+      vp9_write(bc, sz != TX_8X8, c->prob_tx[1]);
+      if (m->mbmi.sb_type >= BLOCK_SIZE_SB32X32 && sz != TX_8X8)
+        vp9_write(bc, sz != TX_16X16, c->prob_tx[2]);
+    }
+  }
+#else
   if (ym <= I8X8_PRED && c->txfm_mode == TX_MODE_SELECT &&
       !(skip_coeff || vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP))) {
     TX_SIZE sz = m->mbmi.txfm_size;
@@ -955,6 +1002,7 @@ static void write_mb_modes_kf(const VP9_COMP *cpi,
         vp9_write(bc, sz != TX_16X16, c->prob_tx[2]);
     }
   }
+#endif
 }
 
 
@@ -2153,15 +2201,19 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest,
   vp9_copy(cpi->common.fc.pre_uv_mode_prob, cpi->common.fc.uv_mode_prob);
   vp9_copy(cpi->common.fc.pre_bmode_prob, cpi->common.fc.bmode_prob);
   vp9_copy(cpi->common.fc.pre_sub_mv_ref_prob, cpi->common.fc.sub_mv_ref_prob);
+#if !CONFIG_SB8X8
   vp9_copy(cpi->common.fc.pre_mbsplit_prob, cpi->common.fc.mbsplit_prob);
   vp9_copy(cpi->common.fc.pre_i8x8_mode_prob, cpi->common.fc.i8x8_mode_prob);
+#endif
   vp9_copy(cpi->common.fc.pre_partition_prob, cpi->common.fc.partition_prob);
   cpi->common.fc.pre_nmvc = cpi->common.fc.nmvc;
 #if CONFIG_COMP_INTERINTRA_PRED
   cpi->common.fc.pre_interintra_prob = cpi->common.fc.interintra_prob;
 #endif
   vp9_zero(cpi->sub_mv_ref_count);
+#if !CONFIG_SB8X8
   vp9_zero(cpi->mbsplit_count);
+#endif
   vp9_zero(cpi->common.fc.mv_ref_ct);
 
   update_coef_probs(cpi, &header_bc);
index 2c06457..40ad680 100644 (file)
@@ -117,7 +117,9 @@ struct macroblock {
   int mbmode_cost[2][MB_MODE_COUNT];
   int intra_uv_mode_cost[2][MB_MODE_COUNT];
   int bmode_costs[VP9_KF_BINTRAMODES][VP9_KF_BINTRAMODES][VP9_KF_BINTRAMODES];
+#if !CONFIG_SB8X8
   int i8x8_mode_costs[MB_MODE_COUNT];
+#endif
   int inter_bmode_costs[B_MODE_COUNT];
   int switchable_interp_costs[VP9_SWITCHABLE_FILTERS + 1]
                              [VP9_SWITCHABLE_FILTERS];
@@ -141,6 +143,11 @@ struct macroblock {
 
   // Structure to hold context for each of the 4 MBs within a SB:
   // when encoded as 4 independent MBs:
+#if CONFIG_SB8X8
+  PICK_MODE_CONTEXT sb8_context[4][4][4];
+  PICK_MODE_CONTEXT sb8x16_context[4][4][2];
+  PICK_MODE_CONTEXT sb16x8_context[4][4][2];
+#endif
   PICK_MODE_CONTEXT mb_context[4][4];
   PICK_MODE_CONTEXT sb32x16_context[4][2];
   PICK_MODE_CONTEXT sb16x32_context[4][2];
index 52065df..8fc1448 100644 (file)
@@ -47,8 +47,10 @@ int enc_debug = 0;
 
 void vp9_select_interp_filter_type(VP9_COMP *cpi);
 
+#if !CONFIG_SB8X8
 static void encode_macroblock(VP9_COMP *cpi, TOKENEXTRA **t,
                               int output_enabled, int mi_row, int mi_col);
+#endif
 
 static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t,
                               int output_enabled, int mi_row, int mi_col,
@@ -380,6 +382,8 @@ static void update_state(VP9_COMP *cpi,
     }
   }
   if (bsize < BLOCK_SIZE_SB32X32) {
+    if (bsize < BLOCK_SIZE_MB16X16)
+      ctx->txfm_rd_diff[ALLOW_16X16] = ctx->txfm_rd_diff[ALLOW_8X8];
     ctx->txfm_rd_diff[ALLOW_32X32] = ctx->txfm_rd_diff[ALLOW_16X16];
   }
 
@@ -387,8 +391,10 @@ static void update_state(VP9_COMP *cpi,
     vpx_memcpy(x->partition_info, &ctx->partition_info,
                sizeof(PARTITION_INFO));
 
-    mbmi->mv[0].as_int = x->partition_info->bmi[15].mv.as_int;
-    mbmi->mv[1].as_int = x->partition_info->bmi[15].second_mv.as_int;
+    mbmi->mv[0].as_int =
+        x->partition_info->bmi[15 >> (CONFIG_SB8X8 * 2)].mv.as_int;
+    mbmi->mv[1].as_int =
+        x->partition_info->bmi[15 >> (CONFIG_SB8X8 * 2)].second_mv.as_int;
 #if CONFIG_SB8X8
     vpx_memcpy(x->partition_info + mis, &ctx->partition_info,
                sizeof(PARTITION_INFO));
@@ -453,7 +459,9 @@ static void update_state(VP9_COMP *cpi,
       THR_D27_PRED /*D27_PRED*/,
       THR_D63_PRED /*D63_PRED*/,
       THR_TM /*TM_PRED*/,
+#if !CONFIG_SB8X8
       THR_I8X8_PRED /*I8X8_PRED*/,
+#endif
       THR_B_PRED /*I4X4_PRED*/,
     };
     cpi->mode_chosen_counts[kf_mode_index[mb_mode]]++;
@@ -667,6 +675,7 @@ static void set_offsets(VP9_COMP *cpi,
   }
 }
 
+#if !CONFIG_SB8X8
 static int pick_mb_mode(VP9_COMP *cpi,
                         int mi_row,
                         int mi_col,
@@ -707,6 +716,7 @@ static int pick_mb_mode(VP9_COMP *cpi,
 
   return splitmodes_used;
 }
+#endif
 
 static void pick_sb_modes(VP9_COMP *cpi, int mi_row, int mi_col,
                           TOKENEXTRA **tp, int *totalrate, int *totaldist,
@@ -790,11 +800,15 @@ static void set_block_index(MACROBLOCKD *xd, int idx,
                             BLOCK_SIZE_TYPE bsize) {
   if (bsize >= BLOCK_SIZE_SB32X32) {
     xd->sb_index = idx;
-  } else {
 #if CONFIG_SB8X8
-    assert(bsize >= BLOCK_SIZE_MB16X16);
-#endif
+  } else if (bsize >= BLOCK_SIZE_MB16X16) {
     xd->mb_index = idx;
+  } else {
+    xd->b_index = idx;
+#else
+  } else {
+    xd->mb_index = idx;
+#endif
   }
 }
 
@@ -817,6 +831,14 @@ static PICK_MODE_CONTEXT *get_block_context(MACROBLOCK *x,
       return &x->sb16x32_context[xd->sb_index][xd->mb_index];
     case BLOCK_SIZE_MB16X16:
       return &x->mb_context[xd->sb_index][xd->mb_index];
+#if CONFIG_SB8X8
+    case BLOCK_SIZE_SB16X8:
+      return &x->sb16x8_context[xd->sb_index][xd->mb_index][xd->b_index];
+    case BLOCK_SIZE_SB8X16:
+      return &x->sb8x16_context[xd->sb_index][xd->mb_index][xd->b_index];
+    case BLOCK_SIZE_SB8X8:
+      return &x->sb8_context[xd->sb_index][xd->mb_index][xd->b_index];
+#endif
     default:
       assert(0);
       return NULL;
@@ -837,12 +859,15 @@ static void encode_b(VP9_COMP *cpi, TOKENEXTRA **tp,
     set_block_index(xd, sub_index, bsize);
   set_offsets(cpi, mi_row, mi_col, bsize);
   update_state(cpi, get_block_context(x, bsize), bsize, output_enabled);
+#if !CONFIG_SB8X8
   if (bsize == BLOCK_SIZE_MB16X16) {
     if (cpi->oxcf.tuning == VP8_TUNE_SSIM)
       vp9_activity_masking(cpi, x);
 
     encode_macroblock(cpi, tp, output_enabled, mi_row, mi_col);
-  } else {
+  } else
+#endif
+  {
     encode_superblock(cpi, tp, output_enabled, mi_row, mi_col, bsize);
   }
 
@@ -857,22 +882,38 @@ static void encode_b(VP9_COMP *cpi, TOKENEXTRA **tp,
 static void encode_sb(VP9_COMP *cpi, TOKENEXTRA **tp,
                       int mi_row, int mi_col, int output_enabled,
                       BLOCK_SIZE_TYPE level,
-                      BLOCK_SIZE_TYPE c1, BLOCK_SIZE_TYPE c2[4]) {
+                      BLOCK_SIZE_TYPE c1, BLOCK_SIZE_TYPE c2[4]
+#if CONFIG_SB8X8
+                      , BLOCK_SIZE_TYPE c3[4][4]
+#endif
+                      ) {
   VP9_COMMON *const cm = &cpi->common;
   MACROBLOCK *const x = &cpi->mb;
   MACROBLOCKD *const xd = &x->e_mbd;
   const int bsl = mi_width_log2(level), bs = 1 << (bsl - 1);
   const int bwl = mi_width_log2(c1), bhl = mi_height_log2(c1);
-  int pl;
+  int UNINITIALIZED_IS_SAFE(pl);
 
   if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
     return;
 
-  set_partition_seg_context(cpi, mi_row, mi_col);
-  pl = partition_plane_context(xd, level);
+#if CONFIG_SB8X8
+  if (level > BLOCK_SIZE_SB8X8) {
+#endif
+    set_partition_seg_context(cpi, mi_row, mi_col);
+    pl = partition_plane_context(xd, level);
+#if CONFIG_SB8X8
+  }
+#endif
 
   if (bsl == bwl && bsl == bhl) {
-    if (output_enabled && level > BLOCK_SIZE_MB16X16)
+    if (output_enabled &&
+#if CONFIG_SB8X8
+        level > BLOCK_SIZE_SB8X8
+#else
+        level > BLOCK_SIZE_MB16X16
+#endif
+        )
       cpi->partition_count[pl][PARTITION_NONE]++;
     encode_b(cpi, tp, mi_row, mi_col, output_enabled, c1, -1);
   } else if (bsl == bhl && bsl > bwl) {
@@ -892,9 +933,17 @@ static void encode_sb(VP9_COMP *cpi, TOKENEXTRA **tp,
     assert(bwl < bsl && bhl < bsl);
     if (level == BLOCK_SIZE_SB64X64) {
       subsize = BLOCK_SIZE_SB32X32;
+#if CONFIG_SB8X8
+    } else if (level == BLOCK_SIZE_SB32X32) {
+      subsize = BLOCK_SIZE_MB16X16;
+    } else {
+      assert(level == BLOCK_SIZE_MB16X16);
+      subsize = BLOCK_SIZE_SB8X8;
+#else
     } else {
       assert(level == BLOCK_SIZE_SB32X32);
       subsize = BLOCK_SIZE_MB16X16;
+#endif
     }
 
     if (output_enabled)
@@ -906,12 +955,22 @@ static void encode_sb(VP9_COMP *cpi, TOKENEXTRA **tp,
       set_block_index(xd, i, subsize);
       encode_sb(cpi, tp, mi_row + y_idx * bs, mi_col + x_idx * bs,
                 output_enabled, subsize,
-                subsize == BLOCK_SIZE_MB16X16 ? c1 : c2[i], c2);
+#if CONFIG_SB8X8
+                c2 ? c2[i] : c1, c3 ? c3[i] : NULL, NULL);
+#else
+                c2 ? c2[i] : c1, NULL);
+#endif
     }
   }
 
+#if CONFIG_SB8X8
+  if (level > BLOCK_SIZE_SB8X8 &&
+      (level == BLOCK_SIZE_MB16X16 || bsl == bwl || bsl == bhl))
+#else
   if (level > BLOCK_SIZE_MB16X16 &&
-      (level == BLOCK_SIZE_SB32X32 || bsl == bwl || bsl == bhl)) {
+      (level == BLOCK_SIZE_SB32X32 || bsl == bwl || bsl == bhl))
+#endif
+  {
     set_partition_seg_context(cpi, mi_row, mi_col);
     update_partition_context(xd, c1, level);
   }
@@ -934,7 +993,11 @@ static void encode_sb_row(VP9_COMP *cpi,
   for (mi_col = cm->cur_tile_mi_col_start;
        mi_col < cm->cur_tile_mi_col_end; mi_col += (4 << CONFIG_SB8X8)) {
     int i, p;
+#if CONFIG_SB8X8
+    BLOCK_SIZE_TYPE mb_partitioning[4][4];
+#endif
     BLOCK_SIZE_TYPE sb_partitioning[4];
+    BLOCK_SIZE_TYPE sb64_partitioning = BLOCK_SIZE_SB32X32;
     int sb64_rate = 0, sb64_dist = 0;
     int sb64_skip = 0;
     ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE];
@@ -951,6 +1014,9 @@ static void encode_sb_row(VP9_COMP *cpi,
     memcpy(&seg_a, cm->above_seg_context + (mi_col >> CONFIG_SB8X8),
            sizeof(seg_a));
     memcpy(&seg_l, cm->left_seg_context, sizeof(seg_l));
+
+    // FIXME(rbultje): this function should probably be rewritten to be
+    // recursive at some point in the future.
     for (i = 0; i < 4; i++) {
       const int x_idx = (i & 1) << (1 + CONFIG_SB8X8);
       const int y_idx = (i & 2) << CONFIG_SB8X8;
@@ -985,6 +1051,10 @@ static void encode_sb_row(VP9_COMP *cpi,
         const int x_idx_m = x_idx + ((j & 1) << CONFIG_SB8X8);
         const int y_idx_m = y_idx + ((j >> 1) << CONFIG_SB8X8);
         int r, d;
+#if CONFIG_SB8X8
+        int r2, d2, mb16_rate = 0, mb16_dist = 0, k;
+        ENTROPY_CONTEXT l3[4 * MAX_MB_PLANE], a3[4 * MAX_MB_PLANE];
+#endif
 
         if (mi_row + y_idx_m >= cm->mi_rows ||
             mi_col + x_idx_m >= cm->mi_cols) {
@@ -995,18 +1065,175 @@ static void encode_sb_row(VP9_COMP *cpi,
         // Index of the MB in the SB 0..3
         xd->mb_index = j;
 
+#if CONFIG_SB8X8
+        for (p = 0; p < MAX_MB_PLANE; p++) {
+          vpx_memcpy(l3 + 4 * p,
+                     cm->left_context[p] +
+                         (y_idx_m * 4 >> (CONFIG_SB8X8 +
+                                          xd->plane[p].subsampling_y)),
+                     sizeof(ENTROPY_CONTEXT) * 4 >> xd->plane[p].subsampling_y);
+          vpx_memcpy(a3 + 4 * p,
+                     cm->above_context[p] +
+                         ((mi_col + x_idx_m) * 4 >> (CONFIG_SB8X8 +
+                                                   xd->plane[p].subsampling_x)),
+                     sizeof(ENTROPY_CONTEXT) * 4 >> xd->plane[p].subsampling_x);
+        }
+
+        mb_partitioning[i][j] = BLOCK_SIZE_SB8X8;
+        for (k = 0; k < 4; k++) {
+          xd->b_index = k;
+
+          // try 8x8 coding
+          pick_sb_modes(cpi, mi_row + y_idx_m + (k & 1),
+                        mi_col + x_idx_m + (k >> 1),
+                        tp, &r, &d, BLOCK_SIZE_SB8X8,
+                        &x->sb8_context[xd->sb_index][xd->mb_index]
+                                       [xd->b_index]);
+          mb16_rate += r;
+          mb16_dist += d;
+          update_state(cpi, &x->sb8_context[xd->sb_index][xd->mb_index]
+                                           [xd->b_index],
+                       BLOCK_SIZE_SB8X8, 0);
+          encode_superblock(cpi, tp,
+                            0, mi_row + y_idx_m, mi_col + x_idx_m,
+                            BLOCK_SIZE_SB8X8);
+        }
+        set_partition_seg_context(cpi, mi_row + y_idx_m, mi_col + x_idx_m);
+        pl = partition_plane_context(xd, BLOCK_SIZE_MB16X16);
+        mb16_rate += x->partition_cost[pl][PARTITION_SPLIT];
+        for (p = 0; p < MAX_MB_PLANE; p++) {
+          vpx_memcpy(cm->left_context[p] +
+                         (y_idx_m * 4 >> (CONFIG_SB8X8 +
+                                          xd->plane[p].subsampling_y)),
+                     l3 + 4 * p,
+                     sizeof(ENTROPY_CONTEXT) * 4 >> xd->plane[p].subsampling_y);
+          vpx_memcpy(cm->above_context[p] +
+                         ((mi_col + x_idx_m) * 4 >> (CONFIG_SB8X8 +
+                                                   xd->plane[p].subsampling_x)),
+                     a3 + 4 * p,
+                     sizeof(ENTROPY_CONTEXT) * 4 >> xd->plane[p].subsampling_x);
+        }
+
+        // try 8x16 coding
+        r2 = 0;
+        d2 = 0;
+        xd->b_index = 0;
+        pick_sb_modes(cpi, mi_row + y_idx_m, mi_col + x_idx_m,
+                      tp, &r, &d, BLOCK_SIZE_SB8X16,
+                      &x->sb8x16_context[xd->sb_index][xd->mb_index]
+                                        [xd->b_index]);
+        r2 += r;
+        d2 += d;
+        update_state(cpi, &x->sb8x16_context[xd->sb_index][xd->mb_index]
+                                            [xd->b_index],
+                     BLOCK_SIZE_SB8X16, 0);
+        encode_superblock(cpi, tp,
+                          0, mi_row + y_idx_m, mi_col + x_idx_m,
+                          BLOCK_SIZE_SB8X16);
+        xd->b_index = 1;
+        pick_sb_modes(cpi, mi_row + y_idx_m, mi_col + x_idx_m + 1,
+                      tp, &r, &d, BLOCK_SIZE_SB8X16,
+                      &x->sb8x16_context[xd->sb_index][xd->mb_index]
+                                        [xd->b_index]);
+        r2 += r;
+        d2 += d;
+        set_partition_seg_context(cpi, mi_row + y_idx_m, mi_col + x_idx_m);
+        pl = partition_plane_context(xd, BLOCK_SIZE_MB16X16);
+        r2 += x->partition_cost[pl][PARTITION_VERT];
+        if (RDCOST(x->rdmult, x->rddiv, r2, d2) <
+                RDCOST(x->rdmult, x->rddiv, mb16_rate, mb16_dist)) {
+          mb16_rate = r;
+          mb16_dist = d;
+          mb_partitioning[i][j] = BLOCK_SIZE_SB8X16;
+        }
+        for (p = 0; p < MAX_MB_PLANE; p++) {
+          vpx_memcpy(cm->left_context[p] +
+                         (y_idx_m * 4 >> (CONFIG_SB8X8 +
+                                          xd->plane[p].subsampling_y)),
+                     l3 + 4 * p,
+                     sizeof(ENTROPY_CONTEXT) * 4 >> xd->plane[p].subsampling_y);
+          vpx_memcpy(cm->above_context[p] +
+                         ((mi_col + x_idx_m) * 4 >> (CONFIG_SB8X8 +
+                                                   xd->plane[p].subsampling_x)),
+                     a3 + 4 * p,
+                     sizeof(ENTROPY_CONTEXT) * 4 >> xd->plane[p].subsampling_x);
+        }
+
+        // try 16x8 coding
+        r2 = 0;
+        d2 = 0;
+        xd->b_index = 0;
+        pick_sb_modes(cpi, mi_row + y_idx_m, mi_col + x_idx_m,
+                      tp, &r, &d, BLOCK_SIZE_SB16X8,
+                      &x->sb16x8_context[xd->sb_index][xd->mb_index]
+                                        [xd->b_index]);
+        r2 += r;
+        d2 += d;
+        update_state(cpi, &x->sb16x8_context[xd->sb_index][xd->mb_index]
+                                            [xd->b_index],
+                     BLOCK_SIZE_SB16X8, 0);
+        encode_superblock(cpi, tp,
+                          0, mi_row + y_idx_m, mi_col + x_idx_m,
+                          BLOCK_SIZE_SB16X8);
+        xd->b_index = 1;
+        pick_sb_modes(cpi, mi_row + y_idx_m + 1, mi_col + x_idx_m,
+                      tp, &r, &d, BLOCK_SIZE_SB16X8,
+                      &x->sb16x8_context[xd->sb_index][xd->mb_index]
+                                        [xd->b_index]);
+        r2 += r;
+        d2 += d;
+        set_partition_seg_context(cpi, mi_row + y_idx_m, mi_col + x_idx_m);
+        pl = partition_plane_context(xd, BLOCK_SIZE_MB16X16);
+        r2 += x->partition_cost[pl][PARTITION_HORZ];
+        if (RDCOST(x->rdmult, x->rddiv, r2, d2) <
+                RDCOST(x->rdmult, x->rddiv, mb16_rate, mb16_dist)) {
+          mb16_rate = r;
+          mb16_dist = d;
+          mb_partitioning[i][j] = BLOCK_SIZE_SB16X8;
+        }
+        for (p = 0; p < MAX_MB_PLANE; p++) {
+          vpx_memcpy(cm->left_context[p] +
+                         (y_idx_m * 4 >> (CONFIG_SB8X8 +
+                                          xd->plane[p].subsampling_y)),
+                     l3 + 4 * p,
+                     sizeof(ENTROPY_CONTEXT) * 4 >> xd->plane[p].subsampling_y);
+          vpx_memcpy(cm->above_context[p] +
+                         ((mi_col + x_idx_m) * 4 >> (CONFIG_SB8X8 +
+                                                   xd->plane[p].subsampling_x)),
+                     a3 + 4 * p,
+                     sizeof(ENTROPY_CONTEXT) * 4 >> xd->plane[p].subsampling_x);
+        }
+
+        // try as 16x16
+        pick_sb_modes(cpi, mi_row + y_idx_m, mi_col + x_idx_m,
+                      tp, &r, &d, BLOCK_SIZE_MB16X16,
+                      &x->mb_context[xd->sb_index][xd->mb_index]);
+        set_partition_seg_context(cpi, mi_row + y_idx_m, mi_col + x_idx_m);
+        pl = partition_plane_context(xd, BLOCK_SIZE_MB16X16);
+        r += x->partition_cost[pl][PARTITION_NONE];
+        if (RDCOST(x->rdmult, x->rddiv, r, d) <
+                RDCOST(x->rdmult, x->rddiv, mb16_rate, mb16_dist)) {
+          mb16_rate = r;
+          mb16_dist = d;
+          mb_partitioning[i][j] = BLOCK_SIZE_MB16X16;
+        }
+        sb32_rate += mb16_rate;
+        sb32_dist += mb16_dist;
+#else
         splitmodes_used += pick_mb_mode(cpi, mi_row + y_idx_m,
                                         mi_col + x_idx_m, tp, &r, &d);
         sb32_rate += r;
         sb32_dist += d;
+#endif
 
         // Dummy encode, do not do the tokenization
 #if CONFIG_SB8X8
-        update_state(cpi, &x->mb_context[xd->sb_index][xd->mb_index],
-                     BLOCK_SIZE_MB16X16, 0);
-#endif
+        encode_sb(cpi, tp, mi_row + y_idx, mi_col + x_idx, 0,
+                  BLOCK_SIZE_MB16X16, mb_partitioning[i][j], NULL, NULL);
+#else
         encode_macroblock(cpi, tp, 0, mi_row + y_idx_m,
                           mi_col + x_idx_m);
+#endif
       }
 
       /* Restore L & A coding context to those in place on entry */
@@ -1170,7 +1397,12 @@ static void encode_sb_row(VP9_COMP *cpi,
       // instead of small->big) means we can use as threshold for small, which
       // may enable breakouts if RD is not good enough (i.e. faster)
       encode_sb(cpi, tp, mi_row + y_idx, mi_col + x_idx, 0,
-                BLOCK_SIZE_SB32X32, sb_partitioning[i], sb_partitioning);
+#if CONFIG_SB8X8
+                BLOCK_SIZE_SB32X32, sb_partitioning[i], mb_partitioning[i],
+                NULL);
+#else
+                BLOCK_SIZE_SB32X32, sb_partitioning[i], NULL);
+#endif
     }
 
     for (p = 0; p < MAX_MB_PLANE; p++) {
@@ -1221,7 +1453,7 @@ static void encode_sb_row(VP9_COMP *cpi,
               RDCOST(x->rdmult, x->rddiv, sb64_rate, sb64_dist)) {
         sb64_rate = r;
         sb64_dist = d;
-        sb_partitioning[0] = BLOCK_SIZE_SB64X32;
+        sb64_partitioning = BLOCK_SIZE_SB64X32;
       }
 
       for (p = 0; p < MAX_MB_PLANE; p++) {
@@ -1266,7 +1498,7 @@ static void encode_sb_row(VP9_COMP *cpi,
               RDCOST(x->rdmult, x->rddiv, sb64_rate, sb64_dist)) {
         sb64_rate = r;
         sb64_dist = d;
-        sb_partitioning[0] = BLOCK_SIZE_SB32X64;
+        sb64_partitioning = BLOCK_SIZE_SB32X64;
       }
 
       for (p = 0; p < MAX_MB_PLANE; p++) {
@@ -1295,13 +1527,17 @@ static void encode_sb_row(VP9_COMP *cpi,
               RDCOST(x->rdmult, x->rddiv, sb64_rate, sb64_dist)) {
         sb64_rate = r;
         sb64_dist = d;
-        sb_partitioning[0] = BLOCK_SIZE_SB64X64;
+        sb64_partitioning = BLOCK_SIZE_SB64X64;
       }
     }
 
     assert(tp_orig == *tp);
-    encode_sb(cpi, tp, mi_row, mi_col, 1,
-              BLOCK_SIZE_SB64X64, sb_partitioning[0], sb_partitioning);
+    encode_sb(cpi, tp, mi_row, mi_col, 1, BLOCK_SIZE_SB64X64,
+#if CONFIG_SB8X8
+              sb64_partitioning, sb_partitioning, mb_partitioning);
+#else
+              sb64_partitioning, sb_partitioning);
+#endif
     assert(tp_orig < *tp);
   }
 }
@@ -1346,10 +1582,14 @@ static void init_encode_frame_mb_context(VP9_COMP *cpi) {
   vp9_zero(cpi->count_mb_ref_frame_usage)
   vp9_zero(cpi->bmode_count)
   vp9_zero(cpi->ymode_count)
+#if !CONFIG_SB8X8
   vp9_zero(cpi->i8x8_mode_count)
+#endif
   vp9_zero(cpi->y_uv_mode_count)
   vp9_zero(cpi->sub_mv_ref_count)
+#if !CONFIG_SB8X8
   vp9_zero(cpi->mbsplit_count)
+#endif
   vp9_zero(cpi->common.fc.mv_ref_ct)
   vp9_zero(cpi->sb_ymode_count)
   vp9_zero(cpi->partition_count);
@@ -1616,9 +1856,17 @@ static void reset_skip_txfm_size_sb(VP9_COMP *cpi, MODE_INFO *mi,
     assert(bwl < bsl && bhl < bsl);
     if (bsize == BLOCK_SIZE_SB64X64) {
       subsize = BLOCK_SIZE_SB32X32;
+#if CONFIG_SB8X8
+    } else if (bsize == BLOCK_SIZE_SB32X32) {
+      subsize = BLOCK_SIZE_MB16X16;
+    } else {
+      assert(bsize == BLOCK_SIZE_MB16X16);
+      subsize = BLOCK_SIZE_SB8X8;
+#else
     } else {
       assert(bsize == BLOCK_SIZE_SB32X32);
       subsize = BLOCK_SIZE_MB16X16;
+#endif
     }
 
     for (n = 0; n < 4; n++) {
@@ -1823,9 +2071,10 @@ static void sum_intra_stats(VP9_COMP *cpi, MACROBLOCK *x) {
 
     do {
       ++ bct[xd->block[b].bmi.as_mode.first];
-    } while (++b < 16);
+    } while (++b < (16 >> (CONFIG_SB8X8 * 2)));
   }
 
+#if !CONFIG_SB8X8
   if (m == I8X8_PRED) {
     i8x8_modes[xd->block[0].bmi.as_mode.first]++;
     i8x8_modes[xd->block[2].bmi.as_mode.first]++;
@@ -1833,20 +2082,25 @@ static void sum_intra_stats(VP9_COMP *cpi, MACROBLOCK *x) {
     i8x8_modes[xd->block[10].bmi.as_mode.first]++;
   }
 #endif
+#endif
 
   if (xd->mode_info_context->mbmi.sb_type > BLOCK_SIZE_MB16X16) {
     ++cpi->sb_ymode_count[m];
   } else {
     ++cpi->ymode_count[m];
   }
+#if !CONFIG_SB8X8
   if (m != I8X8_PRED)
+#endif
     ++cpi->y_uv_mode_count[m][uvm];
+#if !CONFIG_SB8X8
   else {
     cpi->i8x8_mode_count[xd->mode_info_context->bmi[0].as_mode.first]++;
     cpi->i8x8_mode_count[xd->mode_info_context->bmi[2].as_mode.first]++;
     cpi->i8x8_mode_count[xd->mode_info_context->bmi[8].as_mode.first]++;
     cpi->i8x8_mode_count[xd->mode_info_context->bmi[10].as_mode.first]++;
   }
+#endif
   if (m == I4X4_PRED) {
     int b = 0;
     do {
@@ -1855,7 +2109,7 @@ static void sum_intra_stats(VP9_COMP *cpi, MACROBLOCK *x) {
       if (m == B_CONTEXT_PRED) m -= CONTEXT_PRED_REPLACEMENTS;
 #endif
       ++cpi->bmode_count[m];
-    } while (++b < 16);
+    } while (++b < (16 >> (CONFIG_SB8X8 * 2)));
   }
 }
 
@@ -1880,6 +2134,7 @@ static void adjust_act_zbin(VP9_COMP *cpi, MACROBLOCK *x) {
 #endif
 }
 
+#if !CONFIG_SB8X8
 static void encode_macroblock(VP9_COMP *cpi, TOKENEXTRA **t,
                               int output_enabled,
                               int mi_row, int mi_col) {
@@ -2127,6 +2382,7 @@ static void encode_macroblock(VP9_COMP *cpi, TOKENEXTRA **t,
     }
   }
 }
+#endif
 
 static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t,
                               int output_enabled, int mi_row, int mi_col,
@@ -2177,6 +2433,24 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t,
     vp9_update_zbin_extra(cpi, x);
   }
 
+#if CONFIG_SB8X8
+  if (xd->mode_info_context->mbmi.mode == I4X4_PRED) {
+    assert(bsize == BLOCK_SIZE_SB8X8 &&
+           xd->mode_info_context->mbmi.txfm_size == TX_4X4);
+
+    vp9_encode_intra4x4mby(x, bsize);
+    vp9_build_intra_predictors_sbuv_s(&x->e_mbd, bsize);
+    vp9_subtract_sbuv(x, bsize);
+    vp9_transform_sbuv_4x4(x, bsize);
+    vp9_quantize_sbuv_4x4(x, bsize);
+    vp9_optimize_sbuv_4x4(cm, x, bsize);
+    vp9_inverse_transform_sbuv_4x4(xd, bsize);
+    vp9_recon_sbuv(xd, bsize);
+
+    if (output_enabled)
+      sum_intra_stats(cpi, x);
+  } else
+#endif
   if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) {
     vp9_build_intra_predictors_sby_s(&x->e_mbd, bsize);
     vp9_build_intra_predictors_sbuv_s(&x->e_mbd, bsize);
@@ -2212,6 +2486,12 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t,
     vp9_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
   }
 
+#if CONFIG_SB8X8
+  if (xd->mode_info_context->mbmi.mode == I4X4_PRED) {
+    assert(bsize == BLOCK_SIZE_SB8X8);
+    vp9_tokenize_sb(cpi, &x->e_mbd, t, !output_enabled, bsize);
+  } else
+#endif
   if (!x->skip) {
     vp9_subtract_sb(x, bsize);
 
@@ -2264,15 +2544,23 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t,
         break;
       case TX_8X8:
         vp9_transform_sby_8x8(x, bsize);
-        vp9_transform_sbuv_8x8(x, bsize);
         vp9_quantize_sby_8x8(x, bsize);
-        vp9_quantize_sbuv_8x8(x, bsize);
-        if (x->optimize) {
+        if (x->optimize)
           vp9_optimize_sby_8x8(cm, x, bsize);
-          vp9_optimize_sbuv_8x8(cm, x, bsize);
-        }
         vp9_inverse_transform_sby_8x8(xd, bsize);
-        vp9_inverse_transform_sbuv_8x8(xd, bsize);
+        if (bsize >= BLOCK_SIZE_MB16X16) {
+          vp9_transform_sbuv_8x8(x, bsize);
+          vp9_quantize_sbuv_8x8(x, bsize);
+          if (x->optimize)
+            vp9_optimize_sbuv_8x8(cm, x, bsize);
+          vp9_inverse_transform_sbuv_8x8(xd, bsize);
+        } else {
+          vp9_transform_sbuv_4x4(x, bsize);
+          vp9_quantize_sbuv_4x4(x, bsize);
+          if (x->optimize)
+            vp9_optimize_sbuv_4x4(cm, x, bsize);
+          vp9_inverse_transform_sbuv_4x4(xd, bsize);
+        }
         break;
       case TX_4X4:
         vp9_transform_sby_4x4(x, bsize);
@@ -2315,8 +2603,10 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t,
           vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP))) {
       if (bsize >= BLOCK_SIZE_SB32X32) {
         cpi->txfm_count_32x32p[mi->mbmi.txfm_size]++;
-      } else {
+      } else if (bsize >= BLOCK_SIZE_MB16X16) {
         cpi->txfm_count_16x16p[mi->mbmi.txfm_size]++;
+      } else {
+        cpi->txfm_count_8x8p[mi->mbmi.txfm_size]++;
       }
     } else {
       int x, y;
@@ -2324,6 +2614,8 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t,
 
       if (sz == TX_32X32 && bsize < BLOCK_SIZE_SB32X32)
         sz = TX_16X16;
+      if (sz == TX_16X16 && bsize < BLOCK_SIZE_MB16X16)
+        sz = TX_8X8;
 
       for (y = 0; y < bh; y++) {
         for (x = 0; x < bw; x++) {
index f6ddca8..58a6b2a 100644 (file)
@@ -22,12 +22,15 @@ int vp9_encode_intra(VP9_COMP *cpi, MACROBLOCK *x, int use_16x16_pred) {
   MB_MODE_INFO * mbmi = &x->e_mbd.mode_info_context->mbmi;
   (void) cpi;
 
+#if !CONFIG_SB8X8
   if (use_16x16_pred) {
+#endif
     mbmi->mode = DC_PRED;
     mbmi->uv_mode = DC_PRED;
     mbmi->ref_frame = INTRA_FRAME;
 
     vp9_encode_intra16x16mby(&cpi->common, x);
+#if !CONFIG_SB8X8
   } else {
     int i;
 
@@ -36,6 +39,7 @@ int vp9_encode_intra(VP9_COMP *cpi, MACROBLOCK *x, int use_16x16_pred) {
       encode_intra4x4block(x, i, BLOCK_SIZE_MB16X16);
     }
   }
+#endif
 
   return vp9_get_mb_ss(x->plane[0].src_diff);
 }
@@ -58,7 +62,7 @@ static void encode_intra4x4block(MACROBLOCK *x, int ib,
                                 xd->plane[0].diff);
   int16_t* const coeff = BLOCK_OFFSET(x->plane[0].coeff, ib, 16);
 
-  assert(ib < 16);
+  assert(ib < (16 >> (2 * CONFIG_SB8X8)));
 
 #if CONFIG_NEWBINTRAMODES
   xd->mode_info_context->bmi[ib].as_mode.context =
@@ -68,22 +72,22 @@ static void encode_intra4x4block(MACROBLOCK *x, int ib,
   vp9_intra4x4_predict(&x->e_mbd, ib,
                        xd->mode_info_context->bmi[ib].as_mode.first,
                        dst, xd->plane[0].dst.stride);
-  vp9_subtract_block(4, 4, src_diff, 16,
+  vp9_subtract_block(4, 4, src_diff, 16 >> CONFIG_SB8X8,
                      src, x->plane[0].src.stride,
                      dst, xd->plane[0].dst.stride);
 
   tx_type = get_tx_type_4x4(&x->e_mbd, ib);
   if (tx_type != DCT_DCT) {
-    vp9_short_fht4x4(src_diff, coeff, 16, tx_type);
+    vp9_short_fht4x4(src_diff, coeff, 16 >> CONFIG_SB8X8, tx_type);
     x->quantize_b_4x4(x, ib, tx_type, 16);
     vp9_short_iht4x4(BLOCK_OFFSET(xd->plane[0].dqcoeff, ib, 16),
-                     diff, 16, tx_type);
+                     diff, 16 >> CONFIG_SB8X8, tx_type);
   } else {
-    x->fwd_txm4x4(src_diff, coeff, 32);
+    x->fwd_txm4x4(src_diff, coeff, 32 >> CONFIG_SB8X8);
     x->quantize_b_4x4(x, ib, tx_type, 16);
     vp9_inverse_transform_b_4x4(&x->e_mbd, xd->plane[0].eobs[ib],
                                 BLOCK_OFFSET(xd->plane[0].dqcoeff, ib, 16),
-                                diff, 32);
+                                diff, 32 >> CONFIG_SB8X8);
   }
 
   vp9_recon_b(dst, diff, dst, xd->plane[0].dst.stride);
@@ -159,6 +163,7 @@ void vp9_encode_intra16x16mbuv(VP9_COMMON *const cm, MACROBLOCK *x) {
   vp9_recon_sbuv(xd, BLOCK_SIZE_MB16X16);
 }
 
+#if !CONFIG_SB8X8
 void vp9_encode_intra8x8(MACROBLOCK *x, int ib) {
   MACROBLOCKD *xd = &x->e_mbd;
   uint8_t* const src =
@@ -304,3 +309,4 @@ void vp9_encode_intra8x8mbuv(MACROBLOCK *x) {
     encode_intra_uv4x4(x, i + 20, mode);  // v
   }
 }
+#endif
index 7ec2f11..a4f4c18 100644 (file)
@@ -17,8 +17,10 @@ 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, BLOCK_SIZE_TYPE bs);
+#if !CONFIG_SB8X8
 void vp9_encode_intra8x8mby(MACROBLOCK *x);
 void vp9_encode_intra8x8mbuv(MACROBLOCK *x);
 void vp9_encode_intra8x8(MACROBLOCK *x, int ib);
+#endif
 
 #endif  // VP9_ENCODER_VP9_ENCODEINTRA_H_
index 0cb1ae9..5e7437e 100644 (file)
@@ -677,6 +677,7 @@ void vp9_optimize_sbuv_4x4(VP9_COMMON *const cm, MACROBLOCK *x,
   }
 }
 
+#if !CONFIG_SB8X8
 void vp9_fidct_mb(VP9_COMMON *const cm, MACROBLOCK *x) {
   MACROBLOCKD *const xd = &x->e_mbd;
   const TX_SIZE tx_size = xd->mode_info_context->mbmi.txfm_size;
@@ -735,6 +736,7 @@ void vp9_encode_inter16x16(VP9_COMMON *const cm, MACROBLOCK *x,
   vp9_fidct_mb(cm, x);
   vp9_recon_sb(xd, BLOCK_SIZE_MB16X16);
 }
+#endif
 
 /* this function is used by first pass only */
 void vp9_encode_inter16x16y(MACROBLOCK *x, int mi_row, int mi_col) {
index da134a8..cd20659 100644 (file)
@@ -24,8 +24,10 @@ typedef struct {
 
 
 struct VP9_ENCODER_RTCD;
+#if !CONFIG_SB8X8
 void vp9_encode_inter16x16(VP9_COMMON *const cm, MACROBLOCK *x,
                            int mb_row, int mb_col);
+#endif
 
 void vp9_encode_inter16x16y(MACROBLOCK *x, int mb_row, int mb_col);
 
@@ -54,7 +56,9 @@ void vp9_transform_sbuv_4x4(MACROBLOCK *x, BLOCK_SIZE_TYPE bsize);
 void vp9_optimize_sbuv_4x4(VP9_COMMON *const cm, MACROBLOCK *x,
                            BLOCK_SIZE_TYPE bsize);
 
+#if !CONFIG_SB8X8
 void vp9_fidct_mb(VP9_COMMON *const cm, MACROBLOCK *x);
+#endif
 
 void vp9_subtract_block(int rows, int cols,
                         int16_t *diff_ptr, int diff_stride,
index 7d9462f..88cd1f4 100644 (file)
@@ -41,8 +41,10 @@ void vp9_init_mode_costs(VP9_COMP *c) {
                   x->fc.uv_mode_prob[VP9_YMODES - 1], vp9_uv_mode_tree);
   vp9_cost_tokens(c->mb.intra_uv_mode_cost[0],
                   x->kf_uv_mode_prob[VP9_YMODES - 1], vp9_uv_mode_tree);
+#if !CONFIG_SB8X8
   vp9_cost_tokens(c->mb.i8x8_mode_costs,
                   x->fc.i8x8_mode_prob, vp9_i8x8_mode_tree);
+#endif
 
   for (i = 0; i <= VP9_SWITCHABLE_FILTERS; ++i)
     vp9_cost_tokens((int *)c->mb.switchable_interp_costs[i],
index 0af232e..86e0666 100644 (file)
@@ -628,7 +628,9 @@ static void set_rd_speed_thresholds(VP9_COMP *cpi, int mode, int speed) {
   sf->thresh_mult[THR_D63_PRED ] += speed_multiplier * 1500;
 
   sf->thresh_mult[THR_B_PRED   ] += speed_multiplier * 2500;
+#if !CONFIG_SB8X8
   sf->thresh_mult[THR_I8X8_PRED] += speed_multiplier * 2500;
+#endif
 
   sf->thresh_mult[THR_NEWMV    ] += speed_multiplier * 1000;
   sf->thresh_mult[THR_NEWG     ] += speed_multiplier * 1000;
@@ -3326,9 +3328,13 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
     vp9_copy(cpi->common.fc.ymode_counts, cpi->ymode_count);
     vp9_copy(cpi->common.fc.uv_mode_counts, cpi->y_uv_mode_count);
     vp9_copy(cpi->common.fc.bmode_counts, cpi->bmode_count);
+#if !CONFIG_SB8X8
     vp9_copy(cpi->common.fc.i8x8_mode_counts, cpi->i8x8_mode_count);
+#endif
     vp9_copy(cpi->common.fc.sub_mv_ref_counts, cpi->sub_mv_ref_count);
+#if !CONFIG_SB8X8
     vp9_copy(cpi->common.fc.mbsplit_counts, cpi->mbsplit_count);
+#endif
     vp9_copy(cpi->common.fc.partition_counts, cpi->partition_count);
 #if CONFIG_COMP_INTERINTRA_PRED
     vp9_copy(cpi->common.fc.interintra_counts, cpi->interintra_count);
index aeaf1bd..541127e 100644 (file)
@@ -48,9 +48,9 @@
 #define KEY_FRAME_CONTEXT 5
 
 #if CONFIG_COMP_INTERINTRA_PRED
-#define MAX_MODES 54
+#define MAX_MODES 54 - CONFIG_SB8X8
 #else
-#define MAX_MODES 42
+#define MAX_MODES 42 - CONFIG_SB8X8
 #endif
 
 #define MIN_THRESHMULT  32
@@ -72,7 +72,9 @@ typedef struct {
   // Stats
   int y_modes[VP9_YMODES];
   int uv_modes[VP9_UV_MODES];
+#if !CONFIG_SB8X8
   int i8x8_modes[VP9_I8X8_MODES];
+#endif
   int b_modes[B_MODE_COUNT];
   int inter_y_modes[MB_MODE_COUNT];
   int inter_uv_modes[VP9_UV_MODES];
@@ -100,9 +102,13 @@ typedef struct {
   vp9_prob ymode_prob[VP9_YMODES - 1]; /* interframe intra mode probs */
   vp9_prob uv_mode_prob[VP9_YMODES][VP9_UV_MODES - 1];
   vp9_prob bmode_prob[VP9_NKF_BINTRAMODES - 1];
+#if !CONFIG_SB8X8
   vp9_prob i8x8_mode_prob[VP9_I8X8_MODES - 1];
+#endif
   vp9_prob sub_mv_ref_prob[SUBMVREF_COUNT][VP9_SUBMVREFS - 1];
+#if !CONFIG_SB8X8
   vp9_prob mbsplit_prob[VP9_NUMMBSPLITS - 1];
+#endif
   vp9_prob partition_prob[NUM_PARTITION_CONTEXTS][PARTITION_TYPES - 1];
 
   vp9_prob switchable_interp_prob[VP9_SWITCHABLE_FILTERS + 1]
@@ -207,7 +213,9 @@ typedef enum {
   THR_SPLITA,
 
   THR_B_PRED,
+#if !CONFIG_SB8X8
   THR_I8X8_PRED,
+#endif
 
   THR_COMP_ZEROLG,
   THR_COMP_NEARESTLG,
@@ -273,10 +281,17 @@ typedef struct {
 } SPEED_FEATURES;
 
 enum BlockSize {
+#if CONFIG_SB8X8
+  BLOCK_4X4,
+  BLOCK_8X8,
+  BLOCK_8X16,
+  BLOCK_16X8,
+#else
   BLOCK_16X8 = PARTITIONING_16X8,
   BLOCK_8X16 = PARTITIONING_8X16,
   BLOCK_8X8 = PARTITIONING_8X8,
   BLOCK_4X4 = PARTITIONING_4X4,
+#endif
   BLOCK_16X16,
   BLOCK_MAX_SEGMENTS,
   BLOCK_32X32 = BLOCK_MAX_SEGMENTS,
@@ -451,9 +466,13 @@ typedef struct VP9_COMP {
   int sb_ymode_count [VP9_I32X32_MODES];
   int ymode_count[VP9_YMODES];        /* intra MB type cts this frame */
   int bmode_count[VP9_NKF_BINTRAMODES];
+#if !CONFIG_SB8X8
   int i8x8_mode_count[VP9_I8X8_MODES];
+#endif
   int sub_mv_ref_count[SUBMVREF_COUNT][VP9_SUBMVREFS];
+#if !CONFIG_SB8X8
   int mbsplit_count[VP9_NUMMBSPLITS];
+#endif
   int y_uv_mode_count[VP9_YMODES][VP9_UV_MODES];
   unsigned int partition_count[NUM_PARTITION_CONTEXTS][PARTITION_TYPES];
 #if CONFIG_COMP_INTERINTRA_PRED
index 77e1972..b36a4bc 100644 (file)
@@ -223,9 +223,9 @@ void vp9_quantize_sbuv_16x16(MACROBLOCK *x, BLOCK_SIZE_TYPE bsize) {
 }
 
 void vp9_quantize_sbuv_8x8(MACROBLOCK *x, BLOCK_SIZE_TYPE bsize) {
-  const int bwl = b_width_log2(bsize) - 2;
-  const int bhl = b_height_log2(bsize) - 2;
-  const int uoff = 16 << (bhl + bwl);
+  const int bwl = b_width_log2(bsize) - 1;
+  const int bhl = b_height_log2(bsize) - 1;
+  const int uoff = 4 << (bhl + bwl);
   int i;
 
   for (i = uoff; i < ((uoff * 3) >> 1); i += 4)
@@ -233,9 +233,9 @@ void vp9_quantize_sbuv_8x8(MACROBLOCK *x, BLOCK_SIZE_TYPE bsize) {
 }
 
 void vp9_quantize_sbuv_4x4(MACROBLOCK *x, BLOCK_SIZE_TYPE bsize) {
-  const int bwl = b_width_log2(bsize) - 2;
-  const int bhl = b_height_log2(bsize) - 2;
-  const int uoff = 16 << (bhl + bwl);
+  const int bwl = b_width_log2(bsize);
+  const int bhl = b_height_log2(bsize);
+  const int uoff = 1 << (bhl + bwl);
   int i;
 
   for (i = uoff; i < ((uoff * 3) >> 1); i++)
index 4725225..42d339d 100644 (file)
@@ -138,9 +138,13 @@ void vp9_save_coding_context(VP9_COMP *cpi) {
   vp9_copy(cc->sb_ymode_prob, cm->fc.sb_ymode_prob);
   vp9_copy(cc->bmode_prob, cm->fc.bmode_prob);
   vp9_copy(cc->uv_mode_prob, cm->fc.uv_mode_prob);
+#if !CONFIG_SB8X8
   vp9_copy(cc->i8x8_mode_prob, cm->fc.i8x8_mode_prob);
+#endif
   vp9_copy(cc->sub_mv_ref_prob, cm->fc.sub_mv_ref_prob);
+#if !CONFIG_SB8X8
   vp9_copy(cc->mbsplit_prob, cm->fc.mbsplit_prob);
+#endif
   vp9_copy(cc->partition_prob, cm->fc.partition_prob);
 
   // Stats
@@ -198,10 +202,14 @@ void vp9_restore_coding_context(VP9_COMP *cpi) {
   vp9_copy(cm->fc.ymode_prob, cc->ymode_prob);
   vp9_copy(cm->fc.sb_ymode_prob, cc->sb_ymode_prob);
   vp9_copy(cm->fc.bmode_prob, cc->bmode_prob);
+#if !CONFIG_SB8X8
   vp9_copy(cm->fc.i8x8_mode_prob, cc->i8x8_mode_prob);
+#endif
   vp9_copy(cm->fc.uv_mode_prob, cc->uv_mode_prob);
   vp9_copy(cm->fc.sub_mv_ref_prob, cc->sub_mv_ref_prob);
+#if !CONFIG_SB8X8
   vp9_copy(cm->fc.mbsplit_prob, cc->mbsplit_prob);
+#endif
   vp9_copy(cm->fc.partition_prob, cc->partition_prob);
 
   // Stats
index 0e85a0c..93d30ff 100644 (file)
@@ -105,7 +105,9 @@ const MODE_DEFINITION vp9_mode_order[MAX_MODES] = {
   {SPLITMV,   ALTREF_FRAME, NONE},
 
   {I4X4_PRED,    INTRA_FRAME,  NONE},
+#if !CONFIG_SB8X8
   {I8X8_PRED, INTRA_FRAME,  NONE},
+#endif
 
   /* compound prediction modes */
   {ZEROMV,    LAST_FRAME,   GOLDEN_FRAME},
@@ -563,17 +565,19 @@ static void choose_txfm_size_from_rd(VP9_COMP *cpi, MACROBLOCK *x,
         rd[TX_32X32][1] < rd[TX_16X16][1] && rd[TX_32X32][1] < rd[TX_8X8][1] &&
         rd[TX_32X32][1] < rd[TX_4X4][1]))) {
     mbmi->txfm_size = TX_32X32;
-  } else if ( cm->txfm_mode == ALLOW_16X16 ||
-             (max_txfm_size == TX_16X16 && cm->txfm_mode == ALLOW_32X32) ||
-             (cm->txfm_mode == TX_MODE_SELECT &&
-              rd[TX_16X16][1] < rd[TX_8X8][1] &&
-              rd[TX_16X16][1] < rd[TX_4X4][1])) {
+  } else if (max_txfm_size >= TX_16X16 &&
+             (cm->txfm_mode == ALLOW_16X16 ||
+              cm->txfm_mode == ALLOW_32X32 ||
+              (cm->txfm_mode == TX_MODE_SELECT &&
+               rd[TX_16X16][1] < rd[TX_8X8][1] &&
+               rd[TX_16X16][1] < rd[TX_4X4][1]))) {
     mbmi->txfm_size = TX_16X16;
   } else if (cm->txfm_mode == ALLOW_8X8 ||
+             cm->txfm_mode == ALLOW_16X16 ||
+             cm->txfm_mode == ALLOW_32X32 ||
            (cm->txfm_mode == TX_MODE_SELECT && rd[TX_8X8][1] < rd[TX_4X4][1])) {
     mbmi->txfm_size = TX_8X8;
   } else {
-    assert(cm->txfm_mode == ONLY_4X4 || cm->txfm_mode == TX_MODE_SELECT);
     mbmi->txfm_size = TX_4X4;
   }
 
@@ -583,13 +587,14 @@ static void choose_txfm_size_from_rd(VP9_COMP *cpi, MACROBLOCK *x,
 
   txfm_cache[ONLY_4X4] = rd[TX_4X4][0];
   txfm_cache[ALLOW_8X8] = rd[TX_8X8][0];
-  txfm_cache[ALLOW_16X16] = rd[TX_16X16][0];
-  txfm_cache[ALLOW_32X32] = rd[max_txfm_size][0];
+  txfm_cache[ALLOW_16X16] = rd[MIN(max_txfm_size, TX_16X16)][0];
+  txfm_cache[ALLOW_32X32] = rd[MIN(max_txfm_size, TX_32X32)][0];
   if (max_txfm_size == TX_32X32 &&
       rd[TX_32X32][1] < rd[TX_16X16][1] && rd[TX_32X32][1] < rd[TX_8X8][1] &&
       rd[TX_32X32][1] < rd[TX_4X4][1])
     txfm_cache[TX_MODE_SELECT] = rd[TX_32X32][1];
-  else if (rd[TX_16X16][1] < rd[TX_8X8][1] && rd[TX_16X16][1] < rd[TX_4X4][1])
+  else if (max_txfm_size >= TX_16X16 &&
+           rd[TX_16X16][1] < rd[TX_8X8][1] && rd[TX_16X16][1] < rd[TX_4X4][1])
     txfm_cache[TX_MODE_SELECT] = rd[TX_16X16][1];
   else
     txfm_cache[TX_MODE_SELECT] = rd[TX_4X4][1] < rd[TX_8X8][1] ?
@@ -794,12 +799,18 @@ static void super_block_yrd(VP9_COMP *cpi,
   if (bs >= BLOCK_SIZE_SB32X32)
     super_block_yrd_32x32(cm, x, &r[TX_32X32][0], &d[TX_32X32], &s[TX_32X32],
                           bs);
-  super_block_yrd_16x16(cm, x, &r[TX_16X16][0], &d[TX_16X16], &s[TX_16X16], bs);
+  if (bs >= BLOCK_SIZE_MB16X16)
+    super_block_yrd_16x16(cm, x, &r[TX_16X16][0], &d[TX_16X16], &s[TX_16X16],
+                          bs);
   super_block_yrd_8x8(cm, x,   &r[TX_8X8][0],   &d[TX_8X8],   &s[TX_8X8],   bs);
   super_block_yrd_4x4(cm, x,   &r[TX_4X4][0],   &d[TX_4X4],   &s[TX_4X4],   bs);
 
   choose_txfm_size_from_rd(cpi, x, r, rate, d, distortion, s, skip, txfm_cache,
-                           TX_32X32 - (bs < BLOCK_SIZE_SB32X32));
+                           TX_32X32 - (bs < BLOCK_SIZE_SB32X32)
+#if CONFIG_SB8X8
+                           - (bs < BLOCK_SIZE_MB16X16)
+#endif
+                           );
 }
 
 static int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, int ib,
@@ -816,17 +827,41 @@ static int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, int ib,
   VP9_COMMON *const cm = &cpi->common;
   const int src_stride = x->plane[0].src.stride;
   uint8_t* const src =
-      raster_block_offset_uint8(xd, BLOCK_SIZE_MB16X16, 0, ib,
+      raster_block_offset_uint8(xd,
+#if CONFIG_SB8X8
+                                BLOCK_SIZE_SB8X8,
+#else
+                                BLOCK_SIZE_MB16X16,
+#endif
+                                0, ib,
                                 x->plane[0].src.buf, src_stride);
   int16_t* const src_diff =
-      raster_block_offset_int16(xd, BLOCK_SIZE_MB16X16, 0, ib,
+      raster_block_offset_int16(xd,
+#if CONFIG_SB8X8
+                                BLOCK_SIZE_SB8X8,
+#else
+                                BLOCK_SIZE_MB16X16,
+#endif
+                                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,
+#if CONFIG_SB8X8
+                                BLOCK_SIZE_SB8X8,
+#else
+                                BLOCK_SIZE_MB16X16,
+#endif
+                                0, ib,
                                 xd->plane[0].diff);
   int16_t* const coeff = BLOCK_OFFSET(x->plane[0].coeff, ib, 16);
   uint8_t* const dst =
-      raster_block_offset_uint8(xd, BLOCK_SIZE_MB16X16, 0, ib,
+      raster_block_offset_uint8(xd,
+#if CONFIG_SB8X8
+                                BLOCK_SIZE_SB8X8,
+#else
+                                BLOCK_SIZE_MB16X16,
+#endif
+                                0, ib,
                                 xd->plane[0].dst.buf, xd->plane[0].dst.stride);
   ENTROPY_CONTEXT ta = *a, tempa = *a;
   ENTROPY_CONTEXT tl = *l, templ = *l;
@@ -839,7 +874,7 @@ static int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, int ib,
    * */
   DECLARE_ALIGNED_ARRAY(16, int16_t, best_dqcoeff, 16);
 
-  assert(ib < 16);
+  assert(ib < (16 >> (2 * CONFIG_SB8X8)));
 #if CONFIG_NEWBINTRAMODES
   xd->mode_info_context->bmi[ib].as_mode.context =
     vp9_find_bpred_context(xd, ib, dst, xd->plane[0].dst.stride);
@@ -868,17 +903,17 @@ static int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, int ib,
 #endif
 
     vp9_intra4x4_predict(xd, ib, mode, dst, xd->plane[0].dst.stride);
-    vp9_subtract_block(4, 4, src_diff, 16,
+    vp9_subtract_block(4, 4, src_diff, 16 >> CONFIG_SB8X8,
                        src, src_stride,
                        dst, xd->plane[0].dst.stride);
 
     xd->mode_info_context->bmi[ib].as_mode.first = mode;
     tx_type = get_tx_type_4x4(xd, ib);
     if (tx_type != DCT_DCT) {
-      vp9_short_fht4x4(src_diff, coeff, 16, tx_type);
+      vp9_short_fht4x4(src_diff, coeff, 16 >> CONFIG_SB8X8, tx_type);
       x->quantize_b_4x4(x, ib, tx_type, 16);
     } else {
-      x->fwd_txm4x4(src_diff, coeff, 32);
+      x->fwd_txm4x4(src_diff, coeff, 32 >> CONFIG_SB8X8);
       x->quantize_b_4x4(x, ib, tx_type, 16);
     }
 
@@ -911,9 +946,9 @@ static int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, int ib,
 
   // inverse transform
   if (best_tx_type != DCT_DCT)
-    vp9_short_iht4x4(best_dqcoeff, diff, 16, best_tx_type);
+    vp9_short_iht4x4(best_dqcoeff, diff, 16 >> CONFIG_SB8X8, best_tx_type);
   else
-    xd->inv_txm4x4(best_dqcoeff, diff, 32);
+    xd->inv_txm4x4(best_dqcoeff, diff, 32 >> CONFIG_SB8X8);
 
   vp9_intra4x4_predict(xd, ib, *best_mode,
                        dst, xd->plane[0].dst.stride);
@@ -932,7 +967,7 @@ static int64_t rd_pick_intra4x4mby_modes(VP9_COMP *cpi, MACROBLOCK *mb,
   int distortion = 0;
   int tot_rate_y = 0;
   int64_t total_rd = 0;
-  ENTROPY_CONTEXT t_above[4], t_left[4];
+  ENTROPY_CONTEXT t_above[4 >> CONFIG_SB8X8], t_left[4 >> CONFIG_SB8X8];
   int *bmode_costs;
 
   vpx_memcpy(t_above, xd->plane[0].above_context, sizeof(t_above));
@@ -941,15 +976,21 @@ static int64_t rd_pick_intra4x4mby_modes(VP9_COMP *cpi, MACROBLOCK *mb,
   xd->mode_info_context->mbmi.mode = I4X4_PRED;
   bmode_costs = mb->inter_bmode_costs;
 
-  for (i = 0; i < 16; i++) {
-    const int x_idx = i & 3, y_idx = i >> 2;
+  for (i = 0; i < (16 >> (2 * CONFIG_SB8X8)); i++) {
+    const int x_idx = i & (3 >> CONFIG_SB8X8), y_idx = i >> (2 >> CONFIG_SB8X8);
     MODE_INFO *const mic = xd->mode_info_context;
     const int mis = xd->mode_info_stride;
     B_PREDICTION_MODE UNINITIALIZED_IS_SAFE(best_mode);
     int UNINITIALIZED_IS_SAFE(r), UNINITIALIZED_IS_SAFE(ry), UNINITIALIZED_IS_SAFE(d);
 #if CONFIG_NEWBINTRAMODES
     uint8_t* const dst =
-        raster_block_offset_uint8(xd, BLOCK_SIZE_MB16X16, 0, i,
+        raster_block_offset_uint8(xd,
+#if CONFIG_SB8X8
+                                  BLOCK_SIZE_SB8X8,
+#else
+                                  BLOCK_SIZE_MB16X16,
+#endif
+                                  0, i,
                                   xd->plane[0].dst.buf,
                                   xd->plane[0].dst.stride);
 #endif
@@ -1046,6 +1087,7 @@ static int64_t rd_pick_intra_sby_mode(VP9_COMP *cpi, MACROBLOCK *x,
   return best_rd;
 }
 
+#if !CONFIG_SB8X8
 static int64_t rd_pick_intra8x8block(VP9_COMP *cpi, MACROBLOCK *x, int ib,
                                      B_PREDICTION_MODE *best_mode,
                                      int *mode_costs,
@@ -1283,6 +1325,7 @@ static int64_t rd_pick_intra8x8mby_modes_and_txsz(VP9_COMP *cpi, MACROBLOCK *x,
 
   return tmp_rd;
 }
+#endif  // !CONFIG_SB8X8
 
 static int rd_cost_sbuv_4x4(VP9_COMMON *const cm, MACROBLOCK *x,
                             BLOCK_SIZE_TYPE bsize) {
@@ -1425,104 +1468,611 @@ static int rd_cost_sbuv_32x32(VP9_COMMON *const cm, MACROBLOCK *x,
                           t_above + x_idx * 8, t_left + y_idx * 8,
                           TX_32X32, 256 * bh * bw);
     }
-    yoff = (yoff * 5) >> 2;  // u -> v
+    yoff = (yoff * 5) >> 2;  // u -> v
+  }
+
+  return cost;
+}
+#undef UVCTX
+
+static void super_block_uvrd_32x32(VP9_COMMON *const cm, MACROBLOCK *x,
+                                   int *rate, int *distortion, int *skip,
+                                   BLOCK_SIZE_TYPE bsize) {
+  MACROBLOCKD *const xd = &x->e_mbd;
+
+  vp9_transform_sbuv_32x32(x, bsize);
+  vp9_quantize_sbuv_32x32(x, bsize);
+
+  *rate       = rd_cost_sbuv_32x32(cm, x, bsize);
+  *distortion = block_error_sbuv(x, bsize, 0);
+  *skip       = vp9_sbuv_is_skippable(xd, bsize);
+}
+
+static void super_block_uvrd(VP9_COMMON *const cm, MACROBLOCK *x,
+                             int *rate, int *distortion, int *skippable,
+                             BLOCK_SIZE_TYPE bsize) {
+  MACROBLOCKD *const xd = &x->e_mbd;
+  MB_MODE_INFO *const mbmi = &xd->mode_info_context->mbmi;
+
+  vp9_subtract_sbuv(x, bsize);
+
+  if (mbmi->txfm_size >= TX_32X32 && bsize >= BLOCK_SIZE_SB64X64) {
+    super_block_uvrd_32x32(cm, x, rate, distortion, skippable, bsize);
+  } else if (mbmi->txfm_size >= TX_16X16 && bsize >= BLOCK_SIZE_SB32X32) {
+    super_block_uvrd_16x16(cm, x, rate, distortion, skippable, bsize);
+  } else if (mbmi->txfm_size >= TX_8X8 && bsize >= BLOCK_SIZE_MB16X16) {
+    super_block_uvrd_8x8(cm, x, rate, distortion, skippable, bsize);
+  } else {
+    super_block_uvrd_4x4(cm, x, rate, distortion, skippable, bsize);
+  }
+}
+
+static int64_t rd_pick_intra_sbuv_mode(VP9_COMP *cpi, MACROBLOCK *x,
+                                       int *rate, int *rate_tokenonly,
+                                       int *distortion, int *skippable,
+                                       BLOCK_SIZE_TYPE bsize) {
+  MB_PREDICTION_MODE mode;
+  MB_PREDICTION_MODE UNINITIALIZED_IS_SAFE(mode_selected);
+  int64_t best_rd = INT64_MAX, this_rd;
+  int this_rate_tokenonly, this_rate;
+  int this_distortion, s;
+
+  for (mode = DC_PRED; mode <= TM_PRED; mode++) {
+    x->e_mbd.mode_info_context->mbmi.uv_mode = mode;
+    vp9_build_intra_predictors_sbuv_s(&x->e_mbd, bsize);
+
+    super_block_uvrd(&cpi->common, x, &this_rate_tokenonly,
+                     &this_distortion, &s, bsize);
+    this_rate = this_rate_tokenonly +
+                x->intra_uv_mode_cost[x->e_mbd.frame_type][mode];
+    this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
+
+    if (this_rd < best_rd) {
+      mode_selected   = mode;
+      best_rd         = this_rd;
+      *rate           = this_rate;
+      *rate_tokenonly = this_rate_tokenonly;
+      *distortion     = this_distortion;
+      *skippable      = s;
+    }
+  }
+
+  x->e_mbd.mode_info_context->mbmi.uv_mode = mode_selected;
+
+  return best_rd;
+}
+
+int vp9_cost_mv_ref(VP9_COMP *cpi,
+                    MB_PREDICTION_MODE m,
+                    const int mode_context) {
+  MACROBLOCKD *xd = &cpi->mb.e_mbd;
+  int segment_id = xd->mode_info_context->mbmi.segment_id;
+
+  // Dont account for mode here if segment skip is enabled.
+  if (!vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)) {
+    VP9_COMMON *pc = &cpi->common;
+
+    vp9_prob p [VP9_MVREFS - 1];
+    assert(NEARESTMV <= m  &&  m <= SPLITMV);
+    vp9_mv_ref_probs(pc, p, mode_context);
+    return cost_token(vp9_mv_ref_tree, p,
+                      vp9_mv_ref_encoding_array - NEARESTMV + m);
+  } else
+    return 0;
+}
+
+void vp9_set_mbmode_and_mvs(MACROBLOCK *x, MB_PREDICTION_MODE mb, int_mv *mv) {
+  x->e_mbd.mode_info_context->mbmi.mode = mb;
+  x->e_mbd.mode_info_context->mbmi.mv[0].as_int = mv->as_int;
+}
+
+#if CONFIG_SB8X8
+static int labels2mode(MACROBLOCK *x,
+                       int const *labelings, int which_label,
+                       B_PREDICTION_MODE this_mode,
+                       int_mv *this_mv, int_mv *this_second_mv,
+                       int_mv seg_mvs[MAX_REF_FRAMES - 1],
+                       int_mv *best_ref_mv,
+                       int_mv *second_best_ref_mv,
+                       int *mvjcost, int *mvcost[2], VP9_COMP *cpi) {
+  MACROBLOCKD *const xd = &x->e_mbd;
+  MODE_INFO *const mic = xd->mode_info_context;
+  MB_MODE_INFO * mbmi = &mic->mbmi;
+  const int mis = xd->mode_info_stride;
+  int i, cost = 0, thismvcost = 0;
+
+  /* We have to be careful retrieving previously-encoded motion vectors.
+   Ones from this macroblock have to be pulled from the BLOCKD array
+   as they have not yet made it to the bmi array in our MB_MODE_INFO. */
+  for (i = 0; i < 4; ++i) {
+    const int row = i >> 1, col = i & 1;
+    B_PREDICTION_MODE m;
+
+    if (labelings[i] != which_label)
+      continue;
+
+    if (col  &&  labelings[i] == labelings[i - 1])
+      m = LEFT4X4;
+    else if (row  &&  labelings[i] == labelings[i - 2])
+      m = ABOVE4X4;
+    else {
+      // the only time we should do costing for new motion vector or mode
+      // is when we are on a new label  (jbb May 08, 2007)
+      switch (m = this_mode) {
+        case NEW4X4 :
+          if (mbmi->second_ref_frame > 0) {
+            this_mv->as_int = seg_mvs[mbmi->ref_frame - 1].as_int;
+            this_second_mv->as_int =
+            seg_mvs[mbmi->second_ref_frame - 1].as_int;
+          }
+
+          thismvcost  = vp9_mv_bit_cost(this_mv, best_ref_mv, mvjcost, mvcost,
+                                        102, xd->allow_high_precision_mv);
+          if (mbmi->second_ref_frame > 0) {
+            thismvcost += vp9_mv_bit_cost(this_second_mv, second_best_ref_mv,
+                                          mvjcost, mvcost, 102,
+                                          xd->allow_high_precision_mv);
+          }
+          break;
+        case LEFT4X4:
+          this_mv->as_int = col ? mic->bmi[i - 1].as_mv[0].as_int :
+          left_block_mv(xd, mic, i);
+          if (mbmi->second_ref_frame > 0)
+            this_second_mv->as_int = col ? mic->bmi[i - 1].as_mv[1].as_int :
+            left_block_second_mv(xd, mic, i);
+          break;
+        case ABOVE4X4:
+          this_mv->as_int = row ? mic->bmi[i - 2].as_mv[0].as_int :
+          above_block_mv(mic, i, mis);
+          if (mbmi->second_ref_frame > 0)
+            this_second_mv->as_int = row ? mic->bmi[i - 2].as_mv[1].as_int :
+            above_block_second_mv(mic, i, mis);
+          break;
+        case ZERO4X4:
+          this_mv->as_int = 0;
+          if (mbmi->second_ref_frame > 0)
+            this_second_mv->as_int = 0;
+          break;
+        default:
+          break;
+      }
+
+      if (m == ABOVE4X4) {  // replace above with left if same
+        int_mv left_mv, left_second_mv;
+
+        left_second_mv.as_int = 0;
+        left_mv.as_int = col ? mic->bmi[i - 1].as_mv[0].as_int :
+        left_block_mv(xd, mic, i);
+        if (mbmi->second_ref_frame > 0)
+          left_second_mv.as_int = col ? mic->bmi[i - 1].as_mv[1].as_int :
+          left_block_second_mv(xd, mic, i);
+
+        if (left_mv.as_int == this_mv->as_int &&
+            (mbmi->second_ref_frame <= 0 ||
+             left_second_mv.as_int == this_second_mv->as_int))
+          m = LEFT4X4;
+      }
+
+#if CONFIG_NEWBINTRAMODES
+      cost = x->inter_bmode_costs[m == B_CONTEXT_PRED ?
+                                  m - CONTEXT_PRED_REPLACEMENTS : m];
+#else
+      cost = x->inter_bmode_costs[m];
+#endif
+    }
+
+    mic->bmi[i].as_mv[0].as_int = this_mv->as_int;
+    if (mbmi->second_ref_frame > 0)
+      mic->bmi[i].as_mv[1].as_int = this_second_mv->as_int;
+
+    x->partition_info->bmi[i].mode = m;
+    x->partition_info->bmi[i].mv.as_int = this_mv->as_int;
+    if (mbmi->second_ref_frame > 0)
+      x->partition_info->bmi[i].second_mv.as_int = this_second_mv->as_int;
+  }
+
+  cost += thismvcost;
+  return cost;
+}
+
+static int64_t encode_inter_mb_segment(VP9_COMMON *const cm,
+                                       MACROBLOCK *x,
+                                       int const *labels,
+                                       int which_label,
+                                       int *labelyrate,
+                                       int *distortion,
+                                       ENTROPY_CONTEXT *ta,
+                                       ENTROPY_CONTEXT *tl) {
+  int i;
+  MACROBLOCKD *xd = &x->e_mbd;
+
+  *labelyrate = 0;
+  *distortion = 0;
+  for (i = 0; i < 4; i++) {
+    if (labels[i] == which_label) {
+      const int src_stride = x->plane[0].src.stride;
+      uint8_t* const src =
+      raster_block_offset_uint8(xd, BLOCK_SIZE_SB8X8, 0, i,
+                                x->plane[0].src.buf, src_stride);
+      int16_t* const src_diff =
+      raster_block_offset_int16(xd, BLOCK_SIZE_SB8X8, 0, i,
+                                x->plane[0].src_diff);
+      int16_t* const coeff = BLOCK_OFFSET(x->plane[0].coeff, 16, i);
+      uint8_t* const pre =
+      raster_block_offset_uint8(xd, BLOCK_SIZE_SB8X8, 0, i,
+                                xd->plane[0].pre[0].buf,
+                                xd->plane[0].pre[0].stride);
+      uint8_t* const dst =
+      raster_block_offset_uint8(xd, BLOCK_SIZE_SB8X8, 0, i,
+                                xd->plane[0].dst.buf,
+                                xd->plane[0].dst.stride);
+      int thisdistortion;
+
+      vp9_build_inter_predictor(pre,
+                                xd->plane[0].pre[0].stride,
+                                dst,
+                                xd->plane[0].dst.stride,
+                                &xd->mode_info_context->bmi[i].as_mv[0],
+                                &xd->scale_factor[0],
+                                4, 4, 0 /* no avg */, &xd->subpix);
+
+      // TODO(debargha): Make this work properly with the
+      // implicit-compoundinter-weight experiment when implicit
+      // weighting for splitmv modes is turned on.
+      if (xd->mode_info_context->mbmi.second_ref_frame > 0) {
+        uint8_t* const second_pre =
+        raster_block_offset_uint8(xd, BLOCK_SIZE_SB8X8, 0, i,
+                                  xd->plane[0].pre[1].buf,
+                                  xd->plane[0].pre[1].stride);
+        vp9_build_inter_predictor(second_pre, xd->plane[0].pre[1].stride,
+                                  dst, xd->plane[0].dst.stride,
+                                  &xd->mode_info_context->bmi[i].as_mv[1],
+                                  &xd->scale_factor[1], 4, 4, 1,
+                                  &xd->subpix);
+      }
+
+      vp9_subtract_block(4, 4, src_diff, 8,
+                         src, src_stride,
+                         dst, xd->plane[0].dst.stride);
+      x->fwd_txm4x4(src_diff, coeff, 16);
+      x->quantize_b_4x4(x, i, DCT_DCT, 16);
+      thisdistortion = vp9_block_error(coeff,
+                                       BLOCK_OFFSET(xd->plane[0].dqcoeff,
+                                                    i, 16), 16);
+      *distortion += thisdistortion;
+      *labelyrate += cost_coeffs(cm, x, i, PLANE_TYPE_Y_WITH_DC,
+                                 ta + (i & 1),
+                                 tl + (i >> 1), TX_4X4, 16);
+    }
+  }
+  *distortion >>= 2;
+  return RDCOST(x->rdmult, x->rddiv, *labelyrate, *distortion);
+}
+
+typedef struct {
+  int_mv *ref_mv, *second_ref_mv;
+  int_mv mvp;
+
+  int64_t segment_rd;
+  int r;
+  int d;
+  int segment_yrate;
+  B_PREDICTION_MODE modes[4];
+  int_mv mvs[4], second_mvs[4];
+  int eobs[4];
+
+  int mvthresh;
+  int *mdcounts;
+} BEST_SEG_INFO;
+#endif  // CONFIG_SB8X8
+
+static INLINE int mv_check_bounds(MACROBLOCK *x, int_mv *mv) {
+  int r = 0;
+  r |= (mv->as_mv.row >> 3) < x->mv_row_min;
+  r |= (mv->as_mv.row >> 3) > x->mv_row_max;
+  r |= (mv->as_mv.col >> 3) < x->mv_col_min;
+  r |= (mv->as_mv.col >> 3) > x->mv_col_max;
+  return r;
+}
+
+#if CONFIG_SB8X8
+static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x,
+                                    BEST_SEG_INFO *bsi,
+                                    int_mv seg_mvs[4][MAX_REF_FRAMES - 1]) {
+  int i, j;
+  static const int labels[4] = { 0, 1, 2, 3 };
+  int br = 0, bd = 0;
+  B_PREDICTION_MODE this_mode;
+  MB_MODE_INFO * mbmi = &x->e_mbd.mode_info_context->mbmi;
+  const int label_count = 4;
+  int64_t this_segment_rd = 0, other_segment_rd;
+  int label_mv_thresh;
+  int rate = 0;
+  int sbr = 0, sbd = 0;
+  int segmentyrate = 0;
+  int best_eobs[4] = { 0 };
+
+  vp9_variance_fn_ptr_t *v_fn_ptr;
+
+  ENTROPY_CONTEXT t_above[2], t_left[2];
+  ENTROPY_CONTEXT t_above_b[2], t_left_b[2];
+
+  vpx_memcpy(t_above, x->e_mbd.plane[0].above_context, sizeof(t_above));
+  vpx_memcpy(t_left, x->e_mbd.plane[0].left_context, sizeof(t_left));
+
+  v_fn_ptr = &cpi->fn_ptr[BLOCK_4X4];
+
+  // 64 makes this threshold really big effectively
+  // making it so that we very rarely check mvs on
+  // segments.   setting this to 1 would make mv thresh
+  // roughly equal to what it is for macroblocks
+  label_mv_thresh = 1 * bsi->mvthresh / label_count;
+
+  // Segmentation method overheads
+  rate += vp9_cost_mv_ref(cpi, SPLITMV,
+                          mbmi->mb_mode_context[mbmi->ref_frame]);
+  this_segment_rd += RDCOST(x->rdmult, x->rddiv, rate, 0);
+  br += rate;
+  other_segment_rd = this_segment_rd;
+
+  for (i = 0; i < label_count && this_segment_rd < bsi->segment_rd; i++) {
+    int_mv mode_mv[B_MODE_COUNT], second_mode_mv[B_MODE_COUNT];
+    int64_t best_label_rd = INT64_MAX, best_other_rd = INT64_MAX;
+    B_PREDICTION_MODE mode_selected = ZERO4X4;
+    int bestlabelyrate = 0;
+
+    // search for the best motion vector on this segment
+    for (this_mode = LEFT4X4; this_mode <= NEW4X4; this_mode ++) {
+      int64_t this_rd;
+      int distortion;
+      int labelyrate;
+      ENTROPY_CONTEXT t_above_s[2], t_left_s[2];
+
+      vpx_memcpy(t_above_s, t_above, sizeof(t_above_s));
+      vpx_memcpy(t_left_s, t_left, sizeof(t_left_s));
+
+      // motion search for newmv (single predictor case only)
+      if (mbmi->second_ref_frame <= 0 && this_mode == NEW4X4) {
+        int sseshift, n;
+        int step_param = 0;
+        int further_steps;
+        int thissme, bestsme = INT_MAX;
+        const struct buf_2d orig_src = x->plane[0].src;
+        const struct buf_2d orig_pre = x->e_mbd.plane[0].pre[0];
+
+        /* Is the best so far sufficiently good that we cant justify doing
+         * and new motion search. */
+        if (best_label_rd < label_mv_thresh)
+          break;
+
+        if (cpi->compressor_speed) {
+          // use previous block's result as next block's MV predictor.
+          if (i > 0) {
+            bsi->mvp.as_int =
+            x->e_mbd.mode_info_context->bmi[i - 1].as_mv[0].as_int;
+            if (i == 2)
+              bsi->mvp.as_int =
+              x->e_mbd.mode_info_context->bmi[i - 2].as_mv[0].as_int;
+            step_param = 2;
+          }
+        }
+
+        further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param;
+
+        {
+          int sadpb = x->sadperbit4;
+          int_mv mvp_full;
+
+          mvp_full.as_mv.row = bsi->mvp.as_mv.row >> 3;
+          mvp_full.as_mv.col = bsi->mvp.as_mv.col >> 3;
+
+          // find first label
+          n = i;
+
+          // adjust src pointer for this segment
+          x->plane[0].src.buf =
+          raster_block_offset_uint8(&x->e_mbd, BLOCK_SIZE_SB8X8, 0, n,
+                                    x->plane[0].src.buf,
+                                    x->plane[0].src.stride);
+          assert(((intptr_t)x->e_mbd.plane[0].pre[0].buf & 0xf) == 0);
+          x->e_mbd.plane[0].pre[0].buf =
+          raster_block_offset_uint8(&x->e_mbd, BLOCK_SIZE_SB8X8, 0, n,
+                                    x->e_mbd.plane[0].pre[0].buf,
+                                    x->e_mbd.plane[0].pre[0].stride);
+
+          bestsme = vp9_full_pixel_diamond(cpi, x, &mvp_full, step_param,
+                                           sadpb, further_steps, 0, v_fn_ptr,
+                                           bsi->ref_mv, &mode_mv[NEW4X4]);
+
+          sseshift = 0;
+
+          // Should we do a full search (best quality only)
+          if ((cpi->compressor_speed == 0) && (bestsme >> sseshift) > 4000) {
+            /* Check if mvp_full is within the range. */
+            clamp_mv(&mvp_full, x->mv_col_min, x->mv_col_max,
+                     x->mv_row_min, x->mv_row_max);
+
+            thissme = cpi->full_search_sad(x, &mvp_full,
+                                           sadpb, 16, v_fn_ptr,
+                                           x->nmvjointcost, x->mvcost,
+                                           bsi->ref_mv,
+                                           n);
+
+            if (thissme < bestsme) {
+              bestsme = thissme;
+              mode_mv[NEW4X4].as_int =
+              x->e_mbd.mode_info_context->bmi[n].as_mv[0].as_int;
+            } else {
+              /* The full search result is actually worse so re-instate the
+               * previous best vector */
+              x->e_mbd.mode_info_context->bmi[n].as_mv[0].as_int =
+              mode_mv[NEW4X4].as_int;
+            }
+          }
+        }
+
+        if (bestsme < INT_MAX) {
+          int distortion;
+          unsigned int sse;
+          cpi->find_fractional_mv_step(x, &mode_mv[NEW4X4],
+                                       bsi->ref_mv, x->errorperbit, v_fn_ptr,
+                                       x->nmvjointcost, x->mvcost,
+                                       &distortion, &sse);
+
+          // safe motion search result for use in compound prediction
+          seg_mvs[i][mbmi->ref_frame - 1].as_int = mode_mv[NEW4X4].as_int;
+        }
+
+        // restore src pointers
+        x->plane[0].src = orig_src;
+        x->e_mbd.plane[0].pre[0] = orig_pre;
+      } else if (mbmi->second_ref_frame > 0 && this_mode == NEW4X4) {
+        /* NEW4X4 */
+        /* motion search not completed? Then skip newmv for this block with
+         * comppred */
+        if (seg_mvs[i][mbmi->second_ref_frame - 1].as_int == INVALID_MV ||
+            seg_mvs[i][mbmi->ref_frame        - 1].as_int == INVALID_MV) {
+          continue;
+        }
+      }
+
+      rate = labels2mode(x, labels, i, this_mode, &mode_mv[this_mode],
+                         &second_mode_mv[this_mode], seg_mvs[i],
+                         bsi->ref_mv, bsi->second_ref_mv, x->nmvjointcost,
+                         x->mvcost, cpi);
+
+      // Trap vectors that reach beyond the UMV borders
+      if (((mode_mv[this_mode].as_mv.row >> 3) < x->mv_row_min) ||
+          ((mode_mv[this_mode].as_mv.row >> 3) > x->mv_row_max) ||
+          ((mode_mv[this_mode].as_mv.col >> 3) < x->mv_col_min) ||
+          ((mode_mv[this_mode].as_mv.col >> 3) > x->mv_col_max)) {
+        continue;
+      }
+      if (mbmi->second_ref_frame > 0 &&
+          mv_check_bounds(x, &second_mode_mv[this_mode]))
+        continue;
+
+      this_rd = encode_inter_mb_segment(&cpi->common,
+                                        x, labels, i, &labelyrate,
+                                        &distortion, t_above_s, t_left_s);
+      this_rd += RDCOST(x->rdmult, x->rddiv, rate, 0);
+      rate += labelyrate;
+
+      if (this_rd < best_label_rd) {
+        sbr = rate;
+        sbd = distortion;
+        bestlabelyrate = labelyrate;
+        mode_selected = this_mode;
+        best_label_rd = this_rd;
+        for (j = 0; j < 4; j++)
+          if (labels[j] == i)
+            best_eobs[j] = x->e_mbd.plane[0].eobs[j];
+
+        vpx_memcpy(t_above_b, t_above_s, sizeof(t_above_s));
+        vpx_memcpy(t_left_b, t_left_s, sizeof(t_left_s));
+      }
+    } /*for each 4x4 mode*/
+
+    vpx_memcpy(t_above, t_above_b, sizeof(t_above));
+    vpx_memcpy(t_left, t_left_b, sizeof(t_left));
+
+    labels2mode(x, labels, i, mode_selected, &mode_mv[mode_selected],
+                &second_mode_mv[mode_selected], seg_mvs[i],
+                bsi->ref_mv, bsi->second_ref_mv, x->nmvjointcost,
+                x->mvcost, cpi);
+
+    br += sbr;
+    bd += sbd;
+    segmentyrate += bestlabelyrate;
+    this_segment_rd += best_label_rd;
+    other_segment_rd += best_other_rd;
+  } /* for each label */
+
+  if (this_segment_rd < bsi->segment_rd) {
+    bsi->r = br;
+    bsi->d = bd;
+    bsi->segment_yrate = segmentyrate;
+    bsi->segment_rd = this_segment_rd;
+
+    // store everything needed to come back to this!!
+    for (i = 0; i < 4; i++) {
+      bsi->mvs[i].as_mv = x->partition_info->bmi[i].mv.as_mv;
+      if (mbmi->second_ref_frame > 0)
+        bsi->second_mvs[i].as_mv = x->partition_info->bmi[i].second_mv.as_mv;
+      bsi->modes[i] = x->partition_info->bmi[i].mode;
+      bsi->eobs[i] = best_eobs[i];
+    }
   }
-
-  return cost;
 }
-#undef UVCTX
-
-static void super_block_uvrd_32x32(VP9_COMMON *const cm, MACROBLOCK *x,
-                                   int *rate, int *distortion, int *skip,
-                                   BLOCK_SIZE_TYPE bsize) {
-  MACROBLOCKD *const xd = &x->e_mbd;
 
-  vp9_transform_sbuv_32x32(x, bsize);
-  vp9_quantize_sbuv_32x32(x, bsize);
-
-  *rate       = rd_cost_sbuv_32x32(cm, x, bsize);
-  *distortion = block_error_sbuv(x, bsize, 0);
-  *skip       = vp9_sbuv_is_skippable(xd, bsize);
+static void rd_check_segment(VP9_COMP *cpi, MACROBLOCK *x,
+                             BEST_SEG_INFO *bsi,
+                             int_mv seg_mvs[4][MAX_REF_FRAMES - 1]) {
+  rd_check_segment_txsize(cpi, x, bsi, seg_mvs);
 }
 
-static void super_block_uvrd(VP9_COMMON *const cm, MACROBLOCK *x,
-                             int *rate, int *distortion, int *skippable,
-                             BLOCK_SIZE_TYPE bsize) {
-  MACROBLOCKD *const xd = &x->e_mbd;
-  MB_MODE_INFO *const mbmi = &xd->mode_info_context->mbmi;
-
-  vp9_subtract_sbuv(x, bsize);
+static int rd_pick_best_mbsegmentation(VP9_COMP *cpi, MACROBLOCK *x,
+                                       int_mv *best_ref_mv,
+                                       int_mv *second_best_ref_mv,
+                                       int64_t best_rd,
+                                       int *mdcounts,
+                                       int *returntotrate,
+                                       int *returnyrate,
+                                       int *returndistortion,
+                                       int *skippable, int mvthresh,
+                                       int_mv seg_mvs[4][MAX_REF_FRAMES - 1]) {
+  int i;
+  BEST_SEG_INFO bsi;
+  MB_MODE_INFO * mbmi = &x->e_mbd.mode_info_context->mbmi;
 
-  if (mbmi->txfm_size >= TX_32X32 && bsize >= BLOCK_SIZE_SB64X64) {
-    super_block_uvrd_32x32(cm, x, rate, distortion, skippable, bsize);
-  } else if (mbmi->txfm_size >= TX_16X16 && bsize >= BLOCK_SIZE_SB32X32) {
-    super_block_uvrd_16x16(cm, x, rate, distortion, skippable, bsize);
-  } else if (mbmi->txfm_size >= TX_8X8) {
-    super_block_uvrd_8x8(cm, x, rate, distortion, skippable, bsize);
-  } else {
-    assert(mbmi->txfm_size == TX_4X4);
-    super_block_uvrd_4x4(cm, x, rate, distortion, skippable, bsize);
-  }
-}
+  vpx_memset(&bsi, 0, sizeof(bsi));
 
-static int64_t rd_pick_intra_sbuv_mode(VP9_COMP *cpi, MACROBLOCK *x,
-                                       int *rate, int *rate_tokenonly,
-                                       int *distortion, int *skippable,
-                                       BLOCK_SIZE_TYPE bsize) {
-  MB_PREDICTION_MODE mode;
-  MB_PREDICTION_MODE UNINITIALIZED_IS_SAFE(mode_selected);
-  int64_t best_rd = INT64_MAX, this_rd;
-  int this_rate_tokenonly, this_rate;
-  int this_distortion, s;
+  bsi.segment_rd = best_rd;
+  bsi.ref_mv = best_ref_mv;
+  bsi.second_ref_mv = second_best_ref_mv;
+  bsi.mvp.as_int = best_ref_mv->as_int;
+  bsi.mvthresh = mvthresh;
+  bsi.mdcounts = mdcounts;
 
-  for (mode = DC_PRED; mode <= TM_PRED; mode++) {
-    x->e_mbd.mode_info_context->mbmi.uv_mode = mode;
-    vp9_build_intra_predictors_sbuv_s(&x->e_mbd, bsize);
+  for (i = 0; i < 4; i++)
+    bsi.modes[i] = ZERO4X4;
 
-    super_block_uvrd(&cpi->common, x, &this_rate_tokenonly,
-                     &this_distortion, &s, bsize);
-    this_rate = this_rate_tokenonly +
-                x->intra_uv_mode_cost[x->e_mbd.frame_type][mode];
-    this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
+  rd_check_segment(cpi, x, &bsi, seg_mvs);
 
-    if (this_rd < best_rd) {
-      mode_selected   = mode;
-      best_rd         = this_rd;
-      *rate           = this_rate;
-      *rate_tokenonly = this_rate_tokenonly;
-      *distortion     = this_distortion;
-      *skippable      = s;
-    }
+  /* set it to the best */
+  for (i = 0; i < 4; i++) {
+    x->e_mbd.mode_info_context->bmi[i].as_mv[0].as_int = bsi.mvs[i].as_int;
+    if (mbmi->second_ref_frame > 0)
+      x->e_mbd.mode_info_context->bmi[i].as_mv[1].as_int =
+      bsi.second_mvs[i].as_int;
+    x->e_mbd.plane[0].eobs[i] = bsi.eobs[i];
   }
 
-  x->e_mbd.mode_info_context->mbmi.uv_mode = mode_selected;
-
-  return best_rd;
-}
+  /* save partitions */
+  x->partition_info->count = 4;
 
-int vp9_cost_mv_ref(VP9_COMP *cpi,
-                    MB_PREDICTION_MODE m,
-                    const int mode_context) {
-  MACROBLOCKD *xd = &cpi->mb.e_mbd;
-  int segment_id = xd->mode_info_context->mbmi.segment_id;
+  for (i = 0; i < x->partition_info->count; i++) {
+    x->partition_info->bmi[i].mode = bsi.modes[i];
+    x->partition_info->bmi[i].mv.as_mv = bsi.mvs[i].as_mv;
+    if (mbmi->second_ref_frame > 0)
+      x->partition_info->bmi[i].second_mv.as_mv = bsi.second_mvs[i].as_mv;
+  }
+  /*
+   * used to set mbmi->mv.as_int
+   */
+  x->partition_info->bmi[3].mv.as_int = bsi.mvs[3].as_int;
+  if (mbmi->second_ref_frame > 0)
+    x->partition_info->bmi[3].second_mv.as_int = bsi.second_mvs[3].as_int;
 
-  // Dont account for mode here if segment skip is enabled.
-  if (!vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)) {
-    VP9_COMMON *pc = &cpi->common;
+  *returntotrate = bsi.r;
+  *returndistortion = bsi.d;
+  *returnyrate = bsi.segment_yrate;
+  *skippable = vp9_sby_is_skippable(&x->e_mbd, BLOCK_SIZE_SB8X8);
 
-    vp9_prob p [VP9_MVREFS - 1];
-    assert(NEARESTMV <= m  &&  m <= SPLITMV);
-    vp9_mv_ref_probs(pc, p, mode_context);
-    return cost_token(vp9_mv_ref_tree, p,
-                      vp9_mv_ref_encoding_array - NEARESTMV + m);
-  } else
-    return 0;
+  return (int)(bsi.segment_rd);
 }
 
-void vp9_set_mbmode_and_mvs(MACROBLOCK *x, MB_PREDICTION_MODE mb, int_mv *mv) {
-  x->e_mbd.mode_info_context->mbmi.mode = mb;
-  x->e_mbd.mode_info_context->mbmi.mv[0].as_int = mv->as_int;
-}
+#else  // !CONFIG_SB8X8
 
 static int labels2mode(
   MACROBLOCK *x,
@@ -1887,15 +2437,6 @@ typedef struct {
 
 } BEST_SEG_INFO;
 
-static INLINE int mv_check_bounds(MACROBLOCK *x, int_mv *mv) {
-  int r = 0;
-  r |= (mv->as_mv.row >> 3) < x->mv_row_min;
-  r |= (mv->as_mv.row >> 3) > x->mv_row_max;
-  r |= (mv->as_mv.col >> 3) < x->mv_col_min;
-  r |= (mv->as_mv.col >> 3) > x->mv_col_max;
-  return r;
-}
-
 static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x,
                                     BEST_SEG_INFO *bsi,
                                     SPLITMV_PARTITIONING_TYPE segmentation,
@@ -2428,6 +2969,7 @@ static int rd_pick_best_mbsegmentation(VP9_COMP *cpi, MACROBLOCK *x,
 
   return (int)(bsi.segment_rd);
 }
+#endif  // !CONFIG_SB8X8
 
 static void mv_pred(VP9_COMP *cpi, MACROBLOCK *x,
                     uint8_t *ref_y_buffer, int ref_y_stride,
@@ -2474,6 +3016,7 @@ static void mv_pred(VP9_COMP *cpi, MACROBLOCK *x,
   x->mv_best_ref_index[ref_frame] = best_index;
 }
 
+#if !CONFIG_SB8X8
 static void set_i8x8_block_modes(MACROBLOCK *x, int modes[4]) {
   int i;
   MACROBLOCKD *xd = &x->e_mbd;
@@ -2487,6 +3030,7 @@ static void set_i8x8_block_modes(MACROBLOCK *x, int modes[4]) {
     //       modes[0], modes[1], modes[2], modes[3]);
   }
 }
+#endif
 
 extern void vp9_calc_ref_probs(int *count, vp9_prob *probs);
 static void estimate_curframe_refprobs(VP9_COMP *cpi, vp9_prob mod_refprobs[3], int pred_ref) {
@@ -3193,6 +3737,7 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
   return this_rd;  // if 0, this will be re-calculated by caller
 }
 
+#if !CONFIG_SB8X8
 static void rd_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
                                int mi_row, int mi_col,
                                int *returnrate, int *returndistortion,
@@ -4053,6 +4598,7 @@ end:
                                       mbmi->second_ref_frame][0],
                        best_pred_diff, best_txfm_diff);
 }
+#endif  // !CONFIG_SB8X8
 
 void vp9_rd_pick_intra_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
                                int *returnrate, int *returndist,
@@ -4065,14 +4611,30 @@ void vp9_rd_pick_intra_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
   int dist_y = 0, dist_uv;
   int y_skip = 0, uv_skip;
   int64_t txfm_cache[NB_TXFM_MODES], err;
+#if CONFIG_SB8X8
+  MB_PREDICTION_MODE mode;
+  TX_SIZE txfm_size;
+  int rate4x4_y, rate4x4_y_tokenonly, dist4x4_y;
+  int64_t err4x4 = INT64_MAX;
+#endif
   int i;
 
   ctx->skip = 0;
   xd->mode_info_context->mbmi.mode = DC_PRED;
   err = rd_pick_intra_sby_mode(cpi, x, &rate_y, &rate_y_tokenonly,
                                &dist_y, &y_skip, bsize, txfm_cache);
+#if CONFIG_SB8X8
+  mode = xd->mode_info_context->mbmi.mode;
+  txfm_size = xd->mode_info_context->mbmi.txfm_size;
+#endif
   rd_pick_intra_sbuv_mode(cpi, x, &rate_uv, &rate_uv_tokenonly,
                           &dist_uv, &uv_skip, bsize);
+#if CONFIG_SB8X8
+  if (bsize == BLOCK_SIZE_SB8X8)
+    err4x4 = rd_pick_intra4x4mby_modes(cpi, x, &rate4x4_y,
+                                       &rate4x4_y_tokenonly,
+                                       &dist4x4_y, err);
+#endif
 
   if (y_skip && uv_skip) {
     *returnrate = rate_y + rate_uv - rate_y_tokenonly - rate_uv_tokenonly +
@@ -4080,18 +4642,39 @@ void vp9_rd_pick_intra_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
     *returndist = dist_y + (dist_uv >> 2);
     memset(ctx->txfm_rd_diff, 0,
            sizeof(x->sb32_context[xd->sb_index].txfm_rd_diff));
+#if CONFIG_SB8X8
+    xd->mode_info_context->mbmi.mode = mode;
+    xd->mode_info_context->mbmi.txfm_size = txfm_size;
+  } else if (bsize == BLOCK_SIZE_SB8X8 && err4x4 < err) {
+    *returnrate = rate4x4_y + rate_uv +
+        vp9_cost_bit(vp9_get_pred_prob(cm, xd, PRED_MBSKIP), 0);
+    *returndist = dist4x4_y + (dist_uv >> 2);
+    for (i = 0; i < NB_TXFM_MODES; i++) {
+      ctx->txfm_rd_diff[i] = MIN(err4x4, err - txfm_cache[i]);
+    }
+    xd->mode_info_context->mbmi.txfm_size = TX_4X4;
+#endif
   } else {
     *returnrate = rate_y + rate_uv +
         vp9_cost_bit(vp9_get_pred_prob(cm, xd, PRED_MBSKIP), 0);
     *returndist = dist_y + (dist_uv >> 2);
     for (i = 0; i < NB_TXFM_MODES; i++) {
+#if CONFIG_SB8X8
+      ctx->txfm_rd_diff[i] = MIN(err4x4, err - txfm_cache[i]);
+#else
       ctx->txfm_rd_diff[i] = err - txfm_cache[i];
+#endif
     }
+#if CONFIG_SB8X8
+    xd->mode_info_context->mbmi.txfm_size = txfm_size;
+    xd->mode_info_context->mbmi.mode = mode;
+#endif
   }
 
   vpx_memcpy(&ctx->mic, xd->mode_info_context, sizeof(MODE_INFO));
 }
 
+#if !CONFIG_SB8X8
 void vp9_rd_pick_intra_mode(VP9_COMP *cpi, MACROBLOCK *x,
                             int *returnrate, int *returndist) {
   VP9_COMMON *cm = &cpi->common;
@@ -4218,6 +4801,7 @@ void vp9_rd_pick_intra_mode(VP9_COMP *cpi, MACROBLOCK *x,
   *returnrate = rate;
   *returndist = dist;
 }
+#endif
 
 int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
                                   int mi_row, int mi_col,
@@ -4272,7 +4856,20 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
   unsigned int mode_mask = 0;
   int64_t mode_distortions[MB_MODE_COUNT] = {-1};
   int64_t frame_distortions[MAX_REF_FRAMES] = {-1};
+  int intra_cost_penalty = 20 * vp9_dc_quant(cpi->common.base_qindex,
+                                             cpi->common.y_dc_delta_q);
+#if CONFIG_SB8X8
+  int_mv seg_mvs[4][MAX_REF_FRAMES - 1];
+#endif
 
+#if CONFIG_SB8X8
+  for (i = 0; i < 4; i++) {
+    int j;
+
+    for (j = 0; j < MAX_REF_FRAMES - 1; j++)
+      seg_mvs[i][j].as_int = INVALID_MV;
+  }
+#endif
   // Everywhere the flag is set the error is much higher than its neighbors.
   ctx->frames_with_high_error = 0;
   ctx->modes_with_high_error = 0;
@@ -4400,9 +4997,16 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
     // if (!(cpi->ref_frame_flags & flag_list[ref_frame]))
     //  continue;
 
-    if (this_mode == I8X8_PRED ||
+    if (
+#if CONFIG_SB8X8
+        bsize != BLOCK_SIZE_SB8X8 &&
+        (this_mode == I4X4_PRED || this_mode == SPLITMV)
+#else
         this_mode == I4X4_PRED ||
-        this_mode == SPLITMV)
+        this_mode == I8X8_PRED ||
+        this_mode == SPLITMV
+#endif
+        )
       continue;
     //  if (vp9_mode_order[mode_index].second_ref_frame == INTRA_FRAME)
     //  continue;
@@ -4465,6 +5069,27 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
       }
     }
 
+#if CONFIG_SB8X8
+    if (this_mode == I4X4_PRED) {
+      int rate;
+
+      // Note the rate value returned here includes the cost of coding
+      // the I4X4_PRED mode : x->mbmode_cost[xd->frame_type][I4X4_PRED];
+      assert(bsize == BLOCK_SIZE_SB8X8);
+      mbmi->txfm_size = TX_4X4;
+      rd_pick_intra4x4mby_modes(cpi, x, &rate, &rate_y,
+                                &distortion_y, INT64_MAX);
+      rate2 += rate;
+      rate2 += intra_cost_penalty;
+      distortion2 += distortion_y;
+
+      rate2 += rate_uv_intra[TX_4X4];
+      rate_uv = rate_uv_intra[TX_4X4];
+      distortion2 += dist_uv[TX_4X4];
+      distortion_uv = dist_uv[TX_4X4];
+      mbmi->uv_mode = mode_uv[TX_4X4];
+    } else
+#endif
     if (ref_frame == INTRA_FRAME) {
       TX_SIZE uv_tx;
       vp9_build_intra_predictors_sby_s(xd, bsize);
@@ -4483,7 +5108,139 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
       mbmi->uv_mode = mode_uv[uv_tx];
 
       rate2 = rate_y + x->mbmode_cost[cm->frame_type][mbmi->mode] + rate_uv;
+      if (mbmi->mode != DC_PRED && mbmi->mode != TM_PRED)
+        rate2 += intra_cost_penalty;
       distortion2 = distortion_y + distortion_uv;
+#if CONFIG_SB8X8
+    } else if (this_mode == SPLITMV) {
+      const int is_comp_pred = mbmi->second_ref_frame > 0;
+      int rate, distortion;
+      int64_t this_rd_thresh;
+      int64_t tmp_rd, tmp_best_rd = INT64_MAX, tmp_best_rdu = INT64_MAX;
+      int tmp_best_rate = INT_MAX, tmp_best_ratey = INT_MAX;
+      int tmp_best_distortion = INT_MAX, tmp_best_skippable = 0;
+      int switchable_filter_index;
+      int_mv *second_ref = is_comp_pred ?
+          &mbmi->ref_mvs[mbmi->second_ref_frame][0] : NULL;
+      union b_mode_info tmp_best_bmodes[16];
+      MB_MODE_INFO tmp_best_mbmode;
+      PARTITION_INFO tmp_best_partition;
+      int pred_exists = 0;
+      int uv_skippable;
+
+      this_rd_thresh = (mbmi->ref_frame == LAST_FRAME) ?
+          cpi->rd_threshes[THR_NEWMV] : cpi->rd_threshes[THR_NEWA];
+      this_rd_thresh = (mbmi->ref_frame == GOLDEN_FRAME) ?
+          cpi->rd_threshes[THR_NEWG] : this_rd_thresh;
+      xd->mode_info_context->mbmi.txfm_size = TX_4X4;
+
+      for (switchable_filter_index = 0;
+           switchable_filter_index < VP9_SWITCHABLE_FILTERS;
+           ++switchable_filter_index) {
+        int newbest;
+        mbmi->interp_filter =
+        vp9_switchable_interp[switchable_filter_index];
+        vp9_setup_interp_filters(xd, mbmi->interp_filter, &cpi->common);
+
+        tmp_rd = rd_pick_best_mbsegmentation(cpi, x,
+                                             &mbmi->ref_mvs[mbmi->ref_frame][0],
+                                             second_ref, INT64_MAX, mdcounts,
+                                             &rate, &rate_y, &distortion,
+                                             &skippable,
+                                             (int)this_rd_thresh, seg_mvs);
+        if (cpi->common.mcomp_filter_type == SWITCHABLE) {
+          int rs = SWITCHABLE_INTERP_RATE_FACTOR * x->switchable_interp_costs
+          [vp9_get_pred_context(&cpi->common, xd,
+                                PRED_SWITCHABLE_INTERP)]
+          [vp9_switchable_interp_map[mbmi->interp_filter]];
+          tmp_rd += RDCOST(x->rdmult, x->rddiv, rs, 0);
+        }
+        newbest = (tmp_rd < tmp_best_rd);
+        if (newbest) {
+          tmp_best_filter = mbmi->interp_filter;
+          tmp_best_rd = tmp_rd;
+        }
+        if ((newbest && cm->mcomp_filter_type == SWITCHABLE) ||
+            (mbmi->interp_filter == cm->mcomp_filter_type &&
+             cm->mcomp_filter_type != SWITCHABLE)) {
+              tmp_best_rdu = tmp_rd;
+              tmp_best_rate = rate;
+              tmp_best_ratey = rate_y;
+              tmp_best_distortion = distortion;
+              tmp_best_skippable = skippable;
+              vpx_memcpy(&tmp_best_mbmode, mbmi, sizeof(MB_MODE_INFO));
+              vpx_memcpy(&tmp_best_partition, x->partition_info,
+                         sizeof(PARTITION_INFO));
+              for (i = 0; i < 4; i++) {
+                tmp_best_bmodes[i] = xd->mode_info_context->bmi[i];
+              }
+              pred_exists = 1;
+            }
+      }  // switchable_filter_index loop
+
+      mbmi->interp_filter = (cm->mcomp_filter_type == SWITCHABLE ?
+                             tmp_best_filter : cm->mcomp_filter_type);
+      vp9_setup_interp_filters(xd, mbmi->interp_filter, &cpi->common);
+      if (!pred_exists) {
+        // Handles the special case when a filter that is not in the
+        // switchable list (bilinear, 6-tap) is indicated at the frame level
+        tmp_rd = rd_pick_best_mbsegmentation(cpi, x,
+                                             &mbmi->ref_mvs[mbmi->ref_frame][0],
+                                             second_ref, INT64_MAX, mdcounts,
+                                             &rate, &rate_y, &distortion,
+                                             &skippable,
+                                             (int)this_rd_thresh, seg_mvs);
+      } else {
+        if (cpi->common.mcomp_filter_type == SWITCHABLE) {
+          int rs = SWITCHABLE_INTERP_RATE_FACTOR * x->switchable_interp_costs
+              [vp9_get_pred_context(&cpi->common, xd,
+                                    PRED_SWITCHABLE_INTERP)]
+              [vp9_switchable_interp_map[mbmi->interp_filter]];
+          tmp_best_rdu -= RDCOST(x->rdmult, x->rddiv, rs, 0);
+        }
+        tmp_rd = tmp_best_rdu;
+        rate = tmp_best_rate;
+        rate_y = tmp_best_ratey;
+        distortion = tmp_best_distortion;
+        skippable = tmp_best_skippable;
+        vpx_memcpy(mbmi, &tmp_best_mbmode, sizeof(MB_MODE_INFO));
+        vpx_memcpy(x->partition_info, &tmp_best_partition,
+                   sizeof(PARTITION_INFO));
+        for (i = 0; i < 4; i++) {
+          xd->mode_info_context->bmi[i] = tmp_best_bmodes[i];
+        }
+      }
+
+      rate2 += rate;
+      distortion2 += distortion;
+
+      if (cpi->common.mcomp_filter_type == SWITCHABLE)
+        rate2 += SWITCHABLE_INTERP_RATE_FACTOR * x->switchable_interp_costs
+            [vp9_get_pred_context(&cpi->common, xd, PRED_SWITCHABLE_INTERP)]
+            [vp9_switchable_interp_map[mbmi->interp_filter]];
+
+      // If even the 'Y' rd value of split is higher than best so far
+      // then dont bother looking at UV
+      vp9_build_inter_predictors_sbuv(&x->e_mbd, mi_row, mi_col,
+                                      bsize);
+      vp9_subtract_sbuv(x, bsize);
+      super_block_uvrd_4x4(cm, x, &rate_uv, &distortion_uv,
+                           &uv_skippable, bsize);
+      rate2 += rate_uv;
+      distortion2 += distortion_uv;
+      skippable = skippable && uv_skippable;
+
+      if (!mode_excluded) {
+        if (is_comp_pred)
+          mode_excluded = cpi->common.comp_pred_mode == SINGLE_PREDICTION_ONLY;
+        else
+          mode_excluded = cpi->common.comp_pred_mode == COMP_PREDICTION_ONLY;
+      }
+
+      compmode_cost =
+          vp9_cost_bit(vp9_get_pred_prob(cm, xd, PRED_COMP), is_comp_pred);
+      mbmi->mode = this_mode;
+#endif
     } else {
       YV12_BUFFER_CONFIG *scaled_ref_frame = NULL;
       int fb;
@@ -4693,6 +5450,14 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
     }
 
     /* keep record of best txfm size */
+    if (bsize < BLOCK_SIZE_SB32X32) {
+      if (bsize < BLOCK_SIZE_MB16X16) {
+        if (this_mode == SPLITMV || this_mode == I4X4_PRED)
+          txfm_cache[ALLOW_8X8] = txfm_cache[ONLY_4X4];
+        txfm_cache[ALLOW_16X16] = txfm_cache[ALLOW_8X8];
+      }
+      txfm_cache[ALLOW_32X32] = txfm_cache[ALLOW_16X16];
+    }
     if (!mode_excluded && this_rd != INT64_MAX) {
       for (i = 0; i < NB_TXFM_MODES; i++) {
         int64_t adj_rd;
@@ -4769,13 +5534,27 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
       (best_mbmode.mode != ZEROMV || best_mbmode.ref_frame != ALTREF_FRAME)) {
     mbmi->mode = ZEROMV;
     mbmi->ref_frame = ALTREF_FRAME;
-    mbmi->second_ref_frame = INTRA_FRAME;
+    mbmi->second_ref_frame = NONE;
     mbmi->mv[0].as_int = 0;
     mbmi->uv_mode = DC_PRED;
     mbmi->mb_skip_coeff = 1;
+#if !CONFIG_SB8X8
     mbmi->partitioning = 0;
-    mbmi->txfm_size = cm->txfm_mode == TX_MODE_SELECT ?
-                      TX_32X32 : cm->txfm_mode;
+#endif
+    if (cm->txfm_mode == TX_MODE_SELECT) {
+      if (bsize >= BLOCK_SIZE_SB32X32)
+        mbmi->txfm_size = TX_32X32;
+#if CONFIG_SB8X8
+      else if (bsize >= BLOCK_SIZE_MB16X16)
+#else
+      else
+#endif
+        mbmi->txfm_size = TX_16X16;
+#if CONFIG_SB8X8
+      else
+        mbmi->txfm_size = TX_8X8;
+#endif
+    }
 
     vpx_memset(best_txfm_diff, 0, sizeof(best_txfm_diff));
     vpx_memset(best_pred_diff, 0, sizeof(best_pred_diff));
@@ -4815,6 +5594,7 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
   return best_rd;
 }
 
+#if !CONFIG_SB8X8
 void vp9_pick_mode_inter_macroblock(VP9_COMP *cpi, MACROBLOCK *x,
                                     int mi_row, int mi_col,
                                     int *totalrate, int *totaldist) {
@@ -4852,3 +5632,4 @@ void vp9_pick_mode_inter_macroblock(VP9_COMP *cpi, MACROBLOCK *x,
   *totalrate = rate;
   *totaldist = distortion;
 }
+#endif
index eef2a4f..6533a82 100644 (file)
@@ -19,16 +19,20 @@ void vp9_initialize_rd_consts(VP9_COMP *cpi, int qindex);
 
 void vp9_initialize_me_consts(VP9_COMP *cpi, int qindex);
 
+#if !CONFIG_SB8X8
 void vp9_rd_pick_intra_mode(VP9_COMP *cpi, MACROBLOCK *x,
                             int *r, int *d);
+#endif
 
 void vp9_rd_pick_intra_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
                                int *r, int *d, BLOCK_SIZE_TYPE bsize,
                                PICK_MODE_CONTEXT *ctx);
 
+#if !CONFIG_SB8X8
 void vp9_pick_mode_inter_macroblock(VP9_COMP *cpi, MACROBLOCK *x,
                                     int mi_row, int mi_col,
                                     int *r, int *d);
+#endif
 
 int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
                                   int mi_row, int mi_col,
index 7f792ae..fbe6c7f 100644 (file)
@@ -199,9 +199,17 @@ static void count_segs_sb(VP9_COMP *cpi, MODE_INFO *mi,
     assert(bwl < bsl && bhl < bsl);
     if (bsize == BLOCK_SIZE_SB64X64) {
       subsize = BLOCK_SIZE_SB32X32;
+#if CONFIG_SB8X8
+    } else if (bsize == BLOCK_SIZE_SB32X32) {
+      subsize = BLOCK_SIZE_MB16X16;
+    } else {
+      assert(bsize == BLOCK_SIZE_MB16X16);
+      subsize = BLOCK_SIZE_SB8X8;
+#else
     } else {
       assert(bsize == BLOCK_SIZE_SB32X32);
       subsize = BLOCK_SIZE_MB16X16;
+#endif
     }
 
     for (n = 0; n < 4; n++) {
index 3c33670..9756e6e 100644 (file)
@@ -376,7 +376,11 @@ int vp9_sb_is_skippable(MACROBLOCKD *xd, BLOCK_SIZE_TYPE bsize) {
 int vp9_sby_is_skippable(MACROBLOCKD *xd, BLOCK_SIZE_TYPE bsize) {
   int result = 1;
   struct is_skippable_args args = {xd, &result};
-  foreach_transformed_block_in_plane(xd, bsize, 0, 0, is_skippable, &args);
+  foreach_transformed_block_in_plane(xd, bsize, 0,
+#if !CONFIG_SB8X8
+                                     0,
+#endif
+                                     is_skippable, &args);
   return result;
 }