Merge "Adjustments to key frame sizing." into experimental
diff --git a/test/acm_random.h b/test/acm_random.h
index 514894e..84c6c75 100644
--- a/test/acm_random.h
+++ b/test/acm_random.h
@@ -35,6 +35,13 @@
     return (rand() >> 8) & 0xff;
   }
 
+  uint8_t Rand8Extremes(void) {
+    // Returns a random value near 0 or near 255, to better exercise
+    // saturation behavior.
+    const uint8_t r = Rand8();
+    return r < 128 ? r << 4 : r >> 4;
+  }
+
   int PseudoUniform(int range) {
     return (rand() >> 8) % range;
   }
diff --git a/test/convolve_test.cc b/test/convolve_test.cc
index 35065a4..a8139cb 100644
--- a/test/convolve_test.cc
+++ b/test/convolve_test.cc
@@ -66,7 +66,7 @@
   // support.
   const int kInterp_Extend = 4;
   const unsigned int intermediate_height =
-    (kInterp_Extend - 1) +     output_height + kInterp_Extend;
+    (kInterp_Extend - 1) + output_height + kInterp_Extend;
 
   /* Size of intermediate_buffer is max_intermediate_height * filter_max_width,
    * where max_intermediate_height = (kInterp_Extend - 1) + filter_max_height
@@ -75,7 +75,7 @@
    *                               = 23
    * and filter_max_width = 16
    */
-  uint8_t intermediate_buffer[23 * 16];
+  uint8_t intermediate_buffer[71 * 64];
   const int intermediate_next_stride = 1 - intermediate_height * output_width;
 
   // Horizontal pass (src -> transposed intermediate).
@@ -158,13 +158,13 @@
                                        unsigned int dst_stride,
                                        unsigned int output_width,
                                        unsigned int output_height) {
-  uint8_t tmp[16*16];
+  uint8_t tmp[64*64];
 
-  assert(output_width <= 16);
-  assert(output_height <= 16);
-  filter_block2d_8_c(src_ptr, src_stride, HFilter, VFilter, tmp, 16,
+  assert(output_width <= 64);
+  assert(output_height <= 64);
+  filter_block2d_8_c(src_ptr, src_stride, HFilter, VFilter, tmp, 64,
                      output_width, output_height);
-  block2d_average_c(tmp, 16, dst_ptr, dst_stride,
+  block2d_average_c(tmp, 64, dst_ptr, dst_stride,
                     output_width, output_height);
 }
 
@@ -188,10 +188,10 @@
 
   protected:
     static const int kDataAlignment = 16;
-    static const int kOuterBlockSize = 32;
+    static const int kOuterBlockSize = 128;
     static const int kInputStride = kOuterBlockSize;
     static const int kOutputStride = kOuterBlockSize;
-    static const int kMaxDimension = 16;
+    static const int kMaxDimension = 64;
 
     int Width() const { return GET_PARAM(0); }
     int Height() const { return GET_PARAM(1); }
@@ -221,7 +221,7 @@
 
       ::libvpx_test::ACMRandom prng;
       for (int i = 0; i < kOuterBlockSize * kOuterBlockSize; ++i)
-        input_[i] = prng.Rand8();
+        input_[i] = prng.Rand8Extremes();
     }
 
     void CheckGuardBlocks() {
@@ -308,6 +308,29 @@
   vp9_sub_pel_filters_8s,
   vp9_sub_pel_filters_8lp
 };
+const int kNumFilterBanks = sizeof(kTestFilterList) /
+    sizeof(kTestFilterList[0]);
+const int kNumFilters = 16;
+
+TEST(ConvolveTest, FiltersWontSaturateWhenAddedPairwise) {
+  for (int filter_bank = 0; filter_bank < kNumFilterBanks; ++filter_bank) {
+    const int16_t (*filters)[8] = kTestFilterList[filter_bank];
+    for (int i = 0; i < kNumFilters; i++) {
+      const int p0 = filters[i][0] + filters[i][1];
+      const int p1 = filters[i][2] + filters[i][3];
+      const int p2 = filters[i][4] + filters[i][5];
+      const int p3 = filters[i][6] + filters[i][7];
+      EXPECT_LE(p0, 128);
+      EXPECT_LE(p1, 128);
+      EXPECT_LE(p2, 128);
+      EXPECT_LE(p3, 128);
+      EXPECT_LE(p0 + p3, 128);
+      EXPECT_LE(p0 + p3 + p1, 128);
+      EXPECT_LE(p0 + p3 + p1 + p2, 128);
+      EXPECT_EQ(p0 + p1 + p2 + p3, 128);
+    }
+  }
+}
 
 const int16_t kInvalidFilter[8] = { 0 };
 
@@ -316,12 +339,9 @@
   uint8_t* const out = output();
   uint8_t ref[kOutputStride * kMaxDimension];
 
-  const int kNumFilterBanks = sizeof(kTestFilterList) /
-      sizeof(kTestFilterList[0]);
 
   for (int filter_bank = 0; filter_bank < kNumFilterBanks; ++filter_bank) {
     const int16_t (*filters)[8] = kTestFilterList[filter_bank];
-    const int kNumFilters = 16;
 
     for (int filter_x = 0; filter_x < kNumFilters; ++filter_x) {
       for (int filter_y = 0; filter_y < kNumFilters; ++filter_y) {
@@ -368,7 +388,7 @@
   ::libvpx_test::ACMRandom prng;
   for (int y = 0; y < Height(); ++y) {
     for (int x = 0; x < Width(); ++x) {
-      const uint8_t r = prng.Rand8();
+      const uint8_t r = prng.Rand8Extremes();
 
       out[y * kOutputStride + x] = r;
       ref[y * kOutputStride + x] = r;
@@ -440,16 +460,17 @@
 TEST_P(ConvolveTest, ChangeFilterWorks) {
   uint8_t* const in = input();
   uint8_t* const out = output();
+  const int kPixelSelected = 4;
 
   REGISTER_STATE_CHECK(UUT_->h8_(in, kInputStride, out, kOutputStride,
                                  kChangeFilters[8], 17, kChangeFilters[4], 16,
                                  Width(), Height()));
 
   for (int x = 0; x < Width(); ++x) {
-    if (x < 8)
-      ASSERT_EQ(in[4], out[x]) << "x == " << x;
-    else
-      ASSERT_EQ(in[12], out[x]) << "x == " << x;
+    const int kQ4StepAdjust = x >> 4;
+    const int kFilterPeriodAdjust = (x >> 3) << 3;
+    const int ref_x = kQ4StepAdjust + kFilterPeriodAdjust + kPixelSelected;
+    ASSERT_EQ(in[ref_x], out[x]) << "x == " << x;
   }
 
   REGISTER_STATE_CHECK(UUT_->v8_(in, kInputStride, out, kOutputStride,
@@ -457,10 +478,10 @@
                                  Width(), Height()));
 
   for (int y = 0; y < Height(); ++y) {
-    if (y < 8)
-      ASSERT_EQ(in[4 * kInputStride], out[y * kOutputStride]) << "y == " << y;
-    else
-      ASSERT_EQ(in[12 * kInputStride], out[y * kOutputStride]) << "y == " << y;
+    const int kQ4StepAdjust = y >> 4;
+    const int kFilterPeriodAdjust = (y >> 3) << 3;
+    const int ref_y = kQ4StepAdjust + kFilterPeriodAdjust + kPixelSelected;
+    ASSERT_EQ(in[ref_y * kInputStride], out[y * kInputStride]) << "y == " << y;
   }
 
   REGISTER_STATE_CHECK(UUT_->hv8_(in, kInputStride, out, kOutputStride,
@@ -468,9 +489,13 @@
                                   Width(), Height()));
 
   for (int y = 0; y < Height(); ++y) {
+    const int kQ4StepAdjustY = y >> 4;
+    const int kFilterPeriodAdjustY = (y >> 3) << 3;
+    const int ref_y = kQ4StepAdjustY + kFilterPeriodAdjustY + kPixelSelected;
     for (int x = 0; x < Width(); ++x) {
-      const int ref_x = x < 8 ? 4 : 12;
-      const int ref_y = y < 8 ? 4 : 12;
+      const int kQ4StepAdjustX = x >> 4;
+      const int kFilterPeriodAdjustX = (x >> 3) << 3;
+      const int ref_x = kQ4StepAdjustX + kFilterPeriodAdjustX + kPixelSelected;
 
       ASSERT_EQ(in[ref_y * kInputStride + ref_x], out[y * kOutputStride + x])
           << "x == " << x << ", y == " << y;
@@ -489,9 +514,17 @@
 INSTANTIATE_TEST_CASE_P(C, ConvolveTest, ::testing::Values(
     make_tuple(4, 4, &convolve8_c),
     make_tuple(8, 4, &convolve8_c),
+    make_tuple(4, 8, &convolve8_c),
     make_tuple(8, 8, &convolve8_c),
     make_tuple(16, 8, &convolve8_c),
-    make_tuple(16, 16, &convolve8_c)));
+    make_tuple(8, 16, &convolve8_c),
+    make_tuple(16, 16, &convolve8_c),
+    make_tuple(32, 16, &convolve8_c),
+    make_tuple(16, 32, &convolve8_c),
+    make_tuple(32, 32, &convolve8_c),
+    make_tuple(64, 32, &convolve8_c),
+    make_tuple(32, 64, &convolve8_c),
+    make_tuple(64, 64, &convolve8_c)));
 }
 
 #if HAVE_SSSE3
@@ -503,7 +536,15 @@
 INSTANTIATE_TEST_CASE_P(SSSE3, ConvolveTest, ::testing::Values(
     make_tuple(4, 4, &convolve8_ssse3),
     make_tuple(8, 4, &convolve8_ssse3),
+    make_tuple(4, 8, &convolve8_ssse3),
     make_tuple(8, 8, &convolve8_ssse3),
     make_tuple(16, 8, &convolve8_ssse3),
-    make_tuple(16, 16, &convolve8_ssse3)));
+    make_tuple(8, 16, &convolve8_ssse3),
+    make_tuple(16, 16, &convolve8_ssse3),
+    make_tuple(32, 16, &convolve8_ssse3),
+    make_tuple(16, 32, &convolve8_ssse3),
+    make_tuple(32, 32, &convolve8_ssse3),
+    make_tuple(64, 32, &convolve8_ssse3),
+    make_tuple(32, 64, &convolve8_ssse3),
+    make_tuple(64, 64, &convolve8_ssse3)));
 #endif
diff --git a/vp9/common/vp9_alloccommon.c b/vp9/common/vp9_alloccommon.c
index 0628a88..e142362 100644
--- a/vp9/common/vp9_alloccommon.c
+++ b/vp9/common/vp9_alloccommon.c
@@ -85,7 +85,7 @@
   oci->new_fb_idx = NUM_YV12_BUFFERS - 1;
   oci->fb_idx_ref_cnt[oci->new_fb_idx] = 1;
 
-  for (i = 0; i < 3; i++)
+  for (i = 0; i < ALLOWED_REFS_PER_FRAME; i++)
     oci->active_ref_idx[i] = i;
 
   for (i = 0; i < NUM_REF_FRAMES; i++) {
diff --git a/vp9/common/vp9_blockd.h b/vp9/common/vp9_blockd.h
index 8d67402..dd95761 100644
--- a/vp9/common/vp9_blockd.h
+++ b/vp9/common/vp9_blockd.h
@@ -26,6 +26,10 @@
 #define MB_FEATURE_TREE_PROBS   3
 #define PREDICTION_PROBS 3
 
+#define DEFAULT_PRED_PROB_0 120
+#define DEFAULT_PRED_PROB_1 80
+#define DEFAULT_PRED_PROB_2 40
+
 #define MBSKIP_CONTEXTS 3
 
 #define MAX_MB_SEGMENTS         4
@@ -51,8 +55,10 @@
   ENTROPY_CONTEXT v[2];
 } ENTROPY_CONTEXT_PLANES;
 
-#define VP9_COMBINEENTROPYCONTEXTS(Dest, A, B) \
-  Dest = ((A)!=0) + ((B)!=0);
+static INLINE int combine_entropy_contexts(ENTROPY_CONTEXT a,
+                                           ENTROPY_CONTEXT b) {
+  return (a != 0) + (b != 0);
+}
 
 typedef enum {
   KEY_FRAME = 0,
@@ -290,7 +296,6 @@
 } MODE_INFO;
 
 typedef struct blockd {
-  uint8_t *predictor;
   int16_t *diff;
   int16_t *dequant;
 
@@ -354,7 +359,6 @@
 
 typedef struct macroblockd {
   DECLARE_ALIGNED(16, int16_t,  diff[64*64+32*32*2]);      /* from idct diff */
-  DECLARE_ALIGNED(16, uint8_t,  predictor[384]);  // unused for superblocks
 #if CONFIG_CODE_NONZEROCOUNT
   DECLARE_ALIGNED(16, uint16_t, nzcs[256+64*2]);
 #endif
@@ -871,4 +875,62 @@
   }
 }
 
+// TODO(jkoleszar): In principle, pred_w, pred_h are unnecessary, as we could
+// calculate the subsampled BLOCK_SIZE_TYPE, but that type isn't defined for
+// sizes smaller than 16x16 yet.
+typedef void (*foreach_predicted_block_visitor)(int plane, int block,
+                                                BLOCK_SIZE_TYPE bsize,
+                                                int pred_w, int pred_h,
+                                                void *arg);
+static INLINE void foreach_predicted_block_in_plane(
+    const MACROBLOCKD* const xd, BLOCK_SIZE_TYPE bsize, int plane,
+    foreach_predicted_block_visitor visit, void *arg) {
+  const int bw = b_width_log2(bsize), bh = b_height_log2(bsize);
+
+  // block sizes in number of 4x4 blocks log 2 ("*_b")
+  // 4x4=0, 8x8=2, 16x16=4, 32x32=6, 64x64=8
+  const MB_PREDICTION_MODE mode = xd->mode_info_context->mbmi.mode;
+  const int block_size_b = bw + bh;
+
+  // subsampled size of the block
+  const int ss_sum = xd->plane[plane].subsampling_x +
+                     xd->plane[plane].subsampling_y;
+  const int ss_block_size = block_size_b - ss_sum;
+
+  // size of the predictor to use.
+  // TODO(jkoleszar): support I8X8, I4X4
+  const int pred_w = bw - xd->plane[plane].subsampling_x;
+  const int pred_h = bh - xd->plane[plane].subsampling_y;
+  const int pred_b = mode == SPLITMV ? 0 : pred_w + pred_h;
+  const int step = 1 << pred_b;
+
+  int i;
+
+  assert(pred_b <= block_size_b);
+  assert(pred_b == ss_block_size);
+  for (i = 0; i < (1 << ss_block_size); i += step) {
+    visit(plane, i, bsize, pred_w, pred_h, arg);
+  }
+}
+static INLINE void foreach_predicted_block(
+    const MACROBLOCKD* const xd, BLOCK_SIZE_TYPE bsize,
+    foreach_predicted_block_visitor visit, void *arg) {
+  int plane;
+
+  for (plane = 0; plane < MAX_MB_PLANE; plane++) {
+    foreach_predicted_block_in_plane(xd, bsize, plane, visit, arg);
+  }
+}
+static INLINE void foreach_predicted_block_uv(
+    const MACROBLOCKD* const xd, BLOCK_SIZE_TYPE bsize,
+    foreach_predicted_block_visitor visit, void *arg) {
+  int plane;
+
+  for (plane = 1; plane < MAX_MB_PLANE; plane++) {
+    foreach_predicted_block_in_plane(xd, bsize, plane, visit, arg);
+  }
+}
+
+
+
 #endif  // VP9_COMMON_VP9_BLOCKD_H_
diff --git a/vp9/common/vp9_convolve.c b/vp9/common/vp9_convolve.c
index 3ab8bec..a27ca6f 100644
--- a/vp9/common/vp9_convolve.c
+++ b/vp9/common/vp9_convolve.c
@@ -331,14 +331,14 @@
                        const int16_t *filter_y, int y_step_q4,
                        int w, int h, int taps) {
   /* Fixed size intermediate buffer places limits on parameters.
-   * Maximum intermediate_height is 39, for y_step_q4 == 32,
-   * h == 16, taps == 8.
+   * Maximum intermediate_height is 135, for y_step_q4 == 32,
+   * h == 64, taps == 8.
    */
-  uint8_t temp[16 * 39];
+  uint8_t temp[64 * 135];
   int intermediate_height = ((h * y_step_q4) >> 4) + taps - 1;
 
-  assert(w <= 16);
-  assert(h <= 16);
+  assert(w <= 64);
+  assert(h <= 64);
   assert(taps <= 8);
   assert(y_step_q4 <= 32);
 
@@ -346,10 +346,10 @@
     intermediate_height = h;
 
   convolve_horiz_c(src - src_stride * (taps / 2 - 1), src_stride,
-                   temp, 16,
+                   temp, 64,
                    filter_x, x_step_q4, filter_y, y_step_q4,
                    w, intermediate_height, taps);
-  convolve_vert_c(temp + 16 * (taps / 2 - 1), 16, dst, dst_stride,
+  convolve_vert_c(temp + 64 * (taps / 2 - 1), 64, dst, dst_stride,
                   filter_x, x_step_q4, filter_y, y_step_q4,
                   w, h, taps);
 }
@@ -360,14 +360,14 @@
                            const int16_t *filter_y, int y_step_q4,
                            int w, int h, int taps) {
   /* Fixed size intermediate buffer places limits on parameters.
-   * Maximum intermediate_height is 39, for y_step_q4 == 32,
-   * h == 16, taps == 8.
+   * Maximum intermediate_height is 135, for y_step_q4 == 32,
+   * h == 64, taps == 8.
    */
-  uint8_t temp[16 * 39];
+  uint8_t temp[64 * 135];
   int intermediate_height = ((h * y_step_q4) >> 4) + taps - 1;
 
-  assert(w <= 16);
-  assert(h <= 16);
+  assert(w <= 64);
+  assert(h <= 64);
   assert(taps <= 8);
   assert(y_step_q4 <= 32);
 
@@ -375,10 +375,10 @@
     intermediate_height = h;
 
   convolve_horiz_c(src - src_stride * (taps / 2 - 1), src_stride,
-                   temp, 16,
+                   temp, 64,
                    filter_x, x_step_q4, filter_y, y_step_q4,
                    w, intermediate_height, taps);
-  convolve_avg_vert_c(temp + 16 * (taps / 2 - 1), 16, dst, dst_stride,
+  convolve_avg_vert_c(temp + 64 * (taps / 2 - 1), 64, dst, dst_stride,
                       filter_x, x_step_q4, filter_y, y_step_q4,
                       w, h, taps);
 }
@@ -563,16 +563,16 @@
                          const int16_t *filter_y, int y_step_q4,
                          int w, int h) {
   /* Fixed size intermediate buffer places limits on parameters. */
-  DECLARE_ALIGNED_ARRAY(16, uint8_t, temp, 16 * 16);
-  assert(w <= 16);
-  assert(h <= 16);
+  DECLARE_ALIGNED_ARRAY(16, uint8_t, temp, 64 * 64);
+  assert(w <= 64);
+  assert(h <= 64);
 
   vp9_convolve8(src, src_stride,
-                temp, 16,
+                temp, 64,
                 filter_x, x_step_q4,
                 filter_y, y_step_q4,
                 w, h);
-  vp9_convolve_avg(temp, 16,
+  vp9_convolve_avg(temp, 64,
                    dst, dst_stride,
                    NULL, 0, /* These unused parameter should be removed! */
                    NULL, 0, /* These unused parameter should be removed! */
diff --git a/vp9/common/vp9_entropymode.c b/vp9/common/vp9_entropymode.c
index 8650349..0db2de6 100644
--- a/vp9/common/vp9_entropymode.c
+++ b/vp9/common/vp9_entropymode.c
@@ -364,9 +364,9 @@
 #if CONFIG_COMP_INTERINTRA_PRED
   x->fc.interintra_prob = VP9_DEF_INTERINTRA_PROB;
 #endif
-  x->ref_pred_probs[0] = 120;
-  x->ref_pred_probs[1] = 80;
-  x->ref_pred_probs[2] = 40;
+  x->ref_pred_probs[0] = DEFAULT_PRED_PROB_0;
+  x->ref_pred_probs[1] = DEFAULT_PRED_PROB_1;
+  x->ref_pred_probs[2] = DEFAULT_PRED_PROB_2;
 }
 
 
diff --git a/vp9/common/vp9_entropymv.c b/vp9/common/vp9_entropymv.c
index fe36677..0a81015 100644
--- a/vp9/common/vp9_entropymv.c
+++ b/vp9/common/vp9_entropymv.c
@@ -87,12 +87,12 @@
   },
 };
 
-MV_JOINT_TYPE vp9_get_mv_joint(MV mv) {
-  if (mv.row == 0 && mv.col == 0)
+MV_JOINT_TYPE vp9_get_mv_joint(const MV *mv) {
+  if (mv->row == 0 && mv->col == 0)
     return MV_JOINT_ZERO;
-  else if (mv.row == 0 && mv.col != 0)
+  else if (mv->row == 0 && mv->col != 0)
     return MV_JOINT_HNZVZ;
-  else if (mv.row != 0 && mv.col == 0)
+  else if (mv->row != 0 && mv->col == 0)
     return MV_JOINT_HZVNZ;
   else
     return MV_JOINT_HNZVNZ;
@@ -209,13 +209,13 @@
 
 void vp9_increment_nmv(const MV *mv, const MV *ref, nmv_context_counts *mvctx,
                        int usehp) {
-  const MV_JOINT_TYPE type = vp9_get_mv_joint(*mv);
-  mvctx->joints[type]++;
+  const MV_JOINT_TYPE j = vp9_get_mv_joint(mv);
+  mvctx->joints[j]++;
   usehp = usehp && vp9_use_nmv_hp(ref);
-  if (mv_joint_vertical(type))
+  if (mv_joint_vertical(j))
     increment_nmv_component_count(mv->row, &mvctx->comps[0], 1, usehp);
 
-  if (mv_joint_horizontal(type))
+  if (mv_joint_horizontal(j))
     increment_nmv_component_count(mv->col, &mvctx->comps[1], 1, usehp);
 }
 
diff --git a/vp9/common/vp9_entropymv.h b/vp9/common/vp9_entropymv.h
index 715b5bb..de1bd43 100644
--- a/vp9/common/vp9_entropymv.h
+++ b/vp9/common/vp9_entropymv.h
@@ -105,7 +105,7 @@
   nmv_component comps[2];
 } nmv_context;
 
-MV_JOINT_TYPE vp9_get_mv_joint(MV mv);
+MV_JOINT_TYPE vp9_get_mv_joint(const MV *mv);
 MV_CLASS_TYPE vp9_get_mv_class(int z, int *offset);
 int vp9_get_mv_mag(MV_CLASS_TYPE c, int offset);
 
diff --git a/vp9/common/vp9_findnearmv.c b/vp9/common/vp9_findnearmv.c
index e4cdd9d..832e8dd 100644
--- a/vp9/common/vp9_findnearmv.c
+++ b/vp9/common/vp9_findnearmv.c
@@ -8,7 +8,6 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-
 #include <limits.h>
 
 #include "vp9/common/vp9_findnearmv.h"
@@ -22,8 +21,7 @@
   { 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15}
 };
 
-static void lower_mv_precision(int_mv *mv, int usehp)
-{
+static void lower_mv_precision(int_mv *mv, int usehp) {
   if (!usehp || !vp9_use_nmv_hp(&mv->as_mv)) {
     if (mv->as_mv.row & 1)
       mv->as_mv.row += (mv->as_mv.row > 0 ? -1 : 1);
@@ -32,8 +30,7 @@
   }
 }
 
-vp9_prob *vp9_mv_ref_probs(VP9_COMMON *pc,
-                           vp9_prob p[4], const int context) {
+vp9_prob *vp9_mv_ref_probs(VP9_COMMON *pc, vp9_prob p[4], int context) {
   p[0] = pc->fc.vp9_mode_contexts[context][0];
   p[1] = pc->fc.vp9_mode_contexts[context][1];
   p[2] = pc->fc.vp9_mode_contexts[context][2];
diff --git a/vp9/common/vp9_findnearmv.h b/vp9/common/vp9_findnearmv.h
index 72b6128..c360c20 100644
--- a/vp9/common/vp9_findnearmv.h
+++ b/vp9/common/vp9_findnearmv.h
@@ -20,10 +20,9 @@
 #define LEFT_TOP_MARGIN     ((VP9BORDERINPIXELS - VP9_INTERP_EXTEND) << 3)
 #define RIGHT_BOTTOM_MARGIN ((VP9BORDERINPIXELS - VP9_INTERP_EXTEND) << 3)
 
-/* check a list of motion vectors by sad score using a number rows of pixels
- * above and a number cols of pixels in the left to select the one with best
- * score to use as ref motion vector
- */
+// check a list of motion vectors by sad score using a number rows of pixels
+// above and a number cols of pixels in the left to select the one with best
+// score to use as ref motion vector
 void vp9_find_best_ref_mvs(MACROBLOCKD *xd,
                            uint8_t *ref_y_buffer,
                            int ref_y_stride,
@@ -49,36 +48,24 @@
                      int mb_to_right_edge,
                      int mb_to_top_edge,
                      int mb_to_bottom_edge) {
-  mv->as_mv.col = (mv->as_mv.col < mb_to_left_edge) ?
-                  mb_to_left_edge : mv->as_mv.col;
-  mv->as_mv.col = (mv->as_mv.col > mb_to_right_edge) ?
-                  mb_to_right_edge : mv->as_mv.col;
-  mv->as_mv.row = (mv->as_mv.row < mb_to_top_edge) ?
-                  mb_to_top_edge : mv->as_mv.row;
-  mv->as_mv.row = (mv->as_mv.row > mb_to_bottom_edge) ?
-                  mb_to_bottom_edge : mv->as_mv.row;
+  mv->as_mv.col = clamp(mv->as_mv.col, mb_to_left_edge, mb_to_right_edge);
+  mv->as_mv.row = clamp(mv->as_mv.row, mb_to_top_edge, mb_to_bottom_edge);
 }
 
 static int clamp_mv2(int_mv *mv, const MACROBLOCKD *xd) {
   int_mv tmp_mv;
-  int    mv_clampped = 0;
   tmp_mv.as_int = mv->as_int;
   clamp_mv(mv,
            xd->mb_to_left_edge - LEFT_TOP_MARGIN,
            xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN,
            xd->mb_to_top_edge - LEFT_TOP_MARGIN,
            xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN);
-  if (tmp_mv.as_int != mv->as_int)
-    mv_clampped = 1;
-
-  return mv_clampped;
+  return tmp_mv.as_int != mv->as_int;
 }
 
-static unsigned int check_mv_bounds(int_mv *mv,
-                                    int mb_to_left_edge,
-                                    int mb_to_right_edge,
-                                    int mb_to_top_edge,
-                                    int mb_to_bottom_edge) {
+static int check_mv_bounds(int_mv *mv,
+                           int mb_to_left_edge, int mb_to_right_edge,
+                           int mb_to_top_edge, int mb_to_bottom_edge) {
   return mv->as_mv.col < mb_to_left_edge ||
          mv->as_mv.col > mb_to_right_edge ||
          mv->as_mv.row < mb_to_top_edge ||
diff --git a/vp9/common/vp9_mbpitch.c b/vp9/common/vp9_mbpitch.c
index aba950e..6ed5f27 100644
--- a/vp9/common/vp9_mbpitch.c
+++ b/vp9/common/vp9_mbpitch.c
@@ -78,7 +78,6 @@
       const int to = r * 4 + c;
       const int from = r * 4 * 16 + c * 4;
       blockd[to].diff = &mb->diff[from];
-      blockd[to].predictor = &mb->predictor[from];
     }
   }
 
@@ -87,7 +86,6 @@
       const int to = 16 + r * 2 + c;
       const int from = 256 + r * 4 * 8 + c * 4;
       blockd[to].diff = &mb->diff[from];
-      blockd[to].predictor = &mb->predictor[from];
     }
   }
 
@@ -96,7 +94,6 @@
       const int to = 20 + r * 2 + c;
       const int from = 320 + r * 4 * 8 + c * 4;
       blockd[to].diff = &mb->diff[from];
-      blockd[to].predictor = &mb->predictor[from];
     }
   }
 
diff --git a/vp9/common/vp9_onyxc_int.h b/vp9/common/vp9_onyxc_int.h
index 66698f7..13ec865 100644
--- a/vp9/common/vp9_onyxc_int.h
+++ b/vp9/common/vp9_onyxc_int.h
@@ -231,9 +231,9 @@
   int base_qindex;
   int last_kf_gf_q;  /* Q used on the last GF or KF */
 
-  int y1dc_delta_q;
-  int uvdc_delta_q;
-  int uvac_delta_q;
+  int y_dc_delta_q;
+  int uv_dc_delta_q;
+  int uv_ac_delta_q;
 
   unsigned int frames_since_golden;
   unsigned int frames_till_alt_ref_frame;
diff --git a/vp9/common/vp9_recon.c b/vp9/common/vp9_recon.c
index 0625ccb..121776c 100644
--- a/vp9/common/vp9_recon.c
+++ b/vp9/common/vp9_recon.c
@@ -32,22 +32,22 @@
 
 void vp9_recon_b_c(uint8_t *pred_ptr, int16_t *diff_ptr, uint8_t *dst_ptr,
                    int stride) {
-  recon(4, 4, pred_ptr, 16, diff_ptr, 16, dst_ptr, stride);
+  recon(4, 4, pred_ptr, stride, diff_ptr, 16, dst_ptr, stride);
 }
 
 void vp9_recon_uv_b_c(uint8_t *pred_ptr, int16_t *diff_ptr, uint8_t *dst_ptr,
                       int stride) {
-  recon(4, 4, pred_ptr, 8, diff_ptr, 8, dst_ptr, stride);
+  recon(4, 4, pred_ptr, stride, diff_ptr, 8, dst_ptr, stride);
 }
 
 void vp9_recon4b_c(uint8_t *pred_ptr, int16_t *diff_ptr, uint8_t *dst_ptr,
                    int stride) {
-  recon(4, 16, pred_ptr, 16, diff_ptr, 16, dst_ptr, stride);
+  recon(4, 16, pred_ptr, stride, diff_ptr, 16, dst_ptr, stride);
 }
 
 void vp9_recon2b_c(uint8_t *pred_ptr, int16_t *diff_ptr, uint8_t *dst_ptr,
                    int stride) {
-  recon(4, 8, pred_ptr, 8, diff_ptr, 8, dst_ptr, stride);
+  recon(4, 8, pred_ptr, stride, diff_ptr, 8, dst_ptr, stride);
 }
 
 void vp9_recon_sby_s_c(MACROBLOCKD *mb, uint8_t *dst,
@@ -95,7 +95,8 @@
   for (i = 0; i < 16; i += 4) {
     BLOCKD *b = &xd->block[i];
 
-    vp9_recon4b(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+    vp9_recon4b(*(b->base_dst) + b->dst, b->diff,
+                *(b->base_dst) + b->dst, b->dst_stride);
   }
 }
 
@@ -104,13 +105,13 @@
 
   for (i = 0; i < 16; i += 4) {
     BLOCKD *b = &xd->block[i];
-
-    vp9_recon4b(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+    vp9_recon4b(*(b->base_dst) + b->dst, b->diff,
+                *(b->base_dst) + b->dst, b->dst_stride);
   }
 
   for (i = 16; i < 24; i += 2) {
     BLOCKD *b = &xd->block[i];
-
-    vp9_recon2b(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+    vp9_recon2b(*(b->base_dst) + b->dst, b->diff,
+                *(b->base_dst) + b->dst, b->dst_stride);
   }
 }
diff --git a/vp9/common/vp9_reconinter.c b/vp9/common/vp9_reconinter.c
index 79ca0b4..64929c1 100644
--- a/vp9/common/vp9_reconinter.c
+++ b/vp9/common/vp9_reconinter.c
@@ -363,21 +363,18 @@
  */
 void vp9_build_inter_predictor_q4(const uint8_t *src, int src_stride,
                                   uint8_t *dst, int dst_stride,
-                                  const int_mv *fullpel_mv_q3,
-                                  const int_mv *frac_mv_q4,
+                                  const int_mv *mv_q4,
                                   const struct scale_factors *scale,
                                   int w, int h, int weight,
                                   const struct subpix_fn_table *subpix) {
-  const int mv_row_q4 = ((fullpel_mv_q3->as_mv.row >> 3) << 4)
-                        + (frac_mv_q4->as_mv.row & 0xf);
-  const int mv_col_q4 = ((fullpel_mv_q3->as_mv.col >> 3) << 4)
-                        + (frac_mv_q4->as_mv.col & 0xf);
   const int scaled_mv_row_q4 =
-      scale->scale_motion_vector_component_q4(mv_row_q4, scale->y_num,
-                                              scale->y_den, scale->y_offset_q4);
+      scale->scale_motion_vector_component_q4(mv_q4->as_mv.row,
+                                              scale->y_num, scale->y_den,
+                                              scale->y_offset_q4);
   const int scaled_mv_col_q4 =
-      scale->scale_motion_vector_component_q4(mv_col_q4, scale->x_num,
-                                              scale->x_den, scale->x_offset_q4);
+      scale->scale_motion_vector_component_q4(mv_q4->as_mv.col,
+                                              scale->x_num, scale->x_den,
+                                              scale->x_offset_q4);
   const int subpel_x = scaled_mv_col_q4 & 15;
   const int subpel_y = scaled_mv_row_q4 & 15;
 
@@ -399,7 +396,7 @@
                                          int row, int col) {
   struct scale_factors * scale = &s[which_mv];
 
-  assert(d1->predictor - d0->predictor == block_size);
+  assert(d1->dst - d0->dst == block_size);
   assert(d1->pre == d0->pre + block_size);
 
   scale->set_scaled_offsets(scale, row, col);
@@ -446,11 +443,11 @@
                                       int block_size, int stride,
                                       int which_mv, int weight,
                                       const struct subpix_fn_table *subpix,
-                                      int row, int col, int use_dst) {
-  uint8_t *d0_predictor = use_dst ? *(d0->base_dst) + d0->dst : d0->predictor;
-  uint8_t *d1_predictor = use_dst ? *(d1->base_dst) + d1->dst : d1->predictor;
+                                      int row, int col) {
+  uint8_t *d0_predictor = *(d0->base_dst) + d0->dst;
+  uint8_t *d1_predictor = *(d1->base_dst) + d1->dst;
   struct scale_factors * scale = &s[which_mv];
-  stride = use_dst ? d0->dst_stride : stride;
+  stride = d0->dst_stride;
 
   assert(d1_predictor - d0_predictor == block_size);
   assert(d1->pre == d0->pre + block_size);
@@ -527,6 +524,92 @@
             (xd->mb_to_bottom_edge + (16 << 3)) >> 1 : mv->row;
 }
 
+#if !CONFIG_IMPLICIT_COMPOUNDINTER_WEIGHT
+// TODO(jkoleszar): yet another mv clamping function :-(
+MV clamp_mv_to_umv_border_sb(const MV *src_mv,
+    int bwl, int bhl,
+    int mb_to_left_edge, int mb_to_top_edge,
+    int mb_to_right_edge, int mb_to_bottom_edge) {
+  /* If the MV points so far into the UMV border that no visible pixels
+   * are used for reconstruction, the subpel part of the MV can be
+   * discarded and the MV limited to 16 pixels with equivalent results.
+   */
+  const int epel_left = (VP9_INTERP_EXTEND + (4 << bwl)) << 3;
+  const int epel_right = epel_left - (1 << 3);
+  const int epel_top = (VP9_INTERP_EXTEND + (4 << bhl)) << 3;
+  const int epel_bottom = epel_top - (1 << 3);
+  MV clamped_mv;
+  clamped_mv.col = clamp(src_mv->col,
+                         mb_to_left_edge - epel_left,
+                         mb_to_right_edge + epel_right);
+  clamped_mv.row = clamp(src_mv->row,
+                         mb_to_top_edge - epel_top,
+                         mb_to_bottom_edge + epel_bottom);
+  return clamped_mv;
+}
+
+struct build_inter_predictors_args {
+  MACROBLOCKD *xd;
+  uint8_t* dst[MAX_MB_PLANE];
+  int dst_stride[MAX_MB_PLANE];
+  int x;
+  int y;
+};
+static void build_inter_predictors(int plane, int block,
+                                   BLOCK_SIZE_TYPE bsize,
+                                   int pred_w, int pred_h,
+                                   void *argv) {
+  const struct build_inter_predictors_args* const arg = argv;
+  const int bwl = pred_w, bw = 4 << bwl;
+  const int bhl = pred_h, bh = 4 << bhl;
+  const int x_idx = block & ((1 << bwl) - 1), y_idx = block >> bwl;
+  const int x = x_idx * 4, y = y_idx * 4;
+  MACROBLOCKD * const xd = arg->xd;
+  const int use_second_ref = xd->mode_info_context->mbmi.second_ref_frame > 0;
+  int which_mv;
+
+  for (which_mv = 0; which_mv < 1 + use_second_ref; ++which_mv) {
+    const MV* const mv = (xd->mode_info_context->mbmi.mode == SPLITMV)
+         ? &xd->block[block].bmi.as_mv[which_mv].as_mv
+         : &xd->mode_info_context->mbmi.mv[which_mv].as_mv;
+
+    const uint8_t * const base_pre = which_mv ? xd->second_pre.y_buffer
+                                             : xd->pre.y_buffer;
+    const int pre_stride = which_mv ? xd->second_pre.y_stride
+                                    : xd->pre.y_stride;
+    const uint8_t *const pre = base_pre +
+        scaled_buffer_offset(x, y, pre_stride, &xd->scale_factor[which_mv]);
+    struct scale_factors * const scale =
+      plane == 0 ? &xd->scale_factor[which_mv] : &xd->scale_factor_uv[which_mv];
+
+    int_mv clamped_mv;
+    clamped_mv.as_mv = clamp_mv_to_umv_border_sb(mv, bwl, bhl,
+                                                 xd->mb_to_left_edge,
+                                                 xd->mb_to_top_edge,
+                                                 xd->mb_to_right_edge,
+                                                 xd->mb_to_bottom_edge);
+
+    scale->set_scaled_offsets(scale, arg->y + y, arg->x + x);
+
+    vp9_build_inter_predictor(pre, pre_stride,
+                              arg->dst[plane], arg->dst_stride[plane],
+                              &clamped_mv, &xd->scale_factor[which_mv],
+                              bw, bh, which_mv, &xd->subpix);
+  }
+}
+void vp9_build_inter_predictors_sby(MACROBLOCKD *xd,
+                                    uint8_t *dst_y,
+                                    int dst_ystride,
+                                    int mb_row,
+                                    int mb_col,
+                                    BLOCK_SIZE_TYPE bsize) {
+  struct build_inter_predictors_args args = {
+    xd, {dst_y, NULL, NULL}, {dst_ystride, 0, 0}, mb_col * 16, mb_row * 16
+  };
+  foreach_predicted_block_in_plane(xd, bsize, 0, build_inter_predictors, &args);
+}
+#endif
+
 #define AVERAGE_WEIGHT  (1 << (2 * CONFIG_IMPLICIT_COMPOUNDINTER_WEIGHT))
 
 #if CONFIG_IMPLICIT_COMPOUNDINTER_WEIGHT
@@ -867,49 +950,6 @@
                               which_mv ? weight : 0, &xd->subpix);
   }
 }
-
-void vp9_build_inter16x16_predictors_mby(MACROBLOCKD *xd,
-                                         uint8_t *dst_y,
-                                         int dst_ystride,
-                                         int mb_row,
-                                         int mb_col) {
-  int weight = get_implicit_compoundinter_weight(xd, mb_row, mb_col);
-
-  build_inter16x16_predictors_mby_w(xd, dst_y, dst_ystride, weight,
-                                    mb_row, mb_col);
-}
-
-#else
-
-void vp9_build_inter16x16_predictors_mby(MACROBLOCKD *xd,
-                                         uint8_t *dst_y,
-                                         int dst_ystride,
-                                         int mb_row,
-                                         int mb_col) {
-  const int use_second_ref = xd->mode_info_context->mbmi.second_ref_frame > 0;
-  int which_mv;
-
-  for (which_mv = 0; which_mv < 1 + use_second_ref; ++which_mv) {
-    const int clamp_mvs = which_mv ?
-         xd->mode_info_context->mbmi.need_to_clamp_secondmv :
-         xd->mode_info_context->mbmi.need_to_clamp_mvs;
-
-    uint8_t *base_pre = which_mv ? xd->second_pre.y_buffer : xd->pre.y_buffer;
-    int pre_stride = which_mv ? xd->second_pre.y_stride : xd->pre.y_stride;
-    int_mv ymv;
-    struct scale_factors *scale = &xd->scale_factor[which_mv];
-
-    ymv.as_int = xd->mode_info_context->mbmi.mv[which_mv].as_int;
-
-    if (clamp_mvs)
-      clamp_mv_to_umv_border(&ymv.as_mv, xd);
-
-    scale->set_scaled_offsets(scale, mb_row * 16, mb_col * 16);
-
-    vp9_build_inter_predictor(base_pre, pre_stride, dst_y, dst_ystride,
-                              &ymv, scale, 16, 16, which_mv, &xd->subpix);
-  }
-}
 #endif
 
 #if CONFIG_IMPLICIT_COMPOUNDINTER_WEIGHT
@@ -930,30 +970,14 @@
     uint8_t *uptr, *vptr;
     int pre_stride = which_mv ? xd->second_pre.uv_stride
                               : xd->pre.uv_stride;
-    int_mv _o16x16mv;
-    int_mv _16x16mv;
+    int_mv mv;
 
     struct scale_factors *scale = &xd->scale_factor_uv[which_mv];
+    mv.as_int = xd->mode_info_context->mbmi.mv[which_mv].as_int;
 
-    _16x16mv.as_int = xd->mode_info_context->mbmi.mv[which_mv].as_int;
 
     if (clamp_mvs)
-      clamp_mv_to_umv_border(&_16x16mv.as_mv, xd);
-
-    _o16x16mv = _16x16mv;
-    /* calc uv motion vectors */
-    if (_16x16mv.as_mv.row < 0)
-      _16x16mv.as_mv.row -= 1;
-    else
-      _16x16mv.as_mv.row += 1;
-
-    if (_16x16mv.as_mv.col < 0)
-      _16x16mv.as_mv.col -= 1;
-    else
-      _16x16mv.as_mv.col += 1;
-
-    _16x16mv.as_mv.row /= 2;
-    _16x16mv.as_mv.col /= 2;
+      clamp_mv_to_umv_border(&mv.as_mv, xd);
 
     uptr = (which_mv ? xd->second_pre.u_buffer : xd->pre.u_buffer);
     vptr = (which_mv ? xd->second_pre.v_buffer : xd->pre.v_buffer);
@@ -961,11 +985,11 @@
     scale->set_scaled_offsets(scale, mb_row * 16, mb_col * 16);
 
     vp9_build_inter_predictor_q4(
-        uptr, pre_stride, dst_u, dst_uvstride, &_16x16mv, &_o16x16mv,
+        uptr, pre_stride, dst_u, dst_uvstride, &mv,
         scale, 8, 8, which_mv ? weight : 0, &xd->subpix);
 
     vp9_build_inter_predictor_q4(
-        vptr, pre_stride, dst_v, dst_uvstride, &_16x16mv, &_o16x16mv,
+        vptr, pre_stride, dst_v, dst_uvstride, &mv,
         scale, 8, 8, which_mv ? weight : 0, &xd->subpix);
   }
 }
@@ -1003,30 +1027,14 @@
     uint8_t *uptr, *vptr;
     int pre_stride = which_mv ? xd->second_pre.uv_stride
                               : xd->pre.uv_stride;
-    int_mv _o16x16mv;
-    int_mv _16x16mv;
+    int_mv mv;
 
     struct scale_factors *scale = &xd->scale_factor_uv[which_mv];
+    mv.as_int = xd->mode_info_context->mbmi.mv[which_mv].as_int;
 
-    _16x16mv.as_int = xd->mode_info_context->mbmi.mv[which_mv].as_int;
 
     if (clamp_mvs)
-      clamp_mv_to_umv_border(&_16x16mv.as_mv, xd);
-
-    _o16x16mv = _16x16mv;
-    /* calc uv motion vectors */
-    if (_16x16mv.as_mv.row < 0)
-      _16x16mv.as_mv.row -= 1;
-    else
-      _16x16mv.as_mv.row += 1;
-
-    if (_16x16mv.as_mv.col < 0)
-      _16x16mv.as_mv.col -= 1;
-    else
-      _16x16mv.as_mv.col += 1;
-
-    _16x16mv.as_mv.row /= 2;
-    _16x16mv.as_mv.col /= 2;
+      clamp_mv_to_umv_border(&mv.as_mv, xd);
 
     uptr = (which_mv ? xd->second_pre.u_buffer : xd->pre.u_buffer);
     vptr = (which_mv ? xd->second_pre.v_buffer : xd->pre.v_buffer);
@@ -1034,12 +1042,12 @@
     scale->set_scaled_offsets(scale, mb_row * 16, mb_col * 16);
 
     vp9_build_inter_predictor_q4(
-        uptr, pre_stride, dst_u, dst_uvstride, &_16x16mv, &_o16x16mv,
+        uptr, pre_stride, dst_u, dst_uvstride, &mv,
         scale, 8, 8,
         which_mv << (2 * CONFIG_IMPLICIT_COMPOUNDINTER_WEIGHT), &xd->subpix);
 
     vp9_build_inter_predictor_q4(
-        vptr, pre_stride, dst_v, dst_uvstride, &_16x16mv, &_o16x16mv,
+        vptr, pre_stride, dst_v, dst_uvstride, &mv,
         scale, 8, 8,
         which_mv << (2 * CONFIG_IMPLICIT_COMPOUNDINTER_WEIGHT), &xd->subpix);
   }
@@ -1109,64 +1117,6 @@
   build_inter_predictors_sby_w(x, dst_y, dst_ystride, weight,
                                     mb_row, mb_col, bsize);
 }
-
-#else
-
-// TODO(jingning): vp9_convolve8_ssse3_ limits the dimension up to 16. Currently
-// handle inter prediction of block sizes above 16x16 separately from those
-// smaller ones. Need to combine them all in to a unified inter prediction
-// function.
-void vp9_build_inter_predictors_sby(MACROBLOCKD *x,
-                                    uint8_t *dst_y,
-                                    int dst_ystride,
-                                    int mb_row,
-                                    int mb_col,
-                                    BLOCK_SIZE_TYPE bsize) {
-  const int bwl = mb_width_log2(bsize),  bw = 1 << bwl;
-  const int bhl = mb_height_log2(bsize), bh = 1 << bhl;
-  uint8_t *y1 = x->pre.y_buffer;
-  uint8_t *y2 = x->second_pre.y_buffer;
-  int edge[4], n;
-
-  edge[0] = x->mb_to_top_edge;
-  edge[1] = x->mb_to_bottom_edge;
-  edge[2] = x->mb_to_left_edge;
-  edge[3] = x->mb_to_right_edge;
-
-  for (n = 0; n < bw * bh; n++) {
-    const int x_idx = n & (bw - 1), y_idx = n >> bwl;
-
-    x->mb_to_top_edge    = edge[0] -           ((y_idx  * 16) << 3);
-    x->mb_to_bottom_edge = edge[1] + (((bh - 1 - y_idx) * 16) << 3);
-    x->mb_to_left_edge   = edge[2] -           ((x_idx  * 16) << 3);
-    x->mb_to_right_edge  = edge[3] + (((bw - 1 - x_idx) * 16) << 3);
-
-    x->pre.y_buffer = y1 + scaled_buffer_offset(x_idx * 16,
-                                                y_idx * 16,
-                                                x->pre.y_stride,
-                                                &x->scale_factor[0]);
-    if (x->mode_info_context->mbmi.second_ref_frame > 0) {
-      x->second_pre.y_buffer = y2 +
-          scaled_buffer_offset(x_idx * 16,
-                               y_idx * 16,
-                               x->second_pre.y_stride,
-                               &x->scale_factor[1]);
-    }
-    vp9_build_inter16x16_predictors_mby(x,
-        dst_y + y_idx * 16 * dst_ystride  + x_idx * 16,
-        dst_ystride, mb_row + y_idx, mb_col + x_idx);
-  }
-  x->mb_to_top_edge    = edge[0];
-  x->mb_to_bottom_edge = edge[1];
-  x->mb_to_left_edge   = edge[2];
-  x->mb_to_right_edge  = edge[3];
-
-  x->pre.y_buffer = y1;
-  if (x->mode_info_context->mbmi.second_ref_frame > 0) {
-    x->second_pre.y_buffer = y2;
-  }
-}
-
 #endif
 
 #if CONFIG_IMPLICIT_COMPOUNDINTER_WEIGHT
@@ -1338,8 +1288,7 @@
 }
 
 static void build_inter4x4_predictors_mb(MACROBLOCKD *xd,
-                                         int mb_row, int mb_col,
-                                         int use_dst) {
+                                         int mb_row, int mb_col) {
   int i;
   MB_MODE_INFO * mbmi = &xd->mode_info_context->mbmi;
   BLOCKD *blockd = xd->block;
@@ -1368,8 +1317,7 @@
 
         build_2x1_inter_predictor(d0, d1, xd->scale_factor, 8, 16, which_mv,
                                   which_mv ? weight : 0,
-                                  &xd->subpix, mb_row * 16 + y, mb_col * 16,
-                                  use_dst);
+                                  &xd->subpix, mb_row * 16 + y, mb_col * 16);
       }
     }
   } else {
@@ -1386,8 +1334,7 @@
         build_2x1_inter_predictor(d0, d1, xd->scale_factor, 4, 16, which_mv,
                                   which_mv ? weight : 0,
                                   &xd->subpix,
-                                  mb_row * 16 + y, mb_col * 16 + x,
-                                  use_dst);
+                                  mb_row * 16 + y, mb_col * 16 + x);
       }
     }
   }
@@ -1405,8 +1352,7 @@
     for (which_mv = 0; which_mv < 1 + use_second_ref; ++which_mv) {
       build_2x1_inter_predictor(d0, d1, xd->scale_factor_uv, 4, 8, which_mv,
                                 which_mv ? weight : 0, &xd->subpix,
-                                mb_row * 8 + y, mb_col * 8 + x,
-                                use_dst);
+                                mb_row * 8 + y, mb_col * 8 + x);
     }
   }
 }
@@ -1493,58 +1439,17 @@
   }
 }
 
-void vp9_build_inter16x16_predictors_mb(MACROBLOCKD *xd,
-                                        uint8_t *dst_y,
-                                        uint8_t *dst_u,
-                                        uint8_t *dst_v,
-                                        int dst_ystride,
-                                        int dst_uvstride,
-                                        int mb_row,
-                                        int mb_col) {
-  vp9_build_inter16x16_predictors_mby(xd, dst_y, dst_ystride, mb_row, mb_col);
-  vp9_build_inter16x16_predictors_mbuv(xd, dst_u, dst_v, dst_uvstride,
-                                       mb_row, mb_col);
-#if CONFIG_COMP_INTERINTRA_PRED
-  if (xd->mode_info_context->mbmi.second_ref_frame == INTRA_FRAME) {
-    vp9_build_interintra_16x16_predictors_mb(xd, dst_y, dst_u, dst_v,
-                                             dst_ystride, dst_uvstride);
-  }
-#endif
-}
-
 void vp9_build_inter_predictors_mb(MACROBLOCKD *xd,
                                    int mb_row,
                                    int mb_col) {
   if (xd->mode_info_context->mbmi.mode != SPLITMV) {
-    // TODO(jingning): to be replaced with vp9_build_inter_predictors_sb() when
-    // converting buffers from predictors to dst.
-    vp9_build_inter16x16_predictors_mb(xd, xd->predictor,
-                                       &xd->predictor[256],
-                                       &xd->predictor[320], 16, 8,
-                                       mb_row, mb_col);
-
+    vp9_build_inter_predictors_sb(xd, mb_row, mb_col, BLOCK_SIZE_MB16X16);
   } else {
     build_4x4uvmvs(xd);
-    build_inter4x4_predictors_mb(xd, mb_row, mb_col, 0);
+    build_inter4x4_predictors_mb(xd, mb_row, mb_col);
   }
 }
 
-void vp9_build_inter_predictors_mb_s(MACROBLOCKD *xd,
-                                   int mb_row,
-                                   int mb_col) {
-  if (xd->mode_info_context->mbmi.mode != SPLITMV) {
-    vp9_build_inter16x16_predictors_mb(xd, xd->dst.y_buffer,
-                                       xd->dst.u_buffer,
-                                       xd->dst.v_buffer,
-                                       xd->dst.y_stride,
-                                       xd->dst.uv_stride,
-                                       mb_row, mb_col);
-
-  } else {
-    build_4x4uvmvs(xd);
-    build_inter4x4_predictors_mb(xd, mb_row, mb_col, 1);
-  }
-}
 /*encoder only*/
 void vp9_build_inter4x4_predictors_mbuv(MACROBLOCKD *xd,
                                         int mb_row, int mb_col) {
@@ -1593,8 +1498,7 @@
     for (which_mv = 0; which_mv < 1 + use_second_ref; ++which_mv) {
       build_2x1_inter_predictor(d0, d1, xd->scale_factor_uv, 4, 8, which_mv,
                                 which_mv ? weight : 0,
-                                &xd->subpix, mb_row * 8 + y, mb_col * 8 + x,
-                                0);
+                                &xd->subpix, mb_row * 8 + y, mb_col * 8 + x);
     }
   }
 }
diff --git a/vp9/common/vp9_reconinter.h b/vp9/common/vp9_reconinter.h
index 068853d..38981e9 100644
--- a/vp9/common/vp9_reconinter.h
+++ b/vp9/common/vp9_reconinter.h
@@ -16,12 +16,6 @@
 
 struct subpix_fn_table;
 
-void vp9_build_inter16x16_predictors_mby(MACROBLOCKD *xd,
-                                         uint8_t *dst_y,
-                                         int dst_ystride,
-                                         int mb_row,
-                                         int mb_col);
-
 void vp9_build_inter16x16_predictors_mbuv(MACROBLOCKD *xd,
                                           uint8_t *dst_u,
                                           uint8_t *dst_v,
@@ -29,14 +23,20 @@
                                           int mb_row,
                                           int mb_col);
 
-void vp9_build_inter16x16_predictors_mb(MACROBLOCKD *xd,
-                                        uint8_t *dst_y,
-                                        uint8_t *dst_u,
-                                        uint8_t *dst_v,
-                                        int dst_ystride,
-                                        int dst_uvstride,
-                                        int mb_row,
-                                        int mb_col);
+void vp9_build_inter_predictors_sby(MACROBLOCKD *x,
+                                    uint8_t *dst_y,
+                                    int dst_ystride,
+                                    int mb_row,
+                                    int mb_col,
+                                    BLOCK_SIZE_TYPE bsize);
+
+void vp9_build_inter_predictors_sbuv(MACROBLOCKD *x,
+                                     uint8_t *dst_u,
+                                     uint8_t *dst_v,
+                                     int dst_uvstride,
+                                     int mb_row,
+                                     int mb_col,
+                                     BLOCK_SIZE_TYPE bsize);
 
 void vp9_build_inter_predictors_sb(MACROBLOCKD *mb,
                                    int mb_row, int mb_col,
@@ -46,10 +46,6 @@
                                    int mb_row,
                                    int mb_col);
 
-void vp9_build_inter_predictors_mb_s(MACROBLOCKD *xd,
-                                     int mb_row,
-                                     int mb_col);
-
 void vp9_build_inter4x4_predictors_mbuv(MACROBLOCKD *xd,
                                         int mb_row,
                                         int mb_col);
@@ -71,8 +67,7 @@
 
 void vp9_build_inter_predictor_q4(const uint8_t *src, int src_stride,
                                   uint8_t *dst, int dst_stride,
-                                  const int_mv *fullpel_mv_q3,
-                                  const int_mv *frac_mv_q4,
+                                  const int_mv *mv_q4,
                                   const struct scale_factors *scale,
                                   int w, int h, int do_avg,
                                   const struct subpix_fn_table *subpix);
diff --git a/vp9/common/vp9_reconintra.c b/vp9/common/vp9_reconintra.c
index 6321911..88c3f19 100644
--- a/vp9/common/vp9_reconintra.c
+++ b/vp9/common/vp9_reconintra.c
@@ -273,7 +273,8 @@
   int i;
   for (i = 16; i < 24; i += 2) {
     BLOCKD *b = &xd->block[i];
-    vp9_recon2b(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+    vp9_recon2b(*(b->base_dst) + b->dst, b->diff,
+                *(b->base_dst) + b->dst, b->dst_stride);
   }
 }
 
@@ -758,40 +759,6 @@
                              xd->left_available, xd->right_available);
 }
 
-// TODO(jingning): merge mby and mbuv into the above sby and sbmu functions
-void vp9_build_intra_predictors_mby(MACROBLOCKD *xd) {
-  vp9_build_intra_predictors(xd->dst.y_buffer, xd->dst.y_stride,
-                             xd->predictor, 16,
-                             xd->mode_info_context->mbmi.mode,
-                             16, 16,
-                             xd->up_available, xd->left_available,
-                             xd->right_available);
-}
-
-void vp9_build_intra_predictors_mbuv_internal(MACROBLOCKD *xd,
-                                              uint8_t *upred_ptr,
-                                              uint8_t *vpred_ptr,
-                                              int uv_stride,
-                                              int mode, int bsize) {
-  vp9_build_intra_predictors(xd->dst.u_buffer, xd->dst.uv_stride,
-                             upred_ptr, uv_stride, mode,
-                             bsize, bsize,
-                             xd->up_available, xd->left_available,
-                             xd->right_available);
-  vp9_build_intra_predictors(xd->dst.v_buffer, xd->dst.uv_stride,
-                             vpred_ptr, uv_stride, mode,
-                             bsize, bsize,
-                             xd->up_available, xd->left_available,
-                             xd->right_available);
-}
-
-void vp9_build_intra_predictors_mbuv(MACROBLOCKD *xd) {
-  vp9_build_intra_predictors_mbuv_internal(xd, &xd->predictor[256],
-                                           &xd->predictor[320], 8,
-                                           xd->mode_info_context->mbmi.uv_mode,
-                                           8);
-}
-
 void vp9_intra8x8_predict(MACROBLOCKD *xd,
                           BLOCKD *b,
                           int mode,
diff --git a/vp9/common/vp9_rtcd_defs.sh b/vp9/common/vp9_rtcd_defs.sh
index ae5b7fb..f9f2395 100644
--- a/vp9/common/vp9_rtcd_defs.sh
+++ b/vp9/common/vp9_rtcd_defs.sh
@@ -68,11 +68,15 @@
 prototype void vp9_recon_uv_b "uint8_t *pred_ptr, int16_t *diff_ptr, uint8_t *dst_ptr, int stride"
 specialize vp9_recon_uv_b
 
+# TODO(jingning): The prototype functions in c are modified to enable block-size configurable
+# operations. Need to change the sse2 accrodingly.
 prototype void vp9_recon2b "uint8_t *pred_ptr, int16_t *diff_ptr, uint8_t *dst_ptr, int stride"
-specialize vp9_recon2b sse2
+specialize vp9_recon2b
+# specialize vp9_recon2b sse2
 
 prototype void vp9_recon4b "uint8_t *pred_ptr, int16_t *diff_ptr, uint8_t *dst_ptr, int stride"
-specialize vp9_recon4b sse2
+specialize vp9_recon4b
+# specialize vp9_recon4b sse2
 
 prototype void vp9_recon_mb "struct macroblockd *x"
 specialize vp9_recon_mb
@@ -86,17 +90,14 @@
 prototype void vp9_recon_sbuv_s "struct macroblockd *x, uint8_t *udst, uint8_t *vdst, enum BLOCK_SIZE_TYPE bsize"
 specialize void vp9_recon_sbuv_s
 
+prototype void vp9_build_intra_predictors "uint8_t *src, int src_stride, uint8_t *pred, int y_stride, int mode, int bw, int bh, int up_available, int left_available, int right_available"
+specialize void vp9_build_intra_predictors
+
 prototype void vp9_build_intra_predictors_sby_s "struct macroblockd *x, enum BLOCK_SIZE_TYPE bsize"
-specialize vp9_build_intra_predictors_sby_s;
+specialize vp9_build_intra_predictors_sby_s
 
 prototype void vp9_build_intra_predictors_sbuv_s "struct macroblockd *x, enum BLOCK_SIZE_TYPE bsize"
-specialize vp9_build_intra_predictors_sbuv_s;
-
-prototype void vp9_build_intra_predictors_mby "struct macroblockd *x"
-specialize vp9_build_intra_predictors_mby;
-
-prototype void vp9_build_intra_predictors_mbuv "struct macroblockd *x"
-specialize vp9_build_intra_predictors_mbuv;
+specialize vp9_build_intra_predictors_sbuv_s
 
 prototype void vp9_intra4x4_predict "struct macroblockd *xd, struct blockd *x, int b_mode, uint8_t *predictor, int pre_stride"
 specialize vp9_intra4x4_predict;
@@ -620,16 +621,10 @@
 vp9_block_error_sse2=vp9_block_error_xmm
 
 prototype void vp9_subtract_b "struct block *be, struct blockd *bd, int pitch"
-specialize vp9_subtract_b mmx sse2
-
-prototype void vp9_subtract_b "struct block *be, struct blockd *bd, int pitch"
-specialize vp9_subtract_b mmx sse2
-
-prototype void vp9_subtract_mby "int16_t *diff, uint8_t *src, uint8_t *pred, int stride"
-specialize vp9_subtract_mby mmx sse2
-
-prototype void vp9_subtract_mbuv "int16_t *diff, uint8_t *usrc, uint8_t *vsrc, uint8_t *pred, int stride"
-specialize vp9_subtract_mbuv mmx sse2
+# TODO(jingning): The prototype function in c has been changed to remove
+# the use of predictor buffer in MACROBLOCKD. Need to modify the mmx and sse2
+# versions accordingly.
+specialize vp9_subtract_b
 
 #
 # Structured Similarity (SSIM)
diff --git a/vp9/common/x86/vp9_asm_stubs.c b/vp9/common/x86/vp9_asm_stubs.c
index 6d3bb02..310f8ed 100644
--- a/vp9/common/x86/vp9_asm_stubs.c
+++ b/vp9/common/x86/vp9_asm_stubs.c
@@ -278,11 +278,9 @@
                          const int16_t *filter_x, int x_step_q4,
                          const int16_t *filter_y, int y_step_q4,
                          int w, int h) {
-  DECLARE_ALIGNED_ARRAY(16, unsigned char, fdata2, 16*23);
+  DECLARE_ALIGNED_ARRAY(16, unsigned char, fdata2, 16*71);
 
-  // check w/h due to fixed size fdata2 array
-  assert(w <= 16);
-  assert(h <= 16);
+  assert(h <= 64);
 
   if (x_step_q4 == 16 && y_step_q4 == 16 &&
       filter_x[3] != 128 && filter_y[3] != 128) {
@@ -324,11 +322,9 @@
                          const int16_t *filter_x, int x_step_q4,
                          const int16_t *filter_y, int y_step_q4,
                          int w, int h) {
-  DECLARE_ALIGNED_ARRAY(16, unsigned char, fdata2, 16*23);
+  DECLARE_ALIGNED_ARRAY(16, unsigned char, fdata2, 16*71);
 
-  // check w/h due to fixed size fdata2 array
-  assert(w <= 16);
-  assert(h <= 16);
+  assert(h <= 64);
 
   if (x_step_q4 == 16 && y_step_q4 == 16 &&
       filter_x[3] != 128 && filter_y[3] != 128) {
diff --git a/vp9/common/x86/vp9_recon_wrapper_sse2.c b/vp9/common/x86/vp9_recon_wrapper_sse2.c
index bb7baf8..12d2f97 100644
--- a/vp9/common/x86/vp9_recon_wrapper_sse2.c
+++ b/vp9/common/x86/vp9_recon_wrapper_sse2.c
@@ -73,15 +73,15 @@
 }
 
 void vp9_build_intra_predictors_mbuv_sse2(MACROBLOCKD *xd) {
-  build_intra_predictors_mbuv_x86(xd, &xd->predictor[256],
-                                  &xd->predictor[320], 8,
+  build_intra_predictors_mbuv_x86(xd, xd->dst.u_buffer,
+                                  xd->dst.v_buffer, xd->dst.uv_stride,
                                   vp9_intra_pred_uv_tm_sse2,
                                   vp9_intra_pred_uv_ho_mmx2);
 }
 
 void vp9_build_intra_predictors_mbuv_ssse3(MACROBLOCKD *xd) {
-  build_intra_predictors_mbuv_x86(xd, &xd->predictor[256],
-                                  &xd->predictor[320], 8,
+  build_intra_predictors_mbuv_x86(xd, xd->dst.u_buffer,
+                                  xd->dst.v_buffer, xd->dst.uv_stride,
                                   vp9_intra_pred_uv_tm_ssse3,
                                   vp9_intra_pred_uv_ho_ssse3);
 }
diff --git a/vp9/common/x86/vp9_subpixel_8t_ssse3.asm b/vp9/common/x86/vp9_subpixel_8t_ssse3.asm
index 32f00e2..bbf9888 100644
--- a/vp9/common/x86/vp9_subpixel_8t_ssse3.asm
+++ b/vp9/common/x86/vp9_subpixel_8t_ssse3.asm
@@ -81,10 +81,10 @@
     pmaddubsw   xmm4, k4k5
     pmaddubsw   xmm6, k6k7
 
+    paddsw      xmm0, xmm6
     paddsw      xmm0, xmm2
-    paddsw      xmm0, krd
-    paddsw      xmm4, xmm6
     paddsw      xmm0, xmm4
+    paddsw      xmm0, krd
 
     psraw       xmm0, 7
     packuswb    xmm0, xmm0
@@ -165,10 +165,10 @@
     pmaddubsw   xmm4, k4k5
     pmaddubsw   xmm6, k6k7
 
+    paddsw      xmm0, xmm6
     paddsw      xmm0, xmm2
-    paddsw      xmm0, krd
-    paddsw      xmm4, xmm6
     paddsw      xmm0, xmm4
+    paddsw      xmm0, krd
 
     psraw       xmm0, 7
     packuswb    xmm0, xmm0
@@ -250,10 +250,10 @@
     pmaddubsw   xmm4, k4k5
     pmaddubsw   xmm6, k6k7
 
+    paddsw      xmm0, xmm6
     paddsw      xmm0, xmm2
-    paddsw      xmm0, krd
-    paddsw      xmm4, xmm6
     paddsw      xmm0, xmm4
+    paddsw      xmm0, krd
 
     psraw       xmm0, 7
     packuswb    xmm0, xmm0
@@ -285,10 +285,10 @@
     pmaddubsw   xmm4, k4k5
     pmaddubsw   xmm6, k6k7
 
+    paddsw      xmm0, xmm6
     paddsw      xmm0, xmm2
-    paddsw      xmm4, xmm6
-    paddsw      xmm0, krd
     paddsw      xmm0, xmm4
+    paddsw      xmm0, krd
 
     psraw       xmm0, 7
     packuswb    xmm0, xmm0
diff --git a/vp9/decoder/vp9_dboolhuff.c b/vp9/decoder/vp9_dboolhuff.c
index dcd5916..390a684 100644
--- a/vp9/decoder/vp9_dboolhuff.c
+++ b/vp9/decoder/vp9_dboolhuff.c
@@ -55,66 +55,3 @@
   br->count = count;
 }
 
-
-static int get_unsigned_bits(unsigned int num_values) {
-  int cat = 0;
-  if (num_values <= 1)
-    return 0;
-  num_values--;
-  while (num_values > 0) {
-    cat++;
-    num_values >>= 1;
-  }
-  return cat;
-}
-
-int vp9_inv_recenter_nonneg(int v, int m) {
-  if (v > (m << 1))
-    return v;
-  else if ((v & 1) == 0)
-    return (v >> 1) + m;
-  else
-    return m - ((v + 1) >> 1);
-}
-
-int vp9_decode_uniform(BOOL_DECODER *br, int n) {
-  int v;
-  const int l = get_unsigned_bits(n);
-  const int m = (1 << l) - n;
-  if (!l)
-    return 0;
-
-  v = vp9_read_literal(br, l - 1);
-  return v < m ?  v : (v << 1) - m + vp9_read_bit(br);
-}
-
-int vp9_decode_term_subexp(BOOL_DECODER *br, int k, int num_syms) {
-  int i = 0, mk = 0, word;
-  while (1) {
-    const int b = i ? k + i - 1 : k;
-    const int a = 1 << b;
-    if (num_syms <= mk + 3 * a) {
-      word = vp9_decode_uniform(br, num_syms - mk) + mk;
-      break;
-    } else {
-      if (vp9_read_bit(br)) {
-        i++;
-        mk += a;
-      } else {
-        word = vp9_read_literal(br, b) + mk;
-        break;
-      }
-    }
-  }
-  return word;
-}
-
-int vp9_decode_unsigned_max(BOOL_DECODER *br, int max) {
-  int data = 0, bit = 0, lmax = max;
-
-  while (lmax) {
-    data |= vp9_read_bit(br) << bit++;
-    lmax >>= 1;
-  }
-  return data > max ? max : data;
-}
diff --git a/vp9/decoder/vp9_dboolhuff.h b/vp9/decoder/vp9_dboolhuff.h
index 10b7a1a..dab330c 100644
--- a/vp9/decoder/vp9_dboolhuff.h
+++ b/vp9/decoder/vp9_dboolhuff.h
@@ -41,10 +41,6 @@
 
 void vp9_reader_fill(BOOL_DECODER *br);
 
-int vp9_decode_uniform(BOOL_DECODER *br, int n);
-int vp9_decode_term_subexp(BOOL_DECODER *br, int k, int num_syms);
-int vp9_inv_recenter_nonneg(int v, int m);
-
 static INLINE const uint8_t *vp9_reader_find_end(BOOL_DECODER *br) {
   // Find the end of the coded buffer
   while (br->count > CHAR_BIT && br->count < VP9_BD_VALUE_SIZE) {
@@ -123,6 +119,4 @@
   return br->count > VP9_BD_VALUE_SIZE && br->count < VP9_LOTS_OF_BITS;
 }
 
-int vp9_decode_unsigned_max(BOOL_DECODER *br, int max);
-
 #endif  // VP9_DECODER_VP9_DBOOLHUFF_H_
diff --git a/vp9/decoder/vp9_decodemv.c b/vp9/decoder/vp9_decodemv.c
index aaa9b2e..6478a8e 100644
--- a/vp9/decoder/vp9_decodemv.c
+++ b/vp9/decoder/vp9_decodemv.c
@@ -85,19 +85,17 @@
 
 // This function reads the current macro block's segnent id from the bitstream
 // It should only be called if a segment map update is indicated.
-static void read_mb_segid_except(VP9_COMMON *cm,
-                                 vp9_reader *r, MB_MODE_INFO *mi,
-                                 MACROBLOCKD *xd, int mb_row, int mb_col) {
+static int read_mb_segid_except(vp9_reader *r,
+                                VP9_COMMON *cm, MACROBLOCKD *xd,
+                                int mb_row, int mb_col) {
   const int mb_index = mb_row * cm->mb_cols + mb_col;
   const int pred_seg_id = vp9_get_pred_mb_segid(cm, xd, mb_index);
   const vp9_prob *const p = xd->mb_segment_tree_probs;
   const vp9_prob prob = xd->mb_segment_mispred_tree_probs[pred_seg_id];
 
-  if (xd->segmentation_enabled && xd->update_mb_segmentation_map) {
-    mi->segment_id = vp9_read(r, prob)
-        ? 2 + (pred_seg_id  < 2 ? vp9_read(r, p[2]) : (pred_seg_id == 2))
-        :     (pred_seg_id >= 2 ? vp9_read(r, p[1]) : (pred_seg_id == 0));
-  }
+  return vp9_read(r, prob)
+             ? 2 + (pred_seg_id  < 2 ? vp9_read(r, p[2]) : (pred_seg_id == 2))
+             :     (pred_seg_id >= 2 ? vp9_read(r, p[1]) : (pred_seg_id == 0));
 }
 
 #if CONFIG_NEW_MVREF
@@ -269,7 +267,7 @@
 
 static void read_nmv_fp(vp9_reader *r, MV *mv, const MV *ref,
                         const nmv_context *mvctx, int usehp) {
-  const MV_JOINT_TYPE j = vp9_get_mv_joint(*mv);
+  const MV_JOINT_TYPE j = vp9_get_mv_joint(mv);
   usehp = usehp && vp9_use_nmv_hp(ref);
   if (mv_joint_vertical(j))
     mv->row = read_nmv_component_fp(r, mv->row, ref->row, &mvctx->comps[0],
@@ -334,7 +332,7 @@
 // Read the referncence frame
 static MV_REFERENCE_FRAME read_ref_frame(VP9D_COMP *pbi,
                                          vp9_reader *r,
-                                         unsigned char segment_id) {
+                                         int segment_id) {
   MV_REFERENCE_FRAME ref_frame;
   VP9_COMMON *const cm = &pbi->common;
   MACROBLOCKD *const xd = &pbi->mb;
@@ -439,7 +437,7 @@
   return (MB_PREDICTION_MODE) treed_read(r, vp9_mv_ref_tree, p);
 }
 
-static B_PREDICTION_MODE sub_mv_ref(vp9_reader *r, const vp9_prob *p) {
+static B_PREDICTION_MODE read_sub_mv_ref(vp9_reader *r, const vp9_prob *p) {
   return (B_PREDICTION_MODE) treed_read(r, vp9_sub_mv_ref_tree, p);
 }
 
@@ -538,9 +536,9 @@
                                vp9_reader *r) {
   VP9_COMMON *const cm = &pbi->common;
   MACROBLOCKD *const xd = &pbi->mb;
-  MODE_INFO *mi = xd->mode_info_context;
-  MB_MODE_INFO *mbmi = &mi->mbmi;
-  int mb_index = mb_row * cm->mb_cols + mb_col;
+  MODE_INFO *const mi = xd->mode_info_context;
+  MB_MODE_INFO *const mbmi = &mi->mbmi;
+  const int mb_index = mb_row * cm->mb_cols + mb_col;
 
   if (xd->segmentation_enabled) {
     if (xd->update_mb_segmentation_map) {
@@ -557,13 +555,10 @@
         vp9_set_pred_flag(xd, PRED_SEG_ID, seg_pred_flag);
 
         // If the value is flagged as correctly predicted
-        // then use the predicted value
-        if (seg_pred_flag) {
-          mbmi->segment_id = vp9_get_pred_mb_segid(cm, xd, mb_index);
-        } else {
-          // Decode it explicitly
-          read_mb_segid_except(cm, r, mbmi, xd, mb_row, mb_col);
-        }
+        // then use the predicted value, otherwise decode it explicitly
+        mbmi->segment_id = seg_pred_flag ?
+                               vp9_get_pred_mb_segid(cm, xd, mb_index) :
+                               read_mb_segid_except(r, cm, xd, mb_row, mb_col);
       } else {
         // Normal unpredicted coding mode
         read_mb_segid(r, mbmi, xd);
@@ -623,8 +618,9 @@
            mb_to_bottom_edge);
 }
 
-static INLINE void process_mv(vp9_reader *r, MV *mv, MV *ref,
-                              nmv_context *nmvc, nmv_context_counts *mvctx,
+static INLINE void process_mv(vp9_reader *r, MV *mv, const MV *ref,
+                              const nmv_context *nmvc,
+                              nmv_context_counts *mvctx,
                               int usehp) {
   read_nmv(r, mv, ref, nmvc);
   read_nmv_fp(r, mv, ref, nmvc, usehp);
@@ -650,7 +646,8 @@
   const int mis = cm->mode_info_stride;
   MACROBLOCKD *const xd = &pbi->mb;
 
-  int_mv *const mv = &mbmi->mv[0];
+  int_mv *const mv0 = &mbmi->mv[0];
+  int_mv *const mv1 = &mbmi->mv[1];
   const int bw = 1 << mb_width_log2(mi->mbmi.sb_type);
   const int bh = 1 << mb_height_log2(mi->mbmi.sb_type);
 
@@ -881,7 +878,7 @@
             second_abovemv.as_int = above_block_second_mv(mi, k, mis);
           }
           mv_contz = vp9_mv_cont(&leftmv, &abovemv);
-          blockmode = sub_mv_ref(r, cm->fc.sub_mv_ref_prob[mv_contz]);
+          blockmode = read_sub_mv_ref(r, cm->fc.sub_mv_ref_prob[mv_contz]);
           cm->fc.sub_mv_ref_counts[mv_contz][blockmode - LEFT4X4]++;
 
           switch (blockmode) {
@@ -947,7 +944,7 @@
              Must do it here because ensuing subsets can
              refer back to us via "left" or "above". */
             unsigned int fill_count = mbsplit_fill_count[s];
-            const unsigned char *fill_offset =
+            const uint8_t *fill_offset =
                 &mbsplit_fill_offset[s][j * fill_count];
 
             do {
@@ -961,56 +958,56 @@
         } while (++j < num_p);
       }
 
-      mv->as_int = mi->bmi[15].as_mv[0].as_int;
-      mbmi->mv[1].as_int = mi->bmi[15].as_mv[1].as_int;
+      mv0->as_int = mi->bmi[15].as_mv[0].as_int;
+      mv1->as_int = mi->bmi[15].as_mv[1].as_int;
 
       break;  /* done with SPLITMV */
 
       case NEARMV:
         // Clip "next_nearest" so that it does not extend to far out of image
-        assign_and_clamp_mv(mv, &nearby, mb_to_left_edge,
-                                         mb_to_right_edge,
-                                         mb_to_top_edge,
-                                         mb_to_bottom_edge);
-        if (mbmi->second_ref_frame > 0)
-          assign_and_clamp_mv(&mbmi->mv[1], &nearby_second, mb_to_left_edge,
-                                                            mb_to_right_edge,
-                                                            mb_to_top_edge,
-                                                            mb_to_bottom_edge);
-        break;
-
-      case NEARESTMV:
-        // Clip "next_nearest" so that it does not extend to far out of image
-        assign_and_clamp_mv(mv, &nearest, mb_to_left_edge,
+        assign_and_clamp_mv(mv0, &nearby, mb_to_left_edge,
                                           mb_to_right_edge,
                                           mb_to_top_edge,
                                           mb_to_bottom_edge);
         if (mbmi->second_ref_frame > 0)
-          assign_and_clamp_mv(&mbmi->mv[1], &nearest_second, mb_to_left_edge,
-                                                             mb_to_right_edge,
-                                                             mb_to_top_edge,
-                                                             mb_to_bottom_edge);
+          assign_and_clamp_mv(mv1, &nearby_second, mb_to_left_edge,
+                                                   mb_to_right_edge,
+                                                   mb_to_top_edge,
+                                                   mb_to_bottom_edge);
+        break;
+
+      case NEARESTMV:
+        // Clip "next_nearest" so that it does not extend to far out of image
+        assign_and_clamp_mv(mv0, &nearest, mb_to_left_edge,
+                                           mb_to_right_edge,
+                                           mb_to_top_edge,
+                                           mb_to_bottom_edge);
+        if (mbmi->second_ref_frame > 0)
+          assign_and_clamp_mv(mv1, &nearest_second, mb_to_left_edge,
+                                                    mb_to_right_edge,
+                                                    mb_to_top_edge,
+                                                    mb_to_bottom_edge);
         break;
 
       case ZEROMV:
-        mv->as_int = 0;
+        mv0->as_int = 0;
         if (mbmi->second_ref_frame > 0)
-          mbmi->mv[1].as_int = 0;
+          mv1->as_int = 0;
         break;
 
       case NEWMV:
-        process_mv(r, &mv->as_mv, &best_mv.as_mv, nmvc, &cm->fc.NMVcount,
+        process_mv(r, &mv0->as_mv, &best_mv.as_mv, nmvc, &cm->fc.NMVcount,
                    xd->allow_high_precision_mv);
-        mbmi->need_to_clamp_mvs = check_mv_bounds(mv,
+        mbmi->need_to_clamp_mvs = check_mv_bounds(mv0,
                                                   mb_to_left_edge,
                                                   mb_to_right_edge,
                                                   mb_to_top_edge,
                                                   mb_to_bottom_edge);
 
         if (mbmi->second_ref_frame > 0) {
-          process_mv(r, &mbmi->mv[1].as_mv, &best_mv_second.as_mv, nmvc,
+          process_mv(r, &mv1->as_mv, &best_mv_second.as_mv, nmvc,
                      &cm->fc.NMVcount, xd->allow_high_precision_mv);
-          mbmi->need_to_clamp_secondmv = check_mv_bounds(&mbmi->mv[1],
+          mbmi->need_to_clamp_secondmv = check_mv_bounds(mv1,
                                                          mb_to_left_edge,
                                                          mb_to_right_edge,
                                                          mb_to_top_edge,
@@ -1024,8 +1021,8 @@
 #endif
     }
   } else {
-    /* required for left and above block mv */
-    mbmi->mv[0].as_int = 0;
+    // required for left and above block mv
+    mv0->as_int = 0;
 
     if (mbmi->sb_type) {
       mbmi->mode = read_sb_ymode(r, cm->fc.sb_ymode_prob);
diff --git a/vp9/decoder/vp9_decodframe.c b/vp9/decoder/vp9_decodframe.c
index d3b18d7..4af9218 100644
--- a/vp9/decoder/vp9_decodframe.c
+++ b/vp9/decoder/vp9_decodframe.c
@@ -65,6 +65,69 @@
   return mode;
 }
 
+static int get_unsigned_bits(unsigned int num_values) {
+  int cat = 0;
+  if (num_values <= 1)
+    return 0;
+  num_values--;
+  while (num_values > 0) {
+    cat++;
+    num_values >>= 1;
+  }
+  return cat;
+}
+
+static int inv_recenter_nonneg(int v, int m) {
+  if (v > (m << 1))
+    return v;
+  else if ((v & 1) == 0)
+    return (v >> 1) + m;
+  else
+    return m - ((v + 1) >> 1);
+}
+
+static int decode_uniform(BOOL_DECODER *br, int n) {
+  int v;
+  const int l = get_unsigned_bits(n);
+  const int m = (1 << l) - n;
+  if (!l)
+    return 0;
+
+  v = vp9_read_literal(br, l - 1);
+  return v < m ?  v : (v << 1) - m + vp9_read_bit(br);
+}
+
+static int decode_term_subexp(BOOL_DECODER *br, int k, int num_syms) {
+  int i = 0, mk = 0, word;
+  while (1) {
+    const int b = i ? k + i - 1 : k;
+    const int a = 1 << b;
+    if (num_syms <= mk + 3 * a) {
+      word = decode_uniform(br, num_syms - mk) + mk;
+      break;
+    } else {
+      if (vp9_read_bit(br)) {
+        i++;
+        mk += a;
+      } else {
+        word = vp9_read_literal(br, b) + mk;
+        break;
+      }
+    }
+  }
+  return word;
+}
+
+static int decode_unsigned_max(BOOL_DECODER *br, int max) {
+  int data = 0, bit = 0, lmax = max;
+
+  while (lmax) {
+    data |= vp9_read_bit(br) << bit++;
+    lmax >>= 1;
+  }
+  return data > max ? max : data;
+}
+
 static int merge_index(int v, int n, int modulus) {
   int max1 = (n - 1 - modulus / 2) / modulus + 1;
   if (v < max1) v = v * modulus + modulus / 2;
@@ -85,14 +148,14 @@
 
   v = merge_index(v, n - 1, modulus);
   if ((m << 1) <= n) {
-    return vp9_inv_recenter_nonneg(v + 1, m);
+    return inv_recenter_nonneg(v + 1, m);
   } else {
-    return n - 1 - vp9_inv_recenter_nonneg(v + 1, n - 1 - m);
+    return n - 1 - inv_recenter_nonneg(v + 1, n - 1 - m);
   }
 }
 
 static vp9_prob read_prob_diff_update(vp9_reader *const bc, int oldp) {
-  int delp = vp9_decode_term_subexp(bc, SUBEXP_PARAM, 255);
+  int delp = decode_term_subexp(bc, SUBEXP_PARAM, 255);
   return (vp9_prob)inv_remap_prob(delp, oldp);
 }
 
@@ -102,15 +165,15 @@
   VP9_COMMON *const pc = &pbi->common;
 
   for (q = 0; q < QINDEX_RANGE; q++) {
-    pc->y_dequant[q][0] = (int16_t)vp9_dc_quant(q, pc->y1dc_delta_q);
-    pc->uv_dequant[q][0] = (int16_t)vp9_dc_uv_quant(q, pc->uvdc_delta_q);
+    pc->y_dequant[q][0] = (int16_t)vp9_dc_quant(q, pc->y_dc_delta_q);
+    pc->uv_dequant[q][0] = (int16_t)vp9_dc_uv_quant(q, pc->uv_dc_delta_q);
 
     /* all the ac values =; */
     for (i = 1; i < 16; i++) {
       const int rc = vp9_default_zig_zag1d_4x4[i];
 
       pc->y_dequant[q][rc] = (int16_t)vp9_ac_yquant(q);
-      pc->uv_dequant[q][rc] = (int16_t)vp9_ac_uv_quant(q, pc->uvac_delta_q);
+      pc->uv_dequant[q][rc] = (int16_t)vp9_ac_uv_quant(q, pc->uv_ac_delta_q);
     }
   }
 }
@@ -645,7 +708,7 @@
            xd->mode_info_context->mbmi.mode, tx_size,
            xd->mode_info_context->mbmi.interp_filter);
 #endif
-    vp9_build_inter_predictors_mb_s(xd, mb_row, mb_col);
+    vp9_build_inter_predictors_mb(xd, mb_row, mb_col);
   }
 
   if (xd->mode_info_context->mbmi.mb_skip_coeff) {
@@ -868,16 +931,18 @@
 }
 
 /* Decode a row of Superblocks (4x4 region of MBs) */
-static void decode_sb_row(VP9D_COMP *pbi, int mb_row, vp9_reader* r) {
+static void decode_tile(VP9D_COMP *pbi, vp9_reader* r) {
   VP9_COMMON *const pc = &pbi->common;
-  int mb_col;
+  int mb_row, mb_col;
 
-  // For a SB there are 2 left contexts, each pertaining to a MB row within
-  vpx_memset(pc->left_context, 0, sizeof(pc->left_context));
-
-  for (mb_col = pc->cur_tile_mb_col_start;
-       mb_col < pc->cur_tile_mb_col_end; mb_col += 4) {
-    decode_modes_sb(pbi, mb_row, mb_col, r, BLOCK_SIZE_SB64X64);
+  for (mb_row = pc->cur_tile_mb_row_start;
+       mb_row < pc->cur_tile_mb_row_end; mb_row += 4) {
+    // For a SB there are 2 left contexts, each pertaining to a MB row within
+    vpx_memset(pc->left_context, 0, sizeof(pc->left_context));
+    for (mb_col = pc->cur_tile_mb_col_start;
+         mb_col < pc->cur_tile_mb_col_end; mb_col += 4) {
+      decode_modes_sb(pbi, mb_row, mb_col, r, BLOCK_SIZE_SB64X64);
+    }
   }
 }
 
@@ -1132,7 +1197,7 @@
           const int feature_enabled = vp9_read_bit(r);
           if (feature_enabled) {
             vp9_enable_segfeature(xd, i, j);
-            data = vp9_decode_unsigned_max(r, vp9_seg_feature_data_max(j));
+            data = decode_unsigned_max(r, vp9_seg_feature_data_max(j));
             if (vp9_is_segfeature_signed(j))
               data = vp9_read_and_apply_sign(r, data);
           }
@@ -1148,9 +1213,9 @@
   // reference frame
   if (pc->frame_type == KEY_FRAME) {
     // Set the prediction probabilities to defaults
-    pc->ref_pred_probs[0] = 120;
-    pc->ref_pred_probs[1] = 80;
-    pc->ref_pred_probs[2] = 40;
+    pc->ref_pred_probs[0] = DEFAULT_PRED_PROB_0;
+    pc->ref_pred_probs[1] = DEFAULT_PRED_PROB_1;
+    pc->ref_pred_probs[2] = DEFAULT_PRED_PROB_2;
   } else {
     int i;
     for (i = 0; i < PREDICTION_PROBS; ++i)
@@ -1203,9 +1268,9 @@
   VP9_COMMON *const pc = &pbi->common;
 
   pc->base_qindex = vp9_read_literal(r, QINDEX_BITS);
-  if (get_delta_q(r, &pc->y1dc_delta_q) |
-      get_delta_q(r, &pc->uvdc_delta_q) |
-      get_delta_q(r, &pc->uvac_delta_q))
+  if (get_delta_q(r, &pc->y_dc_delta_q) |
+      get_delta_q(r, &pc->uv_dc_delta_q) |
+      get_delta_q(r, &pc->uv_ac_delta_q))
     vp9_init_de_quantizer(pbi);
 
   mb_init_dequantizer(pbi, &pbi->mb);  // MB level dequantizer setup
@@ -1215,8 +1280,17 @@
                                       const uint8_t *data_end,
                                       int *width, int *height) {
   if (data + 4 < data_end) {
-    *width = read_le16(data);
-    *height = read_le16(data + 2);
+    const int w = read_le16(data);
+    const int h = read_le16(data + 2);
+    if (w <= 0)
+      vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
+                         "Invalid frame width");
+
+    if (h <= 0)
+      vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
+                         "Invalid frame height");
+    *width = w;
+    *height = h;
     data += 4;
   } else {
     vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
@@ -1242,14 +1316,6 @@
   data = read_frame_size(pc, data, data_end, &width, &height);
 
   if (pc->width != width || pc->height != height) {
-    if (width <= 0)
-      vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
-                         "Invalid frame width");
-
-    if (height <= 0)
-      vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
-                         "Invalid frame height");
-
     if (!pbi->initial_width || !pbi->initial_height) {
       if (vp9_alloc_frame_buffers(pc, width, height))
         vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR,
@@ -1342,7 +1408,6 @@
 
   const uint8_t *data_ptr = data + first_partition_size;
   int tile_row, tile_col, delta_log2_tiles;
-  int mb_row;
 
   vp9_get_tile_n_bits(pc, &pc->log2_tile_columns, &delta_log2_tiles);
   while (delta_log2_tiles--) {
@@ -1388,13 +1453,7 @@
       for (tile_col = n_cols - 1; tile_col >= 0; tile_col--) {
         vp9_get_tile_col_offsets(pc, tile_col);
         setup_token_decoder(pbi, data_ptr2[tile_row][tile_col], residual_bc);
-
-        // Decode a row of superblocks
-        for (mb_row = pc->cur_tile_mb_row_start;
-             mb_row < pc->cur_tile_mb_row_end; mb_row += 4) {
-          decode_sb_row(pbi, mb_row, residual_bc);
-        }
-
+        decode_tile(pbi, residual_bc);
         if (tile_row == pc->tile_rows - 1 && tile_col == n_cols - 1)
           bc_bak = *residual_bc;
       }
@@ -1411,14 +1470,8 @@
         has_more = tile_col < pc->tile_columns - 1 ||
                    tile_row < pc->tile_rows - 1;
 
-        // Setup decoder
         setup_token_decoder(pbi, data_ptr + (has_more ? 4 : 0), residual_bc);
-
-        // Decode a row of superblocks
-        for (mb_row = pc->cur_tile_mb_row_start;
-             mb_row < pc->cur_tile_mb_row_end; mb_row += 4) {
-          decode_sb_row(pbi, mb_row, residual_bc);
-        }
+        decode_tile(pbi, residual_bc);
 
         if (has_more) {
           const int size = read_le32(data_ptr);
diff --git a/vp9/decoder/vp9_detokenize.c b/vp9/decoder/vp9_detokenize.c
index 2679be4..b3a6927 100644
--- a/vp9/decoder/vp9_detokenize.c
+++ b/vp9/decoder/vp9_detokenize.c
@@ -72,7 +72,7 @@
 #if CONFIG_CODE_NONZEROCOUNT
 #define WRITE_COEF_CONTINUE(val, token)                       \
   {                                                           \
-    qcoeff_ptr[scan[c]] = vp9_read_and_apply_sign(br, val);   \
+    qcoeff_ptr[scan[c]] = vp9_read_and_apply_sign(r, val);    \
     INCREMENT_COUNT(token);                                   \
     c++;                                                      \
     nzc++;                                                    \
@@ -81,7 +81,7 @@
 #else
 #define WRITE_COEF_CONTINUE(val, token)                  \
   {                                                      \
-    qcoeff_ptr[scan[c]] = vp9_read_and_apply_sign(br, val); \
+    qcoeff_ptr[scan[c]] = vp9_read_and_apply_sign(r, val); \
     INCREMENT_COUNT(token);                              \
     c++;                                                 \
     continue;                                            \
@@ -90,12 +90,12 @@
 
 #define ADJUST_COEF(prob, bits_count)  \
   do {                                 \
-    if (vp9_read(br, prob))            \
+    if (vp9_read(r, prob))             \
       val += 1 << bits_count;          \
   } while (0);
 
 static int decode_coefs(VP9D_COMP *dx, const MACROBLOCKD *xd,
-                        BOOL_DECODER* const br, int block_idx,
+                        vp9_reader *r, int block_idx,
                         PLANE_TYPE type, int seg_eob, int16_t *qcoeff_ptr,
                         TX_SIZE txfm_size) {
   ENTROPY_CONTEXT* const A0 = (ENTROPY_CONTEXT *) xd->above_context;
@@ -251,7 +251,7 @@
       break;
   }
 
-  VP9_COMBINEENTROPYCONTEXTS(pt, above_ec, left_ec);
+  pt = combine_entropy_contexts(above_ec, left_ec);
   nb = vp9_get_coef_neighbors_handle(scan, &pad);
 
   while (1) {
@@ -270,7 +270,7 @@
 #if CONFIG_CODE_NONZEROCOUNT
     if (!nzc_used)
 #endif
-      if (!vp9_read(br, prob[EOB_CONTEXT_NODE]))
+      if (!vp9_read(r, prob[EOB_CONTEXT_NODE]))
         break;
 SKIP_START:
     if (c >= seg_eob)
@@ -281,29 +281,29 @@
     // decode zero node only if there are zeros left
     if (!nzc_used || seg_eob - nzc_expected - c + nzc > 0)
 #endif
-    if (!vp9_read(br, prob[ZERO_CONTEXT_NODE])) {
+    if (!vp9_read(r, prob[ZERO_CONTEXT_NODE])) {
       INCREMENT_COUNT(ZERO_TOKEN);
       ++c;
       prob = coef_probs[type][ref][get_coef_band(scan, txfm_size, c)][pt];
       goto SKIP_START;
     }
     // ONE_CONTEXT_NODE_0_
-    if (!vp9_read(br, prob[ONE_CONTEXT_NODE])) {
+    if (!vp9_read(r, prob[ONE_CONTEXT_NODE])) {
       WRITE_COEF_CONTINUE(1, ONE_TOKEN);
     }
     // LOW_VAL_CONTEXT_NODE_0_
-    if (!vp9_read(br, prob[LOW_VAL_CONTEXT_NODE])) {
-      if (!vp9_read(br, prob[TWO_CONTEXT_NODE])) {
+    if (!vp9_read(r, prob[LOW_VAL_CONTEXT_NODE])) {
+      if (!vp9_read(r, prob[TWO_CONTEXT_NODE])) {
         WRITE_COEF_CONTINUE(2, TWO_TOKEN);
       }
-      if (!vp9_read(br, prob[THREE_CONTEXT_NODE])) {
+      if (!vp9_read(r, prob[THREE_CONTEXT_NODE])) {
         WRITE_COEF_CONTINUE(3, THREE_TOKEN);
       }
       WRITE_COEF_CONTINUE(4, FOUR_TOKEN);
     }
     // HIGH_LOW_CONTEXT_NODE_0_
-    if (!vp9_read(br, prob[HIGH_LOW_CONTEXT_NODE])) {
-      if (!vp9_read(br, prob[CAT_ONE_CONTEXT_NODE])) {
+    if (!vp9_read(r, prob[HIGH_LOW_CONTEXT_NODE])) {
+      if (!vp9_read(r, prob[CAT_ONE_CONTEXT_NODE])) {
         val = CAT1_MIN_VAL;
         ADJUST_COEF(CAT1_PROB0, 0);
         WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY1);
@@ -314,8 +314,8 @@
       WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY2);
     }
     // CAT_THREEFOUR_CONTEXT_NODE_0_
-    if (!vp9_read(br, prob[CAT_THREEFOUR_CONTEXT_NODE])) {
-      if (!vp9_read(br, prob[CAT_THREE_CONTEXT_NODE])) {
+    if (!vp9_read(r, prob[CAT_THREEFOUR_CONTEXT_NODE])) {
+      if (!vp9_read(r, prob[CAT_THREE_CONTEXT_NODE])) {
         val = CAT3_MIN_VAL;
         ADJUST_COEF(CAT3_PROB2, 2);
         ADJUST_COEF(CAT3_PROB1, 1);
@@ -330,7 +330,7 @@
       WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY4);
     }
     // CAT_FIVE_CONTEXT_NODE_0_:
-    if (!vp9_read(br, prob[CAT_FIVE_CONTEXT_NODE])) {
+    if (!vp9_read(r, prob[CAT_FIVE_CONTEXT_NODE])) {
       val = CAT5_MIN_VAL;
       ADJUST_COEF(CAT5_PROB4, 4);
       ADJUST_COEF(CAT5_PROB3, 3);
@@ -341,7 +341,7 @@
     }
     val = 0;
     while (*cat6) {
-      val = (val << 1) | vp9_read(br, *cat6++);
+      val = (val << 1) | vp9_read(r, *cat6++);
     }
     val += CAT6_MIN_VAL;
     WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY6);
@@ -398,7 +398,7 @@
 struct decode_block_args {
   VP9D_COMP *pbi;
   MACROBLOCKD *xd;
-  BOOL_DECODER *bc;
+  vp9_reader *r;
   int *eobtotal;
 };
 static void decode_block(int plane, int block,
@@ -416,7 +416,7 @@
   const int seg_eob = get_eob(arg->xd, segment_id, 16 << ss_txfrm_size);
   int16_t* const qcoeff_base = arg->xd->plane[plane].qcoeff;
 
-  const int eob = decode_coefs(arg->pbi, arg->xd, arg->bc, old_block_idx,
+  const int eob = decode_coefs(arg->pbi, arg->xd, arg->r, old_block_idx,
                                arg->xd->plane[plane].plane_type, seg_eob,
                                BLOCK_OFFSET(qcoeff_base, block, 16),
                                ss_tx_size);
@@ -427,20 +427,20 @@
 
 int vp9_decode_tokens(VP9D_COMP* const pbi,
                          MACROBLOCKD* const xd,
-                         BOOL_DECODER* const bc,
+                         vp9_reader *r,
                          BLOCK_SIZE_TYPE bsize) {
   int eobtotal = 0;
-  struct decode_block_args args = {pbi, xd, bc, &eobtotal};
+  struct decode_block_args args = {pbi, xd, r, &eobtotal};
   foreach_transformed_block(xd, bsize, decode_block, &args);
   return eobtotal;
 }
 
 #if CONFIG_NEWBINTRAMODES
 static int decode_coefs_4x4(VP9D_COMP *dx, MACROBLOCKD *xd,
-                            BOOL_DECODER* const bc,
+                            vp9_reader *r,
                             PLANE_TYPE type, int i, int seg_eob) {
   const struct plane_block_idx pb_idx = plane_block_idx(16, i);
-  const int c = decode_coefs(dx, xd, bc, i, type, seg_eob,
+  const int c = decode_coefs(dx, xd, r, i, type, seg_eob,
       BLOCK_OFFSET(xd->plane[pb_idx.plane].qcoeff, pb_idx.block, 16), TX_4X4);
   xd->plane[pb_idx.plane].eobs[pb_idx.block] = c;
   return c;
@@ -448,31 +448,31 @@
 
 static int decode_mb_tokens_4x4_uv(VP9D_COMP* const dx,
                                    MACROBLOCKD* const xd,
-                                   BOOL_DECODER* const bc,
+                                   vp9_reader *r,
                                    int seg_eob) {
   int i, eobtotal = 0;
 
   // chroma blocks
   for (i = 16; i < 24; i++)
-    eobtotal += decode_coefs_4x4(dx, xd, bc, PLANE_TYPE_UV, i, seg_eob);
+    eobtotal += decode_coefs_4x4(dx, xd, r, PLANE_TYPE_UV, i, seg_eob);
 
   return eobtotal;
 }
 
 int vp9_decode_mb_tokens_4x4_uv(VP9D_COMP* const dx,
                                 MACROBLOCKD* const xd,
-                                BOOL_DECODER* const bc) {
+                                vp9_reader *r) {
   const int segment_id = xd->mode_info_context->mbmi.segment_id;
   const int seg_eob = get_eob(xd, segment_id, 16);
 
-  return decode_mb_tokens_4x4_uv(dx, xd, bc, seg_eob);
+  return decode_mb_tokens_4x4_uv(dx, xd, r, seg_eob);
 }
 
 int vp9_decode_coefs_4x4(VP9D_COMP *dx, MACROBLOCKD *xd,
-                         BOOL_DECODER* const bc,
+                         vp9_reader *r,
                          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(dx, xd, bc, type, i, seg_eob);
+  return decode_coefs_4x4(dx, xd, r, type, i, seg_eob);
 }
 #endif
diff --git a/vp9/decoder/vp9_detokenize.h b/vp9/decoder/vp9_detokenize.h
index e0c2968..74352a3 100644
--- a/vp9/decoder/vp9_detokenize.h
+++ b/vp9/decoder/vp9_detokenize.h
@@ -16,14 +16,14 @@
 
 int vp9_decode_tokens(VP9D_COMP* const pbi,
                       MACROBLOCKD* const xd,
-                      BOOL_DECODER* const bc,
+                      vp9_reader *r,
                       BLOCK_SIZE_TYPE bsize);
 
 int vp9_decode_mb_tokens_4x4_uv(VP9D_COMP* const dx, MACROBLOCKD* const xd,
-                                BOOL_DECODER* const bc);
+                                vp9_reader *r);
 #if CONFIG_NEWBINTRAMODES
 int vp9_decode_coefs_4x4(VP9D_COMP *dx, MACROBLOCKD *xd,
-                         BOOL_DECODER* const bc,
+                         vp9_reader *r,
                          PLANE_TYPE type, int i);
 #endif
 
diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c
index 8a644d5..bcfbd60 100644
--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -2623,9 +2623,9 @@
   vp9_write_literal(&header_bc, pc->base_qindex, QINDEX_BITS);
 
   // Transmit Dc, Second order and Uv quantizer delta information
-  put_delta_q(&header_bc, pc->y1dc_delta_q);
-  put_delta_q(&header_bc, pc->uvdc_delta_q);
-  put_delta_q(&header_bc, pc->uvac_delta_q);
+  put_delta_q(&header_bc, pc->y_dc_delta_q);
+  put_delta_q(&header_bc, pc->uv_dc_delta_q);
+  put_delta_q(&header_bc, pc->uv_ac_delta_q);
 
   // When there is a key frame all reference buffers are updated using the new key frame
   if (pc->frame_type != KEY_FRAME) {
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c
index 6f0e8c7..5f29c27 100644
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -1405,9 +1405,9 @@
   MACROBLOCKD *const xd = &x->e_mbd;
   int totalrate;
 
-//   fprintf(stderr, "encode_frame_internal frame %d (%d) type %d\n",
-//            cpi->common.current_video_frame, cpi->common.show_frame,
-//            cm->frame_type);
+//  fprintf(stderr, "encode_frame_internal frame %d (%d) type %d\n",
+//           cpi->common.current_video_frame, cpi->common.show_frame,
+//           cm->frame_type);
 
   // Compute a modified set of reference frame probabilities to use when
   // prediction fails. These are based on the current general estimates for
@@ -1456,14 +1456,14 @@
 #endif
 
   cpi->mb.e_mbd.lossless = (cm->base_qindex == 0 &&
-                            cm->y1dc_delta_q == 0 &&
-                            cm->uvdc_delta_q == 0 &&
-                            cm->uvac_delta_q == 0);
+                            cm->y_dc_delta_q == 0 &&
+                            cm->uv_dc_delta_q == 0 &&
+                            cm->uv_ac_delta_q == 0);
   switch_lossless_mode(cpi, cpi->mb.e_mbd.lossless);
 
   vp9_frame_init_quantizer(cpi);
 
-  vp9_initialize_rd_consts(cpi, cm->base_qindex + cm->y1dc_delta_q);
+  vp9_initialize_rd_consts(cpi, cm->base_qindex + cm->y_dc_delta_q);
   vp9_initialize_me_consts(cpi, cm->base_qindex);
 
   if (cpi->oxcf.tuning == VP8_TUNE_SSIM) {
@@ -2230,15 +2230,8 @@
 
     if (!x->skip) {
       vp9_encode_inter16x16(cm, x, mb_row, mb_col);
-
     } else {
-      vp9_build_inter16x16_predictors_mb(xd,
-                                         xd->dst.y_buffer,
-                                         xd->dst.u_buffer,
-                                         xd->dst.v_buffer,
-                                         xd->dst.y_stride,
-                                         xd->dst.uv_stride,
-                                         mb_row, mb_col);
+      vp9_build_inter_predictors_sb(xd, mb_row, mb_col, BLOCK_SIZE_MB16X16);
 #if CONFIG_COMP_INTERINTRA_PRED
       if (xd->mode_info_context->mbmi.second_ref_frame == INTRA_FRAME) {
         vp9_build_interintra_16x16_predictors_mb(xd,
diff --git a/vp9/encoder/vp9_encodeintra.c b/vp9/encoder/vp9_encodeintra.c
index 355867b..bccd22b 100644
--- a/vp9/encoder/vp9_encodeintra.c
+++ b/vp9/encoder/vp9_encodeintra.c
@@ -52,7 +52,8 @@
   b->bmi.as_mode.context = vp9_find_bpred_context(&x->e_mbd, b);
 #endif
 
-  vp9_intra4x4_predict(&x->e_mbd, b, b->bmi.as_mode.first, b->predictor, 16);
+  vp9_intra4x4_predict(&x->e_mbd, b, b->bmi.as_mode.first,
+                       *(b->base_dst) + b->dst, b->dst_stride);
   vp9_subtract_b(be, b, 16);
 
   tx_type = get_tx_type_4x4(&x->e_mbd, ib);
@@ -69,7 +70,8 @@
                                 b->diff, 32);
   }
 
-  vp9_recon_b(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+  vp9_recon_b(*(b->base_dst) + b->dst, b->diff,
+              *(b->base_dst) + b->dst, b->dst_stride);
 }
 
 void vp9_encode_intra4x4mby(MACROBLOCK *mb) {
@@ -81,12 +83,13 @@
 
 void vp9_encode_intra16x16mby(VP9_COMMON *const cm, MACROBLOCK *x) {
   MACROBLOCKD *xd = &x->e_mbd;
-  BLOCK *b = &x->block[0];
   TX_SIZE tx_size = xd->mode_info_context->mbmi.txfm_size;
 
-  vp9_build_intra_predictors_mby(xd);
-
-  vp9_subtract_mby(x->src_diff, *(b->base_src), xd->predictor, b->src_stride);
+  vp9_build_intra_predictors_sby_s(xd, BLOCK_SIZE_MB16X16);
+  vp9_subtract_sby_s_c(x->src_diff,
+                       x->src.y_buffer, x->src.y_stride,
+                       xd->dst.y_buffer, xd->dst.y_stride,
+                       BLOCK_SIZE_MB16X16);
 
   switch (tx_size) {
     case TX_16X16:
@@ -119,10 +122,11 @@
   MACROBLOCKD *xd = &x->e_mbd;
   TX_SIZE tx_size = xd->mode_info_context->mbmi.txfm_size;
 
-  vp9_build_intra_predictors_mbuv(xd);
-
-  vp9_subtract_mbuv(x->src_diff, x->src.u_buffer, x->src.v_buffer,
-                    xd->predictor, x->src.uv_stride);
+  vp9_build_intra_predictors_sbuv_s(xd, BLOCK_SIZE_MB16X16);
+  vp9_subtract_sbuv_s_c(x->src_diff,
+                        x->src.u_buffer, x->src.v_buffer, x->src.uv_stride,
+                        xd->dst.u_buffer, xd->dst.v_buffer, xd->dst.uv_stride,
+                        BLOCK_SIZE_MB16X16);
 
   switch (tx_size) {
     case TX_4X4:
@@ -152,7 +156,8 @@
   int i;
   TX_TYPE tx_type;
 
-  vp9_intra8x8_predict(xd, b, b->bmi.as_mode.first, b->predictor, 16);
+  vp9_intra8x8_predict(xd, b, b->bmi.as_mode.first,
+                       *(b->base_dst) + b->dst, b->dst_stride);
   // generate residual blocks
   vp9_subtract_4b_c(be, b, 16);
 
@@ -206,7 +211,7 @@
   // reconstruct submacroblock
   for (i = 0; i < 4; i++) {
     b = &xd->block[ib + iblock[i]];
-    vp9_recon_b_c(b->predictor, b->diff, *(b->base_dst) + b->dst,
+    vp9_recon_b_c(*(b->base_dst) + b->dst, b->diff, *(b->base_dst) + b->dst,
                   b->dst_stride);
   }
 }
@@ -227,7 +232,8 @@
   const int block = ib < 20 ? ib - 16 : ib - 20;
 
   assert(ib >= 16 && ib < 24);
-  vp9_intra_uv4x4_predict(&x->e_mbd, b, mode, b->predictor, 8);
+  vp9_intra_uv4x4_predict(&x->e_mbd, b, mode,
+                          *(b->base_dst) + b->dst, b->dst_stride);
 
   vp9_subtract_b(be, b, 8);
 
@@ -236,7 +242,7 @@
   vp9_inverse_transform_b_4x4(&x->e_mbd, xd->plane[plane].eobs[block],
                               dqcoeff, b->diff, 16);
 
-  vp9_recon_uv_b_c(b->predictor, b->diff, *(b->base_dst) + b->dst,
+  vp9_recon_uv_b_c(*(b->base_dst) + b->dst, b->diff, *(b->base_dst) + b->dst,
                    b->dst_stride);
 }
 
diff --git a/vp9/encoder/vp9_encodemb.c b/vp9/encoder/vp9_encodemb.c
index 6ecaaa5..dbbde31 100644
--- a/vp9/encoder/vp9_encodemb.c
+++ b/vp9/encoder/vp9_encodemb.c
@@ -23,8 +23,9 @@
 void vp9_subtract_b_c(BLOCK *be, BLOCKD *bd, int pitch) {
   uint8_t *src_ptr = (*(be->base_src) + be->src);
   int16_t *diff_ptr = be->src_diff;
-  uint8_t *pred_ptr = bd->predictor;
+  uint8_t *pred_ptr = *(bd->base_dst) + bd->dst;
   int src_stride = be->src_stride;
+  int dst_stride = bd->dst_stride;
 
   int r, c;
 
@@ -33,7 +34,7 @@
       diff_ptr[c] = src_ptr[c] - pred_ptr[c];
 
     diff_ptr += pitch;
-    pred_ptr += pitch;
+    pred_ptr += dst_stride;
     src_ptr  += src_stride;
   }
 }
@@ -41,8 +42,9 @@
 void vp9_subtract_4b_c(BLOCK *be, BLOCKD *bd, int pitch) {
   uint8_t *src_ptr = (*(be->base_src) + be->src);
   int16_t *diff_ptr = be->src_diff;
-  uint8_t *pred_ptr = bd->predictor;
+  uint8_t *pred_ptr = *(bd->base_dst) + bd->dst;
   int src_stride = be->src_stride;
+  int dst_stride = bd->dst_stride;
   int r, c;
 
   for (r = 0; r < 8; r++) {
@@ -50,7 +52,7 @@
       diff_ptr[c] = src_ptr[c] - pred_ptr[c];
 
     diff_ptr += pitch;
-    pred_ptr += pitch;
+    pred_ptr += dst_stride;
     src_ptr  += src_stride;
   }
 }
@@ -102,25 +104,15 @@
   }
 }
 
-void vp9_subtract_mby_c(int16_t *diff, uint8_t *src,
-                        uint8_t *pred, int stride) {
-  vp9_subtract_sby_s_c(diff, src, stride, pred, 16, BLOCK_SIZE_MB16X16);
-}
-
-void vp9_subtract_mbuv_c(int16_t *diff, uint8_t *usrc,
-                         uint8_t *vsrc, uint8_t *pred, int stride) {
-  uint8_t *upred = pred + 256;
-  uint8_t *vpred = pred + 320;
-
-  vp9_subtract_sbuv_s_c(diff, usrc, vsrc, stride, upred, vpred, 8,
-                        BLOCK_SIZE_MB16X16);
-}
-
 static void subtract_mb(MACROBLOCK *x) {
-  vp9_subtract_mby(x->src_diff, x->src.y_buffer, x->e_mbd.predictor,
-                   x->src.y_stride);
-  vp9_subtract_mbuv(x->src_diff, x->src.u_buffer, x->src.v_buffer,
-                    x->e_mbd.predictor, x->src.uv_stride);
+  MACROBLOCKD *xd = &x->e_mbd;
+  vp9_subtract_sby_s_c(x->src_diff, x->src.y_buffer, x->src.y_stride,
+                       xd->dst.y_buffer, xd->dst.y_stride,
+                       BLOCK_SIZE_MB16X16);
+  vp9_subtract_sbuv_s_c(x->src_diff, x->src.u_buffer, x->src.v_buffer,
+                        x->src.uv_stride,
+                        xd->dst.u_buffer, xd->dst.v_buffer, xd->dst.uv_stride,
+                        BLOCK_SIZE_MB16X16);
 }
 
 void vp9_transform_sby_32x32(MACROBLOCK *x, BLOCK_SIZE_TYPE bsize) {
@@ -582,7 +574,7 @@
 
   /* Now pick the best path through the whole trellis. */
   band = get_coef_band(scan, tx_size, i + 1);
-  VP9_COMBINEENTROPYCONTEXTS(pt, *a, *l);
+  pt = combine_entropy_contexts(*a, *l);
   rate0 = tokens[next][0].rate;
   rate1 = tokens[next][1].rate;
   error0 = tokens[next][0].error;
@@ -920,11 +912,12 @@
 /* this function is used by first pass only */
 void vp9_encode_inter16x16y(MACROBLOCK *x, int mb_row, int mb_col) {
   MACROBLOCKD *xd = &x->e_mbd;
-  BLOCK *b = &x->block[0];
 
-  vp9_build_inter16x16_predictors_mby(xd, xd->predictor, 16, mb_row, mb_col);
-
-  vp9_subtract_mby(x->src_diff, *(b->base_src), xd->predictor, b->src_stride);
+  vp9_build_inter_predictors_sby(xd, xd->dst.y_buffer, xd->dst.y_stride,
+                                 mb_row, mb_col, BLOCK_SIZE_MB16X16);
+  vp9_subtract_sby_s_c(x->src_diff, x->src.y_buffer, x->src.y_stride,
+                       xd->dst.y_buffer, xd->dst.y_stride,
+                       BLOCK_SIZE_MB16X16);
 
   vp9_transform_sby_4x4(x, BLOCK_SIZE_MB16X16);
   vp9_quantize_sby_4x4(x, BLOCK_SIZE_MB16X16);
diff --git a/vp9/encoder/vp9_encodemb.h b/vp9/encoder/vp9_encodemb.h
index 76fb0f7..3c0d760 100644
--- a/vp9/encoder/vp9_encodemb.h
+++ b/vp9/encoder/vp9_encodemb.h
@@ -58,13 +58,6 @@
 
 void vp9_subtract_4b_c(BLOCK *be, BLOCKD *bd, int pitch);
 
-void vp9_subtract_mbuv_s_c(int16_t *diff, const uint8_t *usrc,
-                           const uint8_t *vsrc, int src_stride,
-                           const uint8_t *upred,
-                           const uint8_t *vpred, int dst_stride);
-void vp9_subtract_mby_s_c(int16_t *diff, const uint8_t *src,
-                          int src_stride, const uint8_t *pred,
-                          int dst_stride);
 void vp9_subtract_sby_s_c(int16_t *diff, const uint8_t *src, int src_stride,
                           const uint8_t *pred, int dst_stride,
                           BLOCK_SIZE_TYPE bsize);
diff --git a/vp9/encoder/vp9_encodemv.c b/vp9/encoder/vp9_encodemv.c
index 7c0b3dd..553c697 100644
--- a/vp9/encoder/vp9_encodemv.c
+++ b/vp9/encoder/vp9_encodemv.c
@@ -556,30 +556,27 @@
   }
 }
 
-void vp9_encode_nmv(vp9_writer* const bc, const MV* const mv,
+void vp9_encode_nmv(vp9_writer* w, const MV* const mv,
                     const MV* const ref, const nmv_context* const mvctx) {
-  MV_JOINT_TYPE j = vp9_get_mv_joint(*mv);
-  write_token(bc, vp9_mv_joint_tree, mvctx->joints,
-              vp9_mv_joint_encodings + j);
-  if (mv_joint_vertical(j)) {
-    encode_nmv_component(bc, mv->row, ref->col, &mvctx->comps[0]);
-  }
-  if (mv_joint_horizontal(j)) {
-    encode_nmv_component(bc, mv->col, ref->col, &mvctx->comps[1]);
-  }
+  const MV_JOINT_TYPE j = vp9_get_mv_joint(mv);
+  write_token(w, vp9_mv_joint_tree, mvctx->joints, vp9_mv_joint_encodings + j);
+  if (mv_joint_vertical(j))
+    encode_nmv_component(w, mv->row, ref->col, &mvctx->comps[0]);
+
+  if (mv_joint_horizontal(j))
+    encode_nmv_component(w, mv->col, ref->col, &mvctx->comps[1]);
 }
 
 void vp9_encode_nmv_fp(vp9_writer* const bc, const MV* const mv,
                        const MV* const ref, const nmv_context* const mvctx,
                        int usehp) {
-  MV_JOINT_TYPE j = vp9_get_mv_joint(*mv);
+  const MV_JOINT_TYPE j = vp9_get_mv_joint(mv);
   usehp = usehp && vp9_use_nmv_hp(ref);
-  if (mv_joint_vertical(j)) {
+  if (mv_joint_vertical(j))
     encode_nmv_component_fp(bc, mv->row, ref->row, &mvctx->comps[0], usehp);
-  }
-  if (mv_joint_horizontal(j)) {
+
+  if (mv_joint_horizontal(j))
     encode_nmv_component_fp(bc, mv->col, ref->col, &mvctx->comps[1], usehp);
-  }
 }
 
 void vp9_build_nmv_cost_table(int *mvjoint,
diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c
index a995ab3..f2e0046 100644
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -505,7 +505,7 @@
   // if ( 0 )
   {
     vp9_init_mv_probs(cm);
-    vp9_initialize_rd_consts(cpi, cm->base_qindex + cm->y1dc_delta_q);
+    vp9_initialize_rd_consts(cpi, cm->base_qindex + cm->y_dc_delta_q);
   }
 
   // for each macroblock row in image
@@ -524,6 +524,7 @@
     x->mv_row_max = ((cm->mb_rows - 1 - mb_row) * 16)
                     + (VP9BORDERINPIXELS - 16);
 
+    set_mb_row(cm, xd, mb_row, 1 << mb_height_log2(BLOCK_SIZE_MB16X16));
 
     // for each macroblock col in image
     for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) {
@@ -531,6 +532,7 @@
       int gf_motion_error = INT_MAX;
       int use_dc_pred = (mb_col || mb_row) && (!mb_col || !mb_row);
 
+      set_mb_col(cm, xd, mb_col, 1 << mb_height_log2(BLOCK_SIZE_MB16X16));
       xd->dst.y_buffer = new_yv12->y_buffer + recon_yoffset;
       xd->dst.u_buffer = new_yv12->u_buffer + recon_uvoffset;
       xd->dst.v_buffer = new_yv12->v_buffer + recon_uvoffset;
diff --git a/vp9/encoder/vp9_mbgraph.c b/vp9/encoder/vp9_mbgraph.c
index 715d683..e9da395 100644
--- a/vp9/encoder/vp9_mbgraph.c
+++ b/vp9/encoder/vp9_mbgraph.c
@@ -71,9 +71,10 @@
   }
 
   vp9_set_mbmode_and_mvs(x, NEWMV, dst_mv);
-  vp9_build_inter16x16_predictors_mby(xd, xd->predictor, 16, mb_row, mb_col);
-  best_err = vp9_sad16x16(xd->dst.y_buffer, xd->dst.y_stride,
-                          xd->predictor, 16, INT_MAX);
+  vp9_build_inter_predictors_sby(xd, xd->dst.y_buffer, xd->dst.y_stride,
+                                 mb_row, mb_col, BLOCK_SIZE_MB16X16);
+  best_err = vp9_sad16x16(x->src.y_buffer, x->src.y_stride,
+                          xd->dst.y_buffer, xd->dst.y_stride, INT_MAX);
 
   /* restore UMV window */
   x->mv_col_min = tmp_col_min;
@@ -105,21 +106,19 @@
     BLOCKD *d = &xd->block[n];
     BLOCK *b  = &x->block[n];
 
-    b->base_src   = &buf->y_buffer;
-    b->src_stride = buf->y_stride;
-    b->src        = buf->y_stride * (n & 12) + (n & 3) * 4 + buf_mb_y_offset;
+    b->base_src   = &x->src.y_buffer;
+    b->src_stride = x->src.y_stride;
+    b->src        = x->src.y_stride * (n & 12) + (n & 3) * 4;
 
-    d->base_pre   = &ref->y_buffer;
-    d->pre_stride = ref->y_stride;
-    d->pre        = ref->y_stride * (n & 12) + (n & 3) * 4 + mb_y_offset;
+    d->base_pre   = &xd->pre.y_buffer;
+    d->pre_stride = xd->pre.y_stride;
+    d->pre        = xd->pre.y_stride * (n & 12) + (n & 3) * 4;
   }
 
   // Try zero MV first
   // FIXME should really use something like near/nearest MV and/or MV prediction
-  xd->pre.y_buffer = ref->y_buffer + mb_y_offset;
-  xd->pre.y_stride = ref->y_stride;
-  err = vp9_sad16x16(ref->y_buffer + mb_y_offset, ref->y_stride,
-                     xd->dst.y_buffer, xd->dst.y_stride, INT_MAX);
+  err = vp9_sad16x16(x->src.y_buffer, x->src.y_stride,
+                     xd->pre.y_buffer, xd->pre.y_stride, INT_MAX);
   dst_mv->as_int = 0;
 
   // Test last reference frame using the previous best mv as the
@@ -159,27 +158,11 @@
   MACROBLOCK   *const x  = &cpi->mb;
   MACROBLOCKD *const xd = &x->e_mbd;
   unsigned int err;
-  int n;
-
-  for (n = 0; n < 16; n++) {
-    BLOCKD *d = &xd->block[n];
-    BLOCK *b  = &x->block[n];
-
-    b->base_src   = &buf->y_buffer;
-    b->src_stride = buf->y_stride;
-    b->src        = buf->y_stride * (n & 12) + (n & 3) * 4 + buf_mb_y_offset;
-
-    d->base_pre   = &ref->y_buffer;
-    d->pre_stride = ref->y_stride;
-    d->pre        = ref->y_stride * (n & 12) + (n & 3) * 4 + mb_y_offset;
-  }
 
   // Try zero MV first
   // FIXME should really use something like near/nearest MV and/or MV prediction
-  xd->pre.y_buffer = ref->y_buffer + mb_y_offset;
-  xd->pre.y_stride = ref->y_stride;
-  err = vp9_sad16x16(ref->y_buffer + mb_y_offset, ref->y_stride,
-                     xd->dst.y_buffer, xd->dst.y_stride, INT_MAX);
+  err = vp9_sad16x16(x->src.y_buffer, x->src.y_stride,
+                     xd->pre.y_buffer, xd->pre.y_stride, INT_MAX);
 
   dst_mv->as_int = 0;
 
@@ -201,11 +184,19 @@
   // we're intentionally not doing 4x4, we just want a rough estimate
   for (mode = DC_PRED; mode <= TM_PRED; mode++) {
     unsigned int err;
+    const int bwl = b_width_log2(BLOCK_SIZE_MB16X16),  bw = 4 << bwl;
+    const int bhl = b_height_log2(BLOCK_SIZE_MB16X16), bh = 4 << bhl;
 
     xd->mode_info_context->mbmi.mode = mode;
-    vp9_build_intra_predictors_mby(xd);
-    err = vp9_sad16x16(xd->predictor, 16, buf->y_buffer + mb_y_offset,
-                       buf->y_stride, best_err);
+    vp9_build_intra_predictors(x->src.y_buffer, x->src.y_stride,
+                               xd->dst.y_buffer, xd->dst.y_stride,
+                               xd->mode_info_context->mbmi.mode,
+                               bw, bh,
+                               xd->up_available, xd->left_available,
+                               xd->right_available);
+    err = vp9_sad16x16(x->src.y_buffer, x->src.y_stride,
+                       xd->dst.y_buffer, xd->dst.y_stride, best_err);
+
     // find best
     if (err < best_err) {
       best_err  = err;
@@ -237,23 +228,32 @@
   MACROBLOCK   *const x  = &cpi->mb;
   MACROBLOCKD *const xd = &x->e_mbd;
   int intra_error;
+  VP9_COMMON *cm = &cpi->common;
 
   // FIXME in practice we're completely ignoring chroma here
-  xd->dst.y_buffer = buf->y_buffer + mb_y_offset;
+  x->src.y_buffer = buf->y_buffer + mb_y_offset;
+  x->src.y_stride = buf->y_stride;
+
+  xd->dst.y_buffer = cm->yv12_fb[cm->new_fb_idx].y_buffer + mb_y_offset;
+  xd->dst.y_stride = cm->yv12_fb[cm->new_fb_idx].y_stride;
 
   // do intra 16x16 prediction
-  intra_error = find_best_16x16_intra(cpi, buf, mb_y_offset, &stats->ref[INTRA_FRAME].m.mode);
+  intra_error = find_best_16x16_intra(cpi, buf, mb_y_offset,
+                                      &stats->ref[INTRA_FRAME].m.mode);
   if (intra_error <= 0)
     intra_error = 1;
   stats->ref[INTRA_FRAME].err = intra_error;
 
   // Golden frame MV search, if it exists and is different than last frame
   if (golden_ref) {
-    int g_motion_error = do_16x16_motion_search(cpi, prev_golden_ref_mv,
-                                                &stats->ref[GOLDEN_FRAME].m.mv,
-                                                buf, mb_y_offset,
-                                                golden_ref, gld_y_offset,
-                                                mb_row, mb_col);
+    int g_motion_error;
+    xd->pre.y_buffer = golden_ref->y_buffer + mb_y_offset;
+    xd->pre.y_stride = golden_ref->y_stride;
+    g_motion_error = do_16x16_motion_search(cpi, prev_golden_ref_mv,
+                                            &stats->ref[GOLDEN_FRAME].m.mv,
+                                            buf, mb_y_offset,
+                                            golden_ref, gld_y_offset,
+                                            mb_row, mb_col);
     stats->ref[GOLDEN_FRAME].err = g_motion_error;
   } else {
     stats->ref[GOLDEN_FRAME].err = INT_MAX;
@@ -262,16 +262,13 @@
 
   // Alt-ref frame MV search, if it exists and is different than last/golden frame
   if (alt_ref) {
-    // int a_motion_error = do_16x16_motion_search(cpi, prev_alt_ref_mv,
-    //                                            &stats->ref[ALTREF_FRAME].m.mv,
-    //                                            buf, mb_y_offset,
-    //                                            alt_ref, arf_y_offset);
-
-    int a_motion_error =
-      do_16x16_zerozero_search(cpi,
-                               &stats->ref[ALTREF_FRAME].m.mv,
-                               buf, mb_y_offset,
-                               alt_ref, arf_y_offset);
+    int a_motion_error;
+    xd->pre.y_buffer = alt_ref->y_buffer + mb_y_offset;
+    xd->pre.y_stride = alt_ref->y_stride;
+    a_motion_error = do_16x16_zerozero_search(cpi,
+                                              &stats->ref[ALTREF_FRAME].m.mv,
+                                              buf, mb_y_offset,
+                                              alt_ref, arf_y_offset);
 
     stats->ref[ALTREF_FRAME].err = a_motion_error;
   } else {
diff --git a/vp9/encoder/vp9_mcomp.c b/vp9/encoder/vp9_mcomp.c
index 1649cca..17dafe6 100644
--- a/vp9/encoder/vp9_mcomp.c
+++ b/vp9/encoder/vp9_mcomp.c
@@ -56,8 +56,9 @@
   MV v;
   v.row = mv->as_mv.row - ref->as_mv.row;
   v.col = mv->as_mv.col - ref->as_mv.col;
-  return ((mvjcost[vp9_get_mv_joint(v)] +
-           mvcost[0][v.row] + mvcost[1][v.col]) * weight) >> 7;
+  return ROUND_POWER_OF_TWO((mvjcost[vp9_get_mv_joint(&v)] +
+                             mvcost[0][v.row] +
+                             mvcost[1][v.col]) * weight, 7);
 }
 
 static int mv_err_cost(int_mv *mv, int_mv *ref, int *mvjcost, int *mvcost[2],
@@ -66,9 +67,9 @@
     MV v;
     v.row = mv->as_mv.row - ref->as_mv.row;
     v.col = mv->as_mv.col - ref->as_mv.col;
-    return ((mvjcost[vp9_get_mv_joint(v)] +
-             mvcost[0][v.row] + mvcost[1][v.col]) *
-            error_per_bit + 4096) >> 13;
+    return ROUND_POWER_OF_TWO((mvjcost[vp9_get_mv_joint(&v)] +
+                               mvcost[0][v.row] +
+                               mvcost[1][v.col]) * error_per_bit, 13);
   }
   return 0;
 }
@@ -79,10 +80,9 @@
     MV v;
     v.row = mv->as_mv.row - ref->as_mv.row;
     v.col = mv->as_mv.col - ref->as_mv.col;
-
-    return ROUND_POWER_OF_TWO((mvjsadcost[vp9_get_mv_joint(v)] +
-                                   mvsadcost[0][v.row] + mvsadcost[1][v.col]) *
-                                       error_per_bit, 8);
+    return ROUND_POWER_OF_TWO((mvjsadcost[vp9_get_mv_joint(&v)] +
+                               mvsadcost[0][v.row] +
+                               mvsadcost[1][v.col]) * error_per_bit, 8);
   }
   return 0;
 }
diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c
index 2ebb24b..85ac523 100644
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -3986,13 +3986,13 @@
   cm->frame_type = INTER_FRAME;
   cm->frame_flags = *frame_flags;
 
-  /* Reset the frame pointers to the current frame size */
+  // Reset the frame pointers to the current frame size
   vp8_yv12_realloc_frame_buffer(&cm->yv12_fb[cm->new_fb_idx],
                                 cm->width, cm->height,
                                 VP9BORDERINPIXELS);
 
-  /* Calculate scaling factors for each of the 3 available references */
-  for (i = 0; i < 3; ++i) {
+  // Calculate scaling factors for each of the 3 available references
+  for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) {
     if (cm->active_ref_idx[i] >= NUM_YV12_BUFFERS) {
       memset(&cm->active_ref_scale[i], 0, sizeof(cm->active_ref_scale[i]));
       continue;
diff --git a/vp9/encoder/vp9_quantize.c b/vp9/encoder/vp9_quantize.c
index 1401bd6..80d9849 100644
--- a/vp9/encoder/vp9_quantize.c
+++ b/vp9/encoder/vp9_quantize.c
@@ -542,14 +542,14 @@
       qrounding_factor = 64;
     }
     // dc values
-    quant_val = vp9_dc_quant(q, cpi->common.y1dc_delta_q);
+    quant_val = vp9_dc_quant(q, cpi->common.y_dc_delta_q);
     invert_quant(cpi->Y1quant[q] + 0, cpi->Y1quant_shift[q] + 0, quant_val);
     cpi->Y1zbin[q][0] = ROUND_POWER_OF_TWO(qzbin_factor * quant_val, 7);
     cpi->Y1round[q][0] = (qrounding_factor * quant_val) >> 7;
     cpi->common.y_dequant[q][0] = quant_val;
     cpi->zrun_zbin_boost_y1[q][0] = (quant_val * zbin_boost[0]) >> 7;
 
-    quant_val = vp9_dc_uv_quant(q, cpi->common.uvdc_delta_q);
+    quant_val = vp9_dc_uv_quant(q, cpi->common.uv_dc_delta_q);
     invert_quant(cpi->UVquant[q] + 0, cpi->UVquant_shift[q] + 0, quant_val);
     cpi->UVzbin[q][0] = ROUND_POWER_OF_TWO(qzbin_factor * quant_val, 7);
     cpi->UVround[q][0] = (qrounding_factor * quant_val) >> 7;
@@ -568,7 +568,7 @@
       cpi->zrun_zbin_boost_y1[q][i] =
           ROUND_POWER_OF_TWO(quant_val * zbin_boost[i], 7);
 
-      quant_val = vp9_ac_uv_quant(q, cpi->common.uvac_delta_q);
+      quant_val = vp9_ac_uv_quant(q, cpi->common.uv_ac_delta_q);
       invert_quant(cpi->UVquant[q] + rc, cpi->UVquant_shift[q] + rc, quant_val);
       cpi->UVzbin[q][rc] = ROUND_POWER_OF_TWO(qzbin_factor * quant_val, 7);
       cpi->UVround[q][rc] = (qrounding_factor * quant_val) >> 7;
@@ -677,9 +677,9 @@
 
   // if any of the delta_q values are changing update flag will
   // have to be set.
-  cm->y1dc_delta_q = 0;
-  cm->uvdc_delta_q = 0;
-  cm->uvac_delta_q = 0;
+  cm->y_dc_delta_q = 0;
+  cm->uv_dc_delta_q = 0;
+  cm->uv_ac_delta_q = 0;
 
   // quantizer has to be reinitialized if any delta_q changes.
   // As there are not any here for now this is inactive code.
diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c
index 2f29b1d..900f889 100644
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -496,7 +496,7 @@
   }
   assert(eob <= seg_eob);
 
-  VP9_COMBINEENTROPYCONTEXTS(pt, a_ec, l_ec);
+  pt = combine_entropy_contexts(a_ec, l_ec);
   nb = vp9_get_coef_neighbors_handle(scan, &pad);
   default_eob = seg_eob;
 
@@ -638,15 +638,6 @@
                                  rd[TX_4X4][1] : rd[TX_8X8][1];
 }
 
-static void copy_predictor(uint8_t *dst, const uint8_t *predictor) {
-  const unsigned int *p = (const unsigned int *)predictor;
-  unsigned int *d = (unsigned int *)dst;
-  d[0] = p[0];
-  d[4] = p[4];
-  d[8] = p[8];
-  d[12] = p[12];
-}
-
 static int vp9_sb_block_error_c(int16_t *coeff, int16_t *dqcoeff,
                                 int block_size, int shift) {
   int i;
@@ -849,13 +840,7 @@
   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;
 
-  // FIXME(rbultje): mb code still predicts into xd->predictor
-  if (bs == BLOCK_SIZE_MB16X16) {
-    vp9_subtract_mby(x->src_diff, src, xd->predictor, src_y_stride);
-  } else {
-    vp9_subtract_sby_s_c(x->src_diff, src, src_y_stride, dst, dst_y_stride,
-                         bs);
-  }
+  vp9_subtract_sby_s_c(x->src_diff, src, src_y_stride, dst, dst_y_stride, bs);
 
   if (bs >= BLOCK_SIZE_SB32X32)
     super_block_yrd_32x32(cm, x, &r[TX_32X32][0], &d[TX_32X32], &s[TX_32X32],
@@ -892,7 +877,6 @@
    * a temp buffer that meets the stride requirements, but we are only
    * interested in the left 4x4 block
    * */
-  DECLARE_ALIGNED_ARRAY(16, uint8_t, best_predictor, 16 * 4);
   DECLARE_ALIGNED_ARRAY(16, int16_t, best_dqcoeff, 16);
 
   assert(ib < 16);
@@ -922,7 +906,7 @@
     rate = bmode_costs[mode];
 #endif
 
-    vp9_intra4x4_predict(xd, b, mode, b->predictor, 16);
+    vp9_intra4x4_predict(xd, b, mode, *(b->base_dst) + b->dst, b->dst_stride);
     vp9_subtract_b(be, b, 16);
 
     b->bmi.as_mode.first = mode;
@@ -956,7 +940,6 @@
       best_tx_type = tx_type;
       *a = tempa;
       *l = templ;
-      copy_predictor(best_predictor, b->predictor);
       vpx_memcpy(best_dqcoeff, BLOCK_OFFSET(xd->plane[0].dqcoeff, ib, 16), 32);
     }
   }
@@ -968,7 +951,10 @@
   else
     xd->inv_txm4x4(best_dqcoeff, b->diff, 32);
 
-  vp9_recon_b(best_predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+  vp9_intra4x4_predict(xd, b, *best_mode,
+                       *(b->base_dst) + b->dst, b->dst_stride);
+  vp9_recon_b(*(b->base_dst) + b->dst, b->diff,
+              *(b->base_dst) + b->dst, b->dst_stride);
 
   return best_rd;
 }
@@ -1063,11 +1049,7 @@
     int64_t local_txfm_cache[NB_TXFM_MODES];
 
     x->e_mbd.mode_info_context->mbmi.mode = mode;
-    if (bsize == BLOCK_SIZE_MB16X16) {
-      vp9_build_intra_predictors_mby(&x->e_mbd);
-    } else {
-      vp9_build_intra_predictors_sby_s(&x->e_mbd, bsize);
-    }
+    vp9_build_intra_predictors_sby_s(&x->e_mbd, bsize);
 
     super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion, &s,
                     bsize, local_txfm_cache);
@@ -1129,7 +1111,7 @@
     rate = mode_costs[mode];
     b->bmi.as_mode.first = mode;
 
-    vp9_intra8x8_predict(xd, b, mode, b->predictor, 16);
+    vp9_intra8x8_predict(xd, b, mode, *(b->base_dst) + b->dst, b->dst_stride);
 
     vp9_subtract_4b_c(be, b, 16);
 
@@ -1543,14 +1525,8 @@
   uint8_t *vsrc = x->src.v_buffer, *vdst = xd->dst.v_buffer;
   int src_uv_stride = x->src.uv_stride, dst_uv_stride = xd->dst.uv_stride;
 
-  // FIXME(rbultje): mb code still predicts into xd->predictor
-  if (bsize == BLOCK_SIZE_MB16X16) {
-    vp9_subtract_mbuv(x->src_diff, usrc, vsrc, xd->predictor,
-                      x->src.uv_stride);
-  } else {
-    vp9_subtract_sbuv_s_c(x->src_diff, usrc, vsrc, src_uv_stride,
-                          udst, vdst, dst_uv_stride, bsize);
-  }
+  vp9_subtract_sbuv_s_c(x->src_diff, usrc, vsrc, src_uv_stride,
+                        udst, vdst, dst_uv_stride, bsize);
 
   if (mbmi->txfm_size >= TX_32X32 && bsize >= BLOCK_SIZE_SB64X64) {
     super_block_uvrd_32x32(cm, x, rate, distortion, skippable, bsize);
@@ -1576,10 +1552,7 @@
 
   for (mode = DC_PRED; mode <= TM_PRED; mode++) {
     x->e_mbd.mode_info_context->mbmi.uv_mode = mode;
-    if (bsize == BLOCK_SIZE_MB16X16)
-      vp9_build_intra_predictors_mbuv(&x->e_mbd);
-    else
-      vp9_build_intra_predictors_sbuv_s(&x->e_mbd, bsize);
+    vp9_build_intra_predictors_sbuv_s(&x->e_mbd, bsize);
 
     super_block_uvrd(&cpi->common, x, &this_rate_tokenonly,
                      &this_distortion, &s, bsize);
@@ -1759,7 +1732,8 @@
 
       vp9_build_inter_predictor(*(bd->base_pre) + bd->pre,
                                 bd->pre_stride,
-                                bd->predictor, 16,
+                                *(bd->base_dst) + bd->dst,
+                                bd->dst_stride,
                                 &bd->bmi.as_mv[0],
                                 &xd->scale_factor[0],
                                 4, 4, 0 /* no avg */, &xd->subpix);
@@ -1769,7 +1743,8 @@
       // weighting for splitmv modes is turned on.
       if (xd->mode_info_context->mbmi.second_ref_frame > 0) {
         vp9_build_inter_predictor(
-            *(bd->base_second_pre) + bd->pre, bd->pre_stride, bd->predictor, 16,
+            *(bd->base_second_pre) + bd->pre, bd->pre_stride,
+            *(bd->base_dst) + bd->dst, bd->dst_stride,
             &bd->bmi.as_mv[1], &xd->scale_factor[1], 4, 4,
             1 << (2 * CONFIG_IMPLICIT_COMPOUNDINTER_WEIGHT) /* avg */,
             &xd->subpix);
@@ -1834,7 +1809,8 @@
         // implicit-compoundinter-weight experiment when implicit
         // weighting for splitmv modes is turned on.
         vp9_build_inter_predictor(
-            *base_pre + bd->pre, bd->pre_stride, bd->predictor, 16,
+            *base_pre + bd->pre, bd->pre_stride,
+            *(bd->base_dst) + bd->dst, bd->dst_stride,
             &bd->bmi.as_mv[which_mv], &xd->scale_factor[which_mv], 8, 8,
             which_mv << (2 * CONFIG_IMPLICIT_COMPOUNDINTER_WEIGHT),
             &xd->subpix);
@@ -3144,23 +3120,20 @@
         unsigned int sse, var;
         int tmp_rate_y, tmp_rate_u, tmp_rate_v;
         int tmp_dist_y, tmp_dist_u, tmp_dist_v;
-        vp9_build_inter16x16_predictors_mb(xd, xd->predictor,
-                                           xd->predictor + 256,
-                                           xd->predictor + 320,
-                                           16, 8, mb_row, mb_col);
+        vp9_build_inter_predictors_sb(xd, mb_row, mb_col, BLOCK_SIZE_MB16X16);
         var = vp9_variance16x16(*(b->base_src), b->src_stride,
-                                xd->predictor, 16, &sse);
+                                xd->dst.y_buffer, xd->dst.y_stride, &sse);
         // Note our transform coeffs are 8 times an orthogonal transform.
         // Hence quantizer step is also 8 times. To get effective quantizer
         // we need to divide by 8 before sending to modeling function.
         model_rd_from_var_lapndz(var, 16 * 16, xd->block[0].dequant[1] >> 3,
                                  &tmp_rate_y, &tmp_dist_y);
         var = vp9_variance8x8(x->src.u_buffer, x->src.uv_stride,
-                              &xd->predictor[256], 8, &sse);
+                              xd->dst.u_buffer, xd->dst.uv_stride, &sse);
         model_rd_from_var_lapndz(var, 8 * 8, xd->block[16].dequant[1] >> 3,
                                  &tmp_rate_u, &tmp_dist_u);
         var = vp9_variance8x8(x->src.v_buffer, x->src.uv_stride,
-                              &xd->predictor[320], 8, &sse);
+                              xd->dst.v_buffer, xd->dst.uv_stride, &sse);
         model_rd_from_var_lapndz(var, 8 * 8, xd->block[20].dequant[1] >> 3,
                                  &tmp_rate_v, &tmp_dist_v);
         rd = RDCOST(x->rdmult, x->rddiv,
@@ -3184,9 +3157,19 @@
       if ((cm->mcomp_filter_type == SWITCHABLE && newbest) ||
           (cm->mcomp_filter_type != SWITCHABLE &&
            cm->mcomp_filter_type == mbmi->interp_filter)) {
-        vpx_memcpy(tmp_ybuf, xd->predictor, sizeof(unsigned char) * 256);
-        vpx_memcpy(tmp_ubuf, xd->predictor + 256, sizeof(unsigned char) * 64);
-        vpx_memcpy(tmp_vbuf, xd->predictor + 320, sizeof(unsigned char) * 64);
+        int i;
+        for (i = 0; i < 16 * bh; ++i)
+          vpx_memcpy(tmp_ybuf + i * 16 * bw,
+                     xd->dst.y_buffer + i * xd->dst.y_stride,
+                     sizeof(unsigned char) * 16 * bw);
+        for (i = 0; i < 8 * bh; ++i)
+          vpx_memcpy(tmp_ubuf + i * 8 * bw,
+                     xd->dst.u_buffer + i * xd->dst.uv_stride,
+                     sizeof(unsigned char) * 8 * bw);
+        for (i = 0; i < 8 * bh; ++i)
+          vpx_memcpy(tmp_vbuf + i * 8 * bw,
+                     xd->dst.v_buffer + i * xd->dst.uv_stride,
+                     sizeof(unsigned char) * 8 * bw);
         pred_exists = 1;
       }
       interpolating_intpel_seen |=
@@ -3203,32 +3186,19 @@
 
   if (pred_exists) {
     // FIXME(rbultje): mb code still predicts into xd->predictor
-    if (bsize != BLOCK_SIZE_MB16X16) {
-      for (i = 0; i < bh * 16; ++i)
-        vpx_memcpy(xd->dst.y_buffer + i * xd->dst.y_stride,
-                   tmp_ybuf + i * bw * 16, sizeof(unsigned char) * bw * 16);
-      for (i = 0; i < bh * 8; ++i)
-        vpx_memcpy(xd->dst.u_buffer + i * xd->dst.uv_stride,
-                   tmp_ubuf + i * bw * 8, sizeof(unsigned char) * bw * 8);
-      for (i = 0; i < bh * 8; ++i)
-        vpx_memcpy(xd->dst.v_buffer + i * xd->dst.uv_stride,
-                   tmp_vbuf + i * bw * 8, sizeof(unsigned char) * bw * 8);
-    } else {
-      vpx_memcpy(xd->predictor, tmp_ybuf, sizeof(unsigned char) * 256);
-      vpx_memcpy(xd->predictor + 256, tmp_ubuf, sizeof(unsigned char) * 64);
-      vpx_memcpy(xd->predictor + 320, tmp_vbuf, sizeof(unsigned char) * 64);
-    }
+    for (i = 0; i < bh * 16; ++i)
+      vpx_memcpy(xd->dst.y_buffer + i * xd->dst.y_stride,
+                 tmp_ybuf + i * bw * 16, sizeof(unsigned char) * bw * 16);
+    for (i = 0; i < bh * 8; ++i)
+      vpx_memcpy(xd->dst.u_buffer + i * xd->dst.uv_stride,
+                 tmp_ubuf + i * bw * 8, sizeof(unsigned char) * bw * 8);
+    for (i = 0; i < bh * 8; ++i)
+      vpx_memcpy(xd->dst.v_buffer + i * xd->dst.uv_stride,
+                 tmp_vbuf + i * bw * 8, sizeof(unsigned char) * bw * 8);
   } else {
     // Handles the special case when a filter that is not in the
     // switchable list (ex. bilinear, 6-tap) is indicated at the frame level
-    if (bsize > BLOCK_SIZE_MB16X16) {
-      vp9_build_inter_predictors_sb(xd, mb_row, mb_col, bsize);
-    } else {
-      vp9_build_inter16x16_predictors_mb(xd, xd->predictor,
-                                         xd->predictor + 256,
-                                         xd->predictor + 320,
-                                         16, 8, mb_row, mb_col);
-    }
+    vp9_build_inter_predictors_sb(xd, mb_row, mb_col, bsize);
   }
 
   if (cpi->common.mcomp_filter_type == SWITCHABLE) {
@@ -3253,7 +3223,7 @@
                                        &sse);
     } else {
       var = vp9_variance16x16(*(b->base_src), b->src_stride,
-                              xd->predictor, 16, &sse);
+                              xd->dst.y_buffer, xd->dst.y_stride, &sse);
     }
 
     if ((int)sse < threshold) {
@@ -3278,9 +3248,9 @@
         } else {
           unsigned int sse2u, sse2v;
           var = vp9_variance8x8(x->src.u_buffer, x->src.uv_stride,
-                                xd->predictor + 256, 8, &sse2u);
+                                xd->dst.u_buffer, xd->dst.uv_stride, &sse2u);
           var = vp9_variance8x8(x->src.v_buffer, x->src.uv_stride,
-                                xd->predictor + 320, 8, &sse2v);
+                                xd->dst.v_buffer, xd->dst.uv_stride, &sse2v);
           sse2 = sse2u + sse2v;
         }
 
@@ -3388,7 +3358,7 @@
   int_mv seg_mvs[NB_PARTITIONINGS][16 /* n_blocks */][MAX_REF_FRAMES - 1];
 
   int intra_cost_penalty = 20 * vp9_dc_quant(cpi->common.base_qindex,
-                                             cpi->common.y1dc_delta_q);
+                                             cpi->common.y_dc_delta_q);
 
   struct scale_factors scale_factor[4];
 
@@ -3614,7 +3584,8 @@
         case TM_PRED:
           mbmi->ref_frame = INTRA_FRAME;
           // FIXME compound intra prediction
-          vp9_build_intra_predictors_mby(&x->e_mbd);
+          vp9_build_intra_predictors_sby_s(&x->e_mbd, BLOCK_SIZE_MB16X16);
+          // vp9_build_intra_predictors_mby(&x->e_mbd);
           super_block_yrd(cpi, x, &rate_y, &distortion, &skippable,
                           BLOCK_SIZE_MB16X16, txfm_cache);
           rate2 += rate_y;
@@ -3790,8 +3761,14 @@
         int uv_skippable;
 
         vp9_build_inter4x4_predictors_mbuv(&x->e_mbd, mb_row, mb_col);
-        vp9_subtract_mbuv(x->src_diff, x->src.u_buffer, x->src.v_buffer,
-                          x->e_mbd.predictor, x->src.uv_stride);
+
+        vp9_subtract_sbuv_s_c(x->src_diff,
+                              x->src.u_buffer,
+                              x->src.v_buffer, x->src.uv_stride,
+                              xd->dst.u_buffer,
+                              xd->dst.v_buffer, xd->dst.uv_stride,
+                              BLOCK_SIZE_MB16X16);
+
         super_block_uvrd_4x4(cm, x, &rate_uv, &distortion_uv,
                              &uv_skippable, BLOCK_SIZE_MB16X16);
         rate2 += rate_uv;
diff --git a/vp9/encoder/vp9_temporal_filter.c b/vp9/encoder/vp9_temporal_filter.c
index cf84fa1..6149518 100644
--- a/vp9/encoder/vp9_temporal_filter.c
+++ b/vp9/encoder/vp9_temporal_filter.c
@@ -41,18 +41,14 @@
                                             int mv_col,
                                             uint8_t *pred) {
   const int which_mv = 0;
-  int_mv subpel_mv;
-  int_mv fullpel_mv;
+  int_mv mv;
 
-  subpel_mv.as_mv.row = mv_row;
-  subpel_mv.as_mv.col = mv_col;
-  // TODO(jkoleszar): Make this rounding consistent with the rest of the code
-  fullpel_mv.as_mv.row = (mv_row >> 1) & ~7;
-  fullpel_mv.as_mv.col = (mv_col >> 1) & ~7;
+  mv.as_mv.row = mv_row;
+  mv.as_mv.col = mv_col;
 
   vp9_build_inter_predictor(y_mb_ptr, stride,
                             &pred[0], 16,
-                            &subpel_mv,
+                            &mv,
                             &xd->scale_factor[which_mv],
                             16, 16,
                             which_mv <<
@@ -63,7 +59,7 @@
 
   vp9_build_inter_predictor_q4(u_mb_ptr, stride,
                                &pred[256], 8,
-                               &fullpel_mv, &subpel_mv,
+                               &mv,
                                &xd->scale_factor_uv[which_mv],
                                8, 8,
                                which_mv <<
@@ -72,7 +68,7 @@
 
   vp9_build_inter_predictor_q4(v_mb_ptr, stride,
                                &pred[320], 8,
-                               &fullpel_mv, &subpel_mv,
+                               &mv,
                                &xd->scale_factor_uv[which_mv],
                                8, 8,
                                which_mv <<
diff --git a/vp9/encoder/vp9_tokenize.c b/vp9/encoder/vp9_tokenize.c
index e38add6..b68ef5d 100644
--- a/vp9/encoder/vp9_tokenize.c
+++ b/vp9/encoder/vp9_tokenize.c
@@ -287,7 +287,7 @@
       break;
   }
 
-  VP9_COMBINEENTROPYCONTEXTS(pt, a_ec, l_ec);
+  pt = combine_entropy_contexts(a_ec, l_ec);
   nb = vp9_get_coef_neighbors_handle(scan, &pad);
   default_eob = seg_eob;
 
@@ -807,7 +807,7 @@
 #if CONFIG_CODE_NONZEROCOUNT
   if (!nzc_used) {
 #endif
-    VP9_COMBINEENTROPYCONTEXTS(pt, a_ec, l_ec);
+    pt = combine_entropy_contexts(a_ec, l_ec);
     band = 0;
     t->Token = DCT_EOB_TOKEN;
     t->context_tree = probs[type][ref][band][pt];
diff --git a/vp9/encoder/x86/vp9_x86_csystemdependent.c b/vp9/encoder/x86/vp9_x86_csystemdependent.c
index 310f0d9..04383fc 100644
--- a/vp9/encoder/x86/vp9_x86_csystemdependent.c
+++ b/vp9/encoder/x86/vp9_x86_csystemdependent.c
@@ -30,7 +30,9 @@
   unsigned char *z = *(be->base_src) + be->src;
   unsigned int  src_stride = be->src_stride;
   short *diff = &be->src_diff[0];
-  unsigned char *predictor = &bd->predictor[0];
+  unsigned char *predictor = *(bd->base_dst) + bd->dst;
+  // TODO(jingning): The prototype function in c has been changed. Need to
+  // modify the mmx and sse versions.
   vp9_subtract_b_mmx_impl(z, src_stride, diff, predictor, pitch);
 }
 
@@ -44,7 +46,9 @@
   unsigned char *z = *(be->base_src) + be->src;
   unsigned int  src_stride = be->src_stride;
   short *diff = &be->src_diff[0];
-  unsigned char *predictor = &bd->predictor[0];
+  unsigned char *predictor = *(bd->base_dst) + bd->dst;
+  // TODO(jingning): The prototype function in c has been changed. Need to
+  // modify the mmx and sse versions.
   vp9_subtract_b_sse2_impl(z, src_stride, diff, predictor, pitch);
 }