shithub: libvpx

Download patch

ref: 97096f5fa355a27cd7262bf05f05156e40090c03
parent: 7906ed091ab5d16a7fbdc21109a034644aa6b9a3
parent: f72fdf1c7f443b8b62559279e55b439b0814e58a
author: Ronald S. Bultje <rbultje@google.com>
date: Mon Oct 22 08:54:39 EDT 2012

Merge changes I02e7f64a,Ide954b00,Idc8b5977 into experimental

* changes:
  Fix another typo in 4x4-transform-for-i8x8-intra-pred coeff contexts.
  8x8 transform support in splitmv.
  Use SPLITMV_PARTITIONING instead of a plain integer type.

--- a/vp8/common/blockd.h
+++ b/vp8/common/blockd.h
@@ -175,6 +175,14 @@
 #define VP8_BINTRAMODES (B_HU_PRED + 1)  /* 10 */
 #define VP8_SUBMVREFS (1 + NEW4X4 - LEFT4X4)
 
+typedef enum {
+  PARTITIONING_16X8 = 0,
+  PARTITIONING_8X16,
+  PARTITIONING_8X8,
+  PARTITIONING_4X4,
+  NB_PARTITIONINGS,
+} SPLITMV_PARTITIONING_TYPE;
+
 /* 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
    is a single probability table. */
@@ -216,7 +224,7 @@
   int mv_ref_index[MAX_REF_FRAMES];
 #endif
 
-  unsigned char partitioning;
+  SPLITMV_PARTITIONING_TYPE partitioning;
   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;
--- a/vp8/common/entropymode.c
+++ b/vp8/common/entropymode.c
@@ -215,9 +215,9 @@
 };
 
 const vp8_tree_index vp8_mbsplit_tree[6] = {
-  -3, 2,
-  -2, 4,
-  -0, -1
+  -PARTITIONING_4X4,   2,
+  -PARTITIONING_8X8,   4,
+  -PARTITIONING_16X8, -PARTITIONING_8X16,
 };
 
 const vp8_tree_index vp8_mv_ref_tree[8] = {
--- a/vp8/common/postproc.c
+++ b/vp8/common/postproc.c
@@ -783,7 +783,7 @@
 
         if (mi->mbmi.mode == SPLITMV) {
           switch (mi->mbmi.partitioning) {
-            case 0 : {  /* mv_top_bottom */
+            case PARTITIONING_16X8 : {  /* mv_top_bottom */
               union b_mode_info *bmi = &mi->bmi[0];
               MV *mv = &bmi->mv.as_mv;
 
@@ -803,7 +803,7 @@
 
               break;
             }
-            case 1 : {  /* mv_left_right */
+            case PARTITIONING_8X16 : {  /* mv_left_right */
               union b_mode_info *bmi = &mi->bmi[0];
               MV *mv = &bmi->mv.as_mv;
 
@@ -823,7 +823,7 @@
 
               break;
             }
-            case 2 : {  /* mv_quarters   */
+            case PARTITIONING_8X8 : {  /* mv_quarters   */
               union b_mode_info *bmi = &mi->bmi[0];
               MV *mv = &bmi->mv.as_mv;
 
@@ -858,6 +858,7 @@
               vp8_blit_line(x0 + 12,  x1, y0 + 12,  y1, y_buffer, y_stride);
               break;
             }
+            case PARTITIONING_4X4:
             default : {
               union b_mode_info *bmi = mi->bmi;
               int bx0, by0;
--- a/vp8/common/reconinter.c
+++ b/vp8/common/reconinter.c
@@ -965,7 +965,7 @@
   MB_MODE_INFO * mbmi = &xd->mode_info_context->mbmi;
   BLOCKD *blockd = xd->block;
 
-  if (xd->mode_info_context->mbmi.partitioning < 3) {
+  if (xd->mode_info_context->mbmi.partitioning != PARTITIONING_4X4) {
     blockd[ 0].bmi = xd->mode_info_context->bmi[ 0];
     blockd[ 2].bmi = xd->mode_info_context->bmi[ 2];
     blockd[ 8].bmi = xd->mode_info_context->bmi[ 8];
--- a/vp8/decoder/decodemv.c
+++ b/vp8/decoder/decodemv.c
@@ -1285,10 +1285,12 @@
 #if CONFIG_TX_SELECT
   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->ref_frame != INTRA_FRAME && !(mbmi->mode == SPLITMV &&
+                           mbmi->partitioning == PARTITIONING_4X4)))) {
     // FIXME(rbultje) code ternary symbol once all experiments are merged
     mbmi->txfm_size = vp8_read(bc, cm->prob_tx[0]);
-    if (mbmi->txfm_size != TX_4X4 && mbmi->mode != I8X8_PRED)
+    if (mbmi->txfm_size != TX_4X4 && mbmi->mode != I8X8_PRED &&
+        mbmi->mode != SPLITMV)
       mbmi->txfm_size += vp8_read(bc, cm->prob_tx[1]);
   } else
 #endif
@@ -1297,8 +1299,9 @@
        (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 != B_PRED) ||
-       (mbmi->ref_frame != INTRA_FRAME && mbmi->mode != SPLITMV))) {
+      (!(mbmi->ref_frame == INTRA_FRAME && mbmi->mode == B_PRED) &&
+       !(mbmi->ref_frame != INTRA_FRAME && mbmi->mode == SPLITMV &&
+         mbmi->partitioning == PARTITIONING_4X4))) {
     mbmi->txfm_size = TX_8X8;
   } else {
     mbmi->txfm_size = TX_4X4;
--- a/vp8/decoder/decodframe.c
+++ b/vp8/decoder/decodframe.c
@@ -384,10 +384,16 @@
       }
     }
   } else if (mode == SPLITMV) {
-    DEQUANT_INVOKE(&pbi->dequant, idct_add_y_block)
-    (xd->qcoeff, xd->block[0].dequant,
-     xd->predictor, xd->dst.y_buffer,
-     xd->dst.y_stride, xd->eobs);
+    if (tx_size == TX_8X8) {
+      vp8_dequant_idct_add_y_block_8x8_c(xd->qcoeff, xd->block[0].dequant,
+                                         xd->predictor, xd->dst.y_buffer,
+                                         xd->dst.y_stride, xd->eobs, xd);
+    } else {
+      DEQUANT_INVOKE(&pbi->dequant,
+                     idct_add_y_block)(xd->qcoeff, xd->block[0].dequant,
+                                       xd->predictor, xd->dst.y_buffer,
+                                       xd->dst.y_stride, xd->eobs);
+    }
   } else {
     BLOCKD *b = &xd->block[24];
 
@@ -489,8 +495,10 @@
   if (!xd->mode_info_context->mbmi.encoded_as_sb) {
 #endif
     if ((tx_size == TX_8X8 &&
-         xd->mode_info_context->mbmi.mode != I8X8_PRED)
-        || tx_size == TX_16X16)
+         xd->mode_info_context->mbmi.mode != I8X8_PRED &&
+         xd->mode_info_context->mbmi.mode != SPLITMV)
+        || tx_size == TX_16X16
+       )
       DEQUANT_INVOKE(&pbi->dequant, idct_add_uv_block_8x8) //
           (xd->qcoeff + 16 * 16, xd->block[16].dequant,
            xd->predictor + 16 * 16, xd->dst.u_buffer, xd->dst.v_buffer,
--- a/vp8/decoder/detokenize.c
+++ b/vp8/decoder/detokenize.c
@@ -493,7 +493,8 @@
   INT16 *qcoeff_ptr = &xd->qcoeff[0];
   TX_TYPE tx_type = DCT_DCT;
 
-  int bufthred = (xd->mode_info_context->mbmi.mode == I8X8_PRED) ? 16 : 24;
+  int bufthred = (xd->mode_info_context->mbmi.mode == I8X8_PRED ||
+                  xd->mode_info_context->mbmi.mode == SPLITMV) ? 16 : 24;
   if (xd->mode_info_context->mbmi.mode != B_PRED &&
       xd->mode_info_context->mbmi.mode != SPLITMV &&
       xd->mode_info_context->mbmi.mode != I8X8_PRED) {
--- a/vp8/encoder/bitstream.c
+++ b/vp8/encoder/bitstream.c
@@ -1219,7 +1219,8 @@
 
 #if CONFIG_TX_SELECT
         if (((rf == INTRA_FRAME && mode <= I8X8_PRED) ||
-             (rf != INTRA_FRAME && mode != SPLITMV)) &&
+             (rf != INTRA_FRAME && !(mode == SPLITMV &&
+                                     mi->partitioning == PARTITIONING_4X4))) &&
             pc->txfm_mode == TX_MODE_SELECT &&
             !((pc->mb_no_coeff_skip && mi->mb_skip_coeff) ||
               (segfeature_active(xd, segment_id, SEG_LVL_EOB) &&
@@ -1227,7 +1228,7 @@
           TX_SIZE sz = mi->txfm_size;
           // FIXME(rbultje) code ternary symbol once all experiments are merged
           vp8_write(bc, sz != TX_4X4, pc->prob_tx[0]);
-          if (sz != TX_4X4 && mode != I8X8_PRED)
+          if (sz != TX_4X4 && mode != I8X8_PRED && mode != SPLITMV)
             vp8_write(bc, sz != TX_8X8, pc->prob_tx[1]);
         }
 #endif
--- a/vp8/encoder/encodeframe.c
+++ b/vp8/encoder/encodeframe.c
@@ -2161,7 +2161,9 @@
       if (mbmi->mode != B_PRED && mbmi->mode != I8X8_PRED &&
           mbmi->mode != SPLITMV) {
         cpi->txfm_count[mbmi->txfm_size]++;
-      } else if (mbmi->mode == I8X8_PRED) {
+      } else if (mbmi->mode == I8X8_PRED ||
+                 (mbmi->mode == SPLITMV &&
+                  mbmi->partitioning != PARTITIONING_4X4)) {
         cpi->txfm_count_8x8p[mbmi->txfm_size]++;
       }
     } else
@@ -2169,8 +2171,10 @@
     if (mbmi->mode != B_PRED && mbmi->mode != I8X8_PRED &&
         mbmi->mode != SPLITMV && cpi->common.txfm_mode >= ALLOW_16X16) {
       mbmi->txfm_size = TX_16X16;
-    } else if (mbmi->mode != B_PRED && mbmi->mode != SPLITMV &&
-        cpi->common.txfm_mode >= ALLOW_8X8) {
+    } else if (mbmi->mode != B_PRED &&
+               !(mbmi->mode == SPLITMV &&
+                 mbmi->partitioning == PARTITIONING_4X4) &&
+               cpi->common.txfm_mode >= ALLOW_8X8) {
       mbmi->txfm_size = TX_8X8;
     } else {
       mbmi->txfm_size = TX_4X4;
--- a/vp8/encoder/encodemb.c
+++ b/vp8/encoder/encodemb.c
@@ -636,6 +636,7 @@
   ENTROPY_CONTEXT_PLANES t_above, t_left;
   ENTROPY_CONTEXT *ta;
   ENTROPY_CONTEXT *tl;
+  int has_2nd_order = x->e_mbd.mode_info_context->mbmi.mode != SPLITMV;
 
   if (!x->e_mbd.above_context || !x->e_mbd.left_context)
     return;
@@ -645,7 +646,7 @@
 
   ta = (ENTROPY_CONTEXT *)&t_above;
   tl = (ENTROPY_CONTEXT *)&t_left;
-  type = PLANE_TYPE_Y_NO_DC;
+  type = has_2nd_order ? PLANE_TYPE_Y_NO_DC : PLANE_TYPE_Y_WITH_DC;
   for (b = 0; b < 16; b += 4) {
     optimize_b(x, b, type,
                ta + vp8_block2above_8x8[b], tl + vp8_block2left_8x8[b],
@@ -655,8 +656,11 @@
   }
 
   // 8x8 always have 2nd roder haar block
-  check_reset_8x8_2nd_coeffs(&x->e_mbd,
-                             ta + vp8_block2above_8x8[24], tl + vp8_block2left_8x8[24]);
+  if (has_2nd_order) {
+    check_reset_8x8_2nd_coeffs(&x->e_mbd,
+                               ta + vp8_block2above_8x8[24],
+                               tl + vp8_block2left_8x8[24]);
+  }
 }
 
 void vp8_optimize_mbuv_8x8(MACROBLOCK *x, const VP8_ENCODER_RTCD *rtcd) {
@@ -896,11 +900,25 @@
       optimize_mb_16x16(x, rtcd);
     vp8_inverse_transform_mb_16x16(IF_RTCD(&rtcd->common->idct), xd);
   } else if (tx_size == TX_8X8) {
-    vp8_transform_mb_8x8(x);
-    vp8_quantize_mb_8x8(x);
-    if (x->optimize)
-      optimize_mb_8x8(x, rtcd);
-    vp8_inverse_transform_mb_8x8(IF_RTCD(&rtcd->common->idct), xd);
+    if (xd->mode_info_context->mbmi.mode == SPLITMV) {
+      assert(xd->mode_info_context->mbmi.partitioning != PARTITIONING_4X4);
+      vp8_transform_mby_8x8(x);
+      vp8_transform_mbuv_4x4(x);
+      vp8_quantize_mby_8x8(x);
+      vp8_quantize_mbuv_4x4(x);
+      if (x->optimize) {
+        vp8_optimize_mby_8x8(x, rtcd);
+        vp8_optimize_mbuv_4x4(x, rtcd);
+      }
+      vp8_inverse_transform_mby_8x8(IF_RTCD(&rtcd->common->idct), xd);
+      vp8_inverse_transform_mbuv_4x4(IF_RTCD(&rtcd->common->idct), xd);
+    } else {
+      vp8_transform_mb_8x8(x);
+      vp8_quantize_mb_8x8(x);
+      if (x->optimize)
+        optimize_mb_8x8(x, rtcd);
+      vp8_inverse_transform_mb_8x8(IF_RTCD(&rtcd->common->idct), xd);
+    }
   } else {
     transform_mb_4x4(x);
     vp8_quantize_mb_4x4(x);
--- a/vp8/encoder/onyx_int.h
+++ b/vp8/encoder/onyx_int.h
@@ -366,10 +366,10 @@
 } VP8_ENCODER_RTCD;
 
 enum {
-  BLOCK_16X8,
-  BLOCK_8X16,
-  BLOCK_8X8,
-  BLOCK_4X4,
+  BLOCK_16X8 = PARTITIONING_16X8,
+  BLOCK_8X16 = PARTITIONING_8X16,
+  BLOCK_8X8 = PARTITIONING_8X8,
+  BLOCK_4X4 = PARTITIONING_4X4,
   BLOCK_16X16,
   BLOCK_MAX_SEGMENTS,
   BLOCK_32X32 = BLOCK_MAX_SEGMENTS,
--- a/vp8/encoder/rdopt.c
+++ b/vp8/encoder/rdopt.c
@@ -1583,8 +1583,8 @@
   } else {
     *(a + vp8_block2above[ib])     = besta0;
     *(a + vp8_block2above[ib + 1]) = besta1;
-    *(l + vp8_block2above[ib])     = bestl0;
-    *(l + vp8_block2above[ib + 4]) = bestl1;
+    *(l + vp8_block2left[ib])      = bestl0;
+    *(l + vp8_block2left[ib + 4])  = bestl1;
   }
 
   return best_rd;
@@ -2178,6 +2178,7 @@
                                            int which_label,
                                            int *labelyrate,
                                            int *distortion,
+                                           int64_t *otherrd,
                                            ENTROPY_CONTEXT *ta,
                                            ENTROPY_CONTEXT *tl,
                                            const VP8_ENCODER_RTCD *rtcd) {
@@ -2184,7 +2185,16 @@
   int i, j;
   MACROBLOCKD *xd = &x->e_mbd;
   const int iblock[4] = { 0, 1, 4, 5 };
+  int othercost = 0, otherdist = 0;
+  ENTROPY_CONTEXT_PLANES tac, tlc;
+  ENTROPY_CONTEXT *tacp = (ENTROPY_CONTEXT *) &tac,
+                  *tlcp = (ENTROPY_CONTEXT *) &tlc;
 
+  if (otherrd) {
+    memcpy(&tac, ta, sizeof(ENTROPY_CONTEXT_PLANES));
+    memcpy(&tlc, tl, sizeof(ENTROPY_CONTEXT_PLANES));
+  }
+
   *distortion = 0;
   *labelyrate = 0;
   for (i = 0; i < 4; i++) {
@@ -2191,8 +2201,9 @@
     int ib = vp8_i8x8_block[i];
 
     if (labels[ib] == which_label) {
-      BLOCKD *bd = &xd->block[ib];
-      BLOCK *be = &x->block[ib];
+      int idx = (ib & 8) + ((ib & 2) << 1);
+      BLOCKD *bd = &xd->block[ib], *bd2 = &xd->block[idx];
+      BLOCK *be = &x->block[ib], *be2 = &x->block[idx];
       int thisdistortion;
 
       vp8_build_inter_predictors4b(xd, bd, 16);
@@ -2200,24 +2211,66 @@
         vp8_build_2nd_inter_predictors4b(xd, bd, 16);
       vp8_subtract_4b_c(be, bd, 16);
 
-      for (j = 0; j < 4; j += 2) {
-        bd = &xd->block[ib + iblock[j]];
-        be = &x->block[ib + iblock[j]];
-        x->vp8_short_fdct8x4(be->src_diff, be->coeff, 32);
-        x->quantize_b_4x4_pair(be, be + 1, bd, bd + 1);
-        thisdistortion = vp8_block_error_c(be->coeff, bd->dqcoeff, 32);
+      if (xd->mode_info_context->mbmi.txfm_size == TX_4X4) {
+        if (otherrd) {
+          x->vp8_short_fdct8x8(be->src_diff, be2->coeff, 32);
+          x->quantize_b_8x8(be2, bd2);
+          thisdistortion = vp8_block_error_c(be2->coeff, bd2->dqcoeff, 64);
+          otherdist += thisdistortion;
+          othercost += cost_coeffs(x, bd2, PLANE_TYPE_Y_WITH_DC,
+                                     tacp + vp8_block2above_8x8[idx],
+                                     tlcp + vp8_block2left_8x8[idx], TX_8X8);
+        }
+        for (j = 0; j < 4; j += 2) {
+          bd = &xd->block[ib + iblock[j]];
+          be = &x->block[ib + iblock[j]];
+          x->vp8_short_fdct8x4(be->src_diff, be->coeff, 32);
+          x->quantize_b_4x4_pair(be, be + 1, bd, bd + 1);
+          thisdistortion = vp8_block_error_c(be->coeff, bd->dqcoeff, 32);
+          *distortion += thisdistortion;
+          *labelyrate += cost_coeffs(x, bd, PLANE_TYPE_Y_WITH_DC,
+                                     ta + vp8_block2above[ib + iblock[j]],
+                                     tl + vp8_block2left[ib + iblock[j]],
+                                     TX_4X4);
+          *labelyrate += cost_coeffs(x, bd + 1, PLANE_TYPE_Y_WITH_DC,
+                                     ta + vp8_block2above[ib + iblock[j] + 1],
+                                     tl + vp8_block2left[ib + iblock[j]],
+                                     TX_4X4);
+        }
+      } else /* 8x8 */ {
+        if (otherrd) {
+          for (j = 0; j < 4; j += 2) {
+            BLOCKD *bd3 = &xd->block[ib + iblock[j]];
+            BLOCK *be3 = &x->block[ib + iblock[j]];
+            x->vp8_short_fdct8x4(be3->src_diff, be3->coeff, 32);
+            x->quantize_b_4x4_pair(be3, be3 + 1, bd3, bd3 + 1);
+            thisdistortion = vp8_block_error_c(be3->coeff, bd3->dqcoeff, 32);
+            otherdist += thisdistortion;
+            othercost += cost_coeffs(x, bd3, PLANE_TYPE_Y_WITH_DC,
+                                     tacp + vp8_block2above[ib + iblock[j]],
+                                     tlcp + vp8_block2left[ib + iblock[j]],
+                                     TX_4X4);
+            othercost += cost_coeffs(x, bd3 + 1, PLANE_TYPE_Y_WITH_DC,
+                                     tacp + vp8_block2above[ib + iblock[j] + 1],
+                                     tlcp + vp8_block2left[ib + iblock[j]],
+                                     TX_4X4);
+          }
+        }
+        x->vp8_short_fdct8x8(be->src_diff, be2->coeff, 32);
+        x->quantize_b_8x8(be2, bd2);
+        thisdistortion = vp8_block_error_c(be2->coeff, bd2->dqcoeff, 64);
         *distortion += thisdistortion;
-        *labelyrate += cost_coeffs(x, bd, PLANE_TYPE_Y_WITH_DC,
-                                   ta + vp8_block2above[ib + iblock[j]],
-                                   tl + vp8_block2left[ib + iblock[j]], TX_4X4);
-        *labelyrate += cost_coeffs(x, bd + 1, PLANE_TYPE_Y_WITH_DC,
-                                   ta + vp8_block2above[ib + iblock[j] + 1],
-                                   tl + vp8_block2left[ib + iblock[j]],
-                                   TX_4X4);
+        *labelyrate += cost_coeffs(x, bd2, PLANE_TYPE_Y_WITH_DC,
+                                   ta + vp8_block2above_8x8[idx],
+                                   tl + vp8_block2left_8x8[idx], TX_8X8);
       }
     }
   }
   *distortion >>= 2;
+  if (otherrd) {
+    othercost >>= 2;
+    *otherrd = RDCOST(x->rdmult, x->rddiv, othercost, otherdist);
+  }
   return RDCOST(x->rdmult, x->rddiv, *labelyrate, *distortion);
 }
 
@@ -2229,7 +2282,8 @@
   int_mv mvp;
 
   int64_t segment_rd;
-  int segment_num;
+  SPLITMV_PARTITIONING_TYPE segment_num;
+  TX_SIZE txfm_size;
   int r;
   int d;
   int segment_yrate;
@@ -2255,9 +2309,14 @@
   return r;
 }
 
-static void rd_check_segment(VP8_COMP *cpi, MACROBLOCK *x,
-                             BEST_SEG_INFO *bsi, unsigned int segmentation,
-                             int_mv seg_mvs[16 /* n_blocks */][MAX_REF_FRAMES - 1]) {
+static void rd_check_segment_txsize(VP8_COMP *cpi, MACROBLOCK *x,
+                                    BEST_SEG_INFO *bsi,
+                                    SPLITMV_PARTITIONING_TYPE segmentation,
+                                    TX_SIZE tx_size, int64_t *otherrds,
+                                    int64_t *rds, int *completed,
+                                    /* 16 = n_blocks */
+                                    int_mv seg_mvs[16 /* n_blocks */]
+                                                  [MAX_REF_FRAMES - 1]) {
   int i, j;
   int const *labels;
   int br = 0, bd = 0;
@@ -2265,12 +2324,12 @@
   MB_MODE_INFO * mbmi = &x->e_mbd.mode_info_context->mbmi;
 
   int label_count;
-  int64_t this_segment_rd = 0;
+  int64_t this_segment_rd = 0, other_segment_rd;
   int label_mv_thresh;
   int rate = 0;
   int sbr = 0, sbd = 0;
   int segmentyrate = 0;
-  uint8_t best_eobs[16];
+  uint8_t best_eobs[16] = { 0 };
 
   vp8_variance_fn_ptr_t *v_fn_ptr;
 
@@ -2298,20 +2357,23 @@
   label_mv_thresh = 1 * bsi->mvthresh / label_count;
 
   // Segmentation method overheads
-  rate = vp8_cost_token(vp8_mbsplit_tree, vp8_mbsplit_probs, vp8_mbsplit_encodings + segmentation);
+  rate = vp8_cost_token(vp8_mbsplit_tree, vp8_mbsplit_probs,
+                        vp8_mbsplit_encodings + segmentation);
   rate += vp8_cost_mv_ref(cpi, SPLITMV, bsi->mdcounts);
   this_segment_rd += RDCOST(x->rdmult, x->rddiv, rate, 0);
   br += rate;
+  other_segment_rd = this_segment_rd;
 
-  for (i = 0; i < label_count; i++) {
+  mbmi->txfm_size = tx_size;
+  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;
+    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;
+      int64_t this_rd, other_rd;
       int distortion;
       int labelyrate;
       ENTROPY_CONTEXT_PLANES t_above_s, t_left_s;
@@ -2333,14 +2395,16 @@
         BLOCK *c;
         BLOCKD *e;
 
-        // Is the best so far sufficiently good that we cant justify doing and new motion search.
+        /* 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) {
-          if (segmentation == BLOCK_8X16 || segmentation == BLOCK_16X8) {
+          if (segmentation == PARTITIONING_8X16 ||
+              segmentation == PARTITIONING_16X8) {
             bsi->mvp.as_int = bsi->sv_mvp[i].as_int;
-            if (i == 1 && segmentation == BLOCK_16X8)
+            if (i == 1 && segmentation == PARTITIONING_16X8)
               bsi->mvp.as_int = bsi->sv_mvp[2].as_int;
 
             step_param = bsi->sv_istep[i];
@@ -2347,7 +2411,7 @@
           }
 
           // use previous block's result as next block's MV predictor.
-          if (segmentation == BLOCK_4X4 && i > 0) {
+          if (segmentation == PARTITIONING_4X4 && i > 0) {
             bsi->mvp.as_int = x->e_mbd.block[i - 1].bmi.as_mv.first.as_int;
             if (i == 4 || i == 8 || i == 12)
               bsi->mvp.as_int = x->e_mbd.block[i - 4].bmi.as_mv.first.as_int;
@@ -2379,7 +2443,8 @@
           // 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. */
-            vp8_clamp_mv(&mvp_full, x->mv_col_min, x->mv_col_max, x->mv_row_min, x->mv_row_max);
+            vp8_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, c, e, &mvp_full,
                                            sadpb, 16, v_fn_ptr,
@@ -2389,7 +2454,8 @@
               bestsme = thissme;
               mode_mv[NEW4X4].as_int = e->bmi.as_mv.first.as_int;
             } else {
-              // The full search result is actually worse so re-instate the previous best vector
+              /* The full search result is actually worse so re-instate the
+               * previous best vector */
               e->bmi.as_mv.first.as_int = mode_mv[NEW4X4].as_int;
             }
           }
@@ -2399,8 +2465,8 @@
           int distortion;
           unsigned int sse;
           cpi->find_fractional_mv_step(x, c, e, &mode_mv[NEW4X4],
-                                       bsi->ref_mv, x->errorperbit, v_fn_ptr, XMVCOST,
-                                       &distortion, &sse);
+                                       bsi->ref_mv, x->errorperbit, v_fn_ptr,
+                                       XMVCOST, &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;
@@ -2407,7 +2473,8 @@
         }
       } /* NEW4X4 */
       else if (mbmi->second_ref_frame && this_mode == NEW4X4) {
-        // motion search not completed? Then skip newmv for this block with comppred
+        /* 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;
@@ -2429,14 +2496,15 @@
           mv_check_bounds(x, &second_mode_mv[this_mode]))
         continue;
 
-      if (segmentation == BLOCK_4X4) {
+      if (segmentation == PARTITIONING_4X4) {
         this_rd = encode_inter_mb_segment(x, labels, i, &labelyrate,
                                           &distortion,
                                           ta_s, tl_s, IF_RTCD(&cpi->rtcd));
+        other_rd = this_rd;
       } else {
         this_rd = encode_inter_mb_segment_8x8(x, labels, i, &labelyrate,
-                                              &distortion, ta_s, tl_s,
-                                              IF_RTCD(&cpi->rtcd));
+                                              &distortion, &other_rd,
+                                              ta_s, tl_s, IF_RTCD(&cpi->rtcd));
       }
       this_rd += RDCOST(x->rdmult, x->rddiv, rate, 0);
       rate += labelyrate;
@@ -2447,10 +2515,21 @@
         bestlabelyrate = labelyrate;
         mode_selected = this_mode;
         best_label_rd = this_rd;
-        for (j = 0; j < 16; j++)
-          if (labels[j] == i)
-            best_eobs[j] = x->e_mbd.block[j].eob;
+        if (x->e_mbd.mode_info_context->mbmi.txfm_size == TX_4X4) {
+          for (j = 0; j < 16; j++)
+            if (labels[j] == i)
+              best_eobs[j] = x->e_mbd.block[j].eob;
+        } else {
+          for (j = 0; j < 4; j++) {
+            int ib = vp8_i8x8_block[j], idx = j * 4;
 
+            if (labels[ib] == i)
+              best_eobs[idx] = x->e_mbd.block[idx].eob;
+          }
+        }
+        if (other_rd < best_other_rd)
+          best_other_rd = other_rd;
+
         vpx_memcpy(ta_b, ta_s, sizeof(ENTROPY_CONTEXT_PLANES));
         vpx_memcpy(tl_b, tl_s, sizeof(ENTROPY_CONTEXT_PLANES));
 
@@ -2461,18 +2540,18 @@
     vpx_memcpy(tl, tl_b, sizeof(ENTROPY_CONTEXT_PLANES));
 
     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, XMVCOST);
+                &second_mode_mv[mode_selected], seg_mvs[i],
+                bsi->ref_mv, bsi->second_ref_mv, XMVCOST);
 
     br += sbr;
     bd += sbd;
     segmentyrate += bestlabelyrate;
     this_segment_rd += best_label_rd;
-
-    if (this_segment_rd >= bsi->segment_rd) {
-      break;
-    }
-
-
+    other_segment_rd += best_other_rd;
+    if (rds)
+      rds[i] = this_segment_rd;
+    if (otherrds)
+      rds[i] = other_segment_rd;
   } /* for each label */
 
   if (this_segment_rd < bsi->segment_rd) {
@@ -2481,6 +2560,7 @@
     bsi->segment_yrate = segmentyrate;
     bsi->segment_rd = this_segment_rd;
     bsi->segment_num = segmentation;
+    bsi->txfm_size = mbmi->txfm_size;
 
     // store everything needed to come back to this!!
     for (i = 0; i < 16; i++) {
@@ -2493,8 +2573,114 @@
       bsi->eobs[i] = best_eobs[i];
     }
   }
+
+  if (completed) {
+    *completed = i;
+  }
 }
 
+static void rd_check_segment(VP8_COMP *cpi, MACROBLOCK *x,
+                             BEST_SEG_INFO *bsi,
+                             unsigned int segmentation,
+                             /* 16 = n_blocks */
+                             int_mv seg_mvs[16][MAX_REF_FRAMES - 1],
+                             int64_t txfm_cache[NB_TXFM_MODES]) {
+#if CONFIG_TX_SELECT
+  int i, n, c = vp8_mbsplit_count[segmentation];
+
+  if (segmentation == PARTITIONING_4X4) {
+    int64_t rd[16];
+
+    rd_check_segment_txsize(cpi, x, bsi, segmentation, TX_4X4, NULL,
+                            rd, &n, seg_mvs);
+    if (n == c) {
+      for (i = 0; i < NB_TXFM_MODES; i++) {
+        if (rd[c - 1] < txfm_cache[i])
+          txfm_cache[i] = rd[c - 1];
+      }
+    }
+  } else {
+    int64_t diff, base_rd;
+    int cost4x4 = vp8_cost_bit(cpi->common.prob_tx[0], 0);
+    int cost8x8 = vp8_cost_bit(cpi->common.prob_tx[0], 1);
+
+    if (cpi->common.txfm_mode == TX_MODE_SELECT) {
+      int64_t rd4x4[4], rd8x8[4];
+      int n4x4, n8x8, nmin;
+      BEST_SEG_INFO bsi4x4, bsi8x8;
+
+      /* factor in cost of cost4x4/8x8 in decision */
+      vpx_memcpy(&bsi4x4, bsi, sizeof(*bsi));
+      vpx_memcpy(&bsi8x8, bsi, sizeof(*bsi));
+      rd_check_segment_txsize(cpi, x, &bsi4x4, segmentation,
+                              TX_4X4, NULL, rd4x4, &n4x4, seg_mvs);
+      rd_check_segment_txsize(cpi, x, &bsi8x8, segmentation,
+                              TX_8X8, NULL, rd8x8, &n8x8, seg_mvs);
+      if (bsi4x4.segment_num == segmentation) {
+        bsi4x4.segment_rd += RDCOST(x->rdmult, x->rddiv, cost4x4, 0);
+        if (bsi4x4.segment_rd < bsi->segment_rd)
+          vpx_memcpy(bsi, &bsi4x4, sizeof(*bsi));
+      }
+      if (bsi8x8.segment_num == segmentation) {
+        bsi8x8.segment_rd += RDCOST(x->rdmult, x->rddiv, cost8x8, 0);
+        if (bsi8x8.segment_rd < bsi->segment_rd)
+          vpx_memcpy(bsi, &bsi8x8, sizeof(*bsi));
+      }
+      n = n4x4 > n8x8 ? n4x4 : n8x8;
+      if (n == c) {
+        nmin = n4x4 < n8x8 ? n4x4 : n8x8;
+        diff = rd8x8[nmin - 1] - rd4x4[nmin - 1];
+        if (n == n4x4) {
+          base_rd = rd4x4[c - 1];
+        } else {
+          base_rd = rd8x8[c - 1] - diff;
+        }
+      }
+    } else {
+      int64_t rd[4], otherrd[4];
+
+      if (cpi->common.txfm_mode == ONLY_4X4) {
+        rd_check_segment_txsize(cpi, x, bsi, segmentation, TX_4X4, otherrd,
+                                rd, &n, seg_mvs);
+        if (n == c) {
+          base_rd = rd[c - 1];
+          diff = otherrd[c - 1] - rd[c - 1];
+        }
+      } else /* use 8x8 transform */ {
+        rd_check_segment_txsize(cpi, x, bsi, segmentation, TX_8X8, otherrd,
+                                rd, &n, seg_mvs);
+        if (n == c) {
+          diff = rd[c - 1] - otherrd[c - 1];
+          base_rd = otherrd[c - 1];
+        }
+      }
+    }
+
+    if (n == c) {
+      if (base_rd < txfm_cache[ONLY_4X4]) {
+        txfm_cache[ONLY_4X4] = base_rd;
+      }
+      if (base_rd + diff < txfm_cache[1]) {
+        txfm_cache[ALLOW_8X8] = txfm_cache[ALLOW_16X16] = base_rd + diff;
+      }
+      if (diff < 0) {
+        base_rd += diff + RDCOST(x->rdmult, x->rddiv, cost8x8, 0);
+      } else {
+        base_rd += RDCOST(x->rdmult, x->rddiv, cost4x4, 0);
+      }
+      if (base_rd < txfm_cache[TX_MODE_SELECT]) {
+        txfm_cache[TX_MODE_SELECT] = base_rd;
+      }
+    }
+  }
+#else
+  rd_check_segment_txsize(cpi, x, bsi, segmentation,
+                          (segmentation == PARTITIONING_4X4 ||
+                           cpi->common.txfm_mode == ONLY_4X4) ? TX_4X4 : TX_8X8,
+                          NULL, NULL, NULL, seg_mvs);
+#endif
+}
+
 static __inline
 void vp8_cal_step_param(int sr, int *sp) {
   int step = 0;
@@ -2508,17 +2694,26 @@
   *sp = MAX_MVSEARCH_STEPS - 1 - step;
 }
 
-static int vp8_rd_pick_best_mbsegmentation(VP8_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[BLOCK_MAX_SEGMENTS - 1][16 /* n_blocks */][MAX_REF_FRAMES - 1]) {
+static int rd_pick_best_mbsegmentation(VP8_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[NB_PARTITIONINGS]
+                                                     [16 /* n_blocks */]
+                                                     [MAX_REF_FRAMES - 1],
+                                       int64_t txfm_cache[NB_TXFM_MODES]) {
   int i;
   BEST_SEG_INFO bsi;
   MB_MODE_INFO * mbmi = &x->e_mbd.mode_info_context->mbmi;
 
   vpx_memset(&bsi, 0, sizeof(bsi));
+  for (i = 0; i < NB_TXFM_MODES; i++)
+    txfm_cache[i] = INT64_MAX;
 
   bsi.segment_rd = best_rd;
   bsi.ref_mv = best_ref_mv;
@@ -2526,6 +2721,7 @@
   bsi.mvp.as_int = best_ref_mv->as_int;
   bsi.mvthresh = mvthresh;
   bsi.mdcounts = mdcounts;
+  bsi.txfm_size = TX_4X4;
 
   for (i = 0; i < 16; i++)
     bsi.modes[i] = ZERO4X4;
@@ -2533,16 +2729,20 @@
   if (cpi->compressor_speed == 0) {
     /* for now, we will keep the original segmentation order
        when in best quality mode */
-    rd_check_segment(cpi, x, &bsi, BLOCK_16X8, seg_mvs[BLOCK_16X8]);
-    rd_check_segment(cpi, x, &bsi, BLOCK_8X16, seg_mvs[BLOCK_8X16]);
-    rd_check_segment(cpi, x, &bsi, BLOCK_8X8,  seg_mvs[BLOCK_8X8]);
-    rd_check_segment(cpi, x, &bsi, BLOCK_4X4,  seg_mvs[BLOCK_4X4]);
+    rd_check_segment(cpi, x, &bsi, PARTITIONING_16X8,
+                     seg_mvs[PARTITIONING_16X8], txfm_cache);
+    rd_check_segment(cpi, x, &bsi, PARTITIONING_8X16,
+                     seg_mvs[PARTITIONING_8X16], txfm_cache);
+    rd_check_segment(cpi, x, &bsi, PARTITIONING_8X8,
+                     seg_mvs[PARTITIONING_8X8], txfm_cache);
+    rd_check_segment(cpi, x, &bsi, PARTITIONING_4X4,
+                     seg_mvs[PARTITIONING_4X4], txfm_cache);
   } else {
     int sr;
 
-    rd_check_segment(cpi, x, &bsi, BLOCK_8X8, seg_mvs[BLOCK_8X8]);
+    rd_check_segment(cpi, x, &bsi, PARTITIONING_8X8,
+                     seg_mvs[PARTITIONING_8X8], txfm_cache);
 
-
     if (bsi.segment_rd < best_rd) {
       int tmp_col_min = x->mv_col_min;
       int tmp_col_max = x->mv_col_max;
@@ -2557,34 +2757,40 @@
       bsi.sv_mvp[2].as_int = bsi.mvs[8].as_int;
       bsi.sv_mvp[3].as_int = bsi.mvs[10].as_int;
 
-      /* Use 8x8 result as 16x8/8x16's predictor MV. Adjust search range according to the closeness of 2 MV. */
+      /* Use 8x8 result as 16x8/8x16's predictor MV. Adjust search range
+       * according to the closeness of 2 MV. */
       /* block 8X16 */
-      {
-        sr = MAXF((abs(bsi.sv_mvp[0].as_mv.row - bsi.sv_mvp[2].as_mv.row)) >> 3, (abs(bsi.sv_mvp[0].as_mv.col - bsi.sv_mvp[2].as_mv.col)) >> 3);
-        vp8_cal_step_param(sr, &bsi.sv_istep[0]);
+      sr = MAXF((abs(bsi.sv_mvp[0].as_mv.row - bsi.sv_mvp[2].as_mv.row)) >> 3,
+                (abs(bsi.sv_mvp[0].as_mv.col - bsi.sv_mvp[2].as_mv.col)) >> 3);
+      vp8_cal_step_param(sr, &bsi.sv_istep[0]);
 
-        sr = MAXF((abs(bsi.sv_mvp[1].as_mv.row - bsi.sv_mvp[3].as_mv.row)) >> 3, (abs(bsi.sv_mvp[1].as_mv.col - bsi.sv_mvp[3].as_mv.col)) >> 3);
-        vp8_cal_step_param(sr, &bsi.sv_istep[1]);
+      sr = MAXF((abs(bsi.sv_mvp[1].as_mv.row - bsi.sv_mvp[3].as_mv.row)) >> 3,
+                (abs(bsi.sv_mvp[1].as_mv.col - bsi.sv_mvp[3].as_mv.col)) >> 3);
+      vp8_cal_step_param(sr, &bsi.sv_istep[1]);
 
-        rd_check_segment(cpi, x, &bsi, BLOCK_8X16, seg_mvs[BLOCK_8X16]);
-      }
+      rd_check_segment(cpi, x, &bsi, PARTITIONING_8X16,
+                       seg_mvs[PARTITIONING_8X16], txfm_cache);
 
       /* block 16X8 */
-      {
-        sr = MAXF((abs(bsi.sv_mvp[0].as_mv.row - bsi.sv_mvp[1].as_mv.row)) >> 3, (abs(bsi.sv_mvp[0].as_mv.col - bsi.sv_mvp[1].as_mv.col)) >> 3);
-        vp8_cal_step_param(sr, &bsi.sv_istep[0]);
+      sr = MAXF((abs(bsi.sv_mvp[0].as_mv.row - bsi.sv_mvp[1].as_mv.row)) >> 3,
+                (abs(bsi.sv_mvp[0].as_mv.col - bsi.sv_mvp[1].as_mv.col)) >> 3);
+      vp8_cal_step_param(sr, &bsi.sv_istep[0]);
 
-        sr = MAXF((abs(bsi.sv_mvp[2].as_mv.row - bsi.sv_mvp[3].as_mv.row)) >> 3, (abs(bsi.sv_mvp[2].as_mv.col - bsi.sv_mvp[3].as_mv.col)) >> 3);
-        vp8_cal_step_param(sr, &bsi.sv_istep[1]);
+      sr = MAXF((abs(bsi.sv_mvp[2].as_mv.row - bsi.sv_mvp[3].as_mv.row)) >> 3,
+                (abs(bsi.sv_mvp[2].as_mv.col - bsi.sv_mvp[3].as_mv.col)) >> 3);
+      vp8_cal_step_param(sr, &bsi.sv_istep[1]);
 
-        rd_check_segment(cpi, x, &bsi, BLOCK_16X8, seg_mvs[BLOCK_16X8]);
-      }
+      rd_check_segment(cpi, x, &bsi, PARTITIONING_16X8,
+                       seg_mvs[PARTITIONING_16X8], txfm_cache);
 
       /* If 8x8 is better than 16x8/8x16, then do 4x4 search */
       /* Not skip 4x4 if speed=0 (good quality) */
-      if (cpi->sf.no_skip_block4x4_search || bsi.segment_num == BLOCK_8X8) { /* || (sv_segment_rd8x8-bsi.segment_rd) < sv_segment_rd8x8>>5) */
+      if (cpi->sf.no_skip_block4x4_search ||
+          bsi.segment_num == PARTITIONING_8X8) {
+        /* || (sv_segment_rd8x8-bsi.segment_rd) < sv_segment_rd8x8>>5) */
         bsi.mvp.as_int = bsi.sv_mvp[0].as_int;
-        rd_check_segment(cpi, x, &bsi, BLOCK_4X4, seg_mvs[BLOCK_4X4]);
+        rd_check_segment(cpi, x, &bsi, PARTITIONING_4X4,
+                         seg_mvs[PARTITIONING_4X4], txfm_cache);
       }
 
       /* restore UMV window */
@@ -2608,9 +2814,12 @@
   *returntotrate = bsi.r;
   *returndistortion = bsi.d;
   *returnyrate = bsi.segment_yrate;
-  *skippable = mby_is_skippable_4x4(&x->e_mbd, 0);
+  *skippable = bsi.txfm_size == TX_4X4 ?
+                    mby_is_skippable_4x4(&x->e_mbd, 0) :
+                    mby_is_skippable_8x8(&x->e_mbd, 0);
 
   /* save partitions */
+  mbmi->txfm_size = bsi.txfm_size;
   mbmi->partitioning = bsi.segment_num;
   x->partition_info->count = vp8_mbsplit_count[bsi.segment_num];
 
@@ -3299,7 +3508,7 @@
   unsigned char *y_buffer[4], *u_buffer[4], *v_buffer[4];
 
   unsigned int ref_costs[MAX_REF_FRAMES];
-  int_mv seg_mvs[BLOCK_MAX_SEGMENTS - 1][16 /* n_blocks */][MAX_REF_FRAMES - 1];
+  int_mv seg_mvs[NB_PARTITIONINGS][16 /* n_blocks */][MAX_REF_FRAMES - 1];
 
   vpx_memset(mode8x8, 0, sizeof(mode8x8));
   vpx_memset(&frame_mv, 0, sizeof(frame_mv));
@@ -3314,7 +3523,7 @@
   for (i = 0; i < NB_TXFM_MODES; i++)
     best_txfm_rd[i] = INT64_MAX;
 
-  for (i = 0; i < BLOCK_MAX_SEGMENTS - 1; i++) {
+  for (i = 0; i < NB_PARTITIONINGS; i++) {
     int j, k;
 
     for (j = 0; j < 16; j++)
@@ -3680,12 +3889,12 @@
               (mbmi->ref_frame == GOLDEN_FRAME) ?
           cpi->rd_threshes[THR_NEWG] : this_rd_thresh;
 
-      mbmi->txfm_size = TX_4X4; // FIXME use 8x8 in case of 8x8/8x16/16x8
-      tmp_rd = vp8_rd_pick_best_mbsegmentation(cpi, x, &best_ref_mv,
-                                               second_ref, best_yrd, mdcounts,
-                                               &rate, &rate_y, &distortion,
-                                               &skippable,
-                                               this_rd_thresh, seg_mvs);
+      tmp_rd = rd_pick_best_mbsegmentation(cpi, x, &best_ref_mv,
+                                           second_ref, best_yrd, mdcounts,
+                                           &rate, &rate_y, &distortion,
+                                           &skippable,
+                                           this_rd_thresh, seg_mvs,
+                                           txfm_cache);
       rate2 += rate;
       distortion2 += distortion;
 
@@ -4081,7 +4290,7 @@
       if (!mode_excluded && this_rd != INT64_MAX) {
         for (i = 0; i < NB_TXFM_MODES; i++) {
           int64_t adj_rd;
-          if (this_mode != B_PRED && this_mode != SPLITMV) {
+          if (this_mode != B_PRED) {
             adj_rd = this_rd + txfm_cache[i] - txfm_cache[cm->txfm_mode];
           } else {
             adj_rd = this_rd;
--- a/vp8/encoder/tokenize.c
+++ b/vp8/encoder/tokenize.c
@@ -589,7 +589,8 @@
       xd->mode_info_context->mbmi.mb_skip_coeff = mb_is_skippable_16x16(xd);
       break;
     case TX_8X8:
-      if (xd->mode_info_context->mbmi.mode == I8X8_PRED)
+      if (xd->mode_info_context->mbmi.mode == I8X8_PRED ||
+          xd->mode_info_context->mbmi.mode == SPLITMV)
         xd->mode_info_context->mbmi.mb_skip_coeff = mb_is_skippable_8x8_4x4uv(xd, 0);
       else
         xd->mode_info_context->mbmi.mb_skip_coeff = mb_is_skippable_8x8(xd, has_y2_block);
@@ -665,7 +666,8 @@
       *(A + vp8_block2above_8x8[b] + 1) = *(A + vp8_block2above_8x8[b]);
       *(L + vp8_block2left_8x8[b] + 1)  = *(L + vp8_block2left_8x8[b]);
     }
-    if (xd->mode_info_context->mbmi.mode == I8X8_PRED) {
+    if (xd->mode_info_context->mbmi.mode == I8X8_PRED ||
+        xd->mode_info_context->mbmi.mode == SPLITMV) {
       tokenize1st_order_chroma_4x4(xd, t, cpi, dry_run);
     } else {
       for (b = 16; b < 24; b += 4) {
@@ -1260,7 +1262,8 @@
   if (tx_size == TX_16X16) {
     vp8_stuff_mb_16x16(cpi, xd, t, dry_run);
   } else if (tx_size == TX_8X8) {
-    if (xd->mode_info_context->mbmi.mode == I8X8_PRED) {
+    if (xd->mode_info_context->mbmi.mode == I8X8_PRED ||
+        xd->mode_info_context->mbmi.mode == SPLITMV) {
       vp8_stuff_mb_8x8_4x4uv(cpi, xd, t, dry_run);
     } else {
       vp8_stuff_mb_8x8(cpi, xd, t, dry_run);