Re-add support for ADST in superblocks.

This also changes the RD search to take account of the correct block
index when searching (this is required for ADST positioning to work
correctly in combination with tx_select).

Change-Id: Ie50d05b3a024a64ecd0b376887aa38ac5f7b6af6
diff --git a/vp9/common/vp9_blockd.h b/vp9/common/vp9_blockd.h
index 9f978ce..986ddd8 100644
--- a/vp9/common/vp9_blockd.h
+++ b/vp9/common/vp9_blockd.h
@@ -460,20 +460,20 @@
 #define USE_ADST_FOR_I8X8_4X4     1
 #define USE_ADST_PERIPHERY_ONLY   1
 
-static TX_TYPE get_tx_type_4x4(const MACROBLOCKD *xd, const BLOCKD *b) {
+static TX_TYPE get_tx_type_4x4(const MACROBLOCKD *xd, int ib) {
   // TODO(debargha): explore different patterns for ADST usage when blocksize
   // is smaller than the prediction size
   TX_TYPE tx_type = DCT_DCT;
-  int ib = (int)(b - xd->block);
+  // TODO(rbultje, debargha): Explore ADST usage for superblocks
+  if (xd->mode_info_context->mbmi.sb_type)
+    return tx_type;
   if (ib >= 16)
     return tx_type;
   if (xd->lossless)
     return DCT_DCT;
-  // TODO(rbultje, debargha): Explore ADST usage for superblocks
-  if (xd->mode_info_context->mbmi.sb_type)
-    return tx_type;
   if (xd->mode_info_context->mbmi.mode == B_PRED &&
       xd->q_index < ACTIVE_HT) {
+    const BLOCKD *b = &xd->block[ib];
     tx_type = txfm_map(
 #if CONFIG_NEWBINTRAMODES
         b->bmi.as_mode.first == B_CONTEXT_PRED ? b->bmi.as_mode.context :
@@ -481,6 +481,7 @@
         b->bmi.as_mode.first);
   } else if (xd->mode_info_context->mbmi.mode == I8X8_PRED &&
              xd->q_index < ACTIVE_HT) {
+    const BLOCKD *b = &xd->block[ib];
 #if USE_ADST_FOR_I8X8_4X4
 #if USE_ADST_PERIPHERY_ONLY
     // Use ADST for periphery blocks only
@@ -517,18 +518,18 @@
   return tx_type;
 }
 
-static TX_TYPE get_tx_type_8x8(const MACROBLOCKD *xd, const BLOCKD *b) {
+static TX_TYPE get_tx_type_8x8(const MACROBLOCKD *xd, int ib) {
   // TODO(debargha): explore different patterns for ADST usage when blocksize
   // is smaller than the prediction size
   TX_TYPE tx_type = DCT_DCT;
-  int ib = (int)(b - xd->block);
-  if (ib >= 16)
-    return tx_type;
   // TODO(rbultje, debargha): Explore ADST usage for superblocks
   if (xd->mode_info_context->mbmi.sb_type)
     return tx_type;
+  if (ib >= 16)
+    return tx_type;
   if (xd->mode_info_context->mbmi.mode == I8X8_PRED &&
       xd->q_index < ACTIVE_HT8) {
+    const BLOCKD *b = &xd->block[ib];
     // 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(
@@ -552,14 +553,10 @@
   return tx_type;
 }
 
-static TX_TYPE get_tx_type_16x16(const MACROBLOCKD *xd, const BLOCKD *b) {
+static TX_TYPE get_tx_type_16x16(const MACROBLOCKD *xd, int ib) {
   TX_TYPE tx_type = DCT_DCT;
-  int ib = (int)(b - xd->block);
   if (ib >= 16)
     return tx_type;
-  // TODO(rbultje, debargha): Explore ADST usage for superblocks
-  if (xd->mode_info_context->mbmi.sb_type)
-    return tx_type;
   if (xd->mode_info_context->mbmi.mode < I8X8_PRED &&
       xd->q_index < ACTIVE_HT16) {
     tx_type = txfm_map(pred_mode_conv(xd->mode_info_context->mbmi.mode));
@@ -567,24 +564,6 @@
   return tx_type;
 }
 
-static TX_TYPE get_tx_type(const MACROBLOCKD *xd, const BLOCKD *b) {
-  TX_TYPE tx_type = DCT_DCT;
-  int ib = (int)(b - xd->block);
-  if (ib >= 16)
-    return tx_type;
-  if (xd->mode_info_context->mbmi.txfm_size == TX_16X16) {
-    tx_type = get_tx_type_16x16(xd, b);
-  }
-  if (xd->mode_info_context->mbmi.txfm_size  == TX_8X8) {
-    ib = (ib & 8) + ((ib & 4) >> 1);
-    tx_type = get_tx_type_8x8(xd, &xd->block[ib]);
-  }
-  if (xd->mode_info_context->mbmi.txfm_size  == TX_4X4) {
-    tx_type = get_tx_type_4x4(xd, b);
-  }
-  return tx_type;
-}
-
 void vp9_build_block_doffsets(MACROBLOCKD *xd);
 void vp9_setup_block_dptrs(MACROBLOCKD *xd);
 
diff --git a/vp9/common/vp9_invtrans.c b/vp9/common/vp9_invtrans.c
index a26415f..a03a66e 100644
--- a/vp9/common/vp9_invtrans.c
+++ b/vp9/common/vp9_invtrans.c
@@ -24,7 +24,7 @@
   int i;
 
   for (i = 0; i < 16; i++) {
-    TX_TYPE tx_type = get_tx_type_4x4(xd, &xd->block[i]);
+    TX_TYPE tx_type = get_tx_type_4x4(xd, i);
     if (tx_type != DCT_DCT) {
       vp9_short_iht4x4(xd->block[i].dqcoeff, xd->block[i].diff, 16, tx_type);
     } else {
@@ -58,7 +58,7 @@
   BLOCKD *blockd = xd->block;
 
   for (i = 0; i < 9; i += 8) {
-    TX_TYPE tx_type = get_tx_type_8x8(xd, &xd->block[i]);
+    TX_TYPE tx_type = get_tx_type_8x8(xd, i);
     if (tx_type != DCT_DCT) {
       vp9_short_iht8x8(xd->block[i].dqcoeff, xd->block[i].diff, 16, tx_type);
     } else {
@@ -67,7 +67,7 @@
     }
   }
   for (i = 2; i < 11; i += 8) {
-    TX_TYPE tx_type = get_tx_type_8x8(xd, &xd->block[i]);
+    TX_TYPE tx_type = get_tx_type_8x8(xd, i);
     if (tx_type != DCT_DCT) {
       vp9_short_iht8x8(xd->block[i + 2].dqcoeff, xd->block[i].diff,
                            16, tx_type);
@@ -100,7 +100,7 @@
 
 void vp9_inverse_transform_mby_16x16(MACROBLOCKD *xd) {
   BLOCKD *bd = &xd->block[0];
-  TX_TYPE tx_type = get_tx_type_16x16(xd, bd);
+  TX_TYPE tx_type = get_tx_type_16x16(xd, 0);
   if (tx_type != DCT_DCT) {
     vp9_short_iht16x16(bd->dqcoeff, bd->diff, 16, tx_type);
   } else {
@@ -123,9 +123,16 @@
 
   for (n = 0; n < 4; n++) {
     const int x_idx = n & 1, y_idx = n >> 1;
+    const TX_TYPE tx_type = get_tx_type_16x16(xd, (y_idx * 8 + x_idx) * 4);
 
-    vp9_inverse_transform_b_16x16(xd->dqcoeff + n * 256,
-                                  xd->diff + x_idx * 16 + y_idx * 32 * 16, 64);
+    if (tx_type == DCT_DCT) {
+      vp9_inverse_transform_b_16x16(xd->dqcoeff + n * 256,
+                                    xd->diff + x_idx * 16 + y_idx * 32 * 16,
+                                    64);
+    } else {
+      vp9_short_iht16x16(xd->dqcoeff + n * 256,
+                         xd->diff + x_idx * 16 + y_idx * 32 * 16, 32, tx_type);
+    }
   }
 }
 
@@ -134,9 +141,15 @@
 
   for (n = 0; n < 16; n++) {
     const int x_idx = n & 3, y_idx = n >> 2;
+    const TX_TYPE tx_type = get_tx_type_8x8(xd, (y_idx * 8 + x_idx) * 2);
 
-    vp9_inverse_transform_b_8x8(xd->dqcoeff + n * 64,
-                                xd->diff + x_idx * 8 + y_idx * 32 * 8, 64);
+    if (tx_type == DCT_DCT) {
+      vp9_inverse_transform_b_8x8(xd->dqcoeff + n * 64,
+                                  xd->diff + x_idx * 8 + y_idx * 32 * 8, 64);
+    } else {
+      vp9_short_iht8x8(xd->dqcoeff + n * 64,
+                       xd->diff + x_idx * 8 + y_idx * 32 * 8, 32, tx_type);
+    }
   }
 }
 
@@ -145,9 +158,15 @@
 
   for (n = 0; n < 64; n++) {
     const int x_idx = n & 7, y_idx = n >> 3;
+    const TX_TYPE tx_type = get_tx_type_4x4(xd, y_idx * 8 + x_idx);
 
-    vp9_inverse_transform_b_4x4(xd, xd->eobs[n], xd->dqcoeff + n * 16,
-                                xd->diff + x_idx * 4 + y_idx * 4 * 32, 64);
+    if (tx_type == DCT_DCT) {
+      vp9_inverse_transform_b_4x4(xd, xd->eobs[n], xd->dqcoeff + n * 16,
+                                  xd->diff + x_idx * 4 + y_idx * 4 * 32, 64);
+    } else {
+      vp9_short_iht4x4(xd->dqcoeff + n * 16,
+                       xd->diff + x_idx * 4 + y_idx * 4 * 32, 32, tx_type);
+    }
   }
 }
 
@@ -206,9 +225,16 @@
 
   for (n = 0; n < 16; n++) {
     const int x_idx = n & 3, y_idx = n >> 2;
+    const TX_TYPE tx_type = get_tx_type_16x16(xd, (y_idx * 16 + x_idx) * 4);
 
-    vp9_inverse_transform_b_16x16(xd->dqcoeff + n * 256,
-                                  xd->diff + x_idx * 16 + y_idx * 64 * 16, 128);
+    if (tx_type == DCT_DCT) {
+      vp9_inverse_transform_b_16x16(xd->dqcoeff + n * 256,
+                                    xd->diff + x_idx * 16 + y_idx * 64 * 16,
+                                    128);
+    } else {
+      vp9_short_iht16x16(xd->dqcoeff + n * 256,
+                         xd->diff + x_idx * 16 + y_idx * 64 * 16, 64, tx_type);
+    }
   }
 }
 
@@ -217,9 +243,15 @@
 
   for (n = 0; n < 64; n++) {
     const int x_idx = n & 7, y_idx = n >> 3;
+    const TX_TYPE tx_type = get_tx_type_8x8(xd, (y_idx * 16 + x_idx) * 2);
 
-    vp9_inverse_transform_b_8x8(xd->dqcoeff + n * 64,
-                                xd->diff + x_idx * 8 + y_idx * 64 * 8, 128);
+    if (tx_type == DCT_DCT) {
+      vp9_inverse_transform_b_8x8(xd->dqcoeff + n * 64,
+                                  xd->diff + x_idx * 8 + y_idx * 64 * 8, 128);
+    } else {
+      vp9_short_iht8x8(xd->dqcoeff + n * 64,
+                       xd->diff + x_idx * 8 + y_idx * 64 * 8, 64, tx_type);
+    }
   }
 }
 
@@ -228,9 +260,15 @@
 
   for (n = 0; n < 256; n++) {
     const int x_idx = n & 15, y_idx = n >> 4;
+    const TX_TYPE tx_type = get_tx_type_4x4(xd, y_idx * 16 + x_idx);
 
-    vp9_inverse_transform_b_4x4(xd, xd->eobs[n], xd->dqcoeff + n * 16,
-                                xd->diff + x_idx * 4 + y_idx * 4 * 64, 128);
+    if (tx_type == DCT_DCT) {
+      vp9_inverse_transform_b_4x4(xd, xd->eobs[n], xd->dqcoeff + n * 16,
+                                  xd->diff + x_idx * 4 + y_idx * 4 * 64, 128);
+    } else {
+      vp9_short_iht4x4(xd->dqcoeff + n * 16,
+                       xd->diff + x_idx * 4 + y_idx * 4 * 64, 64, tx_type);
+    }
   }
 }
 
diff --git a/vp9/decoder/vp9_decodframe.c b/vp9/decoder/vp9_decodframe.c
index 8dfb3e8..74b882c 100644
--- a/vp9/decoder/vp9_decodframe.c
+++ b/vp9/decoder/vp9_decodframe.c
@@ -201,8 +201,7 @@
 
 static void decode_16x16(VP9D_COMP *pbi, MACROBLOCKD *xd,
                          BOOL_DECODER* const bc) {
-  BLOCKD *bd = &xd->block[0];
-  TX_TYPE tx_type = get_tx_type_16x16(xd, bd);
+  TX_TYPE tx_type = get_tx_type_16x16(xd, 0);
 #ifdef DEC_DEBUG
   if (dec_debug) {
     int i;
@@ -240,7 +239,7 @@
                        BOOL_DECODER* const bc) {
   // First do Y
   // if the first one is DCT_DCT assume all the rest are as well
-  TX_TYPE tx_type = get_tx_type_8x8(xd, &xd->block[0]);
+  TX_TYPE tx_type = get_tx_type_8x8(xd, 0);
 #ifdef DEC_DEBUG
   if (dec_debug) {
     int i;
@@ -267,7 +266,7 @@
         int i8x8mode = b->bmi.as_mode.first;
         vp9_intra8x8_predict(xd, b, i8x8mode, b->predictor);
       }
-      tx_type = get_tx_type_8x8(xd, &xd->block[ib]);
+      tx_type = get_tx_type_8x8(xd, ib);
       if (tx_type != DCT_DCT) {
         vp9_ht_dequant_idct_add_8x8_c(tx_type, q, dq, pre, dst, 16, stride,
                                       xd->eobs[idx]);
@@ -341,7 +340,7 @@
       vp9_intra8x8_predict(xd, b, i8x8mode, b->predictor);
       for (j = 0; j < 4; j++) {
         b = &xd->block[ib + iblock[j]];
-        tx_type = get_tx_type_4x4(xd, b);
+        tx_type = get_tx_type_4x4(xd, ib + iblock[j]);
         if (tx_type != DCT_DCT) {
           vp9_ht_dequant_idct_add_c(tx_type, b->qcoeff,
                                     b->dequant, b->predictor,
@@ -375,7 +374,7 @@
         eobtotal += vp9_decode_coefs_4x4(pbi, xd, bc, PLANE_TYPE_Y_WITH_DC, i);
 
       vp9_intra4x4_predict(xd, b, b_mode, b->predictor);
-      tx_type = get_tx_type_4x4(xd, b);
+      tx_type = get_tx_type_4x4(xd, i);
       if (tx_type != DCT_DCT) {
         vp9_ht_dequant_idct_add_c(tx_type, b->qcoeff,
                                   b->dequant, b->predictor,
@@ -397,7 +396,7 @@
                            xd->dst.v_buffer,
                            xd->dst.uv_stride,
                            xd);
-  } else if (mode == SPLITMV || get_tx_type_4x4(xd, &xd->block[0]) == DCT_DCT) {
+  } else if (mode == SPLITMV || get_tx_type_4x4(xd, 0) == DCT_DCT) {
     xd->itxm_add_y_block(xd->qcoeff,
                           xd->block[0].dequant,
                           xd->predictor,
@@ -431,7 +430,7 @@
 #endif
     for (i = 0; i < 16; i++) {
       BLOCKD *b = &xd->block[i];
-      tx_type = get_tx_type_4x4(xd, b);
+      tx_type = get_tx_type_4x4(xd, i);
       if (tx_type != DCT_DCT) {
         vp9_ht_dequant_idct_add_c(tx_type, b->qcoeff,
                                   b->dequant, b->predictor,
@@ -517,13 +516,24 @@
             xd->block[20].dequant, xd->dst.v_buffer, xd->dst.v_buffer,
             xd->dst.uv_stride, xd->dst.uv_stride, xd->eobs[320]);
         break;
-      case TX_16X16:  // FIXME(rbultje): adst
+      case TX_16X16:
         for (n = 0; n < 16; n++) {
           const int x_idx = n & 3, y_idx = n >> 2;
-          vp9_dequant_idct_add_16x16(xd->qcoeff + n * 256, xd->block[0].dequant,
-              xd->dst.y_buffer + y_idx * 16 * xd->dst.y_stride + x_idx * 16,
-              xd->dst.y_buffer + y_idx * 16 * xd->dst.y_stride + x_idx * 16,
-              xd->dst.y_stride, xd->dst.y_stride, xd->eobs[n * 16]);
+          const TX_TYPE tx_type = get_tx_type_16x16(xd,
+                                                    (y_idx * 16 + x_idx) * 4);
+          if (tx_type == DCT_DCT) {
+            vp9_dequant_idct_add_16x16(xd->qcoeff + n * 256,
+                xd->block[0].dequant,
+                xd->dst.y_buffer + y_idx * 16 * xd->dst.y_stride + x_idx * 16,
+                xd->dst.y_buffer + y_idx * 16 * xd->dst.y_stride + x_idx * 16,
+                xd->dst.y_stride, xd->dst.y_stride, xd->eobs[n * 16]);
+          } else {
+            vp9_ht_dequant_idct_add_16x16_c(tx_type, xd->qcoeff + n * 256,
+                xd->block[0].dequant,
+                xd->dst.y_buffer + y_idx * 16 * xd->dst.y_stride + x_idx * 16,
+                xd->dst.y_buffer + y_idx * 16 * xd->dst.y_stride + x_idx * 16,
+                xd->dst.y_stride, xd->dst.y_stride, xd->eobs[n * 16]);
+          }
         }
         for (n = 0; n < 4; n++) {
           const int x_idx = n & 1, y_idx = n >> 1;
@@ -539,13 +549,23 @@
               xd->dst.uv_stride, xd->dst.uv_stride, xd->eobs[320 + n * 16]);
         }
         break;
-      case TX_8X8:  // FIXME(rbultje): adst
+      case TX_8X8:
         for (n = 0; n < 64; n++) {
           const int x_idx = n & 7, y_idx = n >> 3;
-          vp9_dequant_idct_add_8x8_c(xd->qcoeff + n * 64, xd->block[0].dequant,
-              xd->dst.y_buffer + y_idx * 8 * xd->dst.y_stride + x_idx * 8,
-              xd->dst.y_buffer + y_idx * 8 * xd->dst.y_stride + x_idx * 8,
-              xd->dst.y_stride, xd->dst.y_stride, xd->eobs[n * 4]);
+          const TX_TYPE tx_type = get_tx_type_8x8(xd, (y_idx * 16 + x_idx) * 2);
+          if (tx_type == DCT_DCT) {
+            vp9_dequant_idct_add_8x8_c(xd->qcoeff + n * 64,
+                xd->block[0].dequant,
+                xd->dst.y_buffer + y_idx * 8 * xd->dst.y_stride + x_idx * 8,
+                xd->dst.y_buffer + y_idx * 8 * xd->dst.y_stride + x_idx * 8,
+                xd->dst.y_stride, xd->dst.y_stride, xd->eobs[n * 4]);
+          } else {
+            vp9_ht_dequant_idct_add_8x8_c(tx_type, xd->qcoeff + n * 64,
+                xd->block[0].dequant,
+                xd->dst.y_buffer + y_idx * 8 * xd->dst.y_stride + x_idx * 8,
+                xd->dst.y_buffer + y_idx * 8 * xd->dst.y_stride + x_idx * 8,
+                xd->dst.y_stride, xd->dst.y_stride, xd->eobs[n * 4]);
+          }
         }
         for (n = 0; n < 16; n++) {
           const int x_idx = n & 3, y_idx = n >> 2;
@@ -561,13 +581,22 @@
               xd->dst.uv_stride, xd->dst.uv_stride, xd->eobs[320 + n * 4]);
         }
         break;
-      case TX_4X4:  // FIXME(rbultje): adst
+      case TX_4X4:
         for (n = 0; n < 256; n++) {
           const int x_idx = n & 15, y_idx = n >> 4;
-          xd->itxm_add(xd->qcoeff + n * 16, xd->block[0].dequant,
-              xd->dst.y_buffer + y_idx * 4 * xd->dst.y_stride + x_idx * 4,
-              xd->dst.y_buffer + y_idx * 4 * xd->dst.y_stride + x_idx * 4,
-              xd->dst.y_stride, xd->dst.y_stride, xd->eobs[n]);
+          const TX_TYPE tx_type = get_tx_type_4x4(xd, y_idx * 16 + x_idx);
+          if (tx_type == DCT_DCT) {
+            xd->itxm_add(xd->qcoeff + n * 16, xd->block[0].dequant,
+                xd->dst.y_buffer + y_idx * 4 * xd->dst.y_stride + x_idx * 4,
+                xd->dst.y_buffer + y_idx * 4 * xd->dst.y_stride + x_idx * 4,
+                xd->dst.y_stride, xd->dst.y_stride, xd->eobs[n]);
+          } else {
+            vp9_ht_dequant_idct_add_c(tx_type, xd->qcoeff + n * 16,
+                xd->block[0].dequant,
+                xd->dst.y_buffer + y_idx * 4 * xd->dst.y_stride + x_idx * 4,
+                xd->dst.y_buffer + y_idx * 4 * xd->dst.y_stride + x_idx * 4,
+                xd->dst.y_stride, xd->dst.y_stride, xd->eobs[n]);
+          }
         }
         for (n = 0; n < 64; n++) {
           const int x_idx = n & 7, y_idx = n >> 3;
@@ -649,14 +678,24 @@
                                               xd->dst.v_buffer,
                                               xd->dst.uv_stride, xd);
         break;
-      case TX_16X16:  // FIXME(rbultje): adst
+      case TX_16X16:
         for (n = 0; n < 4; n++) {
           const int x_idx = n & 1, y_idx = n >> 1;
-          vp9_dequant_idct_add_16x16(
-              xd->qcoeff + n * 256, xd->block[0].dequant,
-              xd->dst.y_buffer + y_idx * 16 * xd->dst.y_stride + x_idx * 16,
-              xd->dst.y_buffer + y_idx * 16 * xd->dst.y_stride + x_idx * 16,
-              xd->dst.y_stride, xd->dst.y_stride, xd->eobs[n * 16]);
+          const TX_TYPE tx_type = get_tx_type_16x16(xd,
+                                                    (y_idx * 8 + x_idx) * 4);
+          if (tx_type == DCT_DCT) {
+            vp9_dequant_idct_add_16x16(
+                xd->qcoeff + n * 256, xd->block[0].dequant,
+                xd->dst.y_buffer + y_idx * 16 * xd->dst.y_stride + x_idx * 16,
+                xd->dst.y_buffer + y_idx * 16 * xd->dst.y_stride + x_idx * 16,
+                xd->dst.y_stride, xd->dst.y_stride, xd->eobs[n * 16]);
+          } else {
+            vp9_ht_dequant_idct_add_16x16_c(tx_type, xd->qcoeff + n * 256,
+                xd->block[0].dequant,
+                xd->dst.y_buffer + y_idx * 16 * xd->dst.y_stride + x_idx * 16,
+                xd->dst.y_buffer + y_idx * 16 * xd->dst.y_stride + x_idx * 16,
+                xd->dst.y_stride, xd->dst.y_stride, xd->eobs[n * 16]);
+          }
         }
         vp9_dequant_idct_add_uv_block_16x16_c(xd->qcoeff + 1024,
                                               xd->block[16].dequant,
@@ -664,13 +703,23 @@
                                               xd->dst.v_buffer,
                                               xd->dst.uv_stride, xd);
         break;
-      case TX_8X8:  // FIXME(rbultje): adst
+      case TX_8X8:
         for (n = 0; n < 16; n++) {
           const int x_idx = n & 3, y_idx = n >> 2;
-          vp9_dequant_idct_add_8x8_c(xd->qcoeff + n * 64, xd->block[0].dequant,
-              xd->dst.y_buffer + y_idx * 8 * xd->dst.y_stride + x_idx * 8,
-              xd->dst.y_buffer + y_idx * 8 * xd->dst.y_stride + x_idx * 8,
-              xd->dst.y_stride, xd->dst.y_stride, xd->eobs[n * 4]);
+          const TX_TYPE tx_type = get_tx_type_8x8(xd, (y_idx * 8 + x_idx) * 2);
+          if (tx_type == DCT_DCT) {
+            vp9_dequant_idct_add_8x8_c(xd->qcoeff + n * 64,
+                xd->block[0].dequant,
+                xd->dst.y_buffer + y_idx * 8 * xd->dst.y_stride + x_idx * 8,
+                xd->dst.y_buffer + y_idx * 8 * xd->dst.y_stride + x_idx * 8,
+                xd->dst.y_stride, xd->dst.y_stride, xd->eobs[n * 4]);
+          } else {
+            vp9_ht_dequant_idct_add_8x8_c(tx_type, xd->qcoeff + n * 64,
+                xd->block[0].dequant,
+                xd->dst.y_buffer + y_idx * 8 * xd->dst.y_stride + x_idx * 8,
+                xd->dst.y_buffer + y_idx * 8 * xd->dst.y_stride + x_idx * 8,
+                xd->dst.y_stride, xd->dst.y_stride, xd->eobs[n * 4]);
+          }
         }
         for (n = 0; n < 4; n++) {
           const int x_idx = n & 1, y_idx = n >> 1;
@@ -686,13 +735,22 @@
               xd->dst.uv_stride, xd->dst.uv_stride, xd->eobs[80 + n * 4]);
         }
         break;
-      case TX_4X4:  // FIXME(rbultje): adst
+      case TX_4X4:
         for (n = 0; n < 64; n++) {
           const int x_idx = n & 7, y_idx = n >> 3;
-          xd->itxm_add(xd->qcoeff + n * 16, xd->block[0].dequant,
-              xd->dst.y_buffer + y_idx * 4 * xd->dst.y_stride + x_idx * 4,
-              xd->dst.y_buffer + y_idx * 4 * xd->dst.y_stride + x_idx * 4,
-              xd->dst.y_stride, xd->dst.y_stride, xd->eobs[n]);
+          const TX_TYPE tx_type = get_tx_type_4x4(xd, y_idx * 8 + x_idx);
+          if (tx_type == DCT_DCT) {
+            xd->itxm_add(xd->qcoeff + n * 16, xd->block[0].dequant,
+                xd->dst.y_buffer + y_idx * 4 * xd->dst.y_stride + x_idx * 4,
+                xd->dst.y_buffer + y_idx * 4 * xd->dst.y_stride + x_idx * 4,
+                xd->dst.y_stride, xd->dst.y_stride, xd->eobs[n]);
+          } else {
+            vp9_ht_dequant_idct_add_c(tx_type, xd->qcoeff + n * 16,
+                xd->block[0].dequant,
+                xd->dst.y_buffer + y_idx * 4 * xd->dst.y_stride + x_idx * 4,
+                xd->dst.y_buffer + y_idx * 4 * xd->dst.y_stride + x_idx * 4,
+                xd->dst.y_stride, xd->dst.y_stride, xd->eobs[n]);
+          }
         }
         for (n = 0; n < 16; n++) {
           const int x_idx = n & 3, y_idx = n >> 2;
diff --git a/vp9/decoder/vp9_detokenize.c b/vp9/decoder/vp9_detokenize.c
index a53edfc..0a584d7 100644
--- a/vp9/decoder/vp9_detokenize.c
+++ b/vp9/decoder/vp9_detokenize.c
@@ -96,9 +96,8 @@
 
 static int decode_coefs(VP9D_COMP *dx, const MACROBLOCKD *xd,
                         BOOL_DECODER* const br, int block_idx,
-                        PLANE_TYPE type, TX_TYPE tx_type,
-                        int seg_eob, int16_t *qcoeff_ptr,
-                        const int *const scan, TX_SIZE txfm_size) {
+                        PLANE_TYPE type, int seg_eob, int16_t *qcoeff_ptr,
+                        TX_SIZE txfm_size) {
   ENTROPY_CONTEXT* const A0 = (ENTROPY_CONTEXT *) xd->above_context;
   ENTROPY_CONTEXT* const L0 = (ENTROPY_CONTEXT *) xd->left_context;
   int aidx, lidx;
@@ -114,6 +113,7 @@
   uint16_t nzc = 0;
   uint16_t nzc_expected = xd->mode_info_context->mbmi.nzcs[block_idx];
 #endif
+  const int *scan;
 
   if (xd->mode_info_context->mbmi.sb_type == BLOCK_SIZE_SB64X64) {
     aidx = vp9_block2above_sb64[txfm_size][block_idx];
@@ -128,19 +128,34 @@
 
   switch (txfm_size) {
     default:
-    case TX_4X4:
+    case TX_4X4: {
+      const TX_TYPE tx_type = get_tx_type_4x4(xd, block_idx);
+      switch (tx_type) {
+        default:
+          scan = vp9_default_zig_zag1d_4x4;
+          break;
+        case ADST_DCT:
+          scan = vp9_row_scan_4x4;
+          break;
+        case DCT_ADST:
+          scan = vp9_col_scan_4x4;
+          break;
+      }
       above_ec = A0[aidx] != 0;
       left_ec = L0[lidx] != 0;
       coef_probs  = fc->coef_probs_4x4;
       coef_counts = fc->coef_counts_4x4;
       break;
+    }
     case TX_8X8:
+      scan = vp9_default_zig_zag1d_8x8;
       coef_probs  = fc->coef_probs_8x8;
       coef_counts = fc->coef_counts_8x8;
       above_ec = (A0[aidx] + A0[aidx + 1]) != 0;
       left_ec  = (L0[lidx] + L0[lidx + 1]) != 0;
       break;
     case TX_16X16:
+      scan = vp9_default_zig_zag1d_16x16;
       coef_probs  = fc->coef_probs_16x16;
       coef_counts = fc->coef_counts_16x16;
       if (type == PLANE_TYPE_UV) {
@@ -154,6 +169,7 @@
       }
       break;
     case TX_32X32:
+      scan = vp9_default_zig_zag1d_32x32;
       coef_probs = fc->coef_probs_32x32;
       coef_counts = fc->coef_counts_32x32;
       if (type == PLANE_TYPE_UV) {
@@ -318,17 +334,15 @@
     case TX_32X32:
       // Luma block
       c = decode_coefs(pbi, xd, bc, 0, PLANE_TYPE_Y_WITH_DC,
-                       DCT_DCT, get_eob(xd, segment_id, 1024),
-                       xd->qcoeff, vp9_default_zig_zag1d_32x32, TX_32X32);
+                       get_eob(xd, segment_id, 1024), xd->qcoeff, TX_32X32);
       xd->eobs[0] = c;
       eobtotal += c;
 
       // 16x16 chroma blocks
       seg_eob = get_eob(xd, segment_id, 256);
       for (i = 64; i < 96; i += 16) {
-        c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_UV, DCT_DCT, seg_eob,
-                         xd->qcoeff + i * 16,
-                         vp9_default_zig_zag1d_16x16, TX_16X16);
+        c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_UV, seg_eob,
+                         xd->qcoeff + i * 16, TX_16X16);
         xd->eobs[i] = c;
         eobtotal += c;
       }
@@ -338,17 +352,15 @@
       seg_eob = get_eob(xd, segment_id, 256);
       for (i = 0; i < 64; i += 16) {
         c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_Y_WITH_DC,
-                         DCT_DCT, seg_eob, xd->qcoeff + i * 16,
-                         vp9_default_zig_zag1d_16x16, TX_16X16);
+                         seg_eob, xd->qcoeff + i * 16, TX_16X16);
         xd->eobs[i] = c;
         eobtotal += c;
       }
 
       // 16x16 chroma blocks
       for (i = 64; i < 96; i += 16) {
-        c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_UV, DCT_DCT, seg_eob,
-                         xd->qcoeff + i * 16,
-                         vp9_default_zig_zag1d_16x16, TX_16X16);
+        c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_UV, seg_eob,
+                         xd->qcoeff + i * 16, TX_16X16);
         xd->eobs[i] = c;
         eobtotal += c;
       }
@@ -358,17 +370,15 @@
       seg_eob = get_eob(xd, segment_id, 64);
       for (i = 0; i < 64; i += 4) {
         c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_Y_WITH_DC,
-                         DCT_DCT, seg_eob, xd->qcoeff + i * 16,
-                         vp9_default_zig_zag1d_8x8, TX_8X8);
+                         seg_eob, xd->qcoeff + i * 16, TX_8X8);
         xd->eobs[i] = c;
         eobtotal += c;
       }
 
       // 8x8 chroma blocks
       for (i = 64; i < 96; i += 4) {
-        c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_UV, DCT_DCT, seg_eob,
-                         xd->qcoeff + i * 16,
-                         vp9_default_zig_zag1d_8x8, TX_8X8);
+        c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_UV, seg_eob,
+                         xd->qcoeff + i * 16, TX_8X8);
         xd->eobs[i] = c;
         eobtotal += c;
       }
@@ -378,17 +388,15 @@
       seg_eob = get_eob(xd, segment_id, 16);
       for (i = 0; i < 64; i++) {
         c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_Y_WITH_DC,
-                         DCT_DCT, seg_eob, xd->qcoeff + i * 16,
-                         vp9_default_zig_zag1d_4x4, TX_4X4);
+                         seg_eob, xd->qcoeff + i * 16, TX_4X4);
         xd->eobs[i] = c;
         eobtotal += c;
       }
 
       // 4x4 chroma blocks
       for (i = 64; i < 96; i++) {
-        c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_UV, DCT_DCT, seg_eob,
-                         xd->qcoeff + i * 16,
-                         vp9_default_zig_zag1d_4x4, TX_4X4);
+        c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_UV, seg_eob,
+                         xd->qcoeff + i * 16, TX_4X4);
         xd->eobs[i] = c;
         eobtotal += c;
       }
@@ -411,17 +419,15 @@
       seg_eob = get_eob(xd, segment_id, 1024);
       for (i = 0; i < 256; i += 64) {
         c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_Y_WITH_DC,
-                         DCT_DCT, seg_eob, xd->qcoeff + i * 16,
-                         vp9_default_zig_zag1d_32x32, TX_32X32);
+                         seg_eob, xd->qcoeff + i * 16, TX_32X32);
         xd->eobs[i] = c;
         eobtotal += c;
       }
 
       // 32x32 chroma blocks
       for (i = 256; i < 384; i += 64) {
-        c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_UV, DCT_DCT, seg_eob,
-                         xd->qcoeff + i * 16,
-                         vp9_default_zig_zag1d_32x32, TX_32X32);
+        c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_UV, seg_eob,
+                         xd->qcoeff + i * 16, TX_32X32);
         xd->eobs[i] = c;
         eobtotal += c;
       }
@@ -431,17 +437,15 @@
       seg_eob = get_eob(xd, segment_id, 256);
       for (i = 0; i < 256; i += 16) {
         c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_Y_WITH_DC,
-                         DCT_DCT, seg_eob, xd->qcoeff + i * 16,
-                         vp9_default_zig_zag1d_16x16, TX_16X16);
+                         seg_eob, xd->qcoeff + i * 16, TX_16X16);
         xd->eobs[i] = c;
         eobtotal += c;
       }
 
       // 16x16 chroma blocks
       for (i = 256; i < 384; i += 16) {
-        c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_UV, DCT_DCT, seg_eob,
-                         xd->qcoeff + i * 16,
-                         vp9_default_zig_zag1d_16x16, TX_16X16);
+        c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_UV, seg_eob,
+                         xd->qcoeff + i * 16, TX_16X16);
         xd->eobs[i] = c;
         eobtotal += c;
       }
@@ -451,17 +455,15 @@
       seg_eob = get_eob(xd, segment_id, 64);
       for (i = 0; i < 256; i += 4) {
         c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_Y_WITH_DC,
-                         DCT_DCT, seg_eob, xd->qcoeff + i * 16,
-                         vp9_default_zig_zag1d_8x8, TX_8X8);
+                         seg_eob, xd->qcoeff + i * 16, TX_8X8);
         xd->eobs[i] = c;
         eobtotal += c;
       }
 
       // 8x8 chroma blocks
       for (i = 256; i < 384; i += 4) {
-        c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_UV, DCT_DCT, seg_eob,
-                         xd->qcoeff + i * 16,
-                         vp9_default_zig_zag1d_8x8, TX_8X8);
+        c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_UV, seg_eob,
+                         xd->qcoeff + i * 16, TX_8X8);
         xd->eobs[i] = c;
         eobtotal += c;
       }
@@ -471,17 +473,15 @@
       seg_eob = get_eob(xd, segment_id, 16);
       for (i = 0; i < 256; i++) {
         c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_Y_WITH_DC,
-                         DCT_DCT, seg_eob, xd->qcoeff + i * 16,
-                         vp9_default_zig_zag1d_4x4, TX_4X4);
+                         seg_eob, xd->qcoeff + i * 16, TX_4X4);
         xd->eobs[i] = c;
         eobtotal += c;
       }
 
       // 4x4 chroma blocks
       for (i = 256; i < 384; i++) {
-        c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_UV, DCT_DCT, seg_eob,
-                         xd->qcoeff + i * 16,
-                         vp9_default_zig_zag1d_4x4, TX_4X4);
+        c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_UV, seg_eob,
+                         xd->qcoeff + i * 16, TX_4X4);
         xd->eobs[i] = c;
         eobtotal += c;
       }
@@ -500,9 +500,7 @@
 
   // Luma block
   int c = decode_coefs(pbi, xd, bc, 0, PLANE_TYPE_Y_WITH_DC,
-                       get_tx_type(xd, &xd->block[0]),
-                       get_eob(xd, segment_id, 256),
-                       xd->qcoeff, vp9_default_zig_zag1d_16x16, TX_16X16);
+                       get_eob(xd, segment_id, 256), xd->qcoeff, TX_16X16);
   xd->eobs[0] = c;
   eobtotal += c;
 
@@ -510,8 +508,7 @@
   seg_eob = get_eob(xd, segment_id, 64);
   for (i = 16; i < 24; i += 4) {
     c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_UV,
-                     DCT_DCT, seg_eob, xd->block[i].qcoeff,
-                     vp9_default_zig_zag1d_8x8, TX_8X8);
+                     seg_eob, xd->block[i].qcoeff, TX_8X8);
     xd->eobs[i] = c;
     eobtotal += c;
   }
@@ -528,9 +525,7 @@
   seg_eob = get_eob(xd, segment_id, 64);
   for (i = 0; i < 16; i += 4) {
     c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_Y_WITH_DC,
-                     get_tx_type(xd, xd->block + i),
-                     seg_eob, xd->block[i].qcoeff,
-                     vp9_default_zig_zag1d_8x8, TX_8X8);
+                     seg_eob, xd->block[i].qcoeff, TX_8X8);
     xd->eobs[i] = c;
     eobtotal += c;
   }
@@ -542,16 +537,14 @@
     seg_eob = get_eob(xd, segment_id, 16);
     for (i = 16; i < 24; i++) {
       c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_UV,
-                       DCT_DCT, seg_eob, xd->block[i].qcoeff,
-                       vp9_default_zig_zag1d_4x4, TX_4X4);
+                       seg_eob, xd->block[i].qcoeff, TX_4X4);
       xd->eobs[i] = c;
       eobtotal += c;
     }
   } else {
     for (i = 16; i < 24; i += 4) {
       c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_UV,
-                       DCT_DCT, seg_eob, xd->block[i].qcoeff,
-                       vp9_default_zig_zag1d_8x8, TX_8X8);
+                       seg_eob, xd->block[i].qcoeff, TX_8X8);
       xd->eobs[i] = c;
       eobtotal += c;
     }
@@ -562,43 +555,20 @@
 
 static int decode_coefs_4x4(VP9D_COMP *dx, MACROBLOCKD *xd,
                             BOOL_DECODER* const bc,
-                            PLANE_TYPE type, int i, int seg_eob,
-                            TX_TYPE tx_type, const int *scan) {
-  int c = decode_coefs(dx, xd, bc, i, type, tx_type, seg_eob,
-                       xd->block[i].qcoeff, scan, TX_4X4);
+                            PLANE_TYPE type, int i, int seg_eob) {
+  int c = decode_coefs(dx, xd, bc, i, type, seg_eob,
+                       xd->block[i].qcoeff, TX_4X4);
   xd->eobs[i] = c;
   return c;
 }
 
-static int decode_coefs_4x4_y(VP9D_COMP *dx, MACROBLOCKD *xd,
-                              BOOL_DECODER* const bc,
-                              PLANE_TYPE type, int i, int seg_eob) {
-  const TX_TYPE tx_type = (type == PLANE_TYPE_Y_WITH_DC) ?
-                          get_tx_type(xd, &xd->block[i]) : DCT_DCT;
-  const int *scan;
-
-  switch (tx_type) {
-    case ADST_DCT:
-      scan = vp9_row_scan_4x4;
-      break;
-    case DCT_ADST:
-      scan = vp9_col_scan_4x4;
-      break;
-    default:
-      scan = vp9_default_zig_zag1d_4x4;
-      break;
-  }
-
-  return decode_coefs_4x4(dx, xd, bc, type, i, seg_eob, tx_type, scan);
-}
-
 int vp9_decode_coefs_4x4(VP9D_COMP *dx, MACROBLOCKD *xd,
                          BOOL_DECODER* const bc,
                          PLANE_TYPE type, int i) {
   const int segment_id = xd->mode_info_context->mbmi.segment_id;
   const int seg_eob = get_eob(xd, segment_id, 16);
 
-  return decode_coefs_4x4_y(dx, xd, bc, type, i, seg_eob);
+  return decode_coefs_4x4(dx, xd, bc, type, i, seg_eob);
 }
 
 static int decode_mb_tokens_4x4_uv(VP9D_COMP* const dx,
@@ -609,8 +579,7 @@
 
   // chroma blocks
   for (i = 16; i < 24; i++) {
-    eobtotal += decode_coefs_4x4(dx, xd, bc, PLANE_TYPE_UV, i, seg_eob,
-                                 DCT_DCT, vp9_default_zig_zag1d_4x4);
+    eobtotal += decode_coefs_4x4(dx, xd, bc, PLANE_TYPE_UV, i, seg_eob);
   }
 
   return eobtotal;
@@ -634,8 +603,7 @@
 
   // luma blocks
   for (i = 0; i < 16; ++i) {
-    eobtotal += decode_coefs_4x4_y(dx, xd, bc,
-                                   PLANE_TYPE_Y_WITH_DC, i, seg_eob);
+    eobtotal += decode_coefs_4x4(dx, xd, bc, PLANE_TYPE_Y_WITH_DC, i, seg_eob);
   }
 
   // chroma blocks
diff --git a/vp9/encoder/vp9_encodeintra.c b/vp9/encoder/vp9_encodeintra.c
index d3b595b..3c98d4a 100644
--- a/vp9/encoder/vp9_encodeintra.c
+++ b/vp9/encoder/vp9_encodeintra.c
@@ -50,7 +50,7 @@
   vp9_intra4x4_predict(&x->e_mbd, b, b->bmi.as_mode.first, b->predictor);
   vp9_subtract_b(be, b, 16);
 
-  tx_type = get_tx_type_4x4(&x->e_mbd, b);
+  tx_type = get_tx_type_4x4(&x->e_mbd, ib);
   if (tx_type != DCT_DCT) {
     vp9_short_fht4x4(be->src_diff, be->coeff, 16, tx_type);
     vp9_ht_quantize_b_4x4(x, ib, tx_type);
@@ -152,7 +152,7 @@
   if (xd->mode_info_context->mbmi.txfm_size == TX_8X8) {
     int idx = (ib & 0x02) ? (ib + 2) : ib;
 
-    tx_type = get_tx_type_8x8(xd, &xd->block[ib]);
+    tx_type = get_tx_type_8x8(xd, ib);
     if (tx_type != DCT_DCT) {
       vp9_short_fht8x8(be->src_diff, (x->block + idx)->coeff, 16, tx_type);
       x->quantize_b_8x8(x, idx);
@@ -167,12 +167,13 @@
     for (i = 0; i < 4; i++) {
       b = &xd->block[ib + iblock[i]];
       be = &x->block[ib + iblock[i]];
-      tx_type = get_tx_type_4x4(xd, b);
+      tx_type = get_tx_type_4x4(xd, ib + iblock[i]);
       if (tx_type != DCT_DCT) {
         vp9_short_fht4x4(be->src_diff, be->coeff, 16, tx_type);
         vp9_ht_quantize_b_4x4(x, ib + iblock[i], tx_type);
         vp9_short_iht4x4(b->dqcoeff, b->diff, 16, tx_type);
-      } else if (!(i & 1) && get_tx_type_4x4(xd, b + 1) == DCT_DCT) {
+      } else if (!(i & 1) &&
+                 get_tx_type_4x4(xd, ib + iblock[i] + 1) == DCT_DCT) {
         x->fwd_txm8x4(be->src_diff, be->coeff, 32);
         x->quantize_b_4x4_pair(x, ib + iblock[i], ib + iblock[i] + 1);
         vp9_inverse_transform_b_4x4(xd, xd->eobs[ib + iblock[i]],
diff --git a/vp9/encoder/vp9_encodemb.c b/vp9/encoder/vp9_encodemb.c
index c038645..dae177a 100644
--- a/vp9/encoder/vp9_encodemb.c
+++ b/vp9/encoder/vp9_encodemb.c
@@ -210,10 +210,10 @@
 
   for (i = 0; i < 16; i++) {
     BLOCK *b = &x->block[i];
-    TX_TYPE tx_type = get_tx_type_4x4(xd, &xd->block[i]);
+    TX_TYPE tx_type = get_tx_type_4x4(xd, i);
     if (tx_type != DCT_DCT) {
       vp9_short_fht4x4(b->src_diff, b->coeff, 16, tx_type);
-    } else if (!(i & 1) && get_tx_type_4x4(xd, &xd->block[i + 1]) == DCT_DCT) {
+    } else if (!(i & 1) && get_tx_type_4x4(xd, i + 1) == DCT_DCT) {
       x->fwd_txm8x4(x->block[i].src_diff, x->block[i].coeff, 32);
       i++;
     } else {
@@ -241,7 +241,7 @@
 
   for (i = 0; i < 9; i += 8) {
     BLOCK *b = &x->block[i];
-    tx_type = get_tx_type_8x8(xd, &xd->block[i]);
+    tx_type = get_tx_type_8x8(xd, i);
     if (tx_type != DCT_DCT) {
       vp9_short_fht8x8(b->src_diff, b->coeff, 16, tx_type);
     } else {
@@ -250,7 +250,7 @@
   }
   for (i = 2; i < 11; i += 8) {
     BLOCK *b = &x->block[i];
-    tx_type = get_tx_type_8x8(xd, &xd->block[i]);
+    tx_type = get_tx_type_8x8(xd, i);
     if (tx_type != DCT_DCT) {
       vp9_short_fht8x8(b->src_diff, (b + 2)->coeff, 16, tx_type);
     } else {
@@ -274,7 +274,7 @@
 void vp9_transform_mby_16x16(MACROBLOCK *x) {
   MACROBLOCKD *xd = &x->e_mbd;
   BLOCK *b = &x->block[0];
-  TX_TYPE tx_type = get_tx_type_16x16(xd, &xd->block[0]);
+  TX_TYPE tx_type = get_tx_type_16x16(xd, 0);
   vp9_clear_system_state();
   if (tx_type != DCT_DCT) {
     vp9_short_fht16x16(b->src_diff, b->coeff, 16, tx_type);
@@ -293,35 +293,56 @@
 }
 
 void vp9_transform_sby_16x16(MACROBLOCK *x) {
+  MACROBLOCKD *const xd = &x->e_mbd;
   int n;
 
   for (n = 0; n < 4; n++) {
     const int x_idx = n & 1, y_idx = n >> 1;
+    const TX_TYPE tx_type = get_tx_type_16x16(xd, (y_idx * 8 + x_idx) * 4);
 
-    x->fwd_txm16x16(x->src_diff + y_idx * 32 * 16 + x_idx * 16,
-                    x->coeff + n * 256, 64);
+    if (tx_type != DCT_DCT) {
+      vp9_short_fht16x16(x->src_diff + y_idx * 32 * 16 + x_idx * 16,
+                         x->coeff + n * 256, 32, tx_type);
+    } else {
+      x->fwd_txm16x16(x->src_diff + y_idx * 32 * 16 + x_idx * 16,
+                      x->coeff + n * 256, 64);
+    }
   }
 }
 
 void vp9_transform_sby_8x8(MACROBLOCK *x) {
+  MACROBLOCKD *const xd = &x->e_mbd;
   int n;
 
   for (n = 0; n < 16; n++) {
     const int x_idx = n & 3, y_idx = n >> 2;
+    const TX_TYPE tx_type = get_tx_type_8x8(xd, (y_idx * 8 + x_idx) * 2);
 
-    x->fwd_txm8x8(x->src_diff + y_idx * 32 * 8 + x_idx * 8,
-                  x->coeff + n * 64, 64);
+    if (tx_type != DCT_DCT) {
+      vp9_short_fht8x8(x->src_diff + y_idx * 32 * 8 + x_idx * 8,
+                       x->coeff + n * 64, 32, tx_type);
+    } else {
+      x->fwd_txm8x8(x->src_diff + y_idx * 32 * 8 + x_idx * 8,
+                    x->coeff + n * 64, 64);
+    }
   }
 }
 
 void vp9_transform_sby_4x4(MACROBLOCK *x) {
+  MACROBLOCKD *const xd = &x->e_mbd;
   int n;
 
   for (n = 0; n < 64; n++) {
     const int x_idx = n & 7, y_idx = n >> 3;
+    const TX_TYPE tx_type = get_tx_type_4x4(xd, y_idx * 8 + x_idx);
 
-    x->fwd_txm4x4(x->src_diff + y_idx * 32 * 4 + x_idx * 4,
-                  x->coeff + n * 16, 64);
+    if (tx_type != DCT_DCT) {
+      vp9_short_fht4x4(x->src_diff + y_idx * 32 * 4 + x_idx * 4,
+                       x->coeff + n * 16, 32, tx_type);
+    } else {
+      x->fwd_txm4x4(x->src_diff + y_idx * 32 * 4 + x_idx * 4,
+                    x->coeff + n * 16, 64);
+    }
   }
 }
 
@@ -371,35 +392,56 @@
 }
 
 void vp9_transform_sb64y_16x16(MACROBLOCK *x) {
+  MACROBLOCKD *const xd = &x->e_mbd;
   int n;
 
   for (n = 0; n < 16; n++) {
     const int x_idx = n & 3, y_idx = n >> 2;
+    const TX_TYPE tx_type = get_tx_type_16x16(xd, (y_idx * 16 + x_idx) * 4);
 
-    x->fwd_txm16x16(x->src_diff + y_idx * 64 * 16 + x_idx * 16,
-                    x->coeff + n * 256, 128);
+    if (tx_type != DCT_DCT) {
+      vp9_short_fht16x16(x->src_diff + y_idx * 64 * 16 + x_idx * 16,
+                         x->coeff + n * 256, 64, tx_type);
+    } else {
+      x->fwd_txm16x16(x->src_diff + y_idx * 64 * 16 + x_idx * 16,
+                      x->coeff + n * 256, 128);
+    }
   }
 }
 
 void vp9_transform_sb64y_8x8(MACROBLOCK *x) {
+  MACROBLOCKD *const xd = &x->e_mbd;
   int n;
 
   for (n = 0; n < 64; n++) {
     const int x_idx = n & 7, y_idx = n >> 3;
+    const TX_TYPE tx_type = get_tx_type_8x8(xd, (y_idx * 16 + x_idx) * 2);
 
-    x->fwd_txm8x8(x->src_diff + y_idx * 64 * 8 + x_idx * 8,
-                  x->coeff + n * 64, 128);
+    if (tx_type != DCT_DCT) {
+      vp9_short_fht8x8(x->src_diff + y_idx * 64 * 8 + x_idx * 8,
+                         x->coeff + n * 64, 64, tx_type);
+    } else {
+      x->fwd_txm8x8(x->src_diff + y_idx * 64 * 8 + x_idx * 8,
+                    x->coeff + n * 64, 128);
+    }
   }
 }
 
 void vp9_transform_sb64y_4x4(MACROBLOCK *x) {
+  MACROBLOCKD *const xd = &x->e_mbd;
   int n;
 
   for (n = 0; n < 256; n++) {
     const int x_idx = n & 15, y_idx = n >> 4;
+    const TX_TYPE tx_type = get_tx_type_4x4(xd, y_idx * 16 + x_idx);
 
-    x->fwd_txm4x4(x->src_diff + y_idx * 64 * 4 + x_idx * 4,
-                  x->coeff + n * 16, 128);
+    if (tx_type != DCT_DCT) {
+      vp9_short_fht8x8(x->src_diff + y_idx * 64 * 4 + x_idx * 4,
+                       x->coeff + n * 16, 64, tx_type);
+    } else {
+      x->fwd_txm4x4(x->src_diff + y_idx * 64 * 4 + x_idx * 4,
+                    x->coeff + n * 16, 128);
+    }
   }
 }
 
@@ -513,7 +555,6 @@
   int default_eob;
   int const *scan;
   const int mul = 1 + (tx_size == TX_32X32);
-  TX_TYPE tx_type;
 #if CONFIG_CODE_NONZEROCOUNT
   // TODO(debargha): the dynamic programming approach used in this function
   // is not compatible with the true rate cost when nzcs are used. Note
@@ -534,32 +575,21 @@
 
   switch (tx_size) {
     default:
-    case TX_4X4:
+    case TX_4X4: {
+      const TX_TYPE tx_type = get_tx_type_4x4(xd, ib);
       default_eob = 16;
 #if CONFIG_CODE_NONZEROCOUNT
       nzc_cost = mb->nzc_costs_4x4[nzc_context][ref][type];
 #endif
-      // NOTE: this isn't called (for intra4x4 modes), but will be left in
-      // since it could be used later
-      tx_type = get_tx_type_4x4(&mb->e_mbd, &xd->block[ib]);
-      if (tx_type != DCT_DCT) {
-        switch (tx_type) {
-          case ADST_DCT:
-            scan = vp9_row_scan_4x4;
-            break;
-
-          case DCT_ADST:
-            scan = vp9_col_scan_4x4;
-            break;
-
-          default:
-            scan = vp9_default_zig_zag1d_4x4;
-            break;
-        }
+      if (tx_type == DCT_ADST) {
+        scan = vp9_col_scan_4x4;
+      } else if (tx_type == ADST_DCT) {
+        scan = vp9_row_scan_4x4;
       } else {
         scan = vp9_default_zig_zag1d_4x4;
       }
       break;
+    }
     case TX_8X8:
       scan = vp9_default_zig_zag1d_8x8;
       default_eob = 64;
diff --git a/vp9/encoder/vp9_quantize.c b/vp9/encoder/vp9_quantize.c
index 66ee248..2488fdd 100644
--- a/vp9/encoder/vp9_quantize.c
+++ b/vp9/encoder/vp9_quantize.c
@@ -21,38 +21,46 @@
 extern int enc_debug;
 #endif
 
+static INLINE int plane_idx(MACROBLOCKD *xd, int b_idx) {
+  const BLOCK_SIZE_TYPE sb_type = xd->mode_info_context->mbmi.sb_type;
+  if (b_idx < (16 << (sb_type * 2)))
+    return 0;  // Y
+  else if (b_idx < (20 << (sb_type * 2)))
+    return 16;  // U
+  assert(b_idx < (24 << (sb_type * 2)));
+  return 20;  // V
+}
+
 void vp9_ht_quantize_b_4x4(MACROBLOCK *mb, int b_idx, TX_TYPE tx_type) {
   MACROBLOCKD *const xd = &mb->e_mbd;
-  BLOCK *const b = &mb->block[b_idx];
-  BLOCKD *const d = &xd->block[b_idx];
+  BLOCK *const b = &mb->block[0];
+  BLOCKD *const d = &xd->block[0];
   int i, rc, eob;
   int zbin;
   int x, y, z, sz;
+  int16_t *coeff_ptr       = mb->coeff + b_idx * 16;
+  int16_t *qcoeff_ptr      = xd->qcoeff + b_idx * 16;
+  int16_t *dqcoeff_ptr     = xd->dqcoeff + b_idx * 16;
   int16_t *zbin_boost_ptr  = b->zrun_zbin_boost;
-  int16_t *coeff_ptr       = b->coeff;
   int16_t *zbin_ptr        = b->zbin;
   int16_t *round_ptr       = b->round;
   int16_t *quant_ptr       = b->quant;
   uint8_t *quant_shift_ptr = b->quant_shift;
-  int16_t *qcoeff_ptr      = d->qcoeff;
-  int16_t *dqcoeff_ptr     = d->dqcoeff;
   int16_t *dequant_ptr     = d->dequant;
   int zbin_oq_value        = b->zbin_extra;
-
-  int const *pt_scan ;
+  const int *pt_scan;
 #if CONFIG_CODE_NONZEROCOUNT
   int nzc = 0;
 #endif
 
+  assert(plane_idx(xd, b_idx) == 0);
   switch (tx_type) {
     case ADST_DCT:
       pt_scan = vp9_row_scan_4x4;
       break;
-
     case DCT_ADST:
       pt_scan = vp9_col_scan_4x4;
       break;
-
     default:
       pt_scan = vp9_default_zig_zag1d_4x4;
       break;
@@ -101,19 +109,20 @@
 
 void vp9_regular_quantize_b_4x4(MACROBLOCK *mb, int b_idx) {
   MACROBLOCKD *const xd = &mb->e_mbd;
-  BLOCK *const b = &mb->block[b_idx];
-  BLOCKD *const d = &xd->block[b_idx];
+  const int c_idx = plane_idx(xd, b_idx);
+  BLOCK *const b = &mb->block[c_idx];
+  BLOCKD *const d = &xd->block[c_idx];
   int i, rc, eob;
   int zbin;
   int x, y, z, sz;
+  int16_t *coeff_ptr       = mb->coeff + b_idx * 16;
+  int16_t *qcoeff_ptr      = xd->qcoeff + b_idx * 16;
+  int16_t *dqcoeff_ptr     = xd->dqcoeff + b_idx * 16;
   int16_t *zbin_boost_ptr  = b->zrun_zbin_boost;
-  int16_t *coeff_ptr       = b->coeff;
   int16_t *zbin_ptr        = b->zbin;
   int16_t *round_ptr       = b->round;
   int16_t *quant_ptr       = b->quant;
   uint8_t *quant_shift_ptr = b->quant_shift;
-  int16_t *qcoeff_ptr      = d->qcoeff;
-  int16_t *dqcoeff_ptr     = d->dqcoeff;
   int16_t *dequant_ptr     = d->dequant;
   int zbin_oq_value        = b->zbin_extra;
 #if CONFIG_CODE_NONZEROCOUNT
@@ -162,11 +171,11 @@
 #endif
 }
 
-void vp9_quantize_mby_4x4_c(MACROBLOCK *x) {
+void vp9_quantize_mby_4x4(MACROBLOCK *x) {
   int i;
 
   for (i = 0; i < 16; i++) {
-    TX_TYPE tx_type = get_tx_type_4x4(&x->e_mbd, &x->e_mbd.block[i]);
+    TX_TYPE tx_type = get_tx_type_4x4(&x->e_mbd, i);
     if (tx_type != DCT_DCT) {
       vp9_ht_quantize_b_4x4(x, i, tx_type);
     } else {
@@ -175,24 +184,25 @@
   }
 }
 
-void vp9_quantize_mbuv_4x4_c(MACROBLOCK *x) {
+void vp9_quantize_mbuv_4x4(MACROBLOCK *x) {
   int i;
 
   for (i = 16; i < 24; i++)
     x->quantize_b_4x4(x, i);
 }
 
-void vp9_quantize_mb_4x4_c(MACROBLOCK *x) {
-  vp9_quantize_mby_4x4_c(x);
-  vp9_quantize_mbuv_4x4_c(x);
+void vp9_quantize_mb_4x4(MACROBLOCK *x) {
+  vp9_quantize_mby_4x4(x);
+  vp9_quantize_mbuv_4x4(x);
 }
 
 void vp9_regular_quantize_b_8x8(MACROBLOCK *mb, int b_idx) {
   MACROBLOCKD *const xd = &mb->e_mbd;
-  BLOCK *const b = &mb->block[b_idx];
-  BLOCKD *const d = &xd->block[b_idx];
-  int16_t *qcoeff_ptr = d->qcoeff;
-  int16_t *dqcoeff_ptr = d->dqcoeff;
+  int16_t *qcoeff_ptr = xd->qcoeff + 16 * b_idx;
+  int16_t *dqcoeff_ptr = xd->dqcoeff + 16 * b_idx;
+  const int c_idx = plane_idx(xd, b_idx);
+  BLOCK *const b = &mb->block[c_idx];
+  BLOCKD *const d = &xd->block[c_idx];
 
   vpx_memset(qcoeff_ptr, 0, 64 * sizeof(int16_t));
   vpx_memset(dqcoeff_ptr, 0, 64 * sizeof(int16_t));
@@ -203,7 +213,7 @@
     int x, y, z, sz;
     int zero_run;
     int16_t *zbin_boost_ptr = b->zrun_zbin_boost;
-    int16_t *coeff_ptr  = b->coeff;
+    int16_t *coeff_ptr  = mb->coeff + 16 * b_idx;
     int16_t *zbin_ptr   = b->zbin;
     int16_t *round_ptr  = b->round;
     int16_t *quant_ptr  = b->quant;
@@ -392,14 +402,16 @@
 
 void vp9_regular_quantize_b_16x16(MACROBLOCK *mb, int b_idx) {
   MACROBLOCKD *const xd = &mb->e_mbd;
-  BLOCK *const b = &mb->block[b_idx];
-  BLOCKD *const d = &xd->block[b_idx];
+  const int c_idx = plane_idx(xd, b_idx);
+  BLOCK *const b = &mb->block[c_idx];
+  BLOCKD *const d = &xd->block[c_idx];
+
   quantize(b->zrun_zbin_boost,
-           b->coeff,
+           mb->coeff + 16 * b_idx,
            256, b->skip_block,
            b->zbin, b->round, b->quant, b->quant_shift,
-           d->qcoeff,
-           d->dqcoeff,
+           xd->qcoeff + 16 * b_idx,
+           xd->dqcoeff + 16 * b_idx,
            d->dequant,
            b->zbin_extra,
            &xd->eobs[b_idx],
@@ -409,347 +421,138 @@
            vp9_default_zig_zag1d_16x16, 1);
 }
 
-void vp9_quantize_sby_32x32(MACROBLOCK *x) {
-  MACROBLOCKD *const xd = &x->e_mbd;
-  BLOCK *const b = &x->block[0];
-  BLOCKD *const d = &xd->block[0];
+void vp9_regular_quantize_b_32x32(MACROBLOCK *mb, int b_idx) {
+  MACROBLOCKD *const xd = &mb->e_mbd;
+  const int c_idx = plane_idx(xd, b_idx);
+  BLOCK *const b = &mb->block[c_idx];
+  BLOCKD *const d = &xd->block[c_idx];
 
   quantize(b->zrun_zbin_boost,
-           x->coeff,
+           mb->coeff + b_idx * 16,
            1024, b->skip_block,
            b->zbin,
            b->round, b->quant, b->quant_shift,
-           xd->qcoeff,
-           xd->dqcoeff,
+           xd->qcoeff + b_idx * 16,
+           xd->dqcoeff + b_idx * 16,
            d->dequant,
            b->zbin_extra,
-           &xd->eobs[0],
+           &xd->eobs[b_idx],
 #if CONFIG_CODE_NONZEROCOUNT
-           &xd->nzcs[0],
+           &xd->nzcs[b_idx],
 #endif
            vp9_default_zig_zag1d_32x32, 2);
 }
 
+void vp9_quantize_sby_32x32(MACROBLOCK *x) {
+  vp9_regular_quantize_b_32x32(x, 0);
+}
+
 void vp9_quantize_sby_16x16(MACROBLOCK *x) {
-  MACROBLOCKD *const xd = &x->e_mbd;
-  BLOCK *const b = &x->block[0];
-  BLOCKD *const d = &xd->block[0];
   int n;
 
   for (n = 0; n < 4; n++)
-    quantize(b->zrun_zbin_boost,
-             x->coeff + n * 256,
-             256, b->skip_block,
-             b->zbin,
-             b->round, b->quant, b->quant_shift,
-             xd->qcoeff + n * 256,
-             xd->dqcoeff + n * 256,
-             d->dequant,
-             b->zbin_extra,
-             &xd->eobs[n * 16],
-#if CONFIG_CODE_NONZEROCOUNT
-             &xd->nzcs[n * 16],
-#endif
-             vp9_default_zig_zag1d_16x16, 1);
+    x->quantize_b_16x16(x, n * 16);
 }
 
 void vp9_quantize_sby_8x8(MACROBLOCK *x) {
-  MACROBLOCKD *const xd = &x->e_mbd;
-  BLOCK *const b = &x->block[0];
-  BLOCKD *const d = &xd->block[0];
   int n;
 
   for (n = 0; n < 16; n++)
-    quantize(b->zrun_zbin_boost,
-             x->coeff + n * 64,
-             64, b->skip_block,
-             b->zbin,
-             b->round, b->quant, b->quant_shift,
-             xd->qcoeff + n * 64,
-             xd->dqcoeff + n * 64,
-             d->dequant,
-             b->zbin_extra,
-             &xd->eobs[n * 4],
-#if CONFIG_CODE_NONZEROCOUNT
-             &xd->nzcs[n * 4],
-#endif
-             vp9_default_zig_zag1d_8x8, 1);
+    x->quantize_b_8x8(x, n * 4);
 }
 
 void vp9_quantize_sby_4x4(MACROBLOCK *x) {
   MACROBLOCKD *const xd = &x->e_mbd;
-  BLOCK *const b = &x->block[0];
-  BLOCKD *const d = &xd->block[0];
   int n;
 
-  for (n = 0; n < 64; n++)
-    quantize(b->zrun_zbin_boost,
-             x->coeff + n * 16,
-             16, b->skip_block,
-             b->zbin,
-             b->round, b->quant, b->quant_shift,
-             xd->qcoeff + n * 16,
-             xd->dqcoeff + n * 16,
-             d->dequant,
-             b->zbin_extra,
-             &xd->eobs[n],
-#if CONFIG_CODE_NONZEROCOUNT
-             &xd->nzcs[n],
-#endif
-             vp9_default_zig_zag1d_4x4, 1);
+  for (n = 0; n < 64; n++) {
+    const TX_TYPE tx_type = get_tx_type_4x4(xd, n);
+    if (tx_type != DCT_DCT) {
+      vp9_ht_quantize_b_4x4(x, n, tx_type);
+    } else {
+      x->quantize_b_4x4(x, n);
+    }
+  }
 }
 
 void vp9_quantize_sbuv_16x16(MACROBLOCK *x) {
-  int i;
-  MACROBLOCKD *const xd = &x->e_mbd;
-
-  for (i = 64; i < 96; i += 16) {
-    int cidx = i < 80 ? 16 : 20;
-    quantize(x->block[cidx].zrun_zbin_boost,
-             x->coeff + i * 16,
-             256, x->block[cidx].skip_block,
-             x->block[cidx].zbin, x->block[cidx].round,
-             x->block[cidx].quant, x->block[cidx].quant_shift,
-             xd->qcoeff + i * 16,
-             xd->dqcoeff + i * 16,
-             xd->block[cidx].dequant,
-             x->block[cidx].zbin_extra,
-             &xd->eobs[i],
-#if CONFIG_CODE_NONZEROCOUNT
-             &xd->nzcs[i],
-#endif
-             vp9_default_zig_zag1d_16x16, 1);
-  }
+  x->quantize_b_16x16(x, 64);
+  x->quantize_b_16x16(x, 80);
 }
 
 void vp9_quantize_sbuv_8x8(MACROBLOCK *x) {
   int i;
-  MACROBLOCKD *const xd = &x->e_mbd;
 
-  for (i = 64; i < 96; i += 4) {
-    int cidx = i < 80 ? 16 : 20;
-    quantize(x->block[cidx].zrun_zbin_boost,
-             x->coeff + i * 16,
-             64, x->block[cidx].skip_block,
-             x->block[cidx].zbin, x->block[cidx].round,
-             x->block[cidx].quant, x->block[cidx].quant_shift,
-             xd->qcoeff + i * 16,
-             xd->dqcoeff + i * 16,
-             xd->block[cidx].dequant,
-             x->block[cidx].zbin_extra,
-             &xd->eobs[i],
-#if CONFIG_CODE_NONZEROCOUNT
-             &xd->nzcs[i],
-#endif
-             vp9_default_zig_zag1d_8x8, 1);
-  }
+  for (i = 64; i < 96; i += 4)
+    x->quantize_b_8x8(x, i);
 }
 
 void vp9_quantize_sbuv_4x4(MACROBLOCK *x) {
   int i;
-  MACROBLOCKD *const xd = &x->e_mbd;
 
-  for (i = 64; i < 96; i++) {
-    int cidx = i < 80 ? 16 : 20;
-    quantize(x->block[cidx].zrun_zbin_boost,
-             x->coeff + i * 16,
-             16, x->block[cidx].skip_block,
-             x->block[cidx].zbin, x->block[cidx].round,
-             x->block[cidx].quant, x->block[cidx].quant_shift,
-             xd->qcoeff + i * 16,
-             xd->dqcoeff + i * 16,
-             xd->block[cidx].dequant,
-             x->block[cidx].zbin_extra,
-             &xd->eobs[i],
-#if CONFIG_CODE_NONZEROCOUNT
-             &xd->nzcs[i],
-#endif
-             vp9_default_zig_zag1d_4x4, 1);
-  }
+  for (i = 64; i < 96; i++)
+    x->quantize_b_4x4(x, i);
 }
 
 void vp9_quantize_sb64y_32x32(MACROBLOCK *x) {
-  MACROBLOCKD *const xd = &x->e_mbd;
-  BLOCK *const b = &x->block[0];
-  BLOCKD *const d = &xd->block[0];
   int n;
 
   for (n = 0; n < 4; n++)
-    quantize(b->zrun_zbin_boost,
-             x->coeff + n * 1024,
-             1024, b->skip_block,
-             b->zbin,
-             b->round, b->quant, b->quant_shift,
-             xd->qcoeff + n * 1024,
-             xd->dqcoeff + n * 1024,
-             d->dequant,
-             b->zbin_extra,
-             &xd->eobs[n * 64],
-#if CONFIG_CODE_NONZEROCOUNT
-             &xd->nzcs[n * 64],
-#endif
-             vp9_default_zig_zag1d_32x32, 2);
+    vp9_regular_quantize_b_32x32(x, n * 64);
 }
 
 void vp9_quantize_sb64y_16x16(MACROBLOCK *x) {
-  MACROBLOCKD *const xd = &x->e_mbd;
-  BLOCK *const b = &x->block[0];
-  BLOCKD *const d = &xd->block[0];
   int n;
 
   for (n = 0; n < 16; n++)
-    quantize(b->zrun_zbin_boost,
-             x->coeff + n * 256,
-             256, b->skip_block,
-             b->zbin,
-             b->round, b->quant, b->quant_shift,
-             xd->qcoeff + n * 256,
-             xd->dqcoeff + n * 256,
-             d->dequant,
-             b->zbin_extra,
-             &xd->eobs[n * 16],
-#if CONFIG_CODE_NONZEROCOUNT
-             &xd->nzcs[n * 16],
-#endif
-             vp9_default_zig_zag1d_16x16, 1);
+    x->quantize_b_16x16(x, n * 16);
 }
 
 void vp9_quantize_sb64y_8x8(MACROBLOCK *x) {
-  MACROBLOCKD *const xd = &x->e_mbd;
-  BLOCK *const b = &x->block[0];
-  BLOCKD *const d = &xd->block[0];
   int n;
 
   for (n = 0; n < 64; n++)
-    quantize(b->zrun_zbin_boost,
-             x->coeff + n * 64,
-             64, b->skip_block,
-             b->zbin,
-             b->round, b->quant, b->quant_shift,
-             xd->qcoeff + n * 64,
-             xd->dqcoeff + n * 64,
-             d->dequant,
-             b->zbin_extra,
-             &xd->eobs[n * 4],
-#if CONFIG_CODE_NONZEROCOUNT
-             &xd->nzcs[n * 4],
-#endif
-             vp9_default_zig_zag1d_8x8, 1);
+    x->quantize_b_8x8(x, n * 4);
 }
 
 void vp9_quantize_sb64y_4x4(MACROBLOCK *x) {
   MACROBLOCKD *const xd = &x->e_mbd;
-  BLOCK *const b = &x->block[0];
-  BLOCKD *const d = &xd->block[0];
   int n;
 
-  for (n = 0; n < 256; n++)
-    quantize(b->zrun_zbin_boost,
-             x->coeff + n * 16,
-             16, b->skip_block,
-             b->zbin,
-             b->round, b->quant, b->quant_shift,
-             xd->qcoeff + n * 16,
-             xd->dqcoeff + n * 16,
-             d->dequant,
-             b->zbin_extra,
-             &xd->eobs[n],
-#if CONFIG_CODE_NONZEROCOUNT
-             &xd->nzcs[n],
-#endif
-             vp9_default_zig_zag1d_4x4, 1);
+  for (n = 0; n < 256; n++) {
+    const TX_TYPE tx_type = get_tx_type_4x4(xd, n);
+    if (tx_type != DCT_DCT) {
+      vp9_ht_quantize_b_4x4(x, n, tx_type);
+    } else {
+      x->quantize_b_4x4(x, n);
+    }
+  }
 }
 
 void vp9_quantize_sb64uv_32x32(MACROBLOCK *x) {
-  int i;
-  MACROBLOCKD *const xd = &x->e_mbd;
-
-  for (i = 256; i < 384; i += 64) {
-    int cidx = i < 320 ? 16 : 20;
-    quantize(x->block[cidx].zrun_zbin_boost,
-             x->coeff + i * 16,
-             1024, x->block[cidx].skip_block,
-             x->block[cidx].zbin, x->block[cidx].round,
-             x->block[cidx].quant, x->block[cidx].quant_shift,
-             xd->qcoeff + i * 16,
-             xd->dqcoeff + i * 16,
-             xd->block[cidx].dequant,
-             x->block[cidx].zbin_extra,
-             &xd->eobs[i],
-#if CONFIG_CODE_NONZEROCOUNT
-             &xd->nzcs[i],
-#endif
-             vp9_default_zig_zag1d_32x32, 2);
-  }
+  vp9_regular_quantize_b_32x32(x, 256);
+  vp9_regular_quantize_b_32x32(x, 320);
 }
 
 void vp9_quantize_sb64uv_16x16(MACROBLOCK *x) {
   int i;
-  MACROBLOCKD *const xd = &x->e_mbd;
 
-  for (i = 256; i < 384; i += 16) {
-    int cidx = i < 320 ? 16 : 20;
-    quantize(x->block[cidx].zrun_zbin_boost,
-             x->coeff + i * 16,
-             256, x->block[cidx].skip_block,
-             x->block[cidx].zbin, x->block[cidx].round,
-             x->block[cidx].quant, x->block[cidx].quant_shift,
-             xd->qcoeff + i * 16,
-             xd->dqcoeff + i * 16,
-             xd->block[cidx].dequant,
-             x->block[cidx].zbin_extra,
-             &xd->eobs[i],
-#if CONFIG_CODE_NONZEROCOUNT
-             &xd->nzcs[i],
-#endif
-             vp9_default_zig_zag1d_16x16, 1);
-  }
+  for (i = 256; i < 384; i += 16)
+    x->quantize_b_16x16(x, i);
 }
 
 void vp9_quantize_sb64uv_8x8(MACROBLOCK *x) {
   int i;
-  MACROBLOCKD *const xd = &x->e_mbd;
 
-  for (i = 256; i < 384; i += 4) {
-    int cidx = i < 320 ? 16 : 20;
-    quantize(x->block[cidx].zrun_zbin_boost,
-             x->coeff + i * 16,
-             64, x->block[cidx].skip_block,
-             x->block[cidx].zbin, x->block[cidx].round,
-             x->block[cidx].quant, x->block[cidx].quant_shift,
-             xd->qcoeff + i * 16,
-             xd->dqcoeff + i * 16,
-             xd->block[cidx].dequant,
-             x->block[cidx].zbin_extra,
-             &xd->eobs[i],
-#if CONFIG_CODE_NONZEROCOUNT
-             &xd->nzcs[i],
-#endif
-             vp9_default_zig_zag1d_8x8, 1);
-  }
+  for (i = 256; i < 384; i += 4)
+    x->quantize_b_8x8(x, i);
 }
 
 void vp9_quantize_sb64uv_4x4(MACROBLOCK *x) {
   int i;
-  MACROBLOCKD *const xd = &x->e_mbd;
 
-  for (i = 256; i < 384; i++) {
-    int cidx = i < 320 ? 16 : 20;
-    quantize(x->block[cidx].zrun_zbin_boost,
-             x->coeff + i * 16,
-             16, x->block[cidx].skip_block,
-             x->block[cidx].zbin, x->block[cidx].round,
-             x->block[cidx].quant, x->block[cidx].quant_shift,
-             xd->qcoeff + i * 16,
-             xd->dqcoeff + i * 16,
-             xd->block[cidx].dequant,
-             x->block[cidx].zbin_extra,
-             &xd->eobs[i],
-#if CONFIG_CODE_NONZEROCOUNT
-             &xd->nzcs[i],
-#endif
-             vp9_default_zig_zag1d_4x4, 1);
-  }
+  for (i = 256; i < 384; i++)
+    x->quantize_b_4x4(x, i);
 }
 
 /* quantize_b_pair function pointer in MACROBLOCK structure is set to one of
diff --git a/vp9/encoder/vp9_quantize.h b/vp9/encoder/vp9_quantize.h
index 32eb05a..7392540 100644
--- a/vp9/encoder/vp9_quantize.h
+++ b/vp9/encoder/vp9_quantize.h
@@ -26,52 +26,24 @@
 #include "x86/vp9_quantize_x86.h"
 #endif
 
-#define prototype_quantize_block_type(sym) \
-  void (sym)(MACROBLOCK *mb, int b_ix, TX_TYPE type)
-extern prototype_quantize_block_type(vp9_ht_quantize_b_4x4);
+void vp9_ht_quantize_b_4x4(MACROBLOCK *mb, int b_ix, TX_TYPE type);
+void vp9_regular_quantize_b_4x4(MACROBLOCK *mb, int b_idx);
+void vp9_regular_quantize_b_4x4_pair(MACROBLOCK *mb, int b_idx1, int b_idx2);
+void vp9_regular_quantize_b_8x8(MACROBLOCK *mb, int b_idx);
+void vp9_regular_quantize_b_16x16(MACROBLOCK *mb, int b_idx);
+void vp9_regular_quantize_b_32x32(MACROBLOCK *mb, int b_idx);
 
-#ifndef vp9_quantize_quantb_4x4
-#define vp9_quantize_quantb_4x4 vp9_regular_quantize_b_4x4
-#endif
-extern prototype_quantize_block(vp9_quantize_quantb_4x4);
-
-#ifndef vp9_quantize_quantb_4x4_pair
-#define vp9_quantize_quantb_4x4_pair vp9_regular_quantize_b_4x4_pair
-#endif
-extern prototype_quantize_block_pair(vp9_quantize_quantb_4x4_pair);
-
-#ifndef vp9_quantize_quantb_8x8
-#define vp9_quantize_quantb_8x8 vp9_regular_quantize_b_8x8
-#endif
-extern prototype_quantize_block(vp9_quantize_quantb_8x8);
-
-#ifndef vp9_quantize_quantb_16x16
-#define vp9_quantize_quantb_16x16 vp9_regular_quantize_b_16x16
-#endif
-extern prototype_quantize_block(vp9_quantize_quantb_16x16);
-
-#ifndef vp9_quantize_mb_4x4
-#define vp9_quantize_mb_4x4 vp9_quantize_mb_4x4_c
-#endif
-extern prototype_quantize_mb(vp9_quantize_mb_4x4);
+void vp9_quantize_mb_4x4(MACROBLOCK *x);
 void vp9_quantize_mb_8x8(MACROBLOCK *x);
 
-#ifndef vp9_quantize_mbuv_4x4
-#define vp9_quantize_mbuv_4x4 vp9_quantize_mbuv_4x4_c
-#endif
-extern prototype_quantize_mb(vp9_quantize_mbuv_4x4);
+void vp9_quantize_mbuv_4x4(MACROBLOCK *x);
+void vp9_quantize_mby_4x4(MACROBLOCK *x);
 
-#ifndef vp9_quantize_mby_4x4
-#define vp9_quantize_mby_4x4 vp9_quantize_mby_4x4_c
-#endif
-extern prototype_quantize_mb(vp9_quantize_mby_4x4);
-
-extern prototype_quantize_mb(vp9_quantize_mby_8x8);
-extern prototype_quantize_mb(vp9_quantize_mbuv_8x8);
+void vp9_quantize_mby_8x8(MACROBLOCK *x);
+void vp9_quantize_mbuv_8x8(MACROBLOCK *x);
 
 void vp9_quantize_mb_16x16(MACROBLOCK *x);
-extern prototype_quantize_block(vp9_quantize_quantb_16x16);
-extern prototype_quantize_mb(vp9_quantize_mby_16x16);
+void vp9_quantize_mby_16x16(MACROBLOCK *x);
 
 void vp9_quantize_sby_32x32(MACROBLOCK *x);
 void vp9_quantize_sby_16x16(MACROBLOCK *x);
diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c
index 1b83091..8778f70 100644
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -453,7 +453,6 @@
                               TX_SIZE tx_size) {
   MACROBLOCKD *const xd = &mb->e_mbd;
   MB_MODE_INFO *mbmi = &xd->mode_info_context->mbmi;
-  const BLOCK_SIZE_TYPE sb_type = mbmi->sb_type;
   int pt;
   const int eob = xd->eobs[ib];
   int c = 0;
@@ -461,9 +460,6 @@
   const int *scan;
   const int16_t *qcoeff_ptr = xd->qcoeff + ib * 16;
   const int ref = mbmi->ref_frame != INTRA_FRAME;
-  const TX_TYPE tx_type = (sb_type == BLOCK_SIZE_MB16X16 &&
-                           type == PLANE_TYPE_Y_WITH_DC) ?
-                          get_tx_type(xd, &xd->block[ib]) : DCT_DCT;
   unsigned int (*token_costs)[PREV_COEF_CONTEXTS][MAX_ENTROPY_TOKENS] =
       mb->token_costs[tx_size][type][ref];
   ENTROPY_CONTEXT a_ec, l_ec;
@@ -489,23 +485,25 @@
   }
 
   switch (tx_size) {
-    case TX_4X4:
+    case TX_4X4: {
+      const TX_TYPE tx_type = (type == PLANE_TYPE_Y_WITH_DC) ?
+                              get_tx_type_4x4(xd, ib) : DCT_DCT;
       a_ec = *a;
       l_ec = *l;
-      scan = vp9_default_zig_zag1d_4x4;
 #if CONFIG_CODE_NONZEROCOUNT
       nzc_cost = mb->nzc_costs_4x4[nzc_context][ref][type];
 #else
       seg_eob = 16;
 #endif
-      if (type == PLANE_TYPE_Y_WITH_DC) {
-        if (tx_type == ADST_DCT) {
-          scan = vp9_row_scan_4x4;
-        } else if (tx_type == DCT_ADST) {
-          scan = vp9_col_scan_4x4;
-        }
+      if (tx_type == ADST_DCT) {
+        scan = vp9_row_scan_4x4;
+      } else if (tx_type == DCT_ADST) {
+        scan = vp9_col_scan_4x4;
+      } else {
+        scan = vp9_default_zig_zag1d_4x4;
       }
       break;
+    }
     case TX_8X8:
       a_ec = (a[0] + a[1]) != 0;
       l_ec = (l[0] + l[1]) != 0;
@@ -611,24 +609,16 @@
   return cost;
 }
 
-static int rdcost_mby_4x4(VP9_COMMON *const cm, MACROBLOCK *mb, int backup) {
+static int rdcost_mby_4x4(VP9_COMMON *const cm, MACROBLOCK *mb) {
   int cost = 0;
   int b;
   MACROBLOCKD *xd = &mb->e_mbd;
   ENTROPY_CONTEXT_PLANES t_above, t_left;
-  ENTROPY_CONTEXT *ta;
-  ENTROPY_CONTEXT *tl;
+  ENTROPY_CONTEXT *ta = (ENTROPY_CONTEXT *)&t_above;
+  ENTROPY_CONTEXT *tl = (ENTROPY_CONTEXT *)&t_left;
 
-  if (backup) {
-    vpx_memcpy(&t_above, xd->above_context, sizeof(ENTROPY_CONTEXT_PLANES));
-    vpx_memcpy(&t_left, xd->left_context, sizeof(ENTROPY_CONTEXT_PLANES));
-
-    ta = (ENTROPY_CONTEXT *)&t_above;
-    tl = (ENTROPY_CONTEXT *)&t_left;
-  } else {
-    ta = (ENTROPY_CONTEXT *)xd->above_context;
-    tl = (ENTROPY_CONTEXT *)xd->left_context;
-  }
+  vpx_memcpy(&t_above, xd->above_context, sizeof(t_above));
+  vpx_memcpy(&t_left, xd->left_context, sizeof(t_left));
 
   for (b = 0; b < 16; b++)
     cost += cost_coeffs(cm, mb, b, PLANE_TYPE_Y_WITH_DC,
@@ -641,38 +631,30 @@
 
 static void macro_block_yrd_4x4(VP9_COMMON *const cm,
                                 MACROBLOCK *mb,
-                                int *Rate,
-                                int *Distortion,
-                                int *skippable, int backup) {
+                                int *rate,
+                                int *distortion,
+                                int *skippable) {
   MACROBLOCKD *const xd = &mb->e_mbd;
 
   xd->mode_info_context->mbmi.txfm_size = TX_4X4;
   vp9_transform_mby_4x4(mb);
   vp9_quantize_mby_4x4(mb);
 
-  *Distortion = vp9_mbblock_error(mb) >> 2;
-  *Rate = rdcost_mby_4x4(cm, mb, backup);
+  *distortion = vp9_mbblock_error(mb) >> 2;
+  *rate = rdcost_mby_4x4(cm, mb);
   *skippable = vp9_mby_is_skippable_4x4(xd);
 }
 
-static int rdcost_mby_8x8(VP9_COMMON *const cm, MACROBLOCK *mb, int backup) {
+static int rdcost_mby_8x8(VP9_COMMON *const cm, MACROBLOCK *mb) {
   int cost = 0;
   int b;
   MACROBLOCKD *xd = &mb->e_mbd;
   ENTROPY_CONTEXT_PLANES t_above, t_left;
-  ENTROPY_CONTEXT *ta;
-  ENTROPY_CONTEXT *tl;
+  ENTROPY_CONTEXT *ta = (ENTROPY_CONTEXT *)&t_above;
+  ENTROPY_CONTEXT *tl = (ENTROPY_CONTEXT *)&t_left;
 
-  if (backup) {
-    vpx_memcpy(&t_above,xd->above_context, sizeof(ENTROPY_CONTEXT_PLANES));
-    vpx_memcpy(&t_left, xd->left_context, sizeof(ENTROPY_CONTEXT_PLANES));
-
-    ta = (ENTROPY_CONTEXT *)&t_above;
-    tl = (ENTROPY_CONTEXT *)&t_left;
-  } else {
-    ta = (ENTROPY_CONTEXT *)mb->e_mbd.above_context;
-    tl = (ENTROPY_CONTEXT *)mb->e_mbd.left_context;
-  }
+  vpx_memcpy(&t_above, xd->above_context, sizeof(t_above));
+  vpx_memcpy(&t_left,  xd->left_context, sizeof(t_left));
 
   for (b = 0; b < 16; b += 4)
     cost += cost_coeffs(cm, mb, b, PLANE_TYPE_Y_WITH_DC,
@@ -685,45 +667,35 @@
 
 static void macro_block_yrd_8x8(VP9_COMMON *const cm,
                                 MACROBLOCK *mb,
-                                int *Rate,
-                                int *Distortion,
-                                int *skippable, int backup) {
+                                int *rate,
+                                int *distortion,
+                                int *skippable) {
   MACROBLOCKD *const xd = &mb->e_mbd;
 
   xd->mode_info_context->mbmi.txfm_size = TX_8X8;
   vp9_transform_mby_8x8(mb);
   vp9_quantize_mby_8x8(mb);
 
-  *Distortion = vp9_mbblock_error(mb) >> 2;
-  *Rate = rdcost_mby_8x8(cm, mb, backup);
+  *distortion = vp9_mbblock_error(mb) >> 2;
+  *rate = rdcost_mby_8x8(cm, mb);
   *skippable = vp9_mby_is_skippable_8x8(xd);
 }
 
-static int rdcost_mby_16x16(VP9_COMMON *const cm, MACROBLOCK *mb, int backup) {
-  int cost;
-  MACROBLOCKD *xd = &mb->e_mbd;
+static int rdcost_mby_16x16(VP9_COMMON *const cm, MACROBLOCK *mb) {
+  MACROBLOCKD *const xd = &mb->e_mbd;
   ENTROPY_CONTEXT_PLANES t_above, t_left;
-  ENTROPY_CONTEXT *ta, *tl;
+  ENTROPY_CONTEXT *ta = (ENTROPY_CONTEXT *)&t_above;
+  ENTROPY_CONTEXT *tl = (ENTROPY_CONTEXT *)&t_left;
 
-  if (backup) {
-    vpx_memcpy(&t_above, xd->above_context, sizeof(ENTROPY_CONTEXT_PLANES));
-    vpx_memcpy(&t_left, xd->left_context, sizeof(ENTROPY_CONTEXT_PLANES));
+  vpx_memcpy(&t_above, xd->above_context, sizeof(t_above));
+  vpx_memcpy(&t_left, xd->left_context, sizeof(t_left));
 
-    ta = (ENTROPY_CONTEXT *)&t_above;
-    tl = (ENTROPY_CONTEXT *)&t_left;
-  } else {
-    ta = (ENTROPY_CONTEXT *)xd->above_context;
-    tl = (ENTROPY_CONTEXT *)xd->left_context;
-  }
-
-  cost = cost_coeffs(cm, mb, 0, PLANE_TYPE_Y_WITH_DC, ta, tl, TX_16X16);
-  return cost;
+  return cost_coeffs(cm, mb, 0, PLANE_TYPE_Y_WITH_DC, ta, tl, TX_16X16);
 }
 
 static void macro_block_yrd_16x16(VP9_COMMON *const cm, MACROBLOCK *mb,
-                                  int *Rate, int *Distortion,
-                                  int *skippable, int backup) {
-  MACROBLOCKD *xd = &mb->e_mbd;
+                                  int *rate, int *distortion, int *skippable) {
+  MACROBLOCKD *const xd = &mb->e_mbd;
 
   xd->mode_info_context->mbmi.txfm_size = TX_16X16;
   vp9_transform_mby_16x16(mb);
@@ -735,8 +707,8 @@
       xd->mode_info_context->mbmi.mode < I8X8_PRED)
     vp9_optimize_mby_16x16(cm, mb);
 
-  *Distortion = vp9_mbblock_error(mb) >> 2;
-  *Rate = rdcost_mby_16x16(cm, mb, backup);
+  *distortion = vp9_mbblock_error(mb) >> 2;
+  *rate = rdcost_mby_16x16(cm, mb);
   *skippable = vp9_mby_is_skippable_16x16(xd);
 }
 
@@ -835,9 +807,9 @@
   vp9_subtract_mby(x->src_diff, *(x->block[0].base_src), xd->predictor,
                    x->block[0].src_stride);
 
-  macro_block_yrd_16x16(cm, x, &r[TX_16X16][0], &d[TX_16X16], &s[TX_16X16], 1);
-  macro_block_yrd_8x8(cm, x, &r[TX_8X8][0], &d[TX_8X8], &s[TX_8X8], 1);
-  macro_block_yrd_4x4(cm, x, &r[TX_4X4][0], &d[TX_4X4], &s[TX_4X4], 1);
+  macro_block_yrd_16x16(cm, x, &r[TX_16X16][0], &d[TX_16X16], &s[TX_16X16]);
+  macro_block_yrd_8x8(cm, x, &r[TX_8X8][0], &d[TX_8X8], &s[TX_8X8]);
+  macro_block_yrd_4x4(cm, x, &r[TX_4X4][0], &d[TX_4X4], &s[TX_4X4]);
 
   choose_txfm_size_from_rd(cpi, x, r, rate, d, distortion, s, skippable,
                            txfm_cache, TX_16X16);
@@ -852,27 +824,8 @@
   d[12] = p[12];
 }
 
-static int rdcost_sby_32x32(VP9_COMMON *const cm, MACROBLOCK *x, int backup) {
-  MACROBLOCKD * xd = &x->e_mbd;
-  ENTROPY_CONTEXT_PLANES t_above[2], t_left[2];
-  ENTROPY_CONTEXT *ta, *tl;
-
-  if (backup) {
-    ta = (ENTROPY_CONTEXT *) &t_above,
-    tl = (ENTROPY_CONTEXT *) &t_left;
-
-    vpx_memcpy(&t_above, xd->above_context, sizeof(ENTROPY_CONTEXT_PLANES) * 2);
-    vpx_memcpy(&t_left,  xd->left_context,  sizeof(ENTROPY_CONTEXT_PLANES) * 2);
-  } else {
-    ta = (ENTROPY_CONTEXT *) xd->above_context;
-    tl = (ENTROPY_CONTEXT *) xd->left_context;
-  }
-
-  return cost_coeffs(cm, x, 0, PLANE_TYPE_Y_WITH_DC, ta, tl, TX_32X32);
-}
-
 static int vp9_sb_block_error_c(int16_t *coeff, int16_t *dqcoeff,
-                                int block_size) {
+                                int block_size, int shift) {
   int i;
   int64_t error = 0;
 
@@ -880,33 +833,126 @@
     unsigned int this_diff = coeff[i] - dqcoeff[i];
     error += this_diff * this_diff;
   }
+  error >>= shift;
 
   return error > INT_MAX ? INT_MAX : (int)error;
 }
 
-#define DEBUG_ERROR 0
-static void super_block_yrd_32x32(VP9_COMMON *const cm, MACROBLOCK *x,
-                                  int *rate, int *distortion, int *skippable,
-                                  int backup) {
+static int rdcost_sby_4x4(VP9_COMMON *const cm, MACROBLOCK *x) {
+  int cost = 0, b;
   MACROBLOCKD *const xd = &x->e_mbd;
-#if DEBUG_ERROR
-  int16_t out[1024];
-#endif
-  xd->mode_info_context->mbmi.txfm_size = TX_32X32;
+  ENTROPY_CONTEXT_PLANES t_above[2], t_left[2];
+  ENTROPY_CONTEXT *ta = (ENTROPY_CONTEXT *) &t_above;
+  ENTROPY_CONTEXT *tl = (ENTROPY_CONTEXT *) &t_left;
 
+  vpx_memcpy(&t_above, xd->above_context, sizeof(t_above));
+  vpx_memcpy(&t_left,  xd->left_context,  sizeof(t_left));
+
+  for (b = 0; b < 64; b++)
+    cost += cost_coeffs(cm, x, b, PLANE_TYPE_Y_WITH_DC,
+                        ta + vp9_block2above_sb[TX_4X4][b],
+                        tl + vp9_block2left_sb[TX_4X4][b], TX_4X4);
+
+  return cost;
+}
+
+static void super_block_yrd_4x4(VP9_COMMON *const cm, MACROBLOCK *x,
+                                int *rate, int *distortion, int *skippable) {
+  MACROBLOCKD *const xd = &x->e_mbd;
+
+  xd->mode_info_context->mbmi.txfm_size = TX_4X4;
+  vp9_transform_sby_4x4(x);
+  vp9_quantize_sby_4x4(x);
+
+  *distortion = vp9_sb_block_error_c(x->coeff, xd->dqcoeff, 1024, 2);
+  *rate       = rdcost_sby_4x4(cm, x);
+  *skippable  = vp9_sby_is_skippable_4x4(xd);
+}
+
+static int rdcost_sby_8x8(VP9_COMMON *const cm, MACROBLOCK *x) {
+  int cost = 0, b;
+  MACROBLOCKD *const xd = &x->e_mbd;
+  ENTROPY_CONTEXT_PLANES t_above[2], t_left[2];
+  ENTROPY_CONTEXT *ta = (ENTROPY_CONTEXT *) &t_above;
+  ENTROPY_CONTEXT *tl = (ENTROPY_CONTEXT *) &t_left;
+
+  vpx_memcpy(&t_above, xd->above_context, sizeof(t_above));
+  vpx_memcpy(&t_left,  xd->left_context,  sizeof(t_left));
+
+  for (b = 0; b < 64; b += 4)
+    cost += cost_coeffs(cm, x, b, PLANE_TYPE_Y_WITH_DC,
+                        ta + vp9_block2above_sb[TX_8X8][b],
+                        tl + vp9_block2left_sb[TX_8X8][b], TX_8X8);
+
+  return cost;
+}
+
+static void super_block_yrd_8x8(VP9_COMMON *const cm, MACROBLOCK *x,
+                                int *rate, int *distortion, int *skippable) {
+  MACROBLOCKD *const xd = &x->e_mbd;
+
+  xd->mode_info_context->mbmi.txfm_size = TX_8X8;
+  vp9_transform_sby_8x8(x);
+  vp9_quantize_sby_8x8(x);
+
+  *distortion = vp9_sb_block_error_c(x->coeff, xd->dqcoeff, 1024, 2);
+  *rate       = rdcost_sby_8x8(cm, x);
+  *skippable  = vp9_sby_is_skippable_8x8(xd);
+}
+
+static int rdcost_sby_16x16(VP9_COMMON *const cm, MACROBLOCK *x) {
+  int cost = 0, b;
+  MACROBLOCKD *const xd = &x->e_mbd;
+  ENTROPY_CONTEXT_PLANES t_above[2], t_left[2];
+  ENTROPY_CONTEXT *ta = (ENTROPY_CONTEXT *) &t_above;
+  ENTROPY_CONTEXT *tl = (ENTROPY_CONTEXT *) &t_left;
+
+  vpx_memcpy(&t_above, xd->above_context, sizeof(t_above));
+  vpx_memcpy(&t_left,  xd->left_context,  sizeof(t_left));
+
+  for (b = 0; b < 64; b += 16)
+    cost += cost_coeffs(cm, x, b, PLANE_TYPE_Y_WITH_DC,
+                        ta + vp9_block2above_sb[TX_16X16][b],
+                        tl + vp9_block2left_sb[TX_16X16][b], TX_16X16);
+
+  return cost;
+}
+
+static void super_block_yrd_16x16(VP9_COMMON *const cm, MACROBLOCK *x,
+                                  int *rate, int *distortion, int *skippable) {
+  MACROBLOCKD *const xd = &x->e_mbd;
+
+  xd->mode_info_context->mbmi.txfm_size = TX_16X16;
+  vp9_transform_sby_16x16(x);
+  vp9_quantize_sby_16x16(x);
+
+  *distortion = vp9_sb_block_error_c(x->coeff, xd->dqcoeff, 1024, 2);
+  *rate       = rdcost_sby_16x16(cm, x);
+  *skippable  = vp9_sby_is_skippable_16x16(xd);
+}
+
+static int rdcost_sby_32x32(VP9_COMMON *const cm, MACROBLOCK *x) {
+  MACROBLOCKD * const xd = &x->e_mbd;
+  ENTROPY_CONTEXT_PLANES t_above[2], t_left[2];
+  ENTROPY_CONTEXT *ta = (ENTROPY_CONTEXT *) &t_above;
+  ENTROPY_CONTEXT *tl = (ENTROPY_CONTEXT *) &t_left;
+
+  vpx_memcpy(&t_above, xd->above_context, sizeof(t_above));
+  vpx_memcpy(&t_left,  xd->left_context,  sizeof(t_left));
+
+  return cost_coeffs(cm, x, 0, PLANE_TYPE_Y_WITH_DC, ta, tl, TX_32X32);
+}
+
+static void super_block_yrd_32x32(VP9_COMMON *const cm, MACROBLOCK *x,
+                                  int *rate, int *distortion, int *skippable) {
+  MACROBLOCKD *const xd = &x->e_mbd;
+
+  xd->mode_info_context->mbmi.txfm_size = TX_32X32;
   vp9_transform_sby_32x32(x);
   vp9_quantize_sby_32x32(x);
-#if DEBUG_ERROR
-  vp9_short_idct32x32(xd->dqcoeff, out, 64);
-#endif
 
-  *distortion = vp9_sb_block_error_c(x->coeff, xd->dqcoeff, 1024);
-
-#if DEBUG_ERROR
-  printf("IDCT/FDCT error 32x32: %d (d: %d)\n",
-         vp9_block_error_c(x->src_diff, out, 1024), *distortion);
-#endif
-  *rate       = rdcost_sby_32x32(cm, x, backup);
+  *distortion = vp9_sb_block_error_c(x->coeff, xd->dqcoeff, 1024, 0);
+  *rate       = rdcost_sby_32x32(cm, x);
   *skippable  = vp9_sby_is_skippable_32x32(xd);
 }
 
@@ -914,180 +960,166 @@
                             MACROBLOCK *x, int *rate, int *distortion,
                             int *skip,
                             int64_t txfm_cache[NB_TXFM_MODES]) {
+  VP9_COMMON *const cm = &cpi->common;
   MACROBLOCKD *const xd = &x->e_mbd;
-  int r[TX_SIZE_MAX_SB][2], d[TX_SIZE_MAX_SB], s[TX_SIZE_MAX_SB], n;
+  int r[TX_SIZE_MAX_SB][2], d[TX_SIZE_MAX_SB], s[TX_SIZE_MAX_SB];
   const uint8_t *src = x->src.y_buffer, *dst = xd->dst.y_buffer;
   int src_y_stride = x->src.y_stride, dst_y_stride = xd->dst.y_stride;
-  ENTROPY_CONTEXT_PLANES t_above[TX_SIZE_MAX_MB][2],
-                        *orig_above = xd->above_context;
-  ENTROPY_CONTEXT_PLANES t_left[TX_SIZE_MAX_MB][2],
-                        *orig_left = xd->left_context;
 
-  for (n = TX_4X4; n < TX_SIZE_MAX_MB; n++) {
-    vpx_memcpy(t_above[n], xd->above_context, sizeof(t_above[n]));
-    vpx_memcpy(t_left[n], xd->left_context, sizeof(t_left[n]));
-    r[n][0] = 0;
-    d[n] = 0;
-    s[n] = 1;
-  }
+  vp9_subtract_sby_s_c(x->src_diff, src, src_y_stride, dst, dst_y_stride);
+  super_block_yrd_32x32(cm, x, &r[TX_32X32][0], &d[TX_32X32], &s[TX_32X32]);
+  super_block_yrd_16x16(cm, x, &r[TX_16X16][0], &d[TX_16X16], &s[TX_16X16]);
+  super_block_yrd_8x8(cm, x,   &r[TX_8X8][0],   &d[TX_8X8],   &s[TX_8X8]);
+  super_block_yrd_4x4(cm, x,   &r[TX_4X4][0],   &d[TX_4X4],   &s[TX_4X4]);
 
-  vp9_subtract_sby_s_c(x->src_diff, src, src_y_stride,
-                       dst, dst_y_stride);
-  super_block_yrd_32x32(&cpi->common, x,
-                        &r[TX_32X32][0], &d[TX_32X32], &s[TX_32X32], 1);
-
-#if DEBUG_ERROR
-  int err[3] = { 0, 0, 0 };
-#endif
-  for (n = 0; n < 4; n++) {
-    int x_idx = n & 1, y_idx = n >> 1;
-    int r_tmp, d_tmp, s_tmp;
-
-    vp9_subtract_mby_s_c(x->src_diff,
-                         src + x_idx * 16 + y_idx * 16 * src_y_stride,
-                         src_y_stride,
-                         dst + x_idx * 16 + y_idx * 16 * dst_y_stride,
-                         dst_y_stride);
-
-    xd->above_context = &t_above[TX_16X16][x_idx];
-    xd->left_context = &t_left[TX_16X16][y_idx];
-    macro_block_yrd_16x16(&cpi->common, x, &r_tmp, &d_tmp, &s_tmp, 0);
-    d[TX_16X16] += d_tmp;
-    r[TX_16X16][0] += r_tmp;
-    s[TX_16X16] = s[TX_16X16] && s_tmp;
-#if DEBUG_ERROR
-    vp9_inverse_transform_mby_16x16(xd);
-    err[2] += vp9_block_error_c(xd->diff, x->src_diff, 256);
-#endif
-
-    xd->above_context = &t_above[TX_4X4][x_idx];
-    xd->left_context = &t_left[TX_4X4][y_idx];
-    macro_block_yrd_4x4(&cpi->common, x, &r_tmp, &d_tmp, &s_tmp, 0);
-    d[TX_4X4] += d_tmp;
-    r[TX_4X4][0] += r_tmp;
-    s[TX_4X4] = s[TX_4X4] && s_tmp;
-#if DEBUG_ERROR
-    vp9_inverse_transform_mby_4x4(xd);
-    err[0] += vp9_block_error_c(xd->diff, x->src_diff, 256);
-#endif
-
-    xd->above_context = &t_above[TX_8X8][x_idx];
-    xd->left_context = &t_left[TX_8X8][y_idx];
-    macro_block_yrd_8x8(&cpi->common, x, &r_tmp, &d_tmp, &s_tmp, 0);
-    d[TX_8X8] += d_tmp;
-    r[TX_8X8][0] += r_tmp;
-    s[TX_8X8] = s[TX_8X8] && s_tmp;
-#if DEBUG_ERROR
-    vp9_inverse_transform_mby_8x8(xd);
-    err[1] += vp9_block_error_c(xd->diff, x->src_diff, 256);
-#endif
-  }
-#if DEBUG_ERROR
-  printf("IDCT/FDCT error 16x16: %d (d: %d)\n", err[2], d[2]);
-  printf("IDCT/FDCT error 8x8: %d (d: %d)\n", err[1], d[1]);
-  printf("IDCT/FDCT error 4x4: %d (d: %d)\n", err[0], d[0]);
-#endif
   choose_txfm_size_from_rd(cpi, x, r, rate, d, distortion, s, skip, txfm_cache,
                            TX_SIZE_MAX_SB - 1);
+}
 
-  xd->above_context = orig_above;
-  xd->left_context = orig_left;
+static int rdcost_sb64y_4x4(VP9_COMMON *const cm, MACROBLOCK *x) {
+  int cost = 0, b;
+  MACROBLOCKD *const xd = &x->e_mbd;
+  ENTROPY_CONTEXT_PLANES t_above[4], t_left[4];
+  ENTROPY_CONTEXT *ta = (ENTROPY_CONTEXT *) &t_above;
+  ENTROPY_CONTEXT *tl = (ENTROPY_CONTEXT *) &t_left;
+
+  vpx_memcpy(&t_above, xd->above_context, sizeof(t_above));
+  vpx_memcpy(&t_left,  xd->left_context,  sizeof(t_left));
+
+  for (b = 0; b < 256; b++)
+    cost += cost_coeffs(cm, x, b, PLANE_TYPE_Y_WITH_DC,
+                        ta + vp9_block2above_sb64[TX_4X4][b],
+                        tl + vp9_block2left_sb64[TX_4X4][b], TX_4X4);
+
+  return cost;
+}
+
+static void super_block64_yrd_4x4(VP9_COMMON *const cm, MACROBLOCK *x,
+                                  int *rate, int *distortion, int *skippable) {
+  MACROBLOCKD *const xd = &x->e_mbd;
+
+  xd->mode_info_context->mbmi.txfm_size = TX_4X4;
+  vp9_transform_sb64y_4x4(x);
+  vp9_quantize_sb64y_4x4(x);
+
+  *distortion = vp9_sb_block_error_c(x->coeff, xd->dqcoeff, 4096, 2);
+  *rate       = rdcost_sb64y_4x4(cm, x);
+  *skippable  = vp9_sb64y_is_skippable_4x4(xd);
+}
+
+static int rdcost_sb64y_8x8(VP9_COMMON *const cm, MACROBLOCK *x) {
+  int cost = 0, b;
+  MACROBLOCKD *const xd = &x->e_mbd;
+  ENTROPY_CONTEXT_PLANES t_above[4], t_left[4];
+  ENTROPY_CONTEXT *ta = (ENTROPY_CONTEXT *) &t_above;
+  ENTROPY_CONTEXT *tl = (ENTROPY_CONTEXT *) &t_left;
+
+  vpx_memcpy(&t_above, xd->above_context, sizeof(t_above));
+  vpx_memcpy(&t_left,  xd->left_context,  sizeof(t_left));
+
+  for (b = 0; b < 256; b += 4)
+    cost += cost_coeffs(cm, x, b, PLANE_TYPE_Y_WITH_DC,
+                        ta + vp9_block2above_sb64[TX_8X8][b],
+                        tl + vp9_block2left_sb64[TX_8X8][b], TX_8X8);
+
+  return cost;
+}
+
+static void super_block64_yrd_8x8(VP9_COMMON *const cm, MACROBLOCK *x,
+                                  int *rate, int *distortion, int *skippable) {
+  MACROBLOCKD *const xd = &x->e_mbd;
+
+  xd->mode_info_context->mbmi.txfm_size = TX_8X8;
+  vp9_transform_sb64y_8x8(x);
+  vp9_quantize_sb64y_8x8(x);
+
+  *distortion = vp9_sb_block_error_c(x->coeff, xd->dqcoeff, 4096, 2);
+  *rate       = rdcost_sb64y_8x8(cm, x);
+  *skippable  = vp9_sb64y_is_skippable_8x8(xd);
+}
+
+static int rdcost_sb64y_16x16(VP9_COMMON *const cm, MACROBLOCK *x) {
+  int cost = 0, b;
+  MACROBLOCKD *const xd = &x->e_mbd;
+  ENTROPY_CONTEXT_PLANES t_above[4], t_left[4];
+  ENTROPY_CONTEXT *ta = (ENTROPY_CONTEXT *) &t_above;
+  ENTROPY_CONTEXT *tl = (ENTROPY_CONTEXT *) &t_left;
+
+  vpx_memcpy(&t_above, xd->above_context, sizeof(t_above));
+  vpx_memcpy(&t_left,  xd->left_context,  sizeof(t_left));
+
+  for (b = 0; b < 256; b += 16)
+    cost += cost_coeffs(cm, x, b, PLANE_TYPE_Y_WITH_DC,
+                        ta + vp9_block2above_sb64[TX_16X16][b],
+                        tl + vp9_block2left_sb64[TX_16X16][b], TX_16X16);
+
+  return cost;
+}
+
+static void super_block64_yrd_16x16(VP9_COMMON *const cm, MACROBLOCK *x,
+                                    int *rate, int *distortion,
+                                    int *skippable) {
+  MACROBLOCKD *const xd = &x->e_mbd;
+
+  xd->mode_info_context->mbmi.txfm_size = TX_16X16;
+  vp9_transform_sb64y_16x16(x);
+  vp9_quantize_sb64y_16x16(x);
+
+  *distortion = vp9_sb_block_error_c(x->coeff, xd->dqcoeff, 4096, 2);
+  *rate       = rdcost_sb64y_16x16(cm, x);
+  *skippable  = vp9_sb64y_is_skippable_16x16(xd);
+}
+
+static int rdcost_sb64y_32x32(VP9_COMMON *const cm, MACROBLOCK *x) {
+  int cost = 0, b;
+  MACROBLOCKD * const xd = &x->e_mbd;
+  ENTROPY_CONTEXT_PLANES t_above[4], t_left[4];
+  ENTROPY_CONTEXT *ta = (ENTROPY_CONTEXT *) &t_above;
+  ENTROPY_CONTEXT *tl = (ENTROPY_CONTEXT *) &t_left;
+
+  vpx_memcpy(&t_above, xd->above_context, sizeof(t_above));
+  vpx_memcpy(&t_left,  xd->left_context,  sizeof(t_left));
+
+  for (b = 0; b < 256; b += 64)
+    cost += cost_coeffs(cm, x, b, PLANE_TYPE_Y_WITH_DC,
+                        ta + vp9_block2above_sb64[TX_32X32][b],
+                        tl + vp9_block2left_sb64[TX_32X32][b], TX_32X32);
+
+  return cost;
+}
+
+static void super_block64_yrd_32x32(VP9_COMMON *const cm, MACROBLOCK *x,
+                                    int *rate, int *distortion,
+                                    int *skippable) {
+  MACROBLOCKD *const xd = &x->e_mbd;
+
+  xd->mode_info_context->mbmi.txfm_size = TX_32X32;
+  vp9_transform_sb64y_32x32(x);
+  vp9_quantize_sb64y_32x32(x);
+
+  *distortion = vp9_sb_block_error_c(x->coeff, xd->dqcoeff, 4096, 0);
+  *rate       = rdcost_sb64y_32x32(cm, x);
+  *skippable  = vp9_sb64y_is_skippable_32x32(xd);
 }
 
 static void super_block_64_yrd(VP9_COMP *cpi,
                                MACROBLOCK *x, int *rate, int *distortion,
                                int *skip,
                                int64_t txfm_cache[NB_TXFM_MODES]) {
+  VP9_COMMON *const cm = &cpi->common;
   MACROBLOCKD *const xd = &x->e_mbd;
-  int r[TX_SIZE_MAX_SB][2], d[TX_SIZE_MAX_SB], s[TX_SIZE_MAX_SB], n;
+  int r[TX_SIZE_MAX_SB][2], d[TX_SIZE_MAX_SB], s[TX_SIZE_MAX_SB];
   const uint8_t *src = x->src.y_buffer, *dst = xd->dst.y_buffer;
   int src_y_stride = x->src.y_stride, dst_y_stride = xd->dst.y_stride;
-  ENTROPY_CONTEXT_PLANES t_above[TX_SIZE_MAX_SB][4],
-                        *orig_above = xd->above_context;
-  ENTROPY_CONTEXT_PLANES t_left[TX_SIZE_MAX_SB][4],
-                        *orig_left = xd->left_context;
 
-  for (n = TX_4X4; n < TX_SIZE_MAX_SB; n++) {
-    vpx_memcpy(t_above[n], xd->above_context, sizeof(t_above[n]));
-    vpx_memcpy(t_left[n], xd->left_context, sizeof(t_left[n]));
-    r[n][0] = 0;
-    d[n] = 0;
-    s[n] = 1;
-  }
+  vp9_subtract_sb64y_s_c(x->src_diff, src, src_y_stride, dst, dst_y_stride);
+  super_block64_yrd_32x32(cm, x, &r[TX_32X32][0], &d[TX_32X32], &s[TX_32X32]);
+  super_block64_yrd_16x16(cm, x, &r[TX_16X16][0], &d[TX_16X16], &s[TX_16X16]);
+  super_block64_yrd_8x8(cm, x,   &r[TX_8X8][0],   &d[TX_8X8],   &s[TX_8X8]);
+  super_block64_yrd_4x4(cm, x,   &r[TX_4X4][0],   &d[TX_4X4],   &s[TX_4X4]);
 
-  for (n = 0; n < 4; n++) {
-    int x_idx = n & 1, y_idx = n >> 1;
-    int r_tmp, d_tmp, s_tmp;
-
-    xd->above_context = &t_above[TX_32X32][x_idx << 1];
-    xd->left_context = &t_left[TX_32X32][y_idx << 1];
-    vp9_subtract_sby_s_c(x->src_diff,
-                         src + 32 * x_idx + 32 * y_idx * src_y_stride,
-                         src_y_stride,
-                         dst + 32 * x_idx + 32 * y_idx * dst_y_stride,
-                         dst_y_stride);
-    super_block_yrd_32x32(&cpi->common, x, &r_tmp, &d_tmp, &s_tmp, 0);
-    r[TX_32X32][0] += r_tmp;
-    d[TX_32X32] += d_tmp;
-    s[TX_32X32] = s[TX_32X32] && s_tmp;
-  }
-
-#if DEBUG_ERROR
-  int err[3] = { 0, 0, 0 };
-#endif
-  for (n = 0; n < 16; n++) {
-    int x_idx = n & 3, y_idx = n >> 2;
-    int r_tmp, d_tmp, s_tmp;
-
-    vp9_subtract_mby_s_c(x->src_diff,
-                         src + x_idx * 16 + y_idx * 16 * src_y_stride,
-                         src_y_stride,
-                         dst + x_idx * 16 + y_idx * 16 * dst_y_stride,
-                         dst_y_stride);
-
-    xd->above_context = &t_above[TX_16X16][x_idx];
-    xd->left_context = &t_left[TX_16X16][y_idx];
-    macro_block_yrd_16x16(&cpi->common, x, &r_tmp, &d_tmp, &s_tmp, 0);
-    d[TX_16X16] += d_tmp;
-    r[TX_16X16][0] += r_tmp;
-    s[TX_16X16] = s[TX_16X16] && s_tmp;
-#if DEBUG_ERROR
-    vp9_inverse_transform_mby_16x16(xd);
-    err[2] += vp9_block_error_c(xd->diff, x->src_diff, 256);
-#endif
-
-    xd->above_context = &t_above[TX_4X4][x_idx];
-    xd->left_context = &t_left[TX_4X4][y_idx];
-    macro_block_yrd_4x4(&cpi->common, x, &r_tmp, &d_tmp, &s_tmp, 0);
-    d[TX_4X4] += d_tmp;
-    r[TX_4X4][0] += r_tmp;
-    s[TX_4X4] = s[TX_4X4] && s_tmp;
-#if DEBUG_ERROR
-    vp9_inverse_transform_mby_4x4(xd);
-    err[0] += vp9_block_error_c(xd->diff, x->src_diff, 256);
-#endif
-
-    xd->above_context = &t_above[TX_8X8][x_idx];
-    xd->left_context = &t_left[TX_8X8][y_idx];
-    macro_block_yrd_8x8(&cpi->common, x, &r_tmp, &d_tmp, &s_tmp, 0);
-    d[TX_8X8] += d_tmp;
-    r[TX_8X8][0] += r_tmp;
-    s[TX_8X8] = s[TX_8X8] && s_tmp;
-#if DEBUG_ERROR
-    vp9_inverse_transform_mby_8x8(xd);
-    err[1] += vp9_block_error_c(xd->diff, x->src_diff, 256);
-#endif
-  }
-#if DEBUG_ERROR
-  printf("IDCT/FDCT error 16x16: %d (d: %d)\n", err[2], d[2]);
-  printf("IDCT/FDCT error 8x8: %d (d: %d)\n", err[1], d[1]);
-  printf("IDCT/FDCT error 4x4: %d (d: %d)\n", err[0], d[0]);
-#endif
   choose_txfm_size_from_rd(cpi, x, r, rate, d, distortion, s, skip, txfm_cache,
                            TX_SIZE_MAX_SB - 1);
-
-  xd->above_context = orig_above;
-  xd->left_context = orig_left;
 }
 
 static void copy_predictor_8x8(uint8_t *dst, const uint8_t *predictor) {
@@ -1166,7 +1198,7 @@
     vp9_subtract_b(be, b, 16);
 
     b->bmi.as_mode.first = mode;
-    tx_type = get_tx_type_4x4(xd, b);
+    tx_type = get_tx_type_4x4(xd, be - x->block);
     if (tx_type != DCT_DCT) {
       vp9_short_fht4x4(be->src_diff, be->coeff, 16, tx_type);
       vp9_ht_quantize_b_4x4(x, be - x->block, tx_type);
@@ -1465,7 +1497,7 @@
     vp9_subtract_4b_c(be, b, 16);
 
     if (xd->mode_info_context->mbmi.txfm_size == TX_8X8) {
-      TX_TYPE tx_type = get_tx_type_8x8(xd, b);
+      TX_TYPE tx_type = get_tx_type_8x8(xd, ib);
       if (tx_type != DCT_DCT)
         vp9_short_fht8x8(be->src_diff, (x->block + idx)->coeff, 16, tx_type);
       else
@@ -1504,11 +1536,12 @@
         int do_two = 0;
         b = &xd->block[ib + iblock[i]];
         be = &x->block[ib + iblock[i]];
-        tx_type = get_tx_type_4x4(xd, b);
+        tx_type = get_tx_type_4x4(xd, ib + iblock[i]);
         if (tx_type != DCT_DCT) {
           vp9_short_fht4x4(be->src_diff, be->coeff, 16, tx_type);
           vp9_ht_quantize_b_4x4(x, ib + iblock[i], tx_type);
-        } else if (!(i & 1) && get_tx_type_4x4(xd, b + 1) == DCT_DCT) {
+        } else if (!(i & 1) &&
+                   get_tx_type_4x4(xd, ib + iblock[i] + 1) == DCT_DCT) {
           x->fwd_txm8x4(be->src_diff, be->coeff, 32);
           x->quantize_b_4x4_pair(x, ib + iblock[i], ib + iblock[i] + 1);
           do_two = 1;
@@ -1725,8 +1758,8 @@
   vp9_quantize_sbuv_16x16(x);
 
   *rate       = rd_cost_sbuv_16x16(cm, x, backup);
-  *distortion = vp9_block_error_c(x->coeff + 1024,
-                                  xd->dqcoeff + 1024, 512) >> 2;
+  *distortion = vp9_sb_block_error_c(x->coeff + 1024,
+                                     xd->dqcoeff + 1024, 512, 2);
   *skip       = vp9_sbuv_is_skippable_16x16(xd);
 }
 
@@ -2001,8 +2034,8 @@
   vp9_quantize_sb64uv_32x32(x);
 
   *rate       = rd_cost_sb64uv_32x32(cm, x, backup);
-  *distortion = vp9_block_error_c(x->coeff + 4096,
-                                  xd->dqcoeff + 4096, 2048);
+  *distortion = vp9_sb_block_error_c(x->coeff + 4096,
+                                     xd->dqcoeff + 4096, 2048, 0);
   *skip       = vp9_sb64uv_is_skippable_32x32(xd);
 }
 
diff --git a/vp9/encoder/vp9_tokenize.c b/vp9/encoder/vp9_tokenize.c
index 0fad9b0..370d53f 100644
--- a/vp9/encoder/vp9_tokenize.c
+++ b/vp9/encoder/vp9_tokenize.c
@@ -114,9 +114,6 @@
   const int *scan;
   vp9_coeff_count *counts;
   vp9_coeff_probs *probs;
-  const TX_TYPE tx_type = (sb_type == BLOCK_SIZE_MB16X16 &&
-                           type == PLANE_TYPE_Y_WITH_DC) ?
-                          get_tx_type(xd, &xd->block[ib]) : DCT_DCT;
   const int ref = mbmi->ref_frame != INTRA_FRAME;
   ENTROPY_CONTEXT *a, *l, *a1, *l1, *a2, *l2, *a3, *l3, a_ec, l_ec;
 #if CONFIG_CODE_NONZEROCOUNT
@@ -149,7 +146,9 @@
 
   switch (tx_size) {
     default:
-    case TX_4X4:
+    case TX_4X4: {
+      const TX_TYPE tx_type = (type == PLANE_TYPE_Y_WITH_DC) ?
+                              get_tx_type_4x4(xd, ib) : DCT_DCT;
       a_ec = *a;
       l_ec = *l;
       seg_eob = 16;
@@ -164,6 +163,7 @@
       counts = cpi->coef_counts_4x4;
       probs = cpi->common.fc.coef_probs_4x4;
       break;
+    }
     case TX_8X8:
       a_ec = (a[0] + a[1]) != 0;
       l_ec = (l[0] + l[1]) != 0;
@@ -354,7 +354,7 @@
          vp9_sbuv_is_skippable_16x16(xd);
 }
 
-static int sby_is_skippable_16x16(MACROBLOCKD *xd) {
+int vp9_sby_is_skippable_16x16(MACROBLOCKD *xd) {
   int skip = 1;
   int i = 0;
 
@@ -365,10 +365,10 @@
 }
 
 static int sb_is_skippable_16x16(MACROBLOCKD *xd) {
-  return sby_is_skippable_16x16(xd) & vp9_sbuv_is_skippable_16x16(xd);
+  return vp9_sby_is_skippable_16x16(xd) & vp9_sbuv_is_skippable_16x16(xd);
 }
 
-static int sby_is_skippable_8x8(MACROBLOCKD *xd) {
+int vp9_sby_is_skippable_8x8(MACROBLOCKD *xd) {
   int skip = 1;
   int i = 0;
 
@@ -378,7 +378,7 @@
   return skip;
 }
 
-static int sbuv_is_skippable_8x8(MACROBLOCKD *xd) {
+int vp9_sbuv_is_skippable_8x8(MACROBLOCKD *xd) {
   int skip = 1;
   int i = 0;
 
@@ -389,10 +389,10 @@
 }
 
 static int sb_is_skippable_8x8(MACROBLOCKD *xd) {
-  return sby_is_skippable_8x8(xd) & sbuv_is_skippable_8x8(xd);
+  return vp9_sby_is_skippable_8x8(xd) & vp9_sbuv_is_skippable_8x8(xd);
 }
 
-static int sby_is_skippable_4x4(MACROBLOCKD *xd) {
+int vp9_sby_is_skippable_4x4(MACROBLOCKD *xd) {
   int skip = 1;
   int i = 0;
 
@@ -402,7 +402,7 @@
   return skip;
 }
 
-static int sbuv_is_skippable_4x4(MACROBLOCKD *xd) {
+int vp9_sbuv_is_skippable_4x4(MACROBLOCKD *xd) {
   int skip = 1;
   int i = 0;
 
@@ -413,7 +413,7 @@
 }
 
 static int sb_is_skippable_4x4(MACROBLOCKD *xd) {
-  return sby_is_skippable_4x4(xd) & sbuv_is_skippable_4x4(xd);
+  return vp9_sby_is_skippable_4x4(xd) & vp9_sbuv_is_skippable_4x4(xd);
 }
 
 void vp9_tokenize_sb(VP9_COMP *cpi,
@@ -499,7 +499,7 @@
     *t = t_backup;
 }
 
-static int sb64y_is_skippable_32x32(MACROBLOCKD *xd) {
+int vp9_sb64y_is_skippable_32x32(MACROBLOCKD *xd) {
   int skip = 1;
   int i = 0;
 
@@ -514,10 +514,10 @@
 }
 
 static int sb64_is_skippable_32x32(MACROBLOCKD *xd) {
-  return sb64y_is_skippable_32x32(xd) & vp9_sb64uv_is_skippable_32x32(xd);
+  return vp9_sb64y_is_skippable_32x32(xd) & vp9_sb64uv_is_skippable_32x32(xd);
 }
 
-static int sb64y_is_skippable_16x16(MACROBLOCKD *xd) {
+int vp9_sb64y_is_skippable_16x16(MACROBLOCKD *xd) {
   int skip = 1;
   int i = 0;
 
@@ -527,7 +527,7 @@
   return skip;
 }
 
-static int sb64uv_is_skippable_16x16(MACROBLOCKD *xd) {
+int vp9_sb64uv_is_skippable_16x16(MACROBLOCKD *xd) {
   int skip = 1;
   int i = 0;
 
@@ -538,10 +538,10 @@
 }
 
 static int sb64_is_skippable_16x16(MACROBLOCKD *xd) {
-  return sb64y_is_skippable_16x16(xd) & sb64uv_is_skippable_16x16(xd);
+  return vp9_sb64y_is_skippable_16x16(xd) & vp9_sb64uv_is_skippable_16x16(xd);
 }
 
-static int sb64y_is_skippable_8x8(MACROBLOCKD *xd) {
+int vp9_sb64y_is_skippable_8x8(MACROBLOCKD *xd) {
   int skip = 1;
   int i = 0;
 
@@ -551,7 +551,7 @@
   return skip;
 }
 
-static int sb64uv_is_skippable_8x8(MACROBLOCKD *xd) {
+int vp9_sb64uv_is_skippable_8x8(MACROBLOCKD *xd) {
   int skip = 1;
   int i = 0;
 
@@ -562,10 +562,10 @@
 }
 
 static int sb64_is_skippable_8x8(MACROBLOCKD *xd) {
-  return sb64y_is_skippable_8x8(xd) & sb64uv_is_skippable_8x8(xd);
+  return vp9_sb64y_is_skippable_8x8(xd) & vp9_sb64uv_is_skippable_8x8(xd);
 }
 
-static int sb64y_is_skippable_4x4(MACROBLOCKD *xd) {
+int vp9_sb64y_is_skippable_4x4(MACROBLOCKD *xd) {
   int skip = 1;
   int i = 0;
 
@@ -575,7 +575,7 @@
   return skip;
 }
 
-static int sb64uv_is_skippable_4x4(MACROBLOCKD *xd) {
+int vp9_sb64uv_is_skippable_4x4(MACROBLOCKD *xd) {
   int skip = 1;
   int i = 0;
 
@@ -586,7 +586,7 @@
 }
 
 static int sb64_is_skippable_4x4(MACROBLOCKD *xd) {
-  return sb64y_is_skippable_4x4(xd) & sb64uv_is_skippable_4x4(xd);
+  return vp9_sb64y_is_skippable_4x4(xd) & vp9_sb64uv_is_skippable_4x4(xd);
 }
 
 void vp9_tokenize_sb64(VP9_COMP *cpi,
diff --git a/vp9/encoder/vp9_tokenize.h b/vp9/encoder/vp9_tokenize.h
index 4d6fe63..464d7ca 100644
--- a/vp9/encoder/vp9_tokenize.h
+++ b/vp9/encoder/vp9_tokenize.h
@@ -37,8 +37,20 @@
 int vp9_mbuv_is_skippable_8x8(MACROBLOCKD *xd);
 int vp9_mby_is_skippable_16x16(MACROBLOCKD *xd);
 int vp9_sby_is_skippable_32x32(MACROBLOCKD *xd);
+int vp9_sby_is_skippable_16x16(MACROBLOCKD *xd);
+int vp9_sby_is_skippable_8x8(MACROBLOCKD *xd);
+int vp9_sby_is_skippable_4x4(MACROBLOCKD *xd);
 int vp9_sbuv_is_skippable_16x16(MACROBLOCKD *xd);
+int vp9_sbuv_is_skippable_8x8(MACROBLOCKD *xd);
+int vp9_sbuv_is_skippable_4x4(MACROBLOCKD *xd);
+int vp9_sb64y_is_skippable_32x32(MACROBLOCKD *xd);
+int vp9_sb64y_is_skippable_16x16(MACROBLOCKD *xd);
+int vp9_sb64y_is_skippable_8x8(MACROBLOCKD *xd);
+int vp9_sb64y_is_skippable_4x4(MACROBLOCKD *xd);
 int vp9_sb64uv_is_skippable_32x32(MACROBLOCKD *xd);
+int vp9_sb64uv_is_skippable_16x16(MACROBLOCKD *xd);
+int vp9_sb64uv_is_skippable_8x8(MACROBLOCKD *xd);
+int vp9_sb64uv_is_skippable_4x4(MACROBLOCKD *xd);
 
 struct VP9_COMP;