Merge "valgrind - txfm_thresh not set" into experimental
diff --git a/configure b/configure
index f22a2dd..4a97889 100755
--- a/configure
+++ b/configure
@@ -244,6 +244,7 @@
     multiple_arf
     non420
     alpha
+    balanced_coeftree
 "
 CONFIG_LIST="
     external_build
diff --git a/test/sad_test.cc b/test/sad_test.cc
index 165e2c8..9555a9a 100644
--- a/test/sad_test.cc
+++ b/test/sad_test.cc
@@ -36,12 +36,15 @@
                                         const unsigned char *reference_ptr,
                                         int reference_stride,
                                         unsigned int max_sad);
+typedef std::tr1::tuple<int, int, sad_m_by_n_fn_t> sad_m_by_n_test_param_t;
 
 typedef void (*sad_n_by_n_by_4_fn_t)(const uint8_t *src_ptr,
                                      int src_stride,
                                      const unsigned char * const ref_ptr[],
                                      int ref_stride,
                                      unsigned int *sad_array);
+typedef std::tr1::tuple<int, int, sad_n_by_n_by_4_fn_t>
+        sad_n_by_n_by_4_test_param_t;
 
 using libvpx_test::ACMRandom;
 
@@ -124,8 +127,7 @@
 };
 
 class SADTest : public SADTestBase,
-    public ::testing::WithParamInterface<
-        std::tr1::tuple<int, int, sad_m_by_n_fn_t> > {
+    public ::testing::WithParamInterface<sad_m_by_n_test_param_t> {
  public:
   SADTest() : SADTestBase(GET_PARAM(0), GET_PARAM(1)) {}
 
@@ -156,8 +158,7 @@
 };
 
 class SADx4Test : public SADTestBase,
-    public ::testing::WithParamInterface<
-        std::tr1::tuple<int, int, sad_n_by_n_by_4_fn_t> > {
+    public ::testing::WithParamInterface<sad_n_by_n_by_4_test_param_t> {
  public:
   SADx4Test() : SADTestBase(GET_PARAM(0), GET_PARAM(1)) {}
 
@@ -293,12 +294,6 @@
 
 using std::tr1::make_tuple;
 
-#if CONFIG_VP8_ENCODER && CONFIG_VP9_ENCODER
-#define VP8_VP9_SEPARATOR ,
-#else
-#define VP8_VP9_SEPARATOR
-#endif
-
 #if CONFIG_VP8_ENCODER
 const sad_m_by_n_fn_t sad_16x16_c = vp8_sad16x16_c;
 const sad_m_by_n_fn_t sad_8x16_c = vp8_sad8x16_c;
@@ -315,25 +310,25 @@
 const sad_m_by_n_fn_t sad_8x8_c_vp9 = vp9_sad8x8_c;
 const sad_m_by_n_fn_t sad_4x4_c_vp9 = vp9_sad4x4_c;
 #endif
-INSTANTIATE_TEST_CASE_P(C, SADTest, ::testing::Values(
+const sad_m_by_n_test_param_t c_tests[] = {
 #if CONFIG_VP8_ENCODER
-                        make_tuple(16, 16, sad_16x16_c),
-                        make_tuple(8, 16, sad_8x16_c),
-                        make_tuple(16, 8, sad_16x8_c),
-                        make_tuple(8, 8, sad_8x8_c),
-                        make_tuple(4, 4, sad_4x4_c)
+  make_tuple(16, 16, sad_16x16_c),
+  make_tuple(8, 16, sad_8x16_c),
+  make_tuple(16, 8, sad_16x8_c),
+  make_tuple(8, 8, sad_8x8_c),
+  make_tuple(4, 4, sad_4x4_c),
 #endif
-                        VP8_VP9_SEPARATOR
 #if CONFIG_VP9_ENCODER
-                        make_tuple(64, 64, sad_64x64_c_vp9),
-                        make_tuple(32, 32, sad_32x32_c_vp9),
-                        make_tuple(16, 16, sad_16x16_c_vp9),
-                        make_tuple(8, 16, sad_8x16_c_vp9),
-                        make_tuple(16, 8, sad_16x8_c_vp9),
-                        make_tuple(8, 8, sad_8x8_c_vp9),
-                        make_tuple(4, 4, sad_4x4_c_vp9)
+  make_tuple(64, 64, sad_64x64_c_vp9),
+  make_tuple(32, 32, sad_32x32_c_vp9),
+  make_tuple(16, 16, sad_16x16_c_vp9),
+  make_tuple(8, 16, sad_8x16_c_vp9),
+  make_tuple(16, 8, sad_16x8_c_vp9),
+  make_tuple(8, 8, sad_8x8_c_vp9),
+  make_tuple(4, 4, sad_4x4_c_vp9),
 #endif
-                        ));
+};
+INSTANTIATE_TEST_CASE_P(C, SADTest, ::testing::ValuesIn(c_tests));
 
 #if CONFIG_VP9_ENCODER
 const sad_n_by_n_by_4_fn_t sad_64x64x4d_c = vp9_sad64x64x4d_c;
@@ -387,23 +382,23 @@
 const sad_m_by_n_fn_t sad_4x4_mmx_vp9 = vp9_sad4x4_mmx;
 #endif
 
-INSTANTIATE_TEST_CASE_P(MMX, SADTest, ::testing::Values(
+const sad_m_by_n_test_param_t mmx_tests[] = {
 #if CONFIG_VP8_ENCODER
-                        make_tuple(16, 16, sad_16x16_mmx),
-                        make_tuple(8, 16, sad_8x16_mmx),
-                        make_tuple(16, 8, sad_16x8_mmx),
-                        make_tuple(8, 8, sad_8x8_mmx),
-                        make_tuple(4, 4, sad_4x4_mmx)
+  make_tuple(16, 16, sad_16x16_mmx),
+  make_tuple(8, 16, sad_8x16_mmx),
+  make_tuple(16, 8, sad_16x8_mmx),
+  make_tuple(8, 8, sad_8x8_mmx),
+  make_tuple(4, 4, sad_4x4_mmx),
 #endif
-                        VP8_VP9_SEPARATOR
 #if CONFIG_VP9_ENCODER
-                        make_tuple(16, 16, sad_16x16_mmx_vp9),
-                        make_tuple(8, 16, sad_8x16_mmx_vp9),
-                        make_tuple(16, 8, sad_16x8_mmx_vp9),
-                        make_tuple(8, 8, sad_8x8_mmx_vp9),
-                        make_tuple(4, 4, sad_4x4_mmx_vp9)
+  make_tuple(16, 16, sad_16x16_mmx_vp9),
+  make_tuple(8, 16, sad_8x16_mmx_vp9),
+  make_tuple(16, 8, sad_16x8_mmx_vp9),
+  make_tuple(8, 8, sad_8x8_mmx_vp9),
+  make_tuple(4, 4, sad_4x4_mmx_vp9),
 #endif
-                        ));
+};
+INSTANTIATE_TEST_CASE_P(MMX, SADTest, ::testing::ValuesIn(mmx_tests));
 #endif
 
 #if HAVE_SSE
@@ -434,24 +429,24 @@
 const sad_m_by_n_fn_t sad_16x8_sse2_vp9 = vp9_sad16x8_sse2;
 const sad_m_by_n_fn_t sad_8x8_sse2_vp9 = vp9_sad8x8_sse2;
 #endif
-INSTANTIATE_TEST_CASE_P(SSE2, SADTest, ::testing::Values(
+const sad_m_by_n_test_param_t sse2_tests[] = {
 #if CONFIG_VP8_ENCODER
-                        make_tuple(16, 16, sad_16x16_wmt),
-                        make_tuple(8, 16, sad_8x16_wmt),
-                        make_tuple(16, 8, sad_16x8_wmt),
-                        make_tuple(8, 8, sad_8x8_wmt),
-                        make_tuple(4, 4, sad_4x4_wmt)
+  make_tuple(16, 16, sad_16x16_wmt),
+  make_tuple(8, 16, sad_8x16_wmt),
+  make_tuple(16, 8, sad_16x8_wmt),
+  make_tuple(8, 8, sad_8x8_wmt),
+  make_tuple(4, 4, sad_4x4_wmt),
 #endif
-                        VP8_VP9_SEPARATOR
 #if CONFIG_VP9_ENCODER
-                        make_tuple(64, 64, sad_64x64_sse2_vp9),
-                        make_tuple(32, 32, sad_32x32_sse2_vp9),
-                        make_tuple(16, 16, sad_16x16_sse2_vp9),
-                        make_tuple(8, 16, sad_8x16_sse2_vp9),
-                        make_tuple(16, 8, sad_16x8_sse2_vp9),
-                        make_tuple(8, 8, sad_8x8_sse2_vp9)
+  make_tuple(64, 64, sad_64x64_sse2_vp9),
+  make_tuple(32, 32, sad_32x32_sse2_vp9),
+  make_tuple(16, 16, sad_16x16_sse2_vp9),
+  make_tuple(8, 16, sad_8x16_sse2_vp9),
+  make_tuple(16, 8, sad_16x8_sse2_vp9),
+  make_tuple(8, 8, sad_8x8_sse2_vp9),
 #endif
-                        ));
+};
+INSTANTIATE_TEST_CASE_P(SSE2, SADTest, ::testing::ValuesIn(sse2_tests));
 
 #if CONFIG_VP9_ENCODER
 const sad_n_by_n_by_4_fn_t sad_64x64x4d_sse2 = vp9_sad64x64x4d_sse2;
diff --git a/vp9/common/vp9_common.h b/vp9/common/vp9_common.h
index b6252d9..5c97f98 100644
--- a/vp9/common/vp9_common.h
+++ b/vp9/common/vp9_common.h
@@ -60,4 +60,9 @@
   return (value + 15) & ~15;
 }
 
+#define SYNC_CODE_0 0x49
+#define SYNC_CODE_1 0x83
+#define SYNC_CODE_2 0x42
+
+
 #endif  // VP9_COMMON_VP9_COMMON_H_
diff --git a/vp9/common/vp9_debugmodes.c b/vp9/common/vp9_debugmodes.c
deleted file mode 100644
index 827e4bf..0000000
--- a/vp9/common/vp9_debugmodes.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#include <stdio.h>
-#include "vp9/common/vp9_onyxc_int.h"
-#include "vp9/common/vp9_blockd.h"
-#include "vp9/common/vp9_tile_common.h"
-typedef struct {
-  char *debug_array;
-  int w;
-  int h;
-} DEBUG_MODE_STRUCT;
-
-static void draw_rect(int r, int c, int w, int h, DEBUG_MODE_STRUCT *da) {
-  int i;
-  da->debug_array[r / 2 * da->w + c] = '+';
-  for (i = r / 2 + 1; i < r / 2 + h / 2; i++) {
-    da->debug_array[i * da->w + c] = '|';
-  }
-  for (i = c + 1; i < c + w; i++) {
-    da->debug_array[r / 2 * da->w + i] = '-';
-  }
-}
-static void debug_partitioning(VP9_COMMON * cm, MODE_INFO *m, int mi_row,
-                               int mi_col, BLOCK_SIZE_TYPE bsize,
-                               DEBUG_MODE_STRUCT *da) {
-  const int mis = cm->mode_info_stride;
-  int bwl, bhl;
-  int bw, bh;
-  int bsl = mi_width_log2(bsize), bs = (1 << bsl) / 2;
-  int n;
-  PARTITION_TYPE partition;
-  BLOCK_SIZE_TYPE subsize;
-
-  if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
-    return;
-
-  bwl = mi_width_log2(m->mbmi.sb_type);
-  bhl = mi_height_log2(m->mbmi.sb_type);
-  bw = 1 << bwl;
-  bh = 1 << bhl;
-
-  // parse the partition type
-  if ((bwl == bsl) && (bhl == bsl))
-    partition = PARTITION_NONE;
-  else if ((bwl == bsl) && (bhl < bsl))
-    partition = PARTITION_HORZ;
-  else if ((bwl < bsl) && (bhl == bsl))
-    partition = PARTITION_VERT;
-  else if ((bwl < bsl) && (bhl < bsl))
-    partition = PARTITION_SPLIT;
-  else
-    assert(0);
-
-#if CONFIG_AB4X4
-  if (bsize == BLOCK_SIZE_SB8X8 && m->mbmi.sb_type < BLOCK_SIZE_SB8X8)
-  partition = PARTITION_SPLIT;
-  if (bsize < BLOCK_SIZE_SB8X8)
-  return;
-#endif
-
-#if CONFIG_AB4X4
-  if (bsize >= BLOCK_SIZE_SB8X8) {
-#else
-  if (bsize > BLOCK_SIZE_SB8X8) {
-#endif
-  }
-
-  subsize = get_subsize(bsize, partition);
-  switch (partition) {
-    case PARTITION_NONE:
-      draw_rect(mi_row * 8, mi_col * 8, bw * 8, bh * 8, da);
-      break;
-    case PARTITION_HORZ:
-      draw_rect(mi_row * 8, mi_col * 8, bw * 8, bh * 8, da);
-      if ((mi_row + bh) < cm->mi_rows)
-        draw_rect(8 * bs + mi_row * 8, mi_col * 8, bw * 8, bh * 8, da);
-      break;
-    case PARTITION_VERT:
-      draw_rect(mi_row * 8, mi_col * 8, bw * 8, bh * 8, da);
-      if ((mi_col + bw) < cm->mi_cols)
-        draw_rect(mi_row * 8, 8 * bs + mi_col * 8, bw * 8, bh * 8, da);
-      break;
-    case PARTITION_SPLIT:
-      for (n = 0; n < 4; n++) {
-        int j = n >> 1, i = n & 0x01;
-        debug_partitioning(cm, m + j * bs * mis + i * bs, mi_row + j * bs,
-                           mi_col + i * bs, subsize, da);
-      }
-      break;
-    default:
-      assert(0);
-  }
-}
-static void debug_partitionings(VP9_COMMON *c, DEBUG_MODE_STRUCT *da) {
-  const int mis = c->mode_info_stride;
-  MODE_INFO *m, *m_ptr = c->mi;
-  int mi_row, mi_col;
-
-  m_ptr += c->cur_tile_mi_col_start + c->cur_tile_mi_row_start * mis;
-
-  for (mi_row = c->cur_tile_mi_row_start; mi_row < c->cur_tile_mi_row_end;
-      mi_row += 8, m_ptr += 8 * mis) {
-    m = m_ptr;
-    for (mi_col = c->cur_tile_mi_col_start; mi_col < c->cur_tile_mi_col_end;
-        mi_col += 8, m += 8) {
-      debug_partitioning(c, m, mi_row, mi_col, BLOCK_SIZE_SB64X64, da);
-    }
-  }
-}
-void vp9_debug_tile_partitionings(VP9_COMMON *pc) {
-  int tile_row, tile_col;
-  DEBUG_MODE_STRUCT da;
-
-  da.w = pc->width;
-  da.h = pc->height / 2;
-  da.debug_array = vpx_malloc(da.h * da.w);
-  vpx_memset(da.debug_array, ' ', da.h * da.w);
-  for (tile_row = 0; tile_row < pc->tile_rows; tile_row++) {
-    vp9_get_tile_row_offsets(pc, tile_row);
-    for (tile_col = 0; tile_col < pc->tile_columns; tile_col++) {
-      vp9_get_tile_col_offsets(pc, tile_col);
-
-      debug_partitionings(pc, &da);
-    }
-  }
-  {
-    FILE *f = fopen("partitionings.txt", "a");
-    int i, j;
-    fprintf(f, "\n\n\nFrame: %d \n", pc->current_video_frame);
-    for (i = 0; i < da.h; i++) {
-      for (j = 0; j < da.w; j++) {
-        fprintf(f, "%c", da.debug_array[i * da.w + j]);
-      }
-      fprintf(f, "\n");
-    }
-    fclose(f);
-  }
-  vpx_free(da.debug_array);
-}
diff --git a/vp9/common/vp9_default_coef_probs.h b/vp9/common/vp9_default_coef_probs.h
index 3e82119..15f9e97 100644
--- a/vp9/common/vp9_default_coef_probs.h
+++ b/vp9/common/vp9_default_coef_probs.h
@@ -11,6 +11,692 @@
 
 /*Generated file, included by vp9_entropy.c*/
 
+#if CONFIG_BALANCED_COEFTREE
+static const vp9_coeff_probs_model default_coef_probs_4x4[BLOCK_TYPES] = {
+  { /* block Type 0 */
+    { /* Intra */
+      { /* Coeff Band 0 */
+        {   6, 213, 178 },
+        {  26, 113, 132 },
+        {  34,  17,  68 }
+      }, { /* Coeff Band 1 */
+        {  66,  96, 178 },
+        {  63,  96, 174 },
+        {  67,  54, 154 },
+        {  62,  28, 126 },
+        {  48,   9,  84 },
+        {  20,   1,  32 }
+      }, { /* Coeff Band 2 */
+        {  64, 144, 206 },
+        {  70,  99, 191 },
+        {  69,  36, 152 },
+        {  55,   9, 106 },
+        {  35,   1,  60 },
+        {  14,   1,  22 }
+      }, { /* Coeff Band 3 */
+        {  82, 154, 222 },
+        {  83, 112, 205 },
+        {  81,  31, 164 },
+        {  62,   7, 118 },
+        {  42,   1,  74 },
+        {  18,   1,  30 }
+      }, { /* Coeff Band 4 */
+        {  52, 179, 233 },
+        {  64, 132, 214 },
+        {  73,  36, 170 },
+        {  59,   8, 116 },
+        {  38,   1,  65 },
+        {  15,   1,  26 }
+      }, { /* Coeff Band 5 */
+        {  29, 175, 238 },
+        {  26, 169, 223 },
+        {  41,  80, 182 },
+        {  39,  32, 127 },
+        {  26,  10,  69 },
+        {  11,   2,  28 }
+      }
+    }, { /* Inter */
+      { /* Coeff Band 0 */
+        {  21, 226, 234 },
+        {  52, 182, 212 },
+        {  80, 112, 177 }
+      }, { /* Coeff Band 1 */
+        { 111, 164, 243 },
+        {  88, 152, 231 },
+        {  90,  43, 186 },
+        {  70,  12, 132 },
+        {  44,   2,  76 },
+        {  19,   1,  33 }
+      }, { /* Coeff Band 2 */
+        {  96, 185, 246 },
+        {  99, 127, 231 },
+        {  88,  21, 177 },
+        {  64,   5, 122 },
+        {  38,   1,  69 },
+        {  18,   1,  30 }
+      }, { /* Coeff Band 3 */
+        {  84, 206, 249 },
+        {  94, 147, 237 },
+        {  95,  33, 187 },
+        {  71,   8, 131 },
+        {  47,   1,  83 },
+        {  26,   1,  44 }
+      }, { /* Coeff Band 4 */
+        {  38, 221, 252 },
+        {  58, 177, 241 },
+        {  78,  46, 188 },
+        {  59,   9, 122 },
+        {  34,   1,  66 },
+        {  18,   1,  34 }
+      }, { /* Coeff Band 5 */
+        {  21, 216, 253 },
+        {  21, 206, 244 },
+        {  42,  93, 200 },
+        {  43,  41, 146 },
+        {  36,  13,  93 },
+        {  31,   1,  55 }
+      }
+    }
+  }, { /* block Type 1 */
+    { /* Intra */
+      { /* Coeff Band 0 */
+        {   7, 213, 219 },
+        {  23, 139, 182 },
+        {  38,  60, 125 }
+      }, { /* Coeff Band 1 */
+        {  69, 156, 220 },
+        {  52, 178, 213 },
+        {  69, 111, 190 },
+        {  69,  58, 155 },
+        {  58,  21, 104 },
+        {  39,   7,  60 }
+      }, { /* Coeff Band 2 */
+        {  68, 189, 228 },
+        {  70, 158, 221 },
+        {  83,  64, 189 },
+        {  73,  18, 141 },
+        {  48,   4,  88 },
+        {  23,   1,  41 }
+      }, { /* Coeff Band 3 */
+        {  99, 194, 236 },
+        {  91, 138, 224 },
+        {  91,  53, 189 },
+        {  74,  20, 142 },
+        {  48,   6,  90 },
+        {  22,   1,  41 }
+      }, { /* Coeff Band 4 */
+        {  52, 203, 244 },
+        {  60, 168, 231 },
+        {  75,  62, 189 },
+        {  61,  18, 132 },
+        {  38,   4,  72 },
+        {  17,   1,  39 }
+      }, { /* Coeff Band 5 */
+        {  33, 192, 247 },
+        {  31, 185, 234 },
+        {  46,  85, 185 },
+        {  39,  35, 132 },
+        {  28,  15,  80 },
+        {  13,   5,  38 }
+      }
+    }, { /* Inter */
+      { /* Coeff Band 0 */
+        {   5, 247, 246 },
+        {  28, 209, 228 },
+        {  65, 137, 203 }
+      }, { /* Coeff Band 1 */
+        {  69, 208, 250 },
+        {  54, 207, 242 },
+        {  81,  92, 204 },
+        {  70,  54, 153 },
+        {  58,  40, 108 },
+        {  58,  35,  71 }
+      }, { /* Coeff Band 2 */
+        {  65, 215, 250 },
+        {  72, 185, 239 },
+        {  92,  50, 197 },
+        {  75,  14, 147 },
+        {  49,   2,  99 },
+        {  26,   1,  53 }
+      }, { /* Coeff Band 3 */
+        {  70, 220, 251 },
+        {  76, 186, 241 },
+        {  90,  65, 198 },
+        {  75,  26, 151 },
+        {  58,  12, 112 },
+        {  34,   6,  49 }
+      }, { /* Coeff Band 4 */
+        {  34, 224, 253 },
+        {  44, 204, 245 },
+        {  69,  85, 204 },
+        {  64,  31, 150 },
+        {  44,   2,  78 },
+        {   1,   1, 128 }
+      }, { /* Coeff Band 5 */
+        {  25, 216, 253 },
+        {  21, 215, 248 },
+        {  47, 108, 214 },
+        {  47,  48, 160 },
+        {  26,  20,  90 },
+        {  64, 171, 128 }
+      }
+    }
+  }
+};
+static const vp9_coeff_probs_model default_coef_probs_8x8[BLOCK_TYPES] = {
+  { /* block Type 0 */
+    { /* Intra */
+      { /* Coeff Band 0 */
+        {   9, 203, 199 },
+        {  26,  92, 128 },
+        {  28,  11,  55 }
+      }, { /* Coeff Band 1 */
+        {  99,  54, 160 },
+        {  78,  99, 155 },
+        {  80,  44, 138 },
+        {  71,  17, 115 },
+        {  51,   5,  80 },
+        {  27,   1,  40 }
+      }, { /* Coeff Band 2 */
+        { 135,  81, 190 },
+        { 113,  61, 182 },
+        {  93,  16, 153 },
+        {  70,   4, 115 },
+        {  41,   1,  68 },
+        {  16,   1,  27 }
+      }, { /* Coeff Band 3 */
+        { 155, 103, 214 },
+        { 129,  48, 199 },
+        {  95,  10, 159 },
+        {  63,   1, 110 },
+        {  32,   1,  58 },
+        {  12,   1,  21 }
+      }, { /* Coeff Band 4 */
+        { 163, 149, 231 },
+        { 137,  69, 213 },
+        {  95,  11, 164 },
+        {  62,   3, 108 },
+        {  32,   1,  57 },
+        {  13,   1,  22 }
+      }, { /* Coeff Band 5 */
+        { 136, 189, 239 },
+        { 123, 102, 223 },
+        {  97,  19, 170 },
+        {  66,   4, 111 },
+        {  38,   1,  60 },
+        {  18,   1,  26 }
+      }
+    }, { /* Inter */
+      { /* Coeff Band 0 */
+        {  24, 226, 244 },
+        {  54, 178, 211 },
+        {  80,  74, 152 }
+      }, { /* Coeff Band 1 */
+        { 145, 153, 236 },
+        { 101, 163, 223 },
+        { 108,  50, 187 },
+        {  90,  22, 145 },
+        {  66,   8,  97 },
+        {  42,   4,  50 }
+      }, { /* Coeff Band 2 */
+        { 150, 159, 238 },
+        { 128,  90, 218 },
+        {  94,   9, 163 },
+        {  64,   3, 110 },
+        {  34,   1,  61 },
+        {  13,   1,  24 }
+      }, { /* Coeff Band 3 */
+        { 151, 162, 242 },
+        { 135,  80, 222 },
+        {  93,   9, 166 },
+        {  61,   3, 111 },
+        {  31,   1,  59 },
+        {  12,   1,  22 }
+      }, { /* Coeff Band 4 */
+        { 161, 170, 245 },
+        { 140,  84, 228 },
+        {  99,   8, 174 },
+        {  64,   1, 116 },
+        {  34,   1,  63 },
+        {  14,   1,  26 }
+      }, { /* Coeff Band 5 */
+        { 138, 197, 246 },
+        { 127, 109, 233 },
+        { 100,  16, 179 },
+        {  66,   3, 119 },
+        {  37,   1,  66 },
+        {  16,   1,  30 }
+      }
+    }
+  }, { /* block Type 1 */
+    { /* Intra */
+      { /* Coeff Band 0 */
+        {   6, 216, 212 },
+        {  25, 134, 171 },
+        {  43,  48, 118 }
+      }, { /* Coeff Band 1 */
+        {  93, 112, 209 },
+        {  66, 159, 206 },
+        {  82,  78, 184 },
+        {  75,  28, 148 },
+        {  46,   4,  82 },
+        {  18,   1,  28 }
+      }, { /* Coeff Band 2 */
+        { 108, 148, 220 },
+        {  90, 130, 216 },
+        {  92,  40, 186 },
+        {  73,  10, 135 },
+        {  46,   1,  79 },
+        {  20,   1,  35 }
+      }, { /* Coeff Band 3 */
+        { 125, 173, 232 },
+        { 109, 117, 223 },
+        {  97,  31, 183 },
+        {  71,   7, 127 },
+        {  44,   1,  76 },
+        {  21,   1,  36 }
+      }, { /* Coeff Band 4 */
+        { 133, 195, 236 },
+        { 112, 121, 224 },
+        {  97,  23, 178 },
+        {  69,   3, 122 },
+        {  42,   1,  72 },
+        {  19,   1,  34 }
+      }, { /* Coeff Band 5 */
+        { 132, 180, 238 },
+        { 119, 102, 225 },
+        { 101,  18, 179 },
+        {  71,   3, 124 },
+        {  42,   1,  70 },
+        {  17,   1,  28 }
+      }
+    }, { /* Inter */
+      { /* Coeff Band 0 */
+        {   5, 242, 250 },
+        {  26, 198, 226 },
+        {  58,  98, 168 }
+      }, { /* Coeff Band 1 */
+        {  82, 201, 246 },
+        {  50, 219, 237 },
+        {  94, 107, 205 },
+        {  89,  61, 167 },
+        {  77,  31, 131 },
+        {  57,  14,  91 }
+      }, { /* Coeff Band 2 */
+        {  99, 202, 247 },
+        {  96, 165, 234 },
+        { 100,  31, 190 },
+        {  72,   8, 131 },
+        {  41,   1,  72 },
+        {  14,   1,  24 }
+      }, { /* Coeff Band 3 */
+        { 108, 204, 248 },
+        { 107, 156, 235 },
+        { 103,  27, 186 },
+        {  71,   4, 124 },
+        {  39,   1,  66 },
+        {  14,   1,  19 }
+      }, { /* Coeff Band 4 */
+        { 120, 211, 248 },
+        { 118, 149, 234 },
+        { 107,  19, 182 },
+        {  72,   3, 126 },
+        {  40,   1,  69 },
+        {  16,   1,  24 }
+      }, { /* Coeff Band 5 */
+        { 127, 199, 245 },
+        { 122, 125, 232 },
+        { 112,  20, 186 },
+        {  82,   3, 136 },
+        {  55,   1,  88 },
+        {  10,   1,  38 }
+      }
+    }
+  }
+};
+static const vp9_coeff_probs_model default_coef_probs_16x16[BLOCK_TYPES] = {
+  { /* block Type 0 */
+    { /* Intra */
+      { /* Coeff Band 0 */
+        {  25,   9, 101 },
+        {  25,   2,  67 },
+        {  15,   1,  28 }
+      }, { /* Coeff Band 1 */
+        {  67,  30, 118 },
+        {  61,  56, 116 },
+        {  60,  31, 105 },
+        {  52,  11,  85 },
+        {  34,   2,  54 },
+        {  14,   1,  22 }
+      }, { /* Coeff Band 2 */
+        { 107,  58, 149 },
+        {  92,  53, 147 },
+        {  78,  14, 123 },
+        {  56,   3,  87 },
+        {  35,   1,  56 },
+        {  17,   1,  27 }
+      }, { /* Coeff Band 3 */
+        { 142,  61, 171 },
+        { 111,  30, 162 },
+        {  80,   4, 128 },
+        {  53,   1,  87 },
+        {  31,   1,  52 },
+        {  14,   1,  24 }
+      }, { /* Coeff Band 4 */
+        { 171,  73, 200 },
+        { 129,  28, 184 },
+        {  86,   3, 140 },
+        {  54,   1,  90 },
+        {  28,   1,  49 },
+        {  12,   1,  21 }
+      }, { /* Coeff Band 5 */
+        { 193, 129, 227 },
+        { 148,  28, 200 },
+        {  90,   2, 144 },
+        {  53,   1,  90 },
+        {  28,   1,  50 },
+        {  13,   1,  22 }
+      }
+    }, { /* Inter */
+      { /* Coeff Band 0 */
+        {  60,   7, 234 },
+        {  64,   4, 184 },
+        {  56,   1, 104 }
+      }, { /* Coeff Band 1 */
+        { 150, 111, 210 },
+        {  87, 185, 202 },
+        { 101,  81, 177 },
+        {  90,  34, 142 },
+        {  67,  11,  95 },
+        {  38,   2,  51 }
+      }, { /* Coeff Band 2 */
+        { 153, 139, 218 },
+        { 120,  72, 195 },
+        {  90,  11, 147 },
+        {  63,   3, 101 },
+        {  39,   1,  61 },
+        {  20,   1,  33 }
+      }, { /* Coeff Band 3 */
+        { 171, 132, 223 },
+        { 131,  56, 200 },
+        {  92,   6, 147 },
+        {  58,   1,  95 },
+        {  32,   1,  52 },
+        {  14,   1,  23 }
+      }, { /* Coeff Band 4 */
+        { 183, 137, 227 },
+        { 139,  48, 204 },
+        {  91,   3, 148 },
+        {  55,   1,  91 },
+        {  28,   1,  47 },
+        {  13,   1,  21 }
+      }, { /* Coeff Band 5 */
+        { 198, 149, 234 },
+        { 153,  32, 208 },
+        {  95,   2, 148 },
+        {  55,   1,  90 },
+        {  30,   1,  51 },
+        {  16,   1,  25 }
+      }
+    }
+  }, { /* block Type 1 */
+    { /* Intra */
+      { /* Coeff Band 0 */
+        {   7, 209, 217 },
+        {  31, 106, 151 },
+        {  40,  21,  86 }
+      }, { /* Coeff Band 1 */
+        { 101,  71, 184 },
+        {  74, 131, 177 },
+        {  88,  50, 158 },
+        {  78,  16, 129 },
+        {  51,   2,  82 },
+        {  18,   1,  29 }
+      }, { /* Coeff Band 2 */
+        { 116, 115, 199 },
+        { 102,  88, 191 },
+        {  94,  22, 160 },
+        {  74,   6, 122 },
+        {  47,   1,  77 },
+        {  18,   1,  30 }
+      }, { /* Coeff Band 3 */
+        { 157, 124, 210 },
+        { 130,  53, 201 },
+        { 102,  10, 165 },
+        {  73,   1, 120 },
+        {  42,   1,  69 },
+        {  16,   1,  27 }
+      }, { /* Coeff Band 4 */
+        { 174, 147, 225 },
+        { 134,  67, 212 },
+        { 100,  10, 168 },
+        {  66,   1, 111 },
+        {  36,   1,  60 },
+        {  16,   1,  27 }
+      }, { /* Coeff Band 5 */
+        { 185, 165, 232 },
+        { 147,  56, 214 },
+        { 105,   5, 165 },
+        {  66,   1, 108 },
+        {  35,   1,  59 },
+        {  16,   1,  27 }
+      }
+    }, { /* Inter */
+      { /* Coeff Band 0 */
+        {   3, 232, 245 },
+        {  18, 162, 210 },
+        {  38,  64, 131 }
+      }, { /* Coeff Band 1 */
+        {  84, 187, 239 },
+        {  35, 231, 231 },
+        {  82, 150, 209 },
+        {  87,  97, 181 },
+        {  81,  64, 151 },
+        {  67,  60, 119 }
+      }, { /* Coeff Band 2 */
+        { 107, 185, 239 },
+        { 100, 149, 224 },
+        { 107,  34, 185 },
+        {  83,  12, 141 },
+        {  49,   4,  92 },
+        {  21,   1,  40 }
+      }, { /* Coeff Band 3 */
+        { 125, 184, 243 },
+        { 121, 127, 228 },
+        { 113,  25, 185 },
+        {  82,   6, 134 },
+        {  48,   1,  82 },
+        {  26,   1,  38 }
+      }, { /* Coeff Band 4 */
+        { 143, 185, 245 },
+        { 133, 115, 231 },
+        { 114,  14, 184 },
+        {  77,   3, 126 },
+        {  43,   1,  68 },
+        {  34,   1,  40 }
+      }, { /* Coeff Band 5 */
+        { 170, 194, 241 },
+        { 151,  80, 226 },
+        { 118,   9, 180 },
+        {  81,   1, 130 },
+        {  51,   1,  78 },
+        {  18,   1,  49 }
+      }
+    }
+  }
+};
+static const vp9_coeff_probs_model default_coef_probs_32x32[BLOCK_TYPES] = {
+  { /* block Type 0 */
+    { /* Intra */
+      { /* Coeff Band 0 */
+        {  29,  42, 137 },
+        {  26,   3,  60 },
+        {  13,   1,  23 }
+      }, { /* Coeff Band 1 */
+        {  69,  36, 122 },
+        {  63,  57, 123 },
+        {  60,  33, 112 },
+        {  52,  11,  90 },
+        {  32,   2,  52 },
+        {  10,   1,  15 }
+      }, { /* Coeff Band 2 */
+        { 107,  55, 143 },
+        {  86,  69, 143 },
+        {  74,  24, 116 },
+        {  52,   5,  78 },
+        {  29,   1,  44 },
+        {  12,   1,  18 }
+      }, { /* Coeff Band 3 */
+        { 137,  71, 160 },
+        { 107,  34, 152 },
+        {  73,   6, 114 },
+        {  44,   1,  69 },
+        {  25,   1,  40 },
+        {  12,   1,  18 }
+      }, { /* Coeff Band 4 */
+        { 165,  70, 174 },
+        { 118,  24, 159 },
+        {  74,   3, 117 },
+        {  45,   1,  73 },
+        {  26,   1,  43 },
+        {  12,   1,  19 }
+      }, { /* Coeff Band 5 */
+        { 220,  93, 223 },
+        { 153,  10, 187 },
+        {  86,   2, 131 },
+        {  49,   1,  79 },
+        {  26,   1,  43 },
+        {  12,   1,  20 }
+      }
+    }, { /* Inter */
+      { /* Coeff Band 0 */
+        {  30,  58, 227 },
+        {  35,  10, 172 },
+        {  24,  23, 112 }
+      }, { /* Coeff Band 1 */
+        { 117, 145, 219 },
+        {  51, 221, 216 },
+        {  75, 169, 196 },
+        {  88,  96, 165 },
+        {  77,  43, 117 },
+        {  53,  18,  60 }
+      }, { /* Coeff Band 2 */
+        { 128, 176, 225 },
+        { 108, 114, 202 },
+        {  92,  19, 152 },
+        {  65,   4, 103 },
+        {  38,   1,  61 },
+        {  19,   1,  30 }
+      }, { /* Coeff Band 3 */
+        { 146, 184, 228 },
+        { 122,  95, 205 },
+        {  92,  11, 149 },
+        {  62,   1,  98 },
+        {  35,   1,  57 },
+        {  17,   1,  26 }
+      }, { /* Coeff Band 4 */
+        { 165, 192, 230 },
+        { 132,  81, 206 },
+        {  93,   6, 147 },
+        {  58,   1,  94 },
+        {  32,   1,  52 },
+        {  15,   1,  24 }
+      }, { /* Coeff Band 5 */
+        { 204, 223, 234 },
+        { 156,  49, 204 },
+        {  97,   3, 145 },
+        {  59,   1,  92 },
+        {  33,   1,  52 },
+        {  15,   1,  24 }
+      }
+    }
+  }, { /* block Type 1 */
+    { /* Intra */
+      { /* Coeff Band 0 */
+        {   7, 184, 200 },
+        {  25,  67, 113 },
+        {  30,   9,  59 }
+      }, { /* Coeff Band 1 */
+        {  92,  42, 158 },
+        {  65, 121, 159 },
+        {  77,  56, 146 },
+        {  70,  22, 120 },
+        {  47,   4,  76 },
+        {  18,   1,  26 }
+      }, { /* Coeff Band 2 */
+        { 113,  81, 177 },
+        {  96,  75, 167 },
+        {  84,  24, 136 },
+        {  63,   8, 100 },
+        {  37,   1,  58 },
+        {  13,   1,  19 }
+      }, { /* Coeff Band 3 */
+        { 147,  85, 194 },
+        { 119,  36, 178 },
+        {  88,   8, 139 },
+        {  59,   1,  93 },
+        {  31,   1,  49 },
+        {  10,   1,  18 }
+      }, { /* Coeff Band 4 */
+        { 169, 108, 210 },
+        { 131,  41, 191 },
+        {  92,   5, 144 },
+        {  56,   1,  88 },
+        {  29,   1,  47 },
+        {  14,   1,  22 }
+      }, { /* Coeff Band 5 */
+        { 210, 106, 223 },
+        { 148,  14, 192 },
+        {  89,   2, 138 },
+        {  52,   1,  84 },
+        {  29,   1,  47 },
+        {  14,   1,  23 }
+      }
+    }, { /* Inter */
+      { /* Coeff Band 0 */
+        {   3, 207, 245 },
+        {  12, 102, 213 },
+        {  18,  33, 144 }
+      }, { /* Coeff Band 1 */
+        {  85, 205, 245 },
+        {  18, 249, 242 },
+        {  59, 221, 229 },
+        {  91, 166, 213 },
+        {  88, 117, 183 },
+        {  70,  95, 149 }
+      }, { /* Coeff Band 2 */
+        { 114, 193, 241 },
+        { 104, 155, 221 },
+        { 100,  33, 181 },
+        {  78,  10, 132 },
+        {  43,   2,  75 },
+        {  15,   1,  48 }
+      }, { /* Coeff Band 3 */
+        { 118, 198, 244 },
+        { 117, 142, 224 },
+        { 111,  25, 179 },
+        {  83,   4, 134 },
+        {  57,   1,  84 },
+        {   1,   1,   1 }
+      }, { /* Coeff Band 4 */
+        { 144, 201, 248 },
+        { 136, 130, 234 },
+        { 124,  12, 188 },
+        {  83,   1, 130 },
+        {  61,   1,  66 },
+        {  64, 171, 128 }
+      }, { /* Coeff Band 5 */
+        { 174, 227, 250 },
+        { 165, 118, 242 },
+        { 132,  21, 197 },
+        {  84,   3, 134 },
+        {  70,   1,  69 },
+        {   1,   1,   1 }
+      }
+    }
+  }
+};
+#else
 static const vp9_coeff_probs_model default_coef_probs_4x4[BLOCK_TYPES] = {
   { /* block Type 0 */
     { /* Intra */
@@ -695,3 +1381,4 @@
     }
   }
 };
+#endif
diff --git a/vp9/common/vp9_entropy.c b/vp9/common/vp9_entropy.c
index 1b7da6c..5a1e91a 100644
--- a/vp9/common/vp9_entropy.c
+++ b/vp9/common/vp9_entropy.c
@@ -201,11 +201,16 @@
 
 const vp9_tree_index vp9_coef_tree[ 22] =     /* corresponding _CONTEXT_NODEs */
 {
-  -DCT_EOB_TOKEN, 2,                        /* 0 = EOB */
-  -ZERO_TOKEN, 4,                           /* 1 = ZERO */
-  -ONE_TOKEN, 6,                            /* 2 = ONE */
-  8, 12,                                    /* 3 = LOW_VAL */
-  -TWO_TOKEN, 10,                           /* 4 = TWO */
+#if CONFIG_BALANCED_COEFTREE
+  -ZERO_TOKEN, 2,                             /* 0 = ZERO */
+  -DCT_EOB_TOKEN, 4,                          /* 1 = EOB  */
+#else
+  -DCT_EOB_TOKEN, 2,                          /* 0 = EOB */
+  -ZERO_TOKEN, 4,                             /* 1 = ZERO */
+#endif
+  -ONE_TOKEN, 6,                              /* 2 = ONE */
+  8, 12,                                      /* 3 = LOW_VAL */
+  -TWO_TOKEN, 10,                            /* 4 = TWO */
   -THREE_TOKEN, -FOUR_TOKEN,                /* 5 = THREE */
   14, 16,                                   /* 6 = HIGH_LOW */
   -DCT_VAL_CATEGORY1, -DCT_VAL_CATEGORY2,   /* 7 = CAT_ONE */
@@ -229,9 +234,14 @@
 };
 
 const vp9_tree_index vp9_coefmodel_tree[6] = {
+#if CONFIG_BALANCED_COEFTREE
+  -ZERO_TOKEN, 2,
+  -DCT_EOB_MODEL_TOKEN, 4,
+#else
   -DCT_EOB_MODEL_TOKEN, 2,                      /* 0 = EOB */
   -ZERO_TOKEN, 4,                               /* 1 = ZERO */
-  -ONE_TOKEN, -TWO_TOKEN,                       /* 2 = ONE */
+#endif
+  -ONE_TOKEN, -TWO_TOKEN,
 };
 
 // Model obtained from a 2-sided zero-centerd distribuition derived
@@ -468,7 +478,7 @@
     } else {
       ctx = token_cache[scan[neighbors[MAX_NEIGHBORS * c + 0]]];
     }
-    return vp9_pt_energy_class[ctx];
+    return ctx;
   }
 };
 
@@ -642,6 +652,17 @@
 #define COEF_COUNT_SAT_AFTER_KEY 24
 #define COEF_MAX_UPDATE_FACTOR_AFTER_KEY 128
 
+void vp9_full_to_model_count(unsigned int *model_count,
+                             unsigned int *full_count) {
+  int n;
+  model_count[ZERO_TOKEN] = full_count[ZERO_TOKEN];
+  model_count[ONE_TOKEN] = full_count[ONE_TOKEN];
+  model_count[TWO_TOKEN] = full_count[TWO_TOKEN];
+  for (n = THREE_TOKEN; n < DCT_EOB_TOKEN; ++n)
+    model_count[TWO_TOKEN] += full_count[n];
+  model_count[DCT_EOB_MODEL_TOKEN] = full_count[DCT_EOB_TOKEN];
+}
+
 void vp9_full_to_model_counts(
     vp9_coeff_count_model *model_count, vp9_coeff_count *full_count) {
   int i, j, k, l;
@@ -649,19 +670,10 @@
     for (j = 0; j < REF_TYPES; ++j)
       for (k = 0; k < COEF_BANDS; ++k)
         for (l = 0; l < PREV_COEF_CONTEXTS; ++l) {
-          int n;
           if (l >= 3 && k == 0)
             continue;
-          model_count[i][j][k][l][ZERO_TOKEN] =
-              full_count[i][j][k][l][ZERO_TOKEN];
-          model_count[i][j][k][l][ONE_TOKEN] =
-              full_count[i][j][k][l][ONE_TOKEN];
-          model_count[i][j][k][l][TWO_TOKEN] =
-              full_count[i][j][k][l][TWO_TOKEN];
-          for (n = THREE_TOKEN; n < DCT_EOB_TOKEN; ++n)
-            model_count[i][j][k][l][TWO_TOKEN] += full_count[i][j][k][l][n];
-          model_count[i][j][k][l][DCT_EOB_MODEL_TOKEN] =
-              full_count[i][j][k][l][DCT_EOB_TOKEN];
+          vp9_full_to_model_count(model_count[i][j][k][l],
+                                  full_count[i][j][k][l]);
         }
 }
 
@@ -688,8 +700,13 @@
               vp9_coefmodel_tree,
               coef_probs, branch_ct,
               coef_counts[i][j][k][l], 0);
+#if CONFIG_BALANCED_COEFTREE
+          branch_ct[1][1] = eob_branch_count[i][j][k][l] - branch_ct[1][0];
+          coef_probs[1] = get_binary_prob(branch_ct[1][0], branch_ct[1][1]);
+#else
           branch_ct[0][1] = eob_branch_count[i][j][k][l] - branch_ct[0][0];
           coef_probs[0] = get_binary_prob(branch_ct[0][0], branch_ct[0][1]);
+#endif
           for (t = 0; t < entropy_nodes_adapt; ++t) {
             count = branch_ct[t][0] + branch_ct[t][1];
             count = count > count_sat ? count_sat : count;
diff --git a/vp9/common/vp9_entropy.h b/vp9/common/vp9_entropy.h
index 5d57f14..27e3bec 100644
--- a/vp9/common/vp9_entropy.h
+++ b/vp9/common/vp9_entropy.h
@@ -85,8 +85,7 @@
 /*# define DC_TOKEN_CONTEXTS        3*/ /* 00, 0!0, !0!0 */
 #define PREV_COEF_CONTEXTS          6
 
-// Disables backward coef probs adaption
-// #define DISABLE_COEF_ADAPT
+// #define ENTROPY_STATS
 
 typedef unsigned int vp9_coeff_count[REF_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS]
                                     [MAX_ENTROPY_TOKENS];
@@ -162,6 +161,7 @@
 
 #define UNCONSTRAINED_NODES         3
 #define MODEL_NODES                 (ENTROPY_NODES - UNCONSTRAINED_NODES)
+
 #define PIVOT_NODE                  2   // which node is pivot
 
 typedef vp9_prob vp9_coeff_probs_model[REF_TYPES][COEF_BANDS]
@@ -174,6 +174,8 @@
 typedef unsigned int vp9_coeff_stats_model[REF_TYPES][COEF_BANDS]
                                           [PREV_COEF_CONTEXTS]
                                           [UNCONSTRAINED_NODES][2];
+extern void vp9_full_to_model_count(unsigned int *model_count,
+                                    unsigned int *full_count);
 extern void vp9_full_to_model_counts(
     vp9_coeff_count_model *model_count, vp9_coeff_count *full_count);
 
diff --git a/vp9/common/vp9_entropymode.c b/vp9/common/vp9_entropymode.c
index 622f1dc..9c390df 100644
--- a/vp9/common/vp9_entropymode.c
+++ b/vp9/common/vp9_entropymode.c
@@ -141,13 +141,6 @@
   -H_PRED, -TM_PRED
 };
 
-const vp9_tree_index vp9_mv_ref_tree[8] = {
-  -ZEROMV, 2,
-  -NEARESTMV, 4,
-  -NEARMV, 6,
-  -NEWMV, -SPLITMV
-};
-
 const vp9_tree_index vp9_sb_mv_ref_tree[6] = {
   -ZEROMV, 2,
   -NEARESTMV, 4,
@@ -168,7 +161,6 @@
 struct vp9_token vp9_kf_ymode_encodings[VP9_YMODES];
 struct vp9_token vp9_uv_mode_encodings[VP9_UV_MODES];
 
-struct vp9_token vp9_mv_ref_encoding_array[VP9_MVREFS];
 struct vp9_token vp9_sb_mv_ref_encoding_array[VP9_MVREFS];
 
 struct vp9_token vp9_partition_encodings[PARTITION_TYPES];
@@ -265,8 +257,6 @@
                        vp9_switchable_interp_tree);
   vp9_tokens_from_tree(vp9_partition_encodings, vp9_partition_tree);
 
-  vp9_tokens_from_tree_offset(vp9_mv_ref_encoding_array,
-                              vp9_mv_ref_tree, NEARESTMV);
   vp9_tokens_from_tree_offset(vp9_sb_mv_ref_encoding_array,
                               vp9_sb_mv_ref_tree, NEARESTMV);
 }
diff --git a/vp9/common/vp9_entropymode.h b/vp9/common/vp9_entropymode.h
index 8fbc6f2..7a83c70 100644
--- a/vp9/common/vp9_entropymode.h
+++ b/vp9/common/vp9_entropymode.h
@@ -29,9 +29,7 @@
 extern const vp9_tree_index  vp9_uv_mode_tree[];
 #define vp9_sb_ymode_tree vp9_uv_mode_tree
 #define vp9_sb_kf_ymode_tree vp9_uv_mode_tree
-extern const vp9_tree_index  vp9_mv_ref_tree[];
 extern const vp9_tree_index  vp9_sb_mv_ref_tree[];
-extern const vp9_tree_index  vp9_sub_mv_ref_tree[];
 
 extern struct vp9_token vp9_bmode_encodings[VP9_BINTRAMODES];
 extern struct vp9_token vp9_kf_bmode_encodings[VP9_BINTRAMODES];
@@ -43,7 +41,6 @@
 
 /* Inter mode values do not start at zero */
 
-extern struct vp9_token vp9_mv_ref_encoding_array[VP9_MVREFS];
 extern struct vp9_token vp9_sb_mv_ref_encoding_array[VP9_MVREFS];
 
 // probability models for partition information
diff --git a/vp9/common/vp9_header.h b/vp9/common/vp9_header.h
deleted file mode 100644
index 96b04e7..0000000
--- a/vp9/common/vp9_header.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef VP9_COMMON_VP9_HEADER_H_
-#define VP9_COMMON_VP9_HEADER_H_
-
-/* 24 bits total */
-typedef struct {
-  unsigned int type: 1;
-  unsigned int version: 3;
-  unsigned int show_frame: 1;
-
-  /* Allow 2^20 bytes = 8 megabits for first partition */
-
-  unsigned int first_partition_length_in_bytes: 19;
-
-#ifdef PACKET_TESTING
-  unsigned int frame_number;
-  unsigned int update_gold: 1;
-  unsigned int uses_gold: 1;
-  unsigned int update_last: 1;
-  unsigned int uses_last: 1;
-#endif
-} VP9_HEADER;
-
-#ifdef PACKET_TESTING
-#define VP9_HEADER_SIZE 8
-#else
-#define VP9_HEADER_SIZE 3
-#endif
-
-#endif  // VP9_COMMON_VP9_HEADER_H_
diff --git a/vp9/common/vp9_modecont.h b/vp9/common/vp9_modecont.h
index 24f1a6c..30deb72 100644
--- a/vp9/common/vp9_modecont.h
+++ b/vp9/common/vp9_modecont.h
@@ -11,6 +11,8 @@
 #ifndef VP9_COMMON_VP9_MODECONT_H_
 #define VP9_COMMON_VP9_MODECONT_H_
 
+#include "vp9/common/vp9_entropy.h"
+
 extern const int vp9_default_mode_contexts[INTER_MODE_CONTEXTS][4];
 
 #endif  // VP9_COMMON_VP9_MODECONT_H_
diff --git a/vp9/common/vp9_onyxc_int.h b/vp9/common/vp9_onyxc_int.h
index c277ea3..b148a63 100644
--- a/vp9/common/vp9_onyxc_int.h
+++ b/vp9/common/vp9_onyxc_int.h
@@ -24,10 +24,6 @@
 #include "vp9/common/vp9_postproc.h"
 #endif
 
-/*#ifdef PACKET_TESTING*/
-#include "vp9/common/vp9_header.h"
-/*#endif*/
-
 /* Create/destroy static data structures. */
 
 void vp9_initialize_common(void);
diff --git a/vp9/common/vp9_reconintra.c b/vp9/common/vp9_reconintra.c
index dd60a76..b1f327b 100644
--- a/vp9/common/vp9_reconintra.c
+++ b/vp9/common/vp9_reconintra.c
@@ -402,7 +402,7 @@
       (block_idx >> bwl) || xd->up_available;
   const int have_left =
       (block_idx & wmask) || xd->left_available;
-  const int have_right = ((block_idx & wmask) != wmask);
+  int have_right = ((block_idx & wmask) != wmask);
   const int txfm_block_size = 4 << tx_size;
 
   assert(bwl >= 0);
diff --git a/vp9/decoder/vp9_decodemv.c b/vp9/decoder/vp9_decodemv.c
index 6b511b5..813a26c 100644
--- a/vp9/decoder/vp9_decodemv.c
+++ b/vp9/decoder/vp9_decodemv.c
@@ -362,10 +362,6 @@
   return (MB_PREDICTION_MODE) treed_read(r, vp9_sb_mv_ref_tree, p);
 }
 
-static MB_PREDICTION_MODE read_mv_ref(vp9_reader *r, const vp9_prob *p) {
-  return (MB_PREDICTION_MODE) treed_read(r, vp9_mv_ref_tree, p);
-}
-
 #ifdef VPX_MODE_COUNT
 unsigned int vp9_mv_cont_count[5][4] = {
   { 0, 0, 0, 0 },
diff --git a/vp9/decoder/vp9_decodframe.c b/vp9/decoder/vp9_decodframe.c
index 70e0c87..4e78ebf 100644
--- a/vp9/decoder/vp9_decodframe.c
+++ b/vp9/decoder/vp9_decodframe.c
@@ -10,29 +10,30 @@
 
 #include <assert.h>
 
-#include "vp9/decoder/vp9_onyxd_int.h"
+#include "./vp9_rtcd.h"
+#include "vpx_mem/vpx_mem.h"
+#include "vpx_scale/vpx_scale.h"
+
+#include "vp9/common/vp9_extend.h"
+#include "vp9/common/vp9_modecont.h"
 #include "vp9/common/vp9_common.h"
-#include "vp9/common/vp9_header.h"
 #include "vp9/common/vp9_reconintra.h"
 #include "vp9/common/vp9_reconinter.h"
 #include "vp9/common/vp9_entropy.h"
-#include "vp9/decoder/vp9_decodframe.h"
-#include "vp9/decoder/vp9_detokenize.h"
 #include "vp9/common/vp9_invtrans.h"
 #include "vp9/common/vp9_alloccommon.h"
 #include "vp9/common/vp9_entropymode.h"
 #include "vp9/common/vp9_quant_common.h"
-#include "vpx_scale/vpx_scale.h"
-
-#include "vp9/decoder/vp9_decodemv.h"
-#include "vp9/common/vp9_extend.h"
-#include "vp9/common/vp9_modecont.h"
-#include "vpx_mem/vpx_mem.h"
-#include "vp9/decoder/vp9_dboolhuff.h"
-
 #include "vp9/common/vp9_seg_common.h"
 #include "vp9/common/vp9_tile_common.h"
-#include "./vp9_rtcd.h"
+
+#include "vp9/decoder/vp9_dboolhuff.h"
+#include "vp9/decoder/vp9_decodframe.h"
+#include "vp9/decoder/vp9_detokenize.h"
+#include "vp9/decoder/vp9_decodemv.h"
+#include "vp9/decoder/vp9_onyxd_int.h"
+#include "vp9/decoder/vp9_read_bit_buffer.h"
+
 
 // #define DEC_DEBUG
 #ifdef DEC_DEBUG
@@ -743,32 +744,24 @@
                          : vp9_read_literal(r, 2);
 }
 
-static const uint8_t *read_frame_size(VP9_COMMON *const pc, const uint8_t *data,
-                                      const uint8_t *data_end,
-                                      int *width, int *height) {
-  if (data + 4 < data_end) {
-    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");
+static void read_frame_size(VP9_COMMON *cm,
+                            struct vp9_read_bit_buffer *rb,
+                            int *width, int *height) {
+  const int w = vp9_rb_read_literal(rb, 16);
+  const int h = vp9_rb_read_literal(rb, 16);
+  if (w <= 0)
+    vpx_internal_error(&cm->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,
-                       "Failed to read frame size");
-  }
-  return data;
+  if (h <= 0)
+    vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME,
+                       "Invalid frame height");
+  *width = w;
+  *height = h;
 }
 
-static const uint8_t *setup_frame_size(VP9D_COMP *pbi, int scaling_active,
-                                       const uint8_t *data,
-                                       const uint8_t *data_end) {
+static void setup_frame_size(VP9D_COMP *pbi, int scaling_active,
+                             struct vp9_read_bit_buffer *rb) {
   // If error concealment is enabled we should only parse the new size
   // if we have enough data. Otherwise we will end up with the wrong size.
   VP9_COMMON *const pc = &pbi->common;
@@ -778,9 +771,9 @@
   int height = pc->height;
 
   if (scaling_active)
-    data = read_frame_size(pc, data, data_end, &display_width, &display_height);
+    read_frame_size(pc, rb, &display_width, &display_height);
 
-  data = read_frame_size(pc, data, data_end, &width, &height);
+  read_frame_size(pc, rb, &width, &height);
 
   if (pc->width != width || pc->height != height) {
     if (!pbi->initial_width || !pbi->initial_height) {
@@ -806,8 +799,6 @@
 
     vp9_update_frame_size(pc);
   }
-
-  return data;
 }
 
 static void update_frame_context(FRAME_CONTEXT *fc) {
@@ -937,59 +928,78 @@
   }
 }
 
-int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) {
-  vp9_reader header_bc, residual_bc;
-  VP9_COMMON *const pc = &pbi->common;
-  MACROBLOCKD *const xd  = &pbi->mb;
-  const uint8_t *data = pbi->source;
-  const uint8_t *data_end = data + pbi->source_sz;
-  size_t first_partition_size = 0;
-  YV12_BUFFER_CONFIG *new_fb = &pc->yv12_fb[pc->new_fb_idx];
-  int i;
 
-  xd->corrupted = 0;  // start with no corruption of current frame
-  new_fb->corrupted = 0;
+static void error_handler(void *data, int bit_offset) {
+  VP9_COMMON *const cm = (VP9_COMMON *)data;
+  vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, "Truncated packet");
+}
 
-  if (data_end - data < 3) {
-    vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME, "Truncated packet");
-  } else {
-    int scaling_active;
-    pc->last_frame_type = pc->frame_type;
-    pc->frame_type = (FRAME_TYPE)(data[0] & 1);
-    pc->version = (data[0] >> 1) & 7;
-    pc->show_frame = (data[0] >> 4) & 1;
-    scaling_active = (data[0] >> 5) & 1;
-    pc->subsampling_x = (data[0] >> 6) & 1;
-    pc->subsampling_y = (data[0] >> 7) & 1;
-    first_partition_size = read_le16(data + 1);
+size_t read_uncompressed_header(VP9D_COMP *pbi,
+                                struct vp9_read_bit_buffer *rb) {
+  VP9_COMMON *const cm = &pbi->common;
 
-    if (!read_is_valid(data, first_partition_size, data_end))
-      vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
-                         "Truncated packet or corrupt partition 0 length");
+  int scaling_active;
+  cm->last_frame_type = cm->frame_type;
+  cm->frame_type = (FRAME_TYPE) vp9_rb_read_bit(rb);
+  cm->version = vp9_rb_read_literal(rb, 3);
+  cm->show_frame = vp9_rb_read_bit(rb);
+  scaling_active = vp9_rb_read_bit(rb);
+  cm->subsampling_x = vp9_rb_read_bit(rb);
+  cm->subsampling_y = vp9_rb_read_bit(rb);
 
-    data += 3;
-
-    vp9_setup_version(pc);
-
-    if (pc->frame_type == KEY_FRAME) {
-      // When error concealment is enabled we should only check the sync
-      // code if we have enough bits available
-      if (data + 3 < data_end) {
-        if (data[0] != 0x49 || data[1] != 0x83 || data[2] != 0x42)
-          vpx_internal_error(&pc->error, VPX_CODEC_UNSUP_BITSTREAM,
-                             "Invalid frame sync code");
-      }
-      data += 3;
+  if (cm->frame_type == KEY_FRAME) {
+    if (vp9_rb_read_literal(rb, 8) != SYNC_CODE_0 ||
+        vp9_rb_read_literal(rb, 8) != SYNC_CODE_1 ||
+        vp9_rb_read_literal(rb, 8) != SYNC_CODE_2) {
+        vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
+                           "Invalid frame sync code");
     }
+  }
+  setup_frame_size(pbi, scaling_active, rb);
 
-    data = setup_frame_size(pbi, scaling_active, data, data_end);
+  cm->frame_context_idx = vp9_rb_read_literal(rb, NUM_FRAME_CONTEXTS_LG2);
+  cm->clr_type = (YUV_TYPE)vp9_rb_read_bit(rb);
+
+  cm->error_resilient_mode = vp9_rb_read_bit(rb);
+  if (!cm->error_resilient_mode) {
+    cm->refresh_frame_context = vp9_rb_read_bit(rb);
+    cm->frame_parallel_decoding_mode = vp9_rb_read_bit(rb);
+  } else {
+    cm->refresh_frame_context = 0;
+    cm->frame_parallel_decoding_mode = 1;
   }
 
-  if ((!pbi->decoded_key_frame && pc->frame_type != KEY_FRAME) ||
+  return vp9_rb_read_literal(rb, 16);
+}
+
+int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) {
+  int i;
+  vp9_reader header_bc, residual_bc;
+  VP9_COMMON *const pc = &pbi->common;
+  MACROBLOCKD *const xd = &pbi->mb;
+  YV12_BUFFER_CONFIG *new_fb = &pc->yv12_fb[pc->new_fb_idx];
+  const uint8_t *data = pbi->source;
+  const uint8_t *data_end = pbi->source + pbi->source_sz;
+
+  struct vp9_read_bit_buffer rb = { data, data_end, 0,
+                                    pc, error_handler };
+  const size_t first_partition_size = read_uncompressed_header(pbi, &rb);
+  const int keyframe = pc->frame_type == KEY_FRAME;
+
+  data += vp9_rb_bytes_read(&rb);
+  xd->corrupted = 0;
+  new_fb->corrupted = 0;
+
+  if ((!pbi->decoded_key_frame && !keyframe) ||
       pc->width == 0 || pc->height == 0) {
     return -1;
   }
 
+  vp9_setup_version(pc);
+  if (!read_is_valid(data, first_partition_size, data_end))
+      vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
+                         "Truncated packet or corrupt partition 0 length");
+
   init_frame(pbi);
 
   // Reset the frame pointers to the current frame size
@@ -1001,9 +1011,6 @@
     vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR,
                        "Failed to allocate bool decoder 0");
 
-  pc->clr_type = (YUV_TYPE)vp9_read_bit(&header_bc);
-  pc->error_resilient_mode = vp9_read_bit(&header_bc);
-
   setup_loopfilter(pc, xd, &header_bc);
 
   setup_quantization(pbi, &header_bc);
@@ -1025,7 +1032,7 @@
   // Determine if the golden frame or ARF buffer should be updated and how.
   // For all non key frames the GF and ARF refresh flags and sign bias
   // flags must be set explicitly.
-  if (pc->frame_type == KEY_FRAME) {
+  if (keyframe) {
     for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i)
       pc->active_ref_idx[i] = pc->new_fb_idx;
   } else {
@@ -1050,15 +1057,6 @@
     vp9_setup_interp_filters(xd, pc->mcomp_filter_type, pc);
   }
 
-  if (!pc->error_resilient_mode) {
-    pc->refresh_frame_context = vp9_read_bit(&header_bc);
-    pc->frame_parallel_decoding_mode = vp9_read_bit(&header_bc);
-  } else {
-    pc->refresh_frame_context = 0;
-    pc->frame_parallel_decoding_mode = 1;
-  }
-
-  pc->frame_context_idx = vp9_read_literal(&header_bc, NUM_FRAME_CONTEXTS_LG2);
   pc->fc = pc->frame_contexts[pc->frame_context_idx];
 
   setup_segmentation(pc, xd, &header_bc);
@@ -1068,16 +1066,13 @@
   setup_txfm_mode(pc, xd->lossless, &header_bc);
 
   // Read inter mode probability context updates
-  if (pc->frame_type != KEY_FRAME) {
+  if (!keyframe) {
     int i, j;
     for (i = 0; i < INTER_MODE_CONTEXTS; ++i)
       for (j = 0; j < 4; ++j)
         if (vp9_read(&header_bc, 252))
           pc->fc.vp9_mode_contexts[i][j] = vp9_read_prob(&header_bc);
   }
-  // Is this needed ?
-  if (pc->frame_type == KEY_FRAME)
-    vp9_default_coef_probs(pc);
 
   update_frame_context(&pc->fc);
 
@@ -1109,7 +1104,7 @@
   new_fb->corrupted = vp9_reader_has_error(&header_bc) | xd->corrupted;
 
   if (!pbi->decoded_key_frame) {
-    if (pc->frame_type == KEY_FRAME && !new_fb->corrupted)
+    if (keyframe && !new_fb->corrupted)
       pbi->decoded_key_frame = 1;
     else
       vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
@@ -1120,7 +1115,7 @@
   if (!pc->error_resilient_mode && !pc->frame_parallel_decoding_mode) {
     vp9_adapt_coef_probs(pc);
 
-    if (pc->frame_type != KEY_FRAME) {
+    if (!keyframe) {
       vp9_adapt_mode_probs(pc);
       vp9_adapt_mode_context(pc);
       vp9_adapt_nmv_probs(pc, xd->allow_high_precision_mv);
diff --git a/vp9/decoder/vp9_detokenize.c b/vp9/decoder/vp9_detokenize.c
index 02900c0..6f6c88a 100644
--- a/vp9/decoder/vp9_detokenize.c
+++ b/vp9/decoder/vp9_detokenize.c
@@ -17,8 +17,13 @@
 #include "vp9/decoder/vp9_detokenize.h"
 #include "vp9/common/vp9_seg_common.h"
 
+#if CONFIG_BALANCED_COEFTREE
+#define ZERO_CONTEXT_NODE           0
+#define EOB_CONTEXT_NODE            1
+#else
 #define EOB_CONTEXT_NODE            0
 #define ZERO_CONTEXT_NODE           1
+#endif
 #define ONE_CONTEXT_NODE            2
 #define LOW_VAL_CONTEXT_NODE        3
 #define TWO_CONTEXT_NODE            4
@@ -58,13 +63,15 @@
   254, 254, 254, 252, 249, 243, 230, 196, 177, 153, 140, 133, 130, 129, 0
 };
 
+DECLARE_ALIGNED(16, extern const uint8_t,
+                vp9_pt_energy_class[MAX_ENTROPY_TOKENS]);
 #define INCREMENT_COUNT(token)               \
   do {                                       \
     coef_counts[type][ref][band][pt]         \
                [token >= TWO_TOKEN ?     \
                 (token == DCT_EOB_TOKEN ? DCT_EOB_MODEL_TOKEN : TWO_TOKEN) : \
                 token]++;     \
-    token_cache[scan[c]] = token; \
+    token_cache[scan[c]] = vp9_pt_energy_class[token]; \
   } while (0)
 
 #define WRITE_COEF_CONTINUE(val, token)                  \
@@ -109,6 +116,9 @@
   const int *scan, *nb;
   uint8_t token_cache[1024];
   const uint8_t * band_translate;
+#if CONFIG_BALANCED_COEFTREE
+  int skip_eob_node = 0;
+#endif
 
   switch (txfm_size) {
     default:
@@ -180,11 +190,13 @@
                                 c, default_eob);
     band = get_coef_band(band_translate, c);
     prob = coef_probs[band][pt];
+#if !CONFIG_BALANCED_COEFTREE
     fc->eob_branch_counts[txfm_size][type][ref][band][pt]++;
     if (!vp9_read(r, prob[EOB_CONTEXT_NODE]))
       break;
 
 SKIP_START:
+#endif
     if (c >= seg_eob)
       break;
     if (c)
@@ -196,8 +208,22 @@
     if (!vp9_read(r, prob[ZERO_CONTEXT_NODE])) {
       INCREMENT_COUNT(ZERO_TOKEN);
       ++c;
+#if CONFIG_BALANCED_COEFTREE
+      skip_eob_node = 1;
+      continue;
+#else
       goto SKIP_START;
+#endif
     }
+#if CONFIG_BALANCED_COEFTREE
+    if (!skip_eob_node) {
+      fc->eob_branch_counts[txfm_size][type][ref][band][pt]++;
+      if (!vp9_read(r, prob[EOB_CONTEXT_NODE]))
+        break;
+    }
+    skip_eob_node = 0;
+#endif
+
     // ONE_CONTEXT_NODE_0_
     if (!vp9_read(r, prob[ONE_CONTEXT_NODE])) {
       WRITE_COEF_CONTINUE(1, ONE_TOKEN);
diff --git a/vp9/decoder/vp9_onyxd_if.c b/vp9/decoder/vp9_onyxd_if.c
index 24f9ca3..3cef88b 100644
--- a/vp9/decoder/vp9_onyxd_if.c
+++ b/vp9/decoder/vp9_onyxd_if.c
@@ -387,9 +387,6 @@
     cm->current_video_frame++;
   }
 
-  /*vp9_print_modes_and_motion_vectors(cm->mi, cm->mb_rows,cm->mb_cols,
-                                       cm->current_video_frame);*/
-
   pbi->ready_for_new_data = 0;
   pbi->last_time_stamp = time_stamp;
   pbi->source_sz = 0;
diff --git a/vp9/decoder/vp9_read_bit_buffer.h b/vp9/decoder/vp9_read_bit_buffer.h
new file mode 100644
index 0000000..fa2dbee
--- /dev/null
+++ b/vp9/decoder/vp9_read_bit_buffer.h
@@ -0,0 +1,50 @@
+/*
+ *  Copyright (c) 2013 The WebM project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef VP9_READ_BIT_BUFFER_
+#define VP9_READ_BIT_BUFFER_
+
+typedef void (*vp9_rb_error_handler)(void *data, int bit_offset);
+
+struct vp9_read_bit_buffer {
+  const uint8_t *bit_buffer;
+  const uint8_t *bit_buffer_end;
+  size_t bit_offset;
+
+  void *error_handler_data;
+  vp9_rb_error_handler error_handler;
+};
+
+static size_t vp9_rb_bytes_read(struct vp9_read_bit_buffer *rb) {
+  return rb->bit_offset / CHAR_BIT + (rb->bit_offset % CHAR_BIT > 0);
+}
+
+static int vp9_rb_read_bit(struct vp9_read_bit_buffer *rb) {
+  const int off = rb->bit_offset;
+  const int p = off / CHAR_BIT;
+  const int q = CHAR_BIT - 1 - off % CHAR_BIT;
+  if (rb->bit_buffer + p >= rb->bit_buffer_end) {
+    rb->error_handler(rb->error_handler_data, rb->bit_offset);
+    return 0;
+  } else {
+    const int bit = (rb->bit_buffer[p] & (1 << q)) >> q;
+    rb->bit_offset = off + 1;
+    return bit;
+  }
+}
+
+static int vp9_rb_read_literal(struct vp9_read_bit_buffer *rb, int bits) {
+  int value = 0, bit;
+  for (bit = bits - 1; bit >= 0; bit--)
+    value |= vp9_rb_read_bit(rb) << bit;
+  return value;
+}
+
+#endif  // VP9_READ_BIT_BUFFER_
diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c
index 1525340..e4db5c1 100644
--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -12,35 +12,37 @@
 #include <stdio.h>
 #include <limits.h>
 
-#include "vp9/common/vp9_header.h"
-#include "vp9/encoder/vp9_encodemv.h"
+#include "vpx/vpx_encoder.h"
+#include "vpx_mem/vpx_mem.h"
+
 #include "vp9/common/vp9_entropymode.h"
 #include "vp9/common/vp9_entropymv.h"
 #include "vp9/common/vp9_findnearmv.h"
 #include "vp9/common/vp9_tile_common.h"
-#include "vp9/encoder/vp9_mcomp.h"
-#include "vp9/common/vp9_systemdependent.h"
-#include "vp9/common/vp9_pragmas.h"
-#include "vpx/vpx_encoder.h"
-#include "vpx_mem/vpx_mem.h"
-#include "vp9/encoder/vp9_bitstream.h"
-#include "vp9/encoder/vp9_segmentation.h"
-
 #include "vp9/common/vp9_seg_common.h"
 #include "vp9/common/vp9_pred_common.h"
 #include "vp9/common/vp9_entropy.h"
 #include "vp9/common/vp9_entropymv.h"
 #include "vp9/common/vp9_mvref_common.h"
 #include "vp9/common/vp9_treecoder.h"
+#include "vp9/common/vp9_systemdependent.h"
+#include "vp9/common/vp9_pragmas.h"
+
+#include "vp9/encoder/vp9_mcomp.h"
+#include "vp9/encoder/vp9_encodemv.h"
+#include "vp9/encoder/vp9_bitstream.h"
+#include "vp9/encoder/vp9_segmentation.h"
+#include "vp9/encoder/vp9_write_bit_buffer.h"
+
 
 #if defined(SECTIONBITS_OUTPUT)
 unsigned __int64 Sectionbits[500];
 #endif
 
 #ifdef ENTROPY_STATS
-int intra_mode_stats[VP9_KF_BINTRAMODES]
-                    [VP9_KF_BINTRAMODES]
-                    [VP9_KF_BINTRAMODES];
+int intra_mode_stats[VP9_BINTRAMODES]
+                    [VP9_BINTRAMODES]
+                    [VP9_BINTRAMODES];
 vp9_coeff_stats tree_update_hist_4x4[BLOCK_TYPES];
 vp9_coeff_stats tree_update_hist_8x8[BLOCK_TYPES];
 vp9_coeff_stats tree_update_hist_16x16[BLOCK_TYPES];
@@ -471,7 +473,6 @@
     const vp9_prob *pp;
     int v = a->value;
     int n = a->len;
-    int ncount = n;
     vp9_prob probs[ENTROPY_NODES];
 
     if (t == EOSB_TOKEN) {
@@ -487,18 +488,25 @@
     assert(pp != 0);
 
     /* skip one or two nodes */
+#if !CONFIG_BALANCED_COEFTREE
     if (p->skip_eob_node) {
       n -= p->skip_eob_node;
       i = 2 * p->skip_eob_node;
-      ncount -= p->skip_eob_node;
     }
+#endif
 
     do {
       const int bb = (v >> --n) & 1;
+#if CONFIG_BALANCED_COEFTREE
+      if (i == 2 && p->skip_eob_node) {
+        i += 2;
+        assert(bb == 1);
+        continue;
+      }
+#endif
       vp9_write(bc, bb, pp[i >> 1]);
       i = vp9_coef_tree[i + bb];
-      ncount--;
-    } while (n && ncount);
+    } while (n);
 
     if (b->base_val) {
       const int e = p->extra, l = b->len;
@@ -524,15 +532,6 @@
   *tp = p;
 }
 
-static void write_mv_ref(vp9_writer *bc, MB_PREDICTION_MODE m,
-                         const vp9_prob *p) {
-#if CONFIG_DEBUG
-  assert(NEARESTMV <= m  &&  m <= SPLITMV);
-#endif
-  write_token(bc, vp9_mv_ref_tree, p,
-              vp9_mv_ref_encoding_array - NEARESTMV + m);
-}
-
 static void write_sb_mv_ref(vp9_writer *bc, MB_PREDICTION_MODE m,
                             const vp9_prob *p) {
 #if CONFIG_DEBUG
@@ -869,8 +868,11 @@
         const MB_PREDICTION_MODE A = above_block_mode(m, i, mis);
         const MB_PREDICTION_MODE L = (xd->left_available || idx) ?
                                      left_block_mode(m, i) : DC_PRED;
-        write_kf_bmode(bc, m->bmi[i].as_mode.first,
-                       c->kf_bmode_prob[A][L]);
+        const int bm = m->bmi[i].as_mode.first;
+#ifdef ENTROPY_STATS
+        ++intra_mode_stats[A][L][bm];
+#endif
+        write_kf_bmode(bc, bm, c->kf_bmode_prob[A][L]);
       }
     }
   }
@@ -1045,7 +1047,7 @@
   fclose(f);
 }
 
-static void build_tree_distribution(vp9_coeff_probs *coef_probs,
+static void build_tree_distribution(vp9_coeff_probs_model *coef_probs,
                                     vp9_coeff_count *coef_counts,
                                     unsigned int (*eob_branch_ct)[REF_TYPES]
                                                                  [COEF_BANDS]
@@ -1054,12 +1056,13 @@
                                     VP9_COMP *cpi,
                                     vp9_coeff_accum *context_counters,
 #endif
-                                    vp9_coeff_stats *coef_branch_ct,
+                                    vp9_coeff_stats_model *coef_branch_ct,
                                     int block_types) {
   int i, j, k, l;
 #ifdef ENTROPY_STATS
   int t = 0;
 #endif
+  unsigned int model_counts[UNCONSTRAINED_NODES + 1];
 
   for (i = 0; i < block_types; ++i) {
     for (j = 0; j < REF_TYPES; ++j) {
@@ -1067,15 +1070,24 @@
         for (l = 0; l < PREV_COEF_CONTEXTS; ++l) {
           if (l >= 3 && k == 0)
             continue;
-          vp9_tree_probs_from_distribution(vp9_coef_tree,
+          vp9_full_to_model_count(model_counts, coef_counts[i][j][k][l]);
+          vp9_tree_probs_from_distribution(vp9_coefmodel_tree,
                                            coef_probs[i][j][k][l],
                                            coef_branch_ct[i][j][k][l],
-                                           coef_counts[i][j][k][l], 0);
+                                           model_counts, 0);
+#if CONFIG_BALANCED_COEFTREE
+          coef_branch_ct[i][j][k][l][1][1] = eob_branch_ct[i][j][k][l] -
+                                             coef_branch_ct[i][j][k][l][1][0];
+          coef_probs[i][j][k][l][1] =
+              get_binary_prob(coef_branch_ct[i][j][k][l][1][0],
+                              coef_branch_ct[i][j][k][l][1][1]);
+#else
           coef_branch_ct[i][j][k][l][0][1] = eob_branch_ct[i][j][k][l] -
                                              coef_branch_ct[i][j][k][l][0][0];
           coef_probs[i][j][k][l][0] =
               get_binary_prob(coef_branch_ct[i][j][k][l][0][0],
                               coef_branch_ct[i][j][k][l][0][1]);
+#endif
 #ifdef ENTROPY_STATS
           if (!cpi->dummy_packing) {
             for (t = 0; t < MAX_ENTROPY_TOKENS; ++t)
@@ -1127,9 +1139,9 @@
 #ifdef ENTROPY_STATS
     vp9_coeff_stats *tree_update_hist,
 #endif
-    vp9_coeff_probs *new_frame_coef_probs,
+    vp9_coeff_probs_model *new_frame_coef_probs,
     vp9_coeff_probs_model *old_frame_coef_probs,
-    vp9_coeff_stats *frame_branch_ct,
+    vp9_coeff_stats_model *frame_branch_ct,
     TX_SIZE tx_size) {
   int i, j, k, l, t;
   int update[2] = {0, 0};
@@ -1278,10 +1290,6 @@
   }
 }
 
-#ifdef PACKET_TESTING
-FILE *vpxlogc = 0;
-#endif
-
 static void decide_kf_ymode_entropy(VP9_COMP *cpi) {
   int mode_cost[MB_MODE_COUNT];
   int bestcost = INT_MAX;
@@ -1482,61 +1490,64 @@
   }
 }
 
+
+void write_uncompressed_header(VP9_COMMON *cm,
+                               struct vp9_write_bit_buffer *wb) {
+  const int scaling_active = cm->width != cm->display_width ||
+                             cm->height != cm->display_height;
+
+  vp9_wb_write_bit(wb, cm->frame_type);
+  vp9_wb_write_literal(wb, cm->version, 3);
+  vp9_wb_write_bit(wb, cm->show_frame);
+  vp9_wb_write_bit(wb, scaling_active);
+  vp9_wb_write_bit(wb, cm->subsampling_x);
+  vp9_wb_write_bit(wb, cm->subsampling_y);
+
+  if (cm->frame_type == KEY_FRAME) {
+    vp9_wb_write_literal(wb, SYNC_CODE_0, 8);
+    vp9_wb_write_literal(wb, SYNC_CODE_1, 8);
+    vp9_wb_write_literal(wb, SYNC_CODE_2, 8);
+  }
+
+  if (scaling_active) {
+    vp9_wb_write_literal(wb, cm->display_width, 16);
+    vp9_wb_write_literal(wb, cm->display_height, 16);
+  }
+
+  vp9_wb_write_literal(wb, cm->width, 16);
+  vp9_wb_write_literal(wb, cm->height, 16);
+
+  vp9_wb_write_literal(wb, cm->frame_context_idx, NUM_FRAME_CONTEXTS_LG2);
+  vp9_wb_write_bit(wb, cm->clr_type);
+
+  vp9_wb_write_bit(wb, cm->error_resilient_mode);
+  if (!cm->error_resilient_mode) {
+    vp9_wb_write_bit(wb, cm->refresh_frame_context);
+    vp9_wb_write_bit(wb, cm->frame_parallel_decoding_mode);
+  }
+}
+
 void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, unsigned long *size) {
-  int i;
-  VP9_HEADER oh;
+  int i, bytes_packed;
   VP9_COMMON *const pc = &cpi->common;
   vp9_writer header_bc, residual_bc;
   MACROBLOCKD *const xd = &cpi->mb.e_mbd;
-  int extra_bytes_packed = 0;
 
   uint8_t *cx_data = dest;
+  struct vp9_write_bit_buffer wb = {dest, 0};
+  struct vp9_write_bit_buffer first_partition_size_wb;
 
-  oh.show_frame = (int) pc->show_frame;
-  oh.type = (int)pc->frame_type;
-  oh.version = pc->version;
-  oh.first_partition_length_in_bytes = 0;
+  write_uncompressed_header(pc, &wb);
+  first_partition_size_wb = wb;
+  vp9_wb_write_literal(&wb, 0, 16);  // don't know in advance first part. size
 
-  cx_data += 3;
-
-#if defined(SECTIONBITS_OUTPUT)
-  Sectionbits[active_section = 1] += sizeof(VP9_HEADER) * 8 * 256;
-#endif
+  bytes_packed = vp9_rb_bytes_written(&wb);
+  cx_data += bytes_packed;
 
   compute_update_table();
 
-  /* every keyframe send startcode, width, height, scale factor, clamp
-   * and color type.
-   */
-  if (oh.type == KEY_FRAME) {
-    // Start / synch code
-    cx_data[0] = 0x49;
-    cx_data[1] = 0x83;
-    cx_data[2] = 0x42;
-    extra_bytes_packed = 3;
-    cx_data += extra_bytes_packed;
-  }
-
-  if (pc->width != pc->display_width || pc->height != pc->display_height) {
-    write_le16(cx_data, pc->display_width);
-    write_le16(cx_data + 2, pc->display_height);
-    cx_data += 4;
-    extra_bytes_packed += 4;
-  }
-
-  write_le16(cx_data, pc->width);
-  write_le16(cx_data + 2, pc->height);
-  extra_bytes_packed += 4;
-  cx_data += 4;
-
   vp9_start_encode(&header_bc, cx_data);
 
-  // TODO(jkoleszar): remove these two unused bits?
-  vp9_write_bit(&header_bc, pc->clr_type);
-
-  // error resilient mode
-  vp9_write_bit(&header_bc, pc->error_resilient_mode);
-
   encode_loopfilter(pc, xd, &header_bc);
 
   encode_quantization(pc, &header_bc);
@@ -1617,14 +1628,6 @@
       vp9_write_literal(&header_bc, (pc->mcomp_filter_type), 2);
   }
 
-  if (!pc->error_resilient_mode) {
-    vp9_write_bit(&header_bc, pc->refresh_frame_context);
-    vp9_write_bit(&header_bc, pc->frame_parallel_decoding_mode);
-  }
-
-  vp9_write_literal(&header_bc, pc->frame_context_idx,
-                    NUM_FRAME_CONTEXTS_LG2);
-
 #ifdef ENTROPY_STATS
   if (pc->frame_type == INTER_FRAME)
     active_section = 0;
@@ -1820,27 +1823,11 @@
 
   vp9_stop_encode(&header_bc);
 
-  oh.first_partition_length_in_bytes = header_bc.pos;
 
-  /* update frame tag */
-  {
-    int scaling = (pc->width != pc->display_width ||
-                   pc->height != pc->display_height);
-    int v = (oh.first_partition_length_in_bytes << 8) |
-            (pc->subsampling_y << 7) |
-            (pc->subsampling_x << 6) |
-            (scaling << 5) |
-            (oh.show_frame << 4) |
-            (oh.version << 1) |
-            oh.type;
-
-    assert(oh.first_partition_length_in_bytes <= 0xffff);
-    dest[0] = v;
-    dest[1] = v >> 8;
-    dest[2] = v >> 16;
-  }
-
-  *size = VP9_HEADER_SIZE + extra_bytes_packed + header_bc.pos;
+  // first partition size
+  assert(header_bc.pos <= 0xffff);
+  vp9_wb_write_literal(&first_partition_size_wb, header_bc.pos, 16);
+  *size = bytes_packed + header_bc.pos;
 
   if (pc->frame_type == KEY_FRAME) {
     decide_kf_ymode_entropy(cpi);
diff --git a/vp9/encoder/vp9_block.h b/vp9/encoder/vp9_block.h
index 211eca4..cf34cc1 100644
--- a/vp9/encoder/vp9_block.h
+++ b/vp9/encoder/vp9_block.h
@@ -117,7 +117,6 @@
   int mbmode_cost[2][MB_MODE_COUNT];
   int intra_uv_mode_cost[2][MB_MODE_COUNT];
   int bmode_costs[VP9_BINTRAMODES][VP9_BINTRAMODES][VP9_BINTRAMODES];
-  int inter_bmode_costs[INTRA_MODE_COUNT];
   int switchable_interp_costs[VP9_SWITCHABLE_FILTERS + 1]
                              [VP9_SWITCHABLE_FILTERS];
 
@@ -134,7 +133,11 @@
 
   unsigned char *active_ptr;
 
+  // note that token_costs is the cost when eob node is skipped
   vp9_coeff_count token_costs[TX_SIZE_MAX_SB][BLOCK_TYPES];
+#if CONFIG_BALANCED_COEFTREE
+  vp9_coeff_count token_costs_noskip[TX_SIZE_MAX_SB][BLOCK_TYPES];
+#endif
 
   int optimize;
 
diff --git a/vp9/encoder/vp9_boolhuff.c b/vp9/encoder/vp9_boolhuff.c
index 0fcb257..86143ca 100644
--- a/vp9/encoder/vp9_boolhuff.c
+++ b/vp9/encoder/vp9_boolhuff.c
@@ -10,6 +10,7 @@
 
 #include <assert.h>
 #include "vp9/encoder/vp9_boolhuff.h"
+#include "vp9/common/vp9_entropy.h"
 
 #if defined(SECTIONBITS_OUTPUT)
 unsigned __int64 Sectionbits[500];
diff --git a/vp9/encoder/vp9_encodemb.c b/vp9/encoder/vp9_encodemb.c
index b7f60b1..98ea980 100644
--- a/vp9/encoder/vp9_encodemb.c
+++ b/vp9/encoder/vp9_encodemb.c
@@ -20,6 +20,9 @@
 #include "vp9/common/vp9_systemdependent.h"
 #include "vp9_rtcd.h"
 
+DECLARE_ALIGNED(16, extern const uint8_t,
+                vp9_pt_energy_class[MAX_ENTROPY_TOKENS]);
+
 void vp9_subtract_block(int rows, int cols,
                         int16_t *diff_ptr, int diff_stride,
                         const uint8_t *src_ptr, int src_stride,
@@ -105,7 +108,7 @@
                                      uint8_t *token_cache,
                                      int pad, int l) {
   int bak = token_cache[scan[idx]], pt;
-  token_cache[scan[idx]] = token;
+  token_cache[scan[idx]] = vp9_pt_energy_class[token];
   pt = vp9_get_coef_context(scan, nb, pad, token_cache, idx + 1, l);
   token_cache[scan[idx]] = bak;
   return pt;
@@ -189,7 +192,8 @@
   *(tokens[eob] + 1) = *(tokens[eob] + 0);
   next = eob;
   for (i = 0; i < eob; i++)
-    token_cache[scan[i]] = vp9_dct_value_tokens_ptr[qcoeff_ptr[scan[i]]].token;
+    token_cache[scan[i]] = vp9_pt_energy_class[vp9_dct_value_tokens_ptr[
+        qcoeff_ptr[scan[i]]].token];
   nb = vp9_get_coef_neighbors_handle(scan, &pad);
 
   for (i = eob; i-- > i0;) {
@@ -211,10 +215,21 @@
         band = get_coef_band(band_translate, i + 1);
         pt = trellis_get_coeff_context(scan, nb, i, t0, token_cache,
                                        pad, default_eob);
+#if CONFIG_BALANCED_COEFTREE
         rate0 +=
-          mb->token_costs[tx_size][type][ref][band][pt][tokens[next][0].token];
+          mb->token_costs_noskip[tx_size][type][ref][band][pt]
+                                [tokens[next][0].token];
         rate1 +=
-          mb->token_costs[tx_size][type][ref][band][pt][tokens[next][1].token];
+          mb->token_costs_noskip[tx_size][type][ref][band][pt]
+                                [tokens[next][1].token];
+#else
+        rate0 +=
+          mb->token_costs[tx_size][type][ref][band][pt]
+                         [tokens[next][0].token];
+        rate1 +=
+          mb->token_costs[tx_size][type][ref][band][pt]
+                         [tokens[next][1].token];
+#endif
       }
       UPDATE_RD_COST();
       /* And pick the best. */
@@ -262,14 +277,32 @@
         if (t0 != DCT_EOB_TOKEN) {
           pt = trellis_get_coeff_context(scan, nb, i, t0, token_cache,
                                          pad, default_eob);
+#if CONFIG_BALANCED_COEFTREE
+          if (!x)
+            rate0 += mb->token_costs[tx_size][type][ref][band][pt][
+                tokens[next][0].token];
+          else
+            rate0 += mb->token_costs_noskip[tx_size][type][ref][band][pt][
+                tokens[next][0].token];
+#else
           rate0 += mb->token_costs[tx_size][type][ref][band][pt][
               tokens[next][0].token];
+#endif
         }
         if (t1 != DCT_EOB_TOKEN) {
           pt = trellis_get_coeff_context(scan, nb, i, t1, token_cache,
                                          pad, default_eob);
+#if CONFIG_BALANCED_COEFTREE
+          if (!x)
+            rate1 += mb->token_costs[tx_size][type][ref][band][pt][
+                tokens[next][1].token];
+          else
+            rate1 += mb->token_costs_noskip[tx_size][type][ref][band][pt][
+                tokens[next][1].token];
+#else
           rate1 += mb->token_costs[tx_size][type][ref][band][pt][
               tokens[next][1].token];
+#endif
         }
       }
 
@@ -322,8 +355,13 @@
   error1 = tokens[next][1].error;
   t0 = tokens[next][0].token;
   t1 = tokens[next][1].token;
+#if CONFIG_BALANCED_COEFTREE
+  rate0 += mb->token_costs_noskip[tx_size][type][ref][band][pt][t0];
+  rate1 += mb->token_costs_noskip[tx_size][type][ref][band][pt][t1];
+#else
   rate0 += mb->token_costs[tx_size][type][ref][band][pt][t0];
   rate1 += mb->token_costs[tx_size][type][ref][band][pt][t1];
+#endif
   UPDATE_RD_COST();
   best = rd_cost1 < rd_cost0;
   final_eob = i0 - 1;
@@ -610,6 +648,7 @@
   struct encode_b_args* const args = arg;
   MACROBLOCK* const x = args->x;
   MACROBLOCKD* const xd = &x->e_mbd;
+  MB_MODE_INFO* const mbmi = &xd->mode_info_context->mbmi;
   const TX_SIZE tx_size = (TX_SIZE)(ss_txfrm_size / 2);
   const int bw = 4 << (b_width_log2(bsize) - xd->plane[plane].subsampling_x);
   const int raster_block = txfrm_block_to_raster_block(xd, bsize, plane,
@@ -634,9 +673,9 @@
   TX_TYPE tx_type;
   int mode, b_mode;
 
-  mode = plane == 0? xd->mode_info_context->mbmi.mode:
-                     xd->mode_info_context->mbmi.uv_mode;
-  if (bsize <= BLOCK_SIZE_SB8X8 && mode == I4X4_PRED && plane == 0)
+  mode = plane == 0? mbmi->mode: mbmi->uv_mode;
+  if (mbmi->sb_type < BLOCK_SIZE_SB8X8 && plane == 0 &&
+      mbmi->ref_frame == INTRA_FRAME)
     b_mode = xd->mode_info_context->bmi[ib].as_mode.first;
   else
     b_mode = mode;
diff --git a/vp9/encoder/vp9_modecosts.c b/vp9/encoder/vp9_modecosts.c
index 171b44b..67658f5 100644
--- a/vp9/encoder/vp9_modecosts.c
+++ b/vp9/encoder/vp9_modecosts.c
@@ -17,7 +17,6 @@
 
 void vp9_init_mode_costs(VP9_COMP *c) {
   VP9_COMMON *x = &c->common;
-  const vp9_tree_p T = vp9_bmode_tree;
   const vp9_tree_p KT = vp9_bmode_tree;
   int i, j;
 
@@ -28,8 +27,6 @@
     }
   }
 
-  vp9_cost_tokens((int *)c->mb.inter_bmode_costs, x->fc.bmode_prob, T);
-
   // TODO(rbultje) separate tables for superblock costing?
   vp9_cost_tokens(c->mb.mbmode_cost[1], x->fc.sb_ymode_prob,
                   vp9_sb_ymode_tree);
diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c
index d42bcbb..d9c34fe 100644
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -103,9 +103,9 @@
 
 
 #ifdef ENTROPY_STATS
-extern int intra_mode_stats[VP9_KF_BINTRAMODES]
-                           [VP9_KF_BINTRAMODES]
-                           [VP9_KF_BINTRAMODES];
+extern int intra_mode_stats[VP9_BINTRAMODES]
+                           [VP9_BINTRAMODES]
+                           [VP9_BINTRAMODES];
 #endif
 
 #ifdef NMV_STATS
@@ -258,9 +258,6 @@
     init_done = 1;
   }
 }
-#ifdef PACKET_TESTING
-extern FILE *vpxlogc;
-#endif
 
 static void setup_features(VP9_COMP *cpi) {
   MACROBLOCKD *xd = &cpi->mb.e_mbd;
@@ -287,7 +284,6 @@
   set_default_lf_deltas(cpi);
 }
 
-
 static void dealloc_compressor_data(VP9_COMP *cpi) {
   // Delete sementation map
   vpx_free(cpi->segmentation_map);
@@ -1756,18 +1752,18 @@
 
       fprintf(fmode, "\n#include \"vp9_entropymode.h\"\n\n");
       fprintf(fmode, "const unsigned int vp9_kf_default_bmode_counts ");
-      fprintf(fmode, "[VP9_KF_BINTRAMODES][VP9_KF_BINTRAMODES]"
-                     "[VP9_KF_BINTRAMODES] =\n{\n");
+      fprintf(fmode, "[VP9_BINTRAMODES][VP9_BINTRAMODES]"
+                     "[VP9_BINTRAMODES] =\n{\n");
 
-      for (i = 0; i < VP9_KF_BINTRAMODES; i++) {
+      for (i = 0; i < VP9_BINTRAMODES; i++) {
 
         fprintf(fmode, "    { // Above Mode :  %d\n", i);
 
-        for (j = 0; j < VP9_KF_BINTRAMODES; j++) {
+        for (j = 0; j < VP9_BINTRAMODES; j++) {
 
           fprintf(fmode, "        {");
 
-          for (k = 0; k < VP9_KF_BINTRAMODES; k++) {
+          for (k = 0; k < VP9_BINTRAMODES; k++) {
             if (!intra_mode_stats[i][j][k])
               fprintf(fmode, " %5d, ", 1);
             else
@@ -2938,9 +2934,6 @@
 #endif
 
     // transform / motion compensation build reconstruction frame
-    if (cm->frame_type == KEY_FRAME) {
-      vp9_default_coef_probs(cm);
-    }
 
     vp9_encode_frame(cpi);
 
diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h
index 15f9571..24a2acb 100644
--- a/vp9/encoder/vp9_onyx_int.h
+++ b/vp9/encoder/vp9_onyx_int.h
@@ -422,20 +422,20 @@
   nmv_context_counts NMVcount;
 
   vp9_coeff_count coef_counts_4x4[BLOCK_TYPES];
-  vp9_coeff_probs frame_coef_probs_4x4[BLOCK_TYPES];
-  vp9_coeff_stats frame_branch_ct_4x4[BLOCK_TYPES];
+  vp9_coeff_probs_model frame_coef_probs_4x4[BLOCK_TYPES];
+  vp9_coeff_stats_model frame_branch_ct_4x4[BLOCK_TYPES];
 
   vp9_coeff_count coef_counts_8x8[BLOCK_TYPES];
-  vp9_coeff_probs frame_coef_probs_8x8[BLOCK_TYPES];
-  vp9_coeff_stats frame_branch_ct_8x8[BLOCK_TYPES];
+  vp9_coeff_probs_model frame_coef_probs_8x8[BLOCK_TYPES];
+  vp9_coeff_stats_model frame_branch_ct_8x8[BLOCK_TYPES];
 
   vp9_coeff_count coef_counts_16x16[BLOCK_TYPES];
-  vp9_coeff_probs frame_coef_probs_16x16[BLOCK_TYPES];
-  vp9_coeff_stats frame_branch_ct_16x16[BLOCK_TYPES];
+  vp9_coeff_probs_model frame_coef_probs_16x16[BLOCK_TYPES];
+  vp9_coeff_stats_model frame_branch_ct_16x16[BLOCK_TYPES];
 
   vp9_coeff_count coef_counts_32x32[BLOCK_TYPES];
-  vp9_coeff_probs frame_coef_probs_32x32[BLOCK_TYPES];
-  vp9_coeff_stats frame_branch_ct_32x32[BLOCK_TYPES];
+  vp9_coeff_probs_model frame_coef_probs_32x32[BLOCK_TYPES];
+  vp9_coeff_stats_model frame_branch_ct_32x32[BLOCK_TYPES];
 
   int gfu_boost;
   int last_boost;
diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c
index c11ebb4..6071679 100644
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -46,6 +46,9 @@
 /* Factor to weigh the rate for switchable interp filters */
 #define SWITCHABLE_INTERP_RATE_FACTOR 1
 
+DECLARE_ALIGNED(16, extern const uint8_t,
+                vp9_pt_energy_class[MAX_ENTROPY_TOKENS]);
+
 const MODE_DEFINITION vp9_mode_order[MAX_MODES] = {
   {ZEROMV,    LAST_FRAME,   NONE},
   {DC_PRED,   INTRA_FRAME,  NONE},
@@ -105,11 +108,31 @@
   {SPLITMV,   GOLDEN_FRAME, ALTREF_FRAME},
 };
 
+#if CONFIG_BALANCED_COEFTREE
+static void fill_token_costs(vp9_coeff_count *c,
+                             vp9_coeff_count *cnoskip,
+                             vp9_coeff_probs_model *p,
+                             TX_SIZE tx_size) {
+  int i, j, k, l;
+  for (i = 0; i < BLOCK_TYPES; i++)
+    for (j = 0; j < REF_TYPES; j++)
+      for (k = 0; k < COEF_BANDS; k++)
+        for (l = 0; l < PREV_COEF_CONTEXTS; l++) {
+          vp9_prob probs[ENTROPY_NODES];
+          vp9_model_to_full_probs(p[i][j][k][l], probs);
+          vp9_cost_tokens((int *)cnoskip[i][j][k][l], probs,
+                          vp9_coef_tree);
+          // Replace the eob node prob with a very small value so that the
+          // cost approximately equals the cost without the eob node
+          probs[1] = 1;
+          vp9_cost_tokens((int *)c[i][j][k][l], probs, vp9_coef_tree);
+        }
+}
+#else
 static void fill_token_costs(vp9_coeff_count *c,
                              vp9_coeff_probs_model *p,
                              TX_SIZE tx_size) {
   int i, j, k, l;
-
   for (i = 0; i < BLOCK_TYPES; i++)
     for (j = 0; j < REF_TYPES; j++)
       for (k = 0; k < COEF_BANDS; k++)
@@ -120,6 +143,7 @@
                                vp9_coef_tree);
         }
 }
+#endif
 
 static int rd_iifactor[32] =  { 4, 4, 3, 2, 1, 0, 0, 0,
                                 0, 0, 0, 0, 0, 0, 0, 0,
@@ -210,6 +234,20 @@
     }
   }
 
+#if CONFIG_BALANCED_COEFTREE
+  fill_token_costs(cpi->mb.token_costs[TX_4X4],
+                   cpi->mb.token_costs_noskip[TX_4X4],
+                   cpi->common.fc.coef_probs_4x4, TX_4X4);
+  fill_token_costs(cpi->mb.token_costs[TX_8X8],
+                   cpi->mb.token_costs_noskip[TX_8X8],
+                   cpi->common.fc.coef_probs_8x8, TX_8X8);
+  fill_token_costs(cpi->mb.token_costs[TX_16X16],
+                   cpi->mb.token_costs_noskip[TX_16X16],
+                   cpi->common.fc.coef_probs_16x16, TX_16X16);
+  fill_token_costs(cpi->mb.token_costs[TX_32X32],
+                   cpi->mb.token_costs_noskip[TX_32X32],
+                   cpi->common.fc.coef_probs_32x32, TX_32X32);
+#else
   fill_token_costs(cpi->mb.token_costs[TX_4X4],
                    cpi->common.fc.coef_probs_4x4, TX_4X4);
   fill_token_costs(cpi->mb.token_costs[TX_8X8],
@@ -218,6 +256,7 @@
                    cpi->common.fc.coef_probs_16x16, TX_16X16);
   fill_token_costs(cpi->mb.token_costs[TX_32X32],
                    cpi->common.fc.coef_probs_32x32, TX_32X32);
+#endif
 
   for (i = 0; i < NUM_PARTITION_CONTEXTS; i++)
     vp9_cost_tokens(cpi->mb.partition_cost[i],
@@ -271,7 +310,13 @@
   TX_TYPE tx_type = DCT_DCT;
 
   const int segment_id = xd->mode_info_context->mbmi.segment_id;
+#if CONFIG_BALANCED_COEFTREE
+  unsigned int (*token_costs_noskip)[PREV_COEF_CONTEXTS][MAX_ENTROPY_TOKENS] =
+      mb->token_costs_noskip[tx_size][type][ref];
+#else
   vp9_prob coef_probs[COEF_BANDS][PREV_COEF_CONTEXTS][ENTROPY_NODES];
+#endif
+
   int seg_eob, default_eob;
   uint8_t token_cache[1024];
   const uint8_t * band_translate;
@@ -291,8 +336,10 @@
           get_tx_type_4x4(xd, block) : DCT_DCT;
       above_ec = A[0] != 0;
       left_ec = L[0] != 0;
+#if !CONFIG_BALANCED_COEFTREE
       vp9_model_to_full_probs_sb(cm->fc.coef_probs_4x4[type][ref],
                                  coef_probs);
+#endif
       seg_eob = 16;
       scan = get_scan_4x4(tx_type);
       band_translate = vp9_coefband_trans_4x4;
@@ -307,8 +354,10 @@
       above_ec = (A[0] + A[1]) != 0;
       left_ec = (L[0] + L[1]) != 0;
       scan = get_scan_8x8(tx_type);
+#if !CONFIG_BALANCED_COEFTREE
       vp9_model_to_full_probs_sb(cm->fc.coef_probs_8x8[type][ref],
                                  coef_probs);
+#endif
       seg_eob = 64;
       band_translate = vp9_coefband_trans_8x8plus;
       break;
@@ -320,8 +369,10 @@
       TX_TYPE tx_type = (type == PLANE_TYPE_Y_WITH_DC) ?
           get_tx_type_16x16(xd, y + (x >> 2)) : DCT_DCT;
       scan = get_scan_16x16(tx_type);
+#if !CONFIG_BALANCED_COEFTREE
       vp9_model_to_full_probs_sb(cm->fc.coef_probs_16x16[type][ref],
                                  coef_probs);
+#endif
       seg_eob = 256;
       above_ec = (A[0] + A[1] + A[2] + A[3]) != 0;
       left_ec = (L[0] + L[1] + L[2] + L[3]) != 0;
@@ -330,8 +381,10 @@
     }
     case TX_32X32:
       scan = vp9_default_scan_32x32;
+#if !CONFIG_BALANCED_COEFTREE
       vp9_model_to_full_probs_sb(cm->fc.coef_probs_32x32[type][ref],
                                  coef_probs);
+#endif
       seg_eob = 1024;
       above_ec = (A[0] + A[1] + A[2] + A[3] + A[4] + A[5] + A[6] + A[7]) != 0;
       left_ec = (L[0] + L[1] + L[2] + L[3] + L[4] + L[5] + L[6] + L[7]) != 0;
@@ -362,18 +415,30 @@
       if (c)
         pt = vp9_get_coef_context(scan, nb, pad, token_cache, c, default_eob);
 
+#if CONFIG_BALANCED_COEFTREE
+      if (!c || token_cache[scan[c - 1]])  // do not skip eob
+        cost += token_costs_noskip[band][pt][t] + vp9_dct_value_cost_ptr[v];
+      else
+        cost += token_costs[band][pt][t] + vp9_dct_value_cost_ptr[v];
+#else
       cost += token_costs[band][pt][t] + vp9_dct_value_cost_ptr[v];
-
       if (!c || token_cache[scan[c - 1]])
         cost += vp9_cost_bit(coef_probs[band][pt][0], 1);
-      token_cache[scan[c]] = t;
+#endif
+      token_cache[scan[c]] = vp9_pt_energy_class[t];
     }
     if (c < seg_eob) {
       if (c)
         pt = vp9_get_coef_context(scan, nb, pad, token_cache, c, default_eob);
+#if CONFIG_BALANCED_COEFTREE
+      cost += mb->token_costs_noskip[tx_size][type][ref]
+          [get_coef_band(band_translate, c)]
+          [pt][DCT_EOB_TOKEN];
+#else
       cost += mb->token_costs[tx_size][type][ref]
           [get_coef_band(band_translate, c)]
           [pt][DCT_EOB_TOKEN];
+#endif
     }
   }
 
@@ -611,7 +676,6 @@
     int64_t this_rd;
     int ratey = 0;
 
-    xd->mode_info_context->bmi[ib].as_mode.first = mode;
     if (cm->frame_type == KEY_FRAME)
       rate = bmode_costs[mode];
     else
@@ -653,9 +717,6 @@
         distortion += vp9_block_error(coeff, BLOCK_OFFSET(xd->plane[0].dqcoeff,
                                                          block, 16), 16) >> 2;
 
-        vp9_intra4x4_predict(xd, block, BLOCK_SIZE_SB8X8, mode,
-                             dst, xd->plane[0].dst.stride);
-
         if (best_tx_type != DCT_DCT)
           vp9_short_iht4x4_add(BLOCK_OFFSET(xd->plane[0].dqcoeff, block, 16),
                                dst, xd->plane[0].dst.stride, best_tx_type);
@@ -731,7 +792,7 @@
   vpx_memcpy(t_left, xd->plane[0].left_context, sizeof(t_left));
 
   xd->mode_info_context->mbmi.mode = I4X4_PRED;
-  bmode_costs = mb->inter_bmode_costs;
+  bmode_costs = mb->mbmode_cost[cpi->common.frame_type];
 
   for (idy = 0; idy < 2; idy += bh) {
     for (idx = 0; idx < 2; idx += bw) {
@@ -927,8 +988,8 @@
     vp9_prob p [VP9_MVREFS - 1];
     assert(NEARESTMV <= m  &&  m <= SPLITMV);
     vp9_mv_ref_probs(pc, p, mode_context);
-    return cost_token(vp9_mv_ref_tree, p,
-                      vp9_mv_ref_encoding_array - NEARESTMV + m);
+    return cost_token(vp9_sb_mv_ref_tree, p,
+                      vp9_sb_mv_ref_encoding_array - NEARESTMV + m);
   } else
     return 0;
 }
@@ -938,8 +999,7 @@
   x->e_mbd.mode_info_context->mbmi.mv[0].as_int = mv->as_int;
 }
 
-static int labels2mode(MACROBLOCK *x,
-                       int const *labelings, int which_label,
+static int labels2mode(MACROBLOCK *x, int i,
                        MB_PREDICTION_MODE this_mode,
                        int_mv *this_mv, int_mv *this_second_mv,
                        int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES],
@@ -950,7 +1010,7 @@
   MACROBLOCKD *const xd = &x->e_mbd;
   MODE_INFO *const mic = xd->mode_info_context;
   MB_MODE_INFO * mbmi = &mic->mbmi;
-  int i, cost = 0, thismvcost = 0;
+  int cost = 0, thismvcost = 0;
   int idx, idy;
   int bw = 1 << b_width_log2(mbmi->sb_type);
   int bh = 1 << b_height_log2(mbmi->sb_type);
@@ -958,72 +1018,64 @@
   /* We have to be careful retrieving previously-encoded motion vectors.
    Ones from this macroblock have to be pulled from the BLOCKD array
    as they have not yet made it to the bmi array in our MB_MODE_INFO. */
-  for (i = 0; i < 4; ++i) {
-    MB_PREDICTION_MODE m;
+  MB_PREDICTION_MODE m;
 
-    if (labelings[i] != which_label)
-      continue;
-
-    {
-      // the only time we should do costing for new motion vector or mode
-      // is when we are on a new label  (jbb May 08, 2007)
-      switch (m = this_mode) {
-        case NEWMV:
-          if (mbmi->second_ref_frame > 0) {
-            this_mv->as_int = seg_mvs[mbmi->ref_frame - 1].as_int;
-            this_second_mv->as_int =
-            seg_mvs[mbmi->second_ref_frame - 1].as_int;
-          }
-
-          thismvcost  = vp9_mv_bit_cost(this_mv, best_ref_mv, mvjcost, mvcost,
-                                        102, xd->allow_high_precision_mv);
-          if (mbmi->second_ref_frame > 0) {
-            thismvcost += vp9_mv_bit_cost(this_second_mv, second_best_ref_mv,
-                                          mvjcost, mvcost, 102,
-                                          xd->allow_high_precision_mv);
-          }
-          break;
-        case NEARESTMV:
-          this_mv->as_int = frame_mv[NEARESTMV][mbmi->ref_frame].as_int;
-          if (mbmi->second_ref_frame > 0)
-            this_second_mv->as_int =
-                frame_mv[NEARESTMV][mbmi->second_ref_frame].as_int;
-          break;
-        case NEARMV:
-          this_mv->as_int = frame_mv[NEARMV][mbmi->ref_frame].as_int;
-          if (mbmi->second_ref_frame > 0)
-            this_second_mv->as_int =
-                frame_mv[NEARMV][mbmi->second_ref_frame].as_int;
-          break;
-        case ZEROMV:
-          this_mv->as_int = 0;
-          if (mbmi->second_ref_frame > 0)
-            this_second_mv->as_int = 0;
-          break;
-        default:
-          break;
+  // the only time we should do costing for new motion vector or mode
+  // is when we are on a new label  (jbb May 08, 2007)
+  switch (m = this_mode) {
+    case NEWMV:
+      if (mbmi->second_ref_frame > 0) {
+        this_mv->as_int = seg_mvs[mbmi->ref_frame - 1].as_int;
+        this_second_mv->as_int = seg_mvs[mbmi->second_ref_frame - 1].as_int;
       }
 
-      cost = vp9_cost_mv_ref(cpi, this_mode,
-                             mbmi->mb_mode_context[mbmi->ref_frame]);
-    }
-
-    mic->bmi[i].as_mv[0].as_int = this_mv->as_int;
-    if (mbmi->second_ref_frame > 0)
-      mic->bmi[i].as_mv[1].as_int = this_second_mv->as_int;
-
-    x->partition_info->bmi[i].mode = m;
-    x->partition_info->bmi[i].mv.as_int = this_mv->as_int;
-    if (mbmi->second_ref_frame > 0)
-      x->partition_info->bmi[i].second_mv.as_int = this_second_mv->as_int;
-    for (idy = 0; idy < bh; ++idy) {
-      for (idx = 0; idx < bw; ++idx) {
-        vpx_memcpy(&mic->bmi[i + idy * 2 + idx],
-                   &mic->bmi[i], sizeof(mic->bmi[i]));
-        vpx_memcpy(&x->partition_info->bmi[i + idy * 2 + idx],
-                   &x->partition_info->bmi[i],
-                   sizeof(x->partition_info->bmi[i]));
+      thismvcost  = vp9_mv_bit_cost(this_mv, best_ref_mv, mvjcost, mvcost,
+                                    102, xd->allow_high_precision_mv);
+      if (mbmi->second_ref_frame > 0) {
+        thismvcost += vp9_mv_bit_cost(this_second_mv, second_best_ref_mv,
+                                      mvjcost, mvcost, 102,
+                                      xd->allow_high_precision_mv);
       }
+      break;
+    case NEARESTMV:
+      this_mv->as_int = frame_mv[NEARESTMV][mbmi->ref_frame].as_int;
+      if (mbmi->second_ref_frame > 0)
+        this_second_mv->as_int =
+            frame_mv[NEARESTMV][mbmi->second_ref_frame].as_int;
+      break;
+    case NEARMV:
+      this_mv->as_int = frame_mv[NEARMV][mbmi->ref_frame].as_int;
+      if (mbmi->second_ref_frame > 0)
+        this_second_mv->as_int =
+            frame_mv[NEARMV][mbmi->second_ref_frame].as_int;
+      break;
+    case ZEROMV:
+      this_mv->as_int = 0;
+      if (mbmi->second_ref_frame > 0)
+        this_second_mv->as_int = 0;
+      break;
+    default:
+      break;
+  }
+
+  cost = vp9_cost_mv_ref(cpi, this_mode,
+                         mbmi->mb_mode_context[mbmi->ref_frame]);
+
+  mic->bmi[i].as_mv[0].as_int = this_mv->as_int;
+  if (mbmi->second_ref_frame > 0)
+    mic->bmi[i].as_mv[1].as_int = this_second_mv->as_int;
+
+  x->partition_info->bmi[i].mode = m;
+  x->partition_info->bmi[i].mv.as_int = this_mv->as_int;
+  if (mbmi->second_ref_frame > 0)
+    x->partition_info->bmi[i].second_mv.as_int = this_second_mv->as_int;
+  for (idy = 0; idy < bh; ++idy) {
+    for (idx = 0; idx < bw; ++idx) {
+      vpx_memcpy(&mic->bmi[i + idy * 2 + idx],
+                 &mic->bmi[i], sizeof(mic->bmi[i]));
+      vpx_memcpy(&x->partition_info->bmi[i + idy * 2 + idx],
+                 &x->partition_info->bmi[i],
+                 sizeof(x->partition_info->bmi[i]));
     }
   }
 
@@ -1033,90 +1085,86 @@
 
 static int64_t encode_inter_mb_segment(VP9_COMMON *const cm,
                                        MACROBLOCK *x,
-                                       int const *labels,
-                                       int which_label,
+                                       int i,
                                        int *labelyrate,
                                        int *distortion,
                                        ENTROPY_CONTEXT *ta,
                                        ENTROPY_CONTEXT *tl) {
-  int i, k;
+  int k;
   MACROBLOCKD *xd = &x->e_mbd;
   BLOCK_SIZE_TYPE bsize = xd->mode_info_context->mbmi.sb_type;
   int bwl = b_width_log2(bsize), bw = 1 << bwl;
   int bhl = b_height_log2(bsize), bh = 1 << bhl;
   int idx, idy;
+  const int src_stride = x->plane[0].src.stride;
+  uint8_t* const src =
+  raster_block_offset_uint8(xd, BLOCK_SIZE_SB8X8, 0, i,
+                            x->plane[0].src.buf, src_stride);
+  int16_t* src_diff =
+  raster_block_offset_int16(xd, BLOCK_SIZE_SB8X8, 0, i,
+                            x->plane[0].src_diff);
+  int16_t* coeff = BLOCK_OFFSET(x->plane[0].coeff, 16, i);
+  uint8_t* const pre =
+  raster_block_offset_uint8(xd, BLOCK_SIZE_SB8X8, 0, i,
+                            xd->plane[0].pre[0].buf,
+                            xd->plane[0].pre[0].stride);
+  uint8_t* const dst =
+  raster_block_offset_uint8(xd, BLOCK_SIZE_SB8X8, 0, i,
+                            xd->plane[0].dst.buf,
+                            xd->plane[0].dst.stride);
+  int thisdistortion = 0;
+  int thisrate = 0;
 
   *labelyrate = 0;
   *distortion = 0;
-  for (i = 0; i < 4; i++) {
-    if (labels[i] == which_label) {
-      const int src_stride = x->plane[0].src.stride;
-      uint8_t* const src =
-      raster_block_offset_uint8(xd, BLOCK_SIZE_SB8X8, 0, i,
-                                x->plane[0].src.buf, src_stride);
-      int16_t* src_diff =
-      raster_block_offset_int16(xd, BLOCK_SIZE_SB8X8, 0, i,
-                                x->plane[0].src_diff);
-      int16_t* coeff = BLOCK_OFFSET(x->plane[0].coeff, 16, i);
-      uint8_t* const pre =
-      raster_block_offset_uint8(xd, BLOCK_SIZE_SB8X8, 0, i,
-                                xd->plane[0].pre[0].buf,
-                                xd->plane[0].pre[0].stride);
-      uint8_t* const dst =
-      raster_block_offset_uint8(xd, BLOCK_SIZE_SB8X8, 0, i,
-                                xd->plane[0].dst.buf,
-                                xd->plane[0].dst.stride);
-      int thisdistortion = 0;
-      int thisrate = 0;
 
-      vp9_build_inter_predictor(pre,
-                                xd->plane[0].pre[0].stride,
-                                dst,
-                                xd->plane[0].dst.stride,
-                                &xd->mode_info_context->bmi[i].as_mv[0],
-                                &xd->scale_factor[0],
-                                4 * bw, 4 * bh, 0 /* no avg */, &xd->subpix);
+  vp9_build_inter_predictor(pre,
+                            xd->plane[0].pre[0].stride,
+                            dst,
+                            xd->plane[0].dst.stride,
+                            &xd->mode_info_context->bmi[i].as_mv[0],
+                            &xd->scale_factor[0],
+                            4 * bw, 4 * bh, 0 /* no avg */, &xd->subpix);
 
-      // TODO(debargha): Make this work properly with the
-      // implicit-compoundinter-weight experiment when implicit
-      // weighting for splitmv modes is turned on.
-      if (xd->mode_info_context->mbmi.second_ref_frame > 0) {
-        uint8_t* const second_pre =
-        raster_block_offset_uint8(xd, BLOCK_SIZE_SB8X8, 0, i,
-                                  xd->plane[0].pre[1].buf,
-                                  xd->plane[0].pre[1].stride);
-        vp9_build_inter_predictor(second_pre, xd->plane[0].pre[1].stride,
-                                  dst, xd->plane[0].dst.stride,
-                                  &xd->mode_info_context->bmi[i].as_mv[1],
-                                  &xd->scale_factor[1], 4 * bw, 4 * bh, 1,
-                                  &xd->subpix);
-      }
+  // TODO(debargha): Make this work properly with the
+  // implicit-compoundinter-weight experiment when implicit
+  // weighting for splitmv modes is turned on.
+  if (xd->mode_info_context->mbmi.second_ref_frame > 0) {
+    uint8_t* const second_pre =
+    raster_block_offset_uint8(xd, BLOCK_SIZE_SB8X8, 0, i,
+                              xd->plane[0].pre[1].buf,
+                              xd->plane[0].pre[1].stride);
+    vp9_build_inter_predictor(second_pre, xd->plane[0].pre[1].stride,
+                              dst, xd->plane[0].dst.stride,
+                              &xd->mode_info_context->bmi[i].as_mv[1],
+                              &xd->scale_factor[1], 4 * bw, 4 * bh, 1,
+                              &xd->subpix);
+  }
 
-      vp9_subtract_block(4 * bh, 4 * bw, src_diff, 8,
-                         src, src_stride,
-                         dst, xd->plane[0].dst.stride);
+  vp9_subtract_block(4 * bh, 4 * bw, src_diff, 8,
+                     src, src_stride,
+                     dst, xd->plane[0].dst.stride);
 
-      k = i;
-      for (idy = 0; idy < bh; ++idy) {
-        for (idx = 0; idx < bw; ++idx) {
-          k += (idy * 2 + idx);
-          src_diff = raster_block_offset_int16(xd, BLOCK_SIZE_SB8X8, 0, k,
-                                               x->plane[0].src_diff);
-          coeff = BLOCK_OFFSET(x->plane[0].coeff, 16, k);
-          x->fwd_txm4x4(src_diff, coeff, 16);
-          x->quantize_b_4x4(x, k, DCT_DCT, 16);
-          thisdistortion += vp9_block_error(coeff,
-                                            BLOCK_OFFSET(xd->plane[0].dqcoeff,
-                                                         k, 16), 16);
-          thisrate += cost_coeffs(cm, x, 0, k, PLANE_TYPE_Y_WITH_DC,
-                                  ta + (k & 1),
-                                  tl + (k >> 1), TX_4X4, 16);
-        }
-      }
-      *distortion += thisdistortion;
-      *labelyrate += thisrate;
+  k = i;
+  for (idy = 0; idy < bh; ++idy) {
+    for (idx = 0; idx < bw; ++idx) {
+      k += (idy * 2 + idx);
+      src_diff = raster_block_offset_int16(xd, BLOCK_SIZE_SB8X8, 0, k,
+                                           x->plane[0].src_diff);
+      coeff = BLOCK_OFFSET(x->plane[0].coeff, 16, k);
+      x->fwd_txm4x4(src_diff, coeff, 16);
+      x->quantize_b_4x4(x, k, DCT_DCT, 16);
+      thisdistortion += vp9_block_error(coeff,
+                                        BLOCK_OFFSET(xd->plane[0].dqcoeff,
+                                                     k, 16), 16);
+      thisrate += cost_coeffs(cm, x, 0, k, PLANE_TYPE_Y_WITH_DC,
+                              ta + (k & 1),
+                              tl + (k >> 1), TX_4X4, 16);
     }
   }
+  *distortion += thisdistortion;
+  *labelyrate += thisrate;
+
   *distortion >>= 2;
   return RDCOST(x->rdmult, x->rddiv, *labelyrate, *distortion);
 }
@@ -1192,7 +1240,6 @@
                                     BEST_SEG_INFO *bsi,
                                     int_mv seg_mvs[4][MAX_REF_FRAMES - 1]) {
   int i, j;
-  static const int labels[4] = { 0, 1, 2, 3 };
   int br = 0, bd = 0;
   MB_PREDICTION_MODE this_mode;
   MB_MODE_INFO * mbmi = &x->e_mbd.mode_info_context->mbmi;
@@ -1261,12 +1308,13 @@
 
         // motion search for newmv (single predictor case only)
         if (mbmi->second_ref_frame <= 0 && this_mode == NEWMV) {
-          int sseshift, n;
           int step_param = 0;
           int further_steps;
           int thissme, bestsme = INT_MAX;
           const struct buf_2d orig_src = x->plane[0].src;
           const struct buf_2d orig_pre = x->e_mbd.plane[0].pre[0];
+          int sadpb = x->sadperbit4;
+          int_mv mvp_full;
 
           /* Is the best so far sufficiently good that we cant justify doing
            * and new motion search. */
@@ -1287,55 +1335,44 @@
 
           further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param;
 
-          {
-            int sadpb = x->sadperbit4;
-            int_mv mvp_full;
+          mvp_full.as_mv.row = bsi->mvp.as_mv.row >> 3;
+          mvp_full.as_mv.col = bsi->mvp.as_mv.col >> 3;
 
-            mvp_full.as_mv.row = bsi->mvp.as_mv.row >> 3;
-            mvp_full.as_mv.col = bsi->mvp.as_mv.col >> 3;
+          // adjust src pointer for this segment
+          x->plane[0].src.buf =
+              raster_block_offset_uint8(&x->e_mbd, BLOCK_SIZE_SB8X8, 0, i,
+                                        x->plane[0].src.buf,
+                                        x->plane[0].src.stride);
+          assert(((intptr_t)x->e_mbd.plane[0].pre[0].buf & 0x7) == 0);
+          x->e_mbd.plane[0].pre[0].buf =
+              raster_block_offset_uint8(&x->e_mbd, BLOCK_SIZE_SB8X8, 0, i,
+                                        x->e_mbd.plane[0].pre[0].buf,
+                                        x->e_mbd.plane[0].pre[0].stride);
 
-            // find first label
-            n = i;
+          bestsme = vp9_full_pixel_diamond(cpi, x, &mvp_full, step_param,
+                                           sadpb, further_steps, 0, v_fn_ptr,
+                                           bsi->ref_mv, &mode_mv[NEWMV]);
 
-            // adjust src pointer for this segment
-            x->plane[0].src.buf =
-            raster_block_offset_uint8(&x->e_mbd, BLOCK_SIZE_SB8X8, 0, n,
-                                      x->plane[0].src.buf,
-                                      x->plane[0].src.stride);
-            assert(((intptr_t)x->e_mbd.plane[0].pre[0].buf & 0x7) == 0);
-            x->e_mbd.plane[0].pre[0].buf =
-            raster_block_offset_uint8(&x->e_mbd, BLOCK_SIZE_SB8X8, 0, n,
-                                      x->e_mbd.plane[0].pre[0].buf,
-                                      x->e_mbd.plane[0].pre[0].stride);
+          // Should we do a full search (best quality only)
+          if (cpi->compressor_speed == 0) {
+            /* Check if mvp_full is within the range. */
+            clamp_mv(&mvp_full, x->mv_col_min, x->mv_col_max,
+                     x->mv_row_min, x->mv_row_max);
 
-            bestsme = vp9_full_pixel_diamond(cpi, x, &mvp_full, step_param,
-                                             sadpb, further_steps, 0, v_fn_ptr,
-                                             bsi->ref_mv, &mode_mv[NEWMV]);
+            thissme = cpi->full_search_sad(x, &mvp_full,
+                                           sadpb, 16, v_fn_ptr,
+                                           x->nmvjointcost, x->mvcost,
+                                           bsi->ref_mv, i);
 
-            sseshift = 0;
-
-            // Should we do a full search (best quality only)
-            if ((cpi->compressor_speed == 0) && (bestsme >> sseshift) > 4000) {
-              /* Check if mvp_full is within the range. */
-              clamp_mv(&mvp_full, x->mv_col_min, x->mv_col_max,
-                       x->mv_row_min, x->mv_row_max);
-
-              thissme = cpi->full_search_sad(x, &mvp_full,
-                                             sadpb, 16, v_fn_ptr,
-                                             x->nmvjointcost, x->mvcost,
-                                             bsi->ref_mv,
-                                             n);
-
-              if (thissme < bestsme) {
-                bestsme = thissme;
-                mode_mv[NEWMV].as_int =
-                x->e_mbd.mode_info_context->bmi[n].as_mv[0].as_int;
-              } else {
-                /* The full search result is actually worse so re-instate the
-                 * previous best vector */
-                x->e_mbd.mode_info_context->bmi[n].as_mv[0].as_int =
-                mode_mv[NEWMV].as_int;
-              }
+            if (thissme < bestsme) {
+              bestsme = thissme;
+              mode_mv[NEWMV].as_int =
+                  x->e_mbd.mode_info_context->bmi[i].as_mv[0].as_int;
+            } else {
+              /* The full search result is actually worse so re-instate the
+               * previous best vector */
+              x->e_mbd.mode_info_context->bmi[i].as_mv[0].as_int =
+                  mode_mv[NEWMV].as_int;
             }
           }
 
@@ -1355,16 +1392,12 @@
           x->plane[0].src = orig_src;
           x->e_mbd.plane[0].pre[0] = orig_pre;
         } else if (mbmi->second_ref_frame > 0 && this_mode == NEWMV) {
-          /* NEW4X4 */
-          /* motion search not completed? Then skip newmv for this block with
-           * comppred */
           if (seg_mvs[i][mbmi->second_ref_frame - 1].as_int == INVALID_MV ||
-              seg_mvs[i][mbmi->ref_frame        - 1].as_int == INVALID_MV) {
+              seg_mvs[i][mbmi->ref_frame        - 1].as_int == INVALID_MV)
             continue;
-          }
         }
 
-        rate = labels2mode(x, labels, i, this_mode, &mode_mv[this_mode],
+        rate = labels2mode(x, i, this_mode, &mode_mv[this_mode],
                            &second_mode_mv[this_mode], frame_mv, seg_mvs[i],
                            bsi->ref_mv, bsi->second_ref_mv, x->nmvjointcost,
                            x->mvcost, cpi);
@@ -1381,7 +1414,7 @@
           continue;
 
         this_rd = encode_inter_mb_segment(&cpi->common,
-                                          x, labels, i, &labelyrate,
+                                          x, i, &labelyrate,
                                           &distortion, t_above_s, t_left_s);
         this_rd += RDCOST(x->rdmult, x->rddiv, rate, 0);
         rate += labelyrate;
@@ -1392,10 +1425,7 @@
           bestlabelyrate = labelyrate;
           mode_selected = this_mode;
           best_label_rd = this_rd;
-          for (j = 0; j < 4; j++)
-            if (labels[j] == i)
-              best_eobs[j] = x->e_mbd.plane[0].eobs[j];
-
+          best_eobs[i] = x->e_mbd.plane[0].eobs[i];
           vpx_memcpy(t_above_b, t_above_s, sizeof(t_above_s));
           vpx_memcpy(t_left_b, t_left_s, sizeof(t_left_s));
         }
@@ -1404,7 +1434,7 @@
       vpx_memcpy(t_above, t_above_b, sizeof(t_above));
       vpx_memcpy(t_left, t_left_b, sizeof(t_left));
 
-      labels2mode(x, labels, i, mode_selected, &mode_mv[mode_selected],
+      labels2mode(x, i, mode_selected, &mode_mv[mode_selected],
                   &second_mode_mv[mode_selected], frame_mv, seg_mvs[i],
                   bsi->ref_mv, bsi->second_ref_mv, x->nmvjointcost,
                   x->mvcost, cpi);
@@ -1882,6 +1912,154 @@
   return SWITCHABLE_INTERP_RATE_FACTOR * x->switchable_interp_costs[c][m];
 }
 
+static void iterative_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
+                                    BLOCK_SIZE_TYPE bsize,
+                                    int_mv *frame_mv,
+                                    YV12_BUFFER_CONFIG **scaled_ref_frame,
+                                    int mi_row, int mi_col,
+                                    int_mv single_newmv[MAX_REF_FRAMES]) {
+  int pw = 4 << b_width_log2(bsize), ph = 4 << b_height_log2(bsize);
+  MACROBLOCKD *xd = &x->e_mbd;
+  MB_MODE_INFO *mbmi = &xd->mode_info_context->mbmi;
+  int refs[2] = { mbmi->ref_frame,
+                  (mbmi->second_ref_frame < 0 ? 0 : mbmi->second_ref_frame) };
+  int_mv ref_mv[2];
+  const enum BlockSize block_size = get_plane_block_size(bsize, &xd->plane[0]);
+  int ite;
+  // Prediction buffer from second frame.
+  uint8_t *second_pred = vpx_memalign(16, pw * ph * sizeof(uint8_t));
+
+  // Do joint motion search in compound mode to get more accurate mv.
+  struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0}};
+  struct buf_2d backup_second_yv12[MAX_MB_PLANE] = {{0}};
+  struct buf_2d scaled_first_yv12;
+  int last_besterr[2] = {INT_MAX, INT_MAX};
+
+  ref_mv[0] = mbmi->ref_mvs[refs[0]][0];
+  ref_mv[1] = mbmi->ref_mvs[refs[1]][0];
+
+  if (scaled_ref_frame[0]) {
+    int i;
+    // Swap out the reference frame for a version that's been scaled to
+    // match the resolution of the current frame, allowing the existing
+    // motion search code to be used without additional modifications.
+    for (i = 0; i < MAX_MB_PLANE; i++)
+      backup_yv12[i] = xd->plane[i].pre[0];
+    setup_pre_planes(xd, scaled_ref_frame[0], NULL, mi_row, mi_col,
+                     NULL, NULL);
+  }
+
+  if (scaled_ref_frame[1]) {
+    int i;
+    for (i = 0; i < MAX_MB_PLANE; i++)
+      backup_second_yv12[i] = xd->plane[i].pre[1];
+
+    setup_pre_planes(xd, scaled_ref_frame[1], NULL, mi_row, mi_col,
+                     NULL, NULL);
+  }
+
+  xd->scale_factor[0].set_scaled_offsets(&xd->scale_factor[0],
+                                          mi_row, mi_col);
+  xd->scale_factor[1].set_scaled_offsets(&xd->scale_factor[1],
+                                          mi_row, mi_col);
+  scaled_first_yv12 = xd->plane[0].pre[0];
+
+  // Initialize mv using single prediction mode result.
+  frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
+  frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
+
+  // Allow joint search multiple times iteratively for each ref frame
+  // and break out the search loop if it couldn't find better mv.
+  for (ite = 0; ite < 4; ite++) {
+    struct buf_2d ref_yv12[2];
+    int bestsme = INT_MAX;
+    int sadpb = x->sadperbit16;
+    int_mv tmp_mv;
+    int search_range = 3;
+
+    int tmp_col_min = x->mv_col_min;
+    int tmp_col_max = x->mv_col_max;
+    int tmp_row_min = x->mv_row_min;
+    int tmp_row_max = x->mv_row_max;
+    int id = ite % 2;
+
+    // Initialized here because of compiler problem in Visual Studio.
+    ref_yv12[0] = xd->plane[0].pre[0];
+    ref_yv12[1] = xd->plane[0].pre[1];
+
+    // Get pred block from second frame.
+    vp9_build_inter_predictor(ref_yv12[!id].buf,
+                              ref_yv12[!id].stride,
+                              second_pred, pw,
+                              &frame_mv[refs[!id]],
+                              &xd->scale_factor[!id],
+                              pw, ph, 0,
+                              &xd->subpix);
+
+    // Compound motion search on first ref frame.
+    if (id)
+      xd->plane[0].pre[0] = ref_yv12[id];
+    vp9_clamp_mv_min_max(x, &ref_mv[id]);
+
+    // Use mv result from single mode as mvp.
+    tmp_mv.as_int = frame_mv[refs[id]].as_int;
+
+    tmp_mv.as_mv.col >>= 3;
+    tmp_mv.as_mv.row >>= 3;
+
+    // Small-range full-pixel motion search
+    bestsme = vp9_refining_search_8p_c(x, &tmp_mv, sadpb,
+                                       search_range,
+                                       &cpi->fn_ptr[block_size],
+                                       x->nmvjointcost, x->mvcost,
+                                       &ref_mv[id], second_pred,
+                                       pw, ph);
+
+    x->mv_col_min = tmp_col_min;
+    x->mv_col_max = tmp_col_max;
+    x->mv_row_min = tmp_row_min;
+    x->mv_row_max = tmp_row_max;
+
+    if (bestsme < INT_MAX) {
+      int dis; /* TODO: use dis in distortion calculation later. */
+      unsigned int sse;
+
+      bestsme = vp9_find_best_sub_pixel_comp(x, &tmp_mv,
+                                             &ref_mv[id],
+                                             x->errorperbit,
+                                             &cpi->fn_ptr[block_size],
+                                             x->nmvjointcost, x->mvcost,
+                                             &dis, &sse, second_pred,
+                                             pw, ph);
+    }
+
+    if (id)
+      xd->plane[0].pre[0] = scaled_first_yv12;
+
+    if (bestsme < last_besterr[id]) {
+      frame_mv[refs[id]].as_int = tmp_mv.as_int;
+      last_besterr[id] = bestsme;
+    } else {
+      break;
+    }
+  }
+
+  // restore the predictor
+  if (scaled_ref_frame[0]) {
+    int i;
+    for (i = 0; i < MAX_MB_PLANE; i++)
+      xd->plane[i].pre[0] = backup_yv12[i];
+  }
+
+  if (scaled_ref_frame[1]) {
+    int i;
+    for (i = 0; i < MAX_MB_PLANE; i++)
+      xd->plane[i].pre[1] = backup_second_yv12[i];
+  }
+
+  vpx_free(second_pred);
+}
+
 static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
                                  BLOCK_SIZE_TYPE bsize,
                                  int64_t txfm_cache[],
@@ -1924,145 +2102,13 @@
       ref_mv[1] = mbmi->ref_mvs[refs[1]][0];
 
       if (is_comp_pred) {
-        if (cpi->sf.comp_inter_joint_serach) {
-          int pw = 4 << b_width_log2(bsize), ph = 4 << b_height_log2(bsize);
-          int ite;
-          // Prediction buffer from second frame.
-          uint8_t *second_pred = vpx_memalign(16, pw * ph * sizeof(uint8_t));
+        // Initialize mv using single prediction mode result.
+        frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
+        frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
 
-          // Do joint motion search in compound mode to get more accurate mv.
-          struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0}};
-          struct buf_2d backup_second_yv12[MAX_MB_PLANE] = {{0}};
-          struct buf_2d scaled_first_yv12;
-          int last_besterr[2] = {INT_MAX, INT_MAX};
-
-          if (scaled_ref_frame[0]) {
-            int i;
-
-            // Swap out the reference frame for a version that's been scaled to
-            // match the resolution of the current frame, allowing the existing
-            // motion search code to be used without additional modifications.
-            for (i = 0; i < MAX_MB_PLANE; i++)
-              backup_yv12[i] = xd->plane[i].pre[0];
-
-            setup_pre_planes(xd, scaled_ref_frame[0], NULL, mi_row, mi_col,
-                             NULL, NULL);
-          }
-
-          if (scaled_ref_frame[1]) {
-            int i;
-
-            for (i = 0; i < MAX_MB_PLANE; i++)
-              backup_second_yv12[i] = xd->plane[i].pre[1];
-
-            setup_pre_planes(xd, scaled_ref_frame[1], NULL, mi_row, mi_col,
-                             NULL, NULL);
-          }
-          xd->scale_factor[0].set_scaled_offsets(&xd->scale_factor[0],
-                                                  mi_row, mi_col);
-          xd->scale_factor[1].set_scaled_offsets(&xd->scale_factor[1],
-                                                  mi_row, mi_col);
-
-          scaled_first_yv12 = xd->plane[0].pre[0];
-
-          // Initialize mv using single prediction mode result.
-          frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
-          frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
-
-          // Allow joint search multiple times iteratively for each ref frame
-          // and break out the search loop if it couldn't find better mv.
-          for (ite = 0; ite < 4; ite++) {
-            struct buf_2d ref_yv12[2];
-            int bestsme = INT_MAX;
-            int sadpb = x->sadperbit16;
-            int_mv tmp_mv;
-            int search_range = 3;
-
-            int tmp_col_min = x->mv_col_min;
-            int tmp_col_max = x->mv_col_max;
-            int tmp_row_min = x->mv_row_min;
-            int tmp_row_max = x->mv_row_max;
-            int id = ite % 2;
-
-            // Initialized here because of compiler problem in Visual Studio.
-            ref_yv12[0] = xd->plane[0].pre[0];
-            ref_yv12[1] = xd->plane[0].pre[1];
-
-            // Get pred block from second frame.
-            vp9_build_inter_predictor(ref_yv12[!id].buf,
-                                      ref_yv12[!id].stride,
-                                      second_pred, pw,
-                                      &frame_mv[refs[!id]],
-                                      &xd->scale_factor[!id],
-                                      pw, ph, 0,
-                                      &xd->subpix);
-
-            // Compound motion search on first ref frame.
-            if (id)
-              xd->plane[0].pre[0] = ref_yv12[id];
-            vp9_clamp_mv_min_max(x, &ref_mv[id]);
-
-            // Use mv result from single mode as mvp.
-            tmp_mv.as_int = frame_mv[refs[id]].as_int;
-
-            tmp_mv.as_mv.col >>= 3;
-            tmp_mv.as_mv.row >>= 3;
-
-            // Small-range full-pixel motion search
-            bestsme = vp9_refining_search_8p_c(x, &tmp_mv, sadpb,
-                                               search_range,
-                                               &cpi->fn_ptr[block_size],
-                                               x->nmvjointcost, x->mvcost,
-                                               &ref_mv[id], second_pred,
-                                               pw, ph);
-
-            x->mv_col_min = tmp_col_min;
-            x->mv_col_max = tmp_col_max;
-            x->mv_row_min = tmp_row_min;
-            x->mv_row_max = tmp_row_max;
-
-            if (bestsme < INT_MAX) {
-              int dis; /* TODO: use dis in distortion calculation later. */
-              unsigned int sse;
-
-              bestsme = vp9_find_best_sub_pixel_comp(x, &tmp_mv,
-                                                     &ref_mv[id],
-                                                     x->errorperbit,
-                                                     &cpi->fn_ptr[block_size],
-                                                     x->nmvjointcost, x->mvcost,
-                                                     &dis, &sse, second_pred,
-                                                     pw, ph);
-            }
-
-            if (id)
-              xd->plane[0].pre[0] = scaled_first_yv12;
-
-            if (bestsme < last_besterr[id]) {
-              frame_mv[refs[id]].as_int =
-                  xd->mode_info_context->bmi[0].as_mv[1].as_int = tmp_mv.as_int;
-              last_besterr[id] = bestsme;
-            } else {
-              break;
-            }
-          }
-
-          // restore the predictor
-          if (scaled_ref_frame[0]) {
-            int i;
-
-            for (i = 0; i < MAX_MB_PLANE; i++)
-              xd->plane[i].pre[0] = backup_yv12[i];
-          }
-
-          if (scaled_ref_frame[1]) {
-            int i;
-
-            for (i = 0; i < MAX_MB_PLANE; i++)
-              xd->plane[i].pre[1] = backup_second_yv12[i];
-          }
-
-          vpx_free(second_pred);
-        }
+        if (cpi->sf.comp_inter_joint_serach)
+          iterative_motion_search(cpi, x, bsize, frame_mv, scaled_ref_frame,
+                                  mi_row, mi_col, single_newmv);
 
         if (frame_mv[refs[0]].as_int == INVALID_MV ||
             frame_mv[refs[1]].as_int == INVALID_MV)
@@ -2138,8 +2184,7 @@
                                        x->nmvjointcost, x->mvcost,
                                        &dis, &sse);
         }
-        frame_mv[refs[0]].as_int =
-          xd->mode_info_context->bmi[0].as_mv[0].as_int = tmp_mv.as_int;
+        frame_mv[refs[0]].as_int = tmp_mv.as_int;
         single_newmv[refs[0]].as_int = tmp_mv.as_int;
 
         // Add the new motion vector cost to our rolling cost variable
@@ -2686,8 +2731,6 @@
     if (this_mode == I4X4_PRED) {
       int rate;
 
-      // Note the rate value returned here includes the cost of coding
-      // the I4X4_PRED mode : x->mbmode_cost[xd->frame_type][I4X4_PRED];
       mbmi->txfm_size = TX_4X4;
       rd_pick_intra4x4mby_modes(cpi, x, &rate, &rate_y,
                                 &distortion_y, INT64_MAX);
diff --git a/vp9/encoder/vp9_tokenize.c b/vp9/encoder/vp9_tokenize.c
index 08efc84..79f72bb 100644
--- a/vp9/encoder/vp9_tokenize.c
+++ b/vp9/encoder/vp9_tokenize.c
@@ -36,6 +36,9 @@
 extern vp9_coeff_stats tree_update_hist_32x32[BLOCK_TYPES];
 #endif  /* ENTROPY_STATS */
 
+DECLARE_ALIGNED(16, extern const uint8_t,
+                vp9_pt_energy_class[MAX_ENTROPY_TOKENS]);
+
 static TOKENVALUE dct_value_tokens[DCT_MAX_VALUE * 2];
 const TOKENVALUE *vp9_dct_value_tokens_ptr;
 static int dct_value_cost[DCT_MAX_VALUE * 2];
@@ -221,14 +224,24 @@
     t->token = token;
     t->context_tree = coef_probs[type][ref][band][pt];
     t->skip_eob_node = (c > 0) && (token_cache[scan[c - 1]] == 0);
+
+#if CONFIG_BALANCED_COEFTREE
+    assert(token <= ZERO_TOKEN ||
+           vp9_coef_encodings[t->token].len - t->skip_eob_node > 0);
+#else
     assert(vp9_coef_encodings[t->token].len - t->skip_eob_node > 0);
+#endif
 
     if (!dry_run) {
       ++counts[type][ref][band][pt][token];
+#if CONFIG_BALANCED_COEFTREE
+      if (!t->skip_eob_node && token > ZERO_TOKEN)
+#else
       if (!t->skip_eob_node)
+#endif
         ++cpi->common.fc.eob_branch_counts[tx_size][type][ref][band][pt];
     }
-    token_cache[scan[c]] = token;
+    token_cache[scan[c]] = vp9_pt_energy_class[token];
     ++t;
   } while (c < eob && ++c < seg_eob);
 
diff --git a/vp9/encoder/vp9_write_bit_buffer.h b/vp9/encoder/vp9_write_bit_buffer.h
new file mode 100644
index 0000000..18cf403
--- /dev/null
+++ b/vp9/encoder/vp9_write_bit_buffer.h
@@ -0,0 +1,42 @@
+/*
+ *  Copyright (c) 2013 The WebM project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef VP9_BIT_WRITE_BUFFER_H_
+#define VP9_BIT_WRITE_BUFFER_H_
+
+#include "vpx/vpx_integer.h"
+
+struct vp9_write_bit_buffer {
+  uint8_t *bit_buffer;
+  size_t bit_offset;
+};
+
+static size_t vp9_rb_bytes_written(struct vp9_write_bit_buffer *wb) {
+  return wb->bit_offset / CHAR_BIT + (wb->bit_offset % CHAR_BIT > 0);
+}
+
+static void vp9_wb_write_bit(struct vp9_write_bit_buffer *wb, int bit) {
+  const int off = wb->bit_offset;
+  const int p = off / CHAR_BIT;
+  const int q = CHAR_BIT - 1 - off % CHAR_BIT;
+  wb->bit_buffer[p] &= ~(1 << q);
+  wb->bit_buffer[p] |= bit << q;
+  wb->bit_offset = off + 1;
+}
+
+static void vp9_wb_write_literal(struct vp9_write_bit_buffer *wb,
+                              int data, int bits) {
+  int bit;
+  for (bit = bits - 1; bit >= 0; bit--)
+    vp9_wb_write_bit(wb, (data >> bit) & 1);
+}
+
+
+#endif  // VP9_BIT_WRITE_BUFFER_H_
diff --git a/vp9/vp9_common.mk b/vp9/vp9_common.mk
index 147804d..29e8323 100644
--- a/vp9/vp9_common.mk
+++ b/vp9/vp9_common.mk
@@ -18,7 +18,6 @@
 VP9_COMMON_SRCS-yes += common/vp9_coefupdateprobs.h
 VP9_COMMON_SRCS-yes += common/vp9_convolve.c
 VP9_COMMON_SRCS-yes += common/vp9_convolve.h
-VP9_COMMON_SRCS-yes += common/vp9_debugmodes.c
 VP9_COMMON_SRCS-yes += common/vp9_default_coef_probs.h
 VP9_COMMON_SRCS-yes += common/vp9_entropy.c
 VP9_COMMON_SRCS-yes += common/vp9_entropymode.c
@@ -38,7 +37,6 @@
 VP9_COMMON_SRCS-yes += common/vp9_enums.h
 VP9_COMMON_SRCS-yes += common/vp9_extend.h
 VP9_COMMON_SRCS-yes += common/vp9_findnearmv.h
-VP9_COMMON_SRCS-yes += common/vp9_header.h
 VP9_COMMON_SRCS-yes += common/vp9_idct.h
 VP9_COMMON_SRCS-yes += common/vp9_invtrans.h
 VP9_COMMON_SRCS-yes += common/vp9_loopfilter.h
diff --git a/vp9/vp9_dx_iface.c b/vp9/vp9_dx_iface.c
index ee11304..b5aa10d 100644
--- a/vp9/vp9_dx_iface.c
+++ b/vp9/vp9_dx_iface.c
@@ -215,26 +215,19 @@
   if (data + data_sz <= data)
     res = VPX_CODEC_INVALID_PARAM;
   else {
-    /* Parse uncompresssed part of key frame header.
-     * 3 bytes:- including version, frame type and an offset
-     * 3 bytes:- sync code (0x49, 0x83, 0x42)
-     * 4 bytes:- including image width and height in the lowest 14 bits
-     *           of each 2-byte value.
-     */
     si->is_kf = 0;
 
-    if (data_sz >= 10 && !(data[0] & 0x01)) { /* I-Frame */
-      const uint8_t *c = data + 3;
+    if (data_sz >= 8 && !(data[0] & 0x80)) { /* I-Frame */
+      const uint8_t *c = data + 1;
       si->is_kf = 1;
 
-      /* vet via sync code */
-      if (c[0] != 0x49 || c[1] != 0x83 || c[2] != 0x42)
+      if (c[0] != SYNC_CODE_0 || c[1] != SYNC_CODE_1 || c[2] != SYNC_CODE_2)
         res = VPX_CODEC_UNSUP_BITSTREAM;
 
-      si->w = (c[3] | (c[4] << 8));
-      si->h = (c[5] | (c[6] << 8));
+      si->w = (c[3] << 8) | c[4];
+      si->h = (c[5] << 8) | c[6];
 
-      /*printf("w=%d, h=%d\n", si->w, si->h);*/
+      // printf("w=%d, h=%d\n", si->w, si->h);
       if (!(si->h | si->w))
         res = VPX_CODEC_UNSUP_BITSTREAM;
     } else
@@ -242,7 +235,6 @@
   }
 
   return res;
-
 }
 
 static vpx_codec_err_t vp8_get_si(vpx_codec_alg_priv_t    *ctx,
diff --git a/vp9/vp9cx.mk b/vp9/vp9cx.mk
index 42ab02d..86fd088 100644
--- a/vp9/vp9cx.mk
+++ b/vp9/vp9cx.mk
@@ -28,6 +28,7 @@
 VP9_CX_SRCS-yes += encoder/vp9_firstpass.c
 VP9_CX_SRCS-yes += encoder/vp9_block.h
 VP9_CX_SRCS-yes += encoder/vp9_boolhuff.h
+VP9_CX_SRCS-yes += encoder/vp9_write_bit_buffer.h
 VP9_CX_SRCS-yes += encoder/vp9_bitstream.h
 VP9_CX_SRCS-yes += encoder/vp9_encodeintra.h
 VP9_CX_SRCS-yes += encoder/vp9_encodemb.h
diff --git a/vp9/vp9dx.mk b/vp9/vp9dx.mk
index 3be0b6d..7ae3219 100644
--- a/vp9/vp9dx.mk
+++ b/vp9/vp9dx.mk
@@ -24,6 +24,7 @@
 VP9_DX_SRCS-yes += decoder/vp9_decodframe.h
 VP9_DX_SRCS-yes += decoder/vp9_detokenize.c
 VP9_DX_SRCS-yes += decoder/vp9_dboolhuff.h
+VP9_DX_SRCS-yes += decoder/vp9_read_bit_buffer.h
 VP9_DX_SRCS-yes += decoder/vp9_decodemv.h
 VP9_DX_SRCS-yes += decoder/vp9_detokenize.h
 VP9_DX_SRCS-yes += decoder/vp9_onyxd.h