Merge "Fix mv range border in pixels" into experimental
diff --git a/test/borders_test.cc b/test/borders_test.cc
index 8cac4fd..49505ee 100644
--- a/test/borders_test.cc
+++ b/test/borders_test.cc
@@ -34,7 +34,7 @@
   virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
                                   ::libvpx_test::Encoder *encoder) {
     if ( video->frame() == 1) {
-      encoder->Control(VP8E_SET_CPUUSED, 5);
+      encoder->Control(VP8E_SET_CPUUSED, 0);
       encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
       encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7);
       encoder->Control(VP8E_SET_ARNR_STRENGTH, 5);
diff --git a/vp9/common/vp9_alloccommon.c b/vp9/common/vp9_alloccommon.c
index 4960963..10bf776 100644
--- a/vp9/common/vp9_alloccommon.c
+++ b/vp9/common/vp9_alloccommon.c
@@ -74,7 +74,7 @@
 
   cm->mi_cols = aligned_width >> LOG2_MI_SIZE;
   cm->mi_rows = aligned_height >> LOG2_MI_SIZE;
-  cm->mode_info_stride = cm->mi_cols + 1;
+  cm->mode_info_stride = cm->mi_cols + 64 / MI_SIZE;
 }
 
 static void setup_mi(VP9_COMMON *cm) {
@@ -131,12 +131,13 @@
   set_mb_mi(oci, aligned_width, aligned_height);
 
   // Allocation
-  oci->mip = vpx_calloc(oci->mode_info_stride * (oci->mi_rows + 1),
+  oci->mip = vpx_calloc(oci->mode_info_stride * (oci->mi_rows + 64 / MI_SIZE),
                         sizeof(MODE_INFO));
   if (!oci->mip)
     goto fail;
 
-  oci->prev_mip = vpx_calloc(oci->mode_info_stride * (oci->mi_rows + 1),
+  oci->prev_mip = vpx_calloc(oci->mode_info_stride *
+                             (oci->mi_rows + 64 / MI_SIZE),
                              sizeof(MODE_INFO));
   if (!oci->prev_mip)
     goto fail;
diff --git a/vp9/common/vp9_blockd.h b/vp9/common/vp9_blockd.h
index 52b736b..2380601 100644
--- a/vp9/common/vp9_blockd.h
+++ b/vp9/common/vp9_blockd.h
@@ -124,12 +124,10 @@
 
 #define TX_SIZE_PROBS  6  // (TX_SIZE_MAX_SB * (TX_SIZE_MAX_SB - 1) / 2)
 
-#if TX_SIZE_PROBS == 6
-#define get_tx_probs_offset(b) ((b) < BLOCK_SIZE_MB16X16 ? 0 : \
-                                (b) < BLOCK_SIZE_SB32X32 ? 1 : 3)
-#else
-#define get_tx_probs_offset(b) 0
-#endif
+#define get_tx_probs(c, b) ((b) < BLOCK_SIZE_MB16X16 ? \
+                            (c)->fc.tx_probs_8x8p :    \
+                            (b) < BLOCK_SIZE_SB32X32 ? \
+                            (c)->fc.tx_probs_16x16p : (c)->fc.tx_probs_32x32p)
 
 /* For keyframes, intra block modes are predicted by the (already decoded)
    modes for the Y blocks to the left and above us; for interframes, there
diff --git a/vp9/common/vp9_entropymode.c b/vp9/common/vp9_entropymode.c
index bf57e7e..7a87cfe 100644
--- a/vp9/common/vp9_entropymode.c
+++ b/vp9/common/vp9_entropymode.c
@@ -149,53 +149,56 @@
   { 235, 248 },
 };
 
-void tx_counts_to_branch_counts(unsigned int *tx_count_32x32p,
-                                unsigned int *tx_count_16x16p,
-                                unsigned int *tx_count_8x8p,
-                                unsigned int (*ct)[2]) {
-#if TX_SIZE_PROBS == 6
-  ct[0][0] = tx_count_8x8p[TX_4X4];
-  ct[0][1] = tx_count_8x8p[TX_8X8];
-  ct[1][0] = tx_count_16x16p[TX_4X4];
-  ct[1][1] = tx_count_16x16p[TX_8X8] + tx_count_16x16p[TX_16X16];
-  ct[2][0] = tx_count_16x16p[TX_8X8];
-  ct[2][1] = tx_count_16x16p[TX_16X16];
-  ct[3][0] = tx_count_32x32p[TX_4X4];
-  ct[3][1] = tx_count_32x32p[TX_8X8] + tx_count_32x32p[TX_16X16] +
-             tx_count_32x32p[TX_32X32];
-  ct[4][0] = tx_count_32x32p[TX_8X8];
-  ct[4][1] = tx_count_32x32p[TX_16X16] + tx_count_32x32p[TX_32X32];
-  ct[5][0] = tx_count_32x32p[TX_16X16];
-  ct[5][1] = tx_count_32x32p[TX_32X32];
-#else
-  ct[0][0] = tx_count_32x32p[TX_4X4] +
-             tx_count_16x16p[TX_4X4] +
-             tx_count_8x8p[TX_4X4];
-  ct[0][1] = tx_count_32x32p[TX_8X8] +
-             tx_count_32x32p[TX_16X16] +
-             tx_count_32x32p[TX_32X32] +
-             tx_count_16x16p[TX_8X8] +
-             tx_count_16x16p[TX_16X16] +
-             tx_count_8x8p[TX_8X8];
-  ct[1][0] = tx_count_32x32p[TX_8X8] +
-             tx_count_16x16p[TX_8X8];
-  ct[1][1] = tx_count_32x32p[TX_16X16] +
-             tx_count_32x32p[TX_32X32] +
-             tx_count_16x16p[TX_16X16];
-  ct[2][0] = tx_count_32x32p[TX_16X16];
-  ct[2][1] = tx_count_32x32p[TX_32X32];
-#endif
+const vp9_prob vp9_default_tx_probs_32x32p[TX_SIZE_MAX_SB]
+                                          [TX_SIZE_MAX_SB - 1] = {
+  { 16, 64, 96, },
+  { 32, 64, 96, },
+  { 32, 64, 96, },
+  { 32, 64, 96, },
+};
+const vp9_prob vp9_default_tx_probs_16x16p[TX_SIZE_MAX_SB - 1]
+                                          [TX_SIZE_MAX_SB - 2] = {
+  { 32, 96, },
+  { 64, 96, },
+  { 64, 96, },
+};
+const vp9_prob vp9_default_tx_probs_8x8p[TX_SIZE_MAX_SB - 2]
+                                        [TX_SIZE_MAX_SB - 3] = {
+  { 96, },
+  { 96, },
+};
+
+void tx_counts_to_branch_counts_32x32(unsigned int *tx_count_32x32p,
+                                      unsigned int (*ct_32x32p)[2]) {
+  ct_32x32p[0][0] = tx_count_32x32p[TX_4X4];
+  ct_32x32p[0][1] = tx_count_32x32p[TX_8X8] +
+                    tx_count_32x32p[TX_16X16] +
+                    tx_count_32x32p[TX_32X32];
+  ct_32x32p[1][0] = tx_count_32x32p[TX_8X8];
+  ct_32x32p[1][1] = tx_count_32x32p[TX_16X16] +
+                    tx_count_32x32p[TX_32X32];
+  ct_32x32p[2][0] = tx_count_32x32p[TX_16X16];
+  ct_32x32p[2][1] = tx_count_32x32p[TX_32X32];
 }
 
-#if TX_SIZE_PROBS == 6
-const vp9_prob vp9_default_tx_probs[TX_SIZE_PROBS] = {
-  96, 96, 96, 96, 96, 96
+void tx_counts_to_branch_counts_16x16(unsigned int *tx_count_16x16p,
+                                      unsigned int (*ct_16x16p)[2]) {
+  ct_16x16p[0][0] = tx_count_16x16p[TX_4X4];
+  ct_16x16p[0][1] = tx_count_16x16p[TX_8X8] +
+                    tx_count_16x16p[TX_16X16];
+  ct_16x16p[1][0] = tx_count_16x16p[TX_8X8];
+  ct_16x16p[1][1] = tx_count_16x16p[TX_16X16];
+}
+
+void tx_counts_to_branch_counts_8x8(unsigned int *tx_count_8x8p,
+                                    unsigned int (*ct_8x8p)[2]) {
+  ct_8x8p[0][0] =   tx_count_8x8p[TX_4X4];
+  ct_8x8p[0][1] =   tx_count_8x8p[TX_8X8];
+}
+
+const vp9_prob vp9_default_mbskip_probs[MBSKIP_CONTEXTS] = {
+  192, 128, 64
 };
-#else
-const vp9_prob vp9_default_tx_probs[TX_SIZE_PROBS] = {
-  96, 96, 96
-};
-#endif
 
 void vp9_init_mbmode_probs(VP9_COMMON *x) {
   vpx_memcpy(x->fc.uv_mode_prob, default_if_uv_probs,
@@ -219,8 +222,14 @@
              sizeof(default_comp_ref_p));
   vpx_memcpy(x->fc.single_ref_prob, default_single_ref_p,
              sizeof(default_single_ref_p));
-  vpx_memcpy(x->fc.tx_probs, vp9_default_tx_probs,
-             sizeof(vp9_default_tx_probs));
+  vpx_memcpy(x->fc.tx_probs_32x32p, vp9_default_tx_probs_32x32p,
+             sizeof(vp9_default_tx_probs_32x32p));
+  vpx_memcpy(x->fc.tx_probs_16x16p, vp9_default_tx_probs_16x16p,
+             sizeof(vp9_default_tx_probs_16x16p));
+  vpx_memcpy(x->fc.tx_probs_8x8p, vp9_default_tx_probs_8x8p,
+             sizeof(vp9_default_tx_probs_8x8p));
+  vpx_memcpy(x->fc.mbskip_probs, vp9_default_mbskip_probs,
+             sizeof(vp9_default_mbskip_probs));
 }
 
 #if VP9_SWITCHABLE_FILTERS == 3
@@ -321,7 +330,7 @@
 
 #define MODE_COUNT_SAT 20
 #define MODE_MAX_UPDATE_FACTOR 144
-static int update_mode_ct(int pre_prob, int prob,
+static int update_mode_ct(vp9_prob pre_prob, vp9_prob prob,
                           unsigned int branch_ct[2]) {
   int factor, count = branch_ct[0] + branch_ct[1];
   count = count > MODE_COUNT_SAT ? MODE_COUNT_SAT : count;
@@ -344,7 +353,7 @@
     dst_probs[t] = update_mode_ct(pre_probs[t], probs[t], branch_ct[t]);
 }
 
-static int update_mode_ct2(int pre_prob, unsigned int branch_ct[2]) {
+static int update_mode_ct2(vp9_prob pre_prob, unsigned int branch_ct[2]) {
   return update_mode_ct(pre_prob, get_binary_prob(branch_ct[0],
                                                   branch_ct[1]), branch_ct);
 }
@@ -425,19 +434,56 @@
     }
   }
   if (cm->txfm_mode == TX_MODE_SELECT) {
-    unsigned int branch_ct[TX_SIZE_PROBS][2];
-    tx_counts_to_branch_counts(cm->fc.tx_count_32x32p,
-                               cm->fc.tx_count_16x16p,
-                               cm->fc.tx_count_8x8p, branch_ct);
-    for (i = 0; i < TX_SIZE_PROBS; ++i) {
-      int factor;
-      int count = branch_ct[i][0] + branch_ct[i][1];
-      vp9_prob prob = get_binary_prob(branch_ct[i][0], branch_ct[i][1]);
-      count = count > MODE_COUNT_SAT ? MODE_COUNT_SAT : count;
-      factor = (MODE_MAX_UPDATE_FACTOR * count / MODE_COUNT_SAT);
-      cm->fc.tx_probs[i] = weighted_prob(cm->fc.pre_tx_probs[i], prob, factor);
+    int j;
+    unsigned int branch_ct_8x8p[TX_SIZE_MAX_SB - 3][2];
+    unsigned int branch_ct_16x16p[TX_SIZE_MAX_SB - 2][2];
+    unsigned int branch_ct_32x32p[TX_SIZE_MAX_SB - 1][2];
+    for (i = 0; i < TX_SIZE_MAX_SB - 2; ++i) {
+      tx_counts_to_branch_counts_8x8(cm->fc.tx_count_8x8p[i],
+                                     branch_ct_8x8p);
+      for (j = 0; j < TX_SIZE_MAX_SB - 3; ++j) {
+        int factor;
+        int count = branch_ct_8x8p[j][0] + branch_ct_8x8p[j][1];
+        vp9_prob prob = get_binary_prob(branch_ct_8x8p[j][0],
+                                        branch_ct_8x8p[j][1]);
+        count = count > MODE_COUNT_SAT ? MODE_COUNT_SAT : count;
+        factor = (MODE_MAX_UPDATE_FACTOR * count / MODE_COUNT_SAT);
+        cm->fc.tx_probs_8x8p[i][j] = weighted_prob(
+            cm->fc.pre_tx_probs_8x8p[i][j], prob, factor);
+      }
+    }
+    for (i = 0; i < TX_SIZE_MAX_SB - 1; ++i) {
+      tx_counts_to_branch_counts_16x16(cm->fc.tx_count_16x16p[i],
+                                       branch_ct_16x16p);
+      for (j = 0; j < TX_SIZE_MAX_SB - 2; ++j) {
+        int factor;
+        int count = branch_ct_16x16p[j][0] + branch_ct_16x16p[j][1];
+        vp9_prob prob = get_binary_prob(branch_ct_16x16p[j][0],
+                                        branch_ct_16x16p[j][1]);
+        count = count > MODE_COUNT_SAT ? MODE_COUNT_SAT : count;
+        factor = (MODE_MAX_UPDATE_FACTOR * count / MODE_COUNT_SAT);
+        cm->fc.tx_probs_16x16p[i][j] = weighted_prob(
+            cm->fc.pre_tx_probs_16x16p[i][j], prob, factor);
+      }
+    }
+    for (i = 0; i < TX_SIZE_MAX_SB; ++i) {
+      tx_counts_to_branch_counts_32x32(cm->fc.tx_count_32x32p[i],
+                                       branch_ct_32x32p);
+      for (j = 0; j < TX_SIZE_MAX_SB - 1; ++j) {
+        int factor;
+        int count = branch_ct_32x32p[j][0] + branch_ct_32x32p[j][1];
+        vp9_prob prob = get_binary_prob(branch_ct_32x32p[j][0],
+                                        branch_ct_32x32p[j][1]);
+        count = count > MODE_COUNT_SAT ? MODE_COUNT_SAT : count;
+        factor = (MODE_MAX_UPDATE_FACTOR * count / MODE_COUNT_SAT);
+        cm->fc.tx_probs_32x32p[i][j] = weighted_prob(
+            cm->fc.pre_tx_probs_32x32p[i][j], prob, factor);
+      }
     }
   }
+  for (i = 0; i < MBSKIP_CONTEXTS; ++i)
+    fc->mbskip_probs[i] = update_mode_ct2(fc->pre_mbskip_probs[i],
+                                          fc->mbskip_count[i]);
 }
 
 static void set_default_lf_deltas(MACROBLOCKD *xd) {
diff --git a/vp9/common/vp9_entropymode.h b/vp9/common/vp9_entropymode.h
index ce13a4c..3e8d566 100644
--- a/vp9/common/vp9_entropymode.h
+++ b/vp9/common/vp9_entropymode.h
@@ -16,6 +16,8 @@
 
 #define SUBMVREF_COUNT 5
 
+// #define MODE_STATS
+
 extern int vp9_mv_cont(const int_mv *l, const int_mv *a);
 
 
@@ -75,11 +77,17 @@
 extern const  vp9_prob vp9_switchable_interp_prob[VP9_SWITCHABLE_FILTERS + 1]
                                                  [VP9_SWITCHABLE_FILTERS - 1];
 
-extern const vp9_prob vp9_default_tx_probs[TX_SIZE_PROBS];
+extern const vp9_prob vp9_default_tx_probs_32x32p[TX_SIZE_MAX_SB]
+                                                 [TX_SIZE_MAX_SB - 1];
+extern const vp9_prob vp9_default_tx_probs_16x16p[TX_SIZE_MAX_SB - 1]
+                                                 [TX_SIZE_MAX_SB - 2];
+extern const vp9_prob vp9_default_tx_probs_8x8p[TX_SIZE_MAX_SB - 2]
+                                               [TX_SIZE_MAX_SB - 3];
 
-extern void tx_counts_to_branch_counts(unsigned int *tx_count_32x32p,
-                                       unsigned int *tx_count_16x16p,
-                                       unsigned int *tx_count_8x8p,
-                                       unsigned int (*ct)[2]);
-
+extern void tx_counts_to_branch_counts_32x32(unsigned int *tx_count_32x32p,
+                                             unsigned int (*ct_32x32p)[2]);
+extern void tx_counts_to_branch_counts_16x16(unsigned int *tx_count_16x16p,
+                                             unsigned int (*ct_16x16p)[2]);
+extern void tx_counts_to_branch_counts_8x8(unsigned int *tx_count_8x8p,
+                                           unsigned int (*ct_8x8p)[2]);
 #endif  // VP9_COMMON_VP9_ENTROPYMODE_H_
diff --git a/vp9/common/vp9_onyxc_int.h b/vp9/common/vp9_onyxc_int.h
index dedda20..d91483d 100644
--- a/vp9/common/vp9_onyxc_int.h
+++ b/vp9/common/vp9_onyxc_int.h
@@ -89,11 +89,20 @@
   unsigned int comp_inter_count[COMP_INTER_CONTEXTS][2];
   unsigned int single_ref_count[REF_CONTEXTS][2][2];
   unsigned int comp_ref_count[REF_CONTEXTS][2];
-  vp9_prob tx_probs[TX_SIZE_PROBS];
-  vp9_prob pre_tx_probs[TX_SIZE_PROBS];
-  unsigned int tx_count_32x32p[TX_SIZE_MAX_SB];
-  unsigned int tx_count_16x16p[TX_SIZE_MAX_SB - 1];
-  unsigned int tx_count_8x8p[TX_SIZE_MAX_SB - 2];
+
+  vp9_prob tx_probs_32x32p[TX_SIZE_MAX_SB][TX_SIZE_MAX_SB - 1];
+  vp9_prob tx_probs_16x16p[TX_SIZE_MAX_SB - 1][TX_SIZE_MAX_SB - 2];
+  vp9_prob tx_probs_8x8p[TX_SIZE_MAX_SB - 2][TX_SIZE_MAX_SB - 3];
+  vp9_prob pre_tx_probs_32x32p[TX_SIZE_MAX_SB][TX_SIZE_MAX_SB - 1];
+  vp9_prob pre_tx_probs_16x16p[TX_SIZE_MAX_SB - 1][TX_SIZE_MAX_SB - 2];
+  vp9_prob pre_tx_probs_8x8p[TX_SIZE_MAX_SB - 2][TX_SIZE_MAX_SB - 3];
+  unsigned int tx_count_32x32p[TX_SIZE_MAX_SB][TX_SIZE_MAX_SB];
+  unsigned int tx_count_16x16p[TX_SIZE_MAX_SB - 1][TX_SIZE_MAX_SB - 1];
+  unsigned int tx_count_8x8p[TX_SIZE_MAX_SB - 2][TX_SIZE_MAX_SB - 2];
+
+  vp9_prob mbskip_probs[MBSKIP_CONTEXTS];
+  vp9_prob pre_mbskip_probs[MBSKIP_CONTEXTS];
+  unsigned int mbskip_count[MBSKIP_CONTEXTS][2];
 } FRAME_CONTEXT;
 
 typedef enum {
@@ -165,6 +174,8 @@
   int intra_only;
 
   // Flag signaling that the frame context should be reset to default values.
+  // 0 or 1 implies don't reset, 2 reset just the context specified in the
+  // frame header, 3 reset all contexts.
   int reset_frame_context;
 
   int frame_flags;
@@ -244,8 +255,6 @@
   MV_REFERENCE_FRAME comp_var_ref[2];
   COMPPREDMODE_TYPE comp_pred_mode;
 
-  vp9_prob mbskip_pred_probs[MBSKIP_CONTEXTS];
-
   FRAME_CONTEXT fc;  /* this frame entropy */
   FRAME_CONTEXT frame_contexts[NUM_FRAME_CONTEXTS];
   unsigned int  frame_context_idx; /* Context to use/update */
@@ -301,6 +310,30 @@
   xd->left_seg_context  = cm->left_seg_context + (mi_row & MI_MASK);
 }
 
+static int check_bsize_coverage(VP9_COMMON *cm, MACROBLOCKD *xd,
+                                int mi_row, int mi_col,
+                                BLOCK_SIZE_TYPE bsize) {
+  int bsl = mi_width_log2(bsize), bs = 1 << bsl;
+  int ms = bs / 2;
+
+  if ((mi_row + bs <= cm->mi_rows) && (mi_col + ms < cm->mi_cols))
+    return 0;
+  if ((mi_col + bs <= cm->mi_cols) && (mi_row + ms < cm->mi_rows))
+    return 0;
+
+  // frame width/height are multiples of 8, hence 8x8 block should always
+  // pass the above check
+  assert(bsize > BLOCK_SIZE_SB8X8);
+
+  // return the node index in the prob tree for binary coding
+  if ((mi_col + bs <= cm->mi_cols) && (mi_row + ms >= cm->mi_rows))
+    return 1;
+  if ((mi_row + bs <= cm->mi_rows) && (mi_col + ms >= cm->mi_cols))
+    return 2;
+
+  return -1;
+}
+
 static void set_mi_row_col(VP9_COMMON *cm, MACROBLOCKD *xd,
                        int mi_row, int bh,
                        int mi_col, int bw) {
diff --git a/vp9/common/vp9_pred_common.c b/vp9/common/vp9_pred_common.c
index 73c7278..16ba53e 100644
--- a/vp9/common/vp9_pred_common.c
+++ b/vp9/common/vp9_pred_common.c
@@ -348,6 +348,37 @@
       break;
     }
 
+    case PRED_TX_SIZE: {
+      int above_context = TX_16X16, left_context = TX_16X16;
+      int max_tx_size;
+      if (mi->mbmi.sb_type < BLOCK_SIZE_SB8X8)
+        max_tx_size = TX_4X4;
+      else if (mi->mbmi.sb_type < BLOCK_SIZE_MB16X16)
+        max_tx_size = TX_8X8;
+      else if (mi->mbmi.sb_type < BLOCK_SIZE_SB32X32)
+        max_tx_size = TX_16X16;
+      else
+        max_tx_size = TX_32X32;
+      if (xd->up_available) {
+        above_context = (above_mi->mbmi.mb_skip_coeff ?
+                         max_tx_size : above_mi->mbmi.txfm_size);
+      }
+      if (xd->left_available) {
+        left_context = (left_mi->mbmi.mb_skip_coeff ?
+                        max_tx_size : left_mi->mbmi.txfm_size);
+      }
+      if (!xd->left_available) {
+        left_context = above_context;
+      }
+      if (!xd->up_available) {
+        above_context = left_context;
+      }
+      pred_context = (above_context + left_context + 1) >> 1;
+      if (pred_context > max_tx_size)
+        pred_context = max_tx_size;
+      break;
+    }
+
     default:
       assert(0);
       pred_context = 0;  // *** add error trap code.
@@ -368,7 +399,7 @@
     case PRED_SEG_ID:
       return cm->segment_pred_probs[pred_context];
     case PRED_MBSKIP:
-      return cm->mbskip_pred_probs[pred_context];
+      return cm->fc.mbskip_probs[pred_context];
     case PRED_INTRA_INTER:
       return cm->fc.intra_inter_prob[pred_context];
     case PRED_COMP_INTER_INTER:
@@ -390,11 +421,21 @@
 const vp9_prob *vp9_get_pred_probs(const VP9_COMMON *const cm,
                                    const MACROBLOCKD *const xd,
                                    PRED_ID pred_id) {
+  const MODE_INFO *const mi = xd->mode_info_context;
   const int pred_context = vp9_get_pred_context(cm, xd, pred_id);
 
   switch (pred_id) {
     case PRED_SWITCHABLE_INTERP:
       return &cm->fc.switchable_interp_prob[pred_context][0];
+
+    case PRED_TX_SIZE:
+      if (mi->mbmi.sb_type < BLOCK_SIZE_MB16X16)
+        return cm->fc.tx_probs_8x8p[pred_context];
+      else if (mi->mbmi.sb_type < BLOCK_SIZE_SB32X32)
+        return cm->fc.tx_probs_16x16p[pred_context];
+      else
+        return cm->fc.tx_probs_32x32p[pred_context];
+
     default:
       assert(0);
       return NULL;  // *** add error trap code.
diff --git a/vp9/common/vp9_pred_common.h b/vp9/common/vp9_pred_common.h
index 6d52997..b728724 100644
--- a/vp9/common/vp9_pred_common.h
+++ b/vp9/common/vp9_pred_common.h
@@ -24,6 +24,7 @@
   PRED_SINGLE_REF_P1 = 5,
   PRED_SINGLE_REF_P2 = 6,
   PRED_COMP_REF_P = 7,
+  PRED_TX_SIZE = 8
 } PRED_ID;
 
 unsigned char vp9_get_pred_context(const VP9_COMMON *const cm,
diff --git a/vp9/decoder/vp9_decodemv.c b/vp9/decoder/vp9_decodemv.c
index 82ea7dc..99902d9 100644
--- a/vp9/decoder/vp9_decodemv.c
+++ b/vp9/decoder/vp9_decodemv.c
@@ -63,21 +63,22 @@
   }
 }
 
-static TX_SIZE select_txfm_size(VP9_COMMON *cm, vp9_reader *r,
-                                BLOCK_SIZE_TYPE bsize) {
-  int tx_probs_offset = get_tx_probs_offset(bsize);
-  TX_SIZE txfm_size = vp9_read(r, cm->fc.tx_probs[tx_probs_offset]);
+static TX_SIZE select_txfm_size(VP9_COMMON *cm, MACROBLOCKD *xd,
+                                vp9_reader *r, BLOCK_SIZE_TYPE bsize) {
+  const int context = vp9_get_pred_context(cm, xd, PRED_TX_SIZE);
+  const vp9_prob *tx_probs = vp9_get_pred_probs(cm, xd, PRED_TX_SIZE);
+  TX_SIZE txfm_size = vp9_read(r, tx_probs[0]);
   if (txfm_size != TX_4X4 && bsize >= BLOCK_SIZE_MB16X16) {
-    txfm_size += vp9_read(r, cm->fc.tx_probs[tx_probs_offset + 1]);
+    txfm_size += vp9_read(r, tx_probs[1]);
     if (txfm_size != TX_8X8 && bsize >= BLOCK_SIZE_SB32X32)
-      txfm_size += vp9_read(r, cm->fc.tx_probs[tx_probs_offset + 2]);
+      txfm_size += vp9_read(r, tx_probs[2]);
   }
   if (bsize >= BLOCK_SIZE_SB32X32) {
-    cm->fc.tx_count_32x32p[txfm_size]++;
+    cm->fc.tx_count_32x32p[context][txfm_size]++;
   } else if (bsize >= BLOCK_SIZE_MB16X16) {
-    cm->fc.tx_count_16x16p[txfm_size]++;
+    cm->fc.tx_count_16x16p[context][txfm_size]++;
   } else {
-    cm->fc.tx_count_8x8p[txfm_size]++;
+    cm->fc.tx_count_8x8p[context][txfm_size]++;
   }
   return txfm_size;
 }
@@ -99,12 +100,15 @@
 
   m->mbmi.mb_skip_coeff = vp9_segfeature_active(xd, m->mbmi.segment_id,
                                                 SEG_LVL_SKIP);
-  if (!m->mbmi.mb_skip_coeff)
+  if (!m->mbmi.mb_skip_coeff) {
     m->mbmi.mb_skip_coeff = vp9_read(r, vp9_get_pred_prob(cm, xd, PRED_MBSKIP));
+    cm->fc.mbskip_count[vp9_get_pred_context(cm, xd, PRED_MBSKIP)]
+                       [m->mbmi.mb_skip_coeff]++;
+  }
 
   if (cm->txfm_mode == TX_MODE_SELECT &&
       m->mbmi.sb_type >= BLOCK_SIZE_SB8X8) {
-    m->mbmi.txfm_size = select_txfm_size(cm, r,  m->mbmi.sb_type);
+    m->mbmi.txfm_size = select_txfm_size(cm, xd, r, m->mbmi.sb_type);
   } else if (cm->txfm_mode >= ALLOW_32X32 &&
              m->mbmi.sb_type >= BLOCK_SIZE_SB32X32) {
     m->mbmi.txfm_size = TX_32X32;
@@ -521,8 +525,11 @@
 
   mbmi->mb_skip_coeff = vp9_segfeature_active(xd, mbmi->segment_id,
                                               SEG_LVL_SKIP);
-  if (!mbmi->mb_skip_coeff)
+  if (!mbmi->mb_skip_coeff) {
     mbmi->mb_skip_coeff = vp9_read(r, vp9_get_pred_prob(cm, xd, PRED_MBSKIP));
+    cm->fc.mbskip_count[vp9_get_pred_context(cm, xd, PRED_MBSKIP)]
+                       [mbmi->mb_skip_coeff]++;
+  }
 
   // Read the reference frame
   if (!vp9_segfeature_active(xd, mbmi->segment_id, SEG_LVL_REF_FRAME)) {
@@ -538,7 +545,7 @@
   if (cm->txfm_mode == TX_MODE_SELECT &&
       (mbmi->mb_skip_coeff == 0 || mbmi->ref_frame[0] == INTRA_FRAME) &&
       bsize >= BLOCK_SIZE_SB8X8) {
-    mbmi->txfm_size = select_txfm_size(cm, r, bsize);
+    mbmi->txfm_size = select_txfm_size(cm, xd, r, bsize);
   } else if (bsize >= BLOCK_SIZE_SB32X32 &&
              cm->txfm_mode >= ALLOW_32X32) {
     mbmi->txfm_size = TX_32X32;
@@ -788,9 +795,14 @@
   int k;
 
   // TODO(jkoleszar): does this clear more than MBSKIP_CONTEXTS? Maybe remove.
-  vpx_memset(cm->mbskip_pred_probs, 0, sizeof(cm->mbskip_pred_probs));
-  for (k = 0; k < MBSKIP_CONTEXTS; ++k)
-    cm->mbskip_pred_probs[k] = vp9_read_prob(r);
+  // vpx_memset(cm->fc.mbskip_probs, 0, sizeof(cm->fc.mbskip_probs));
+  for (k = 0; k < MBSKIP_CONTEXTS; ++k) {
+    if (vp9_read(r, VP9_DEF_UPDATE_PROB)) {
+      cm->fc.mbskip_probs[k] =
+          vp9_read_prob_diff_update(r, cm->fc.mbskip_probs[k]);
+    }
+    // cm->fc.mbskip_probs[k] = vp9_read_prob(r);
+  }
 
   mb_mode_mv_init(pbi, r);
 }
diff --git a/vp9/decoder/vp9_decodframe.c b/vp9/decoder/vp9_decodframe.c
index deb3956..880fd79 100644
--- a/vp9/decoder/vp9_decodframe.c
+++ b/vp9/decoder/vp9_decodframe.c
@@ -58,15 +58,35 @@
     if (pc->txfm_mode == ALLOW_32X32)
       pc->txfm_mode += vp9_read_bit(r);
     if (pc->txfm_mode == TX_MODE_SELECT) {
-      int i;
-      for (i = 0; i < TX_SIZE_PROBS; ++i) {
-        if (vp9_read(r, VP9_DEF_UPDATE_PROB))
-           pc->fc.tx_probs[i] =
-               vp9_read_prob_diff_update(r, pc->fc.tx_probs[i]);
+      int i, j;
+      for (i = 0; i < TX_SIZE_MAX_SB - 2; ++i) {
+        for (j = 0; j < TX_SIZE_MAX_SB - 3; ++j) {
+          if (vp9_read(r, VP9_DEF_UPDATE_PROB))
+            pc->fc.tx_probs_8x8p[i][j] =
+                vp9_read_prob_diff_update(r, pc->fc.tx_probs_8x8p[i][j]);
+        }
+      }
+      for (i = 0; i < TX_SIZE_MAX_SB - 1; ++i) {
+        for (j = 0; j < TX_SIZE_MAX_SB - 2; ++j) {
+          if (vp9_read(r, VP9_DEF_UPDATE_PROB))
+            pc->fc.tx_probs_16x16p[i][j] =
+                vp9_read_prob_diff_update(r, pc->fc.tx_probs_16x16p[i][j]);
+        }
+      }
+      for (i = 0; i < TX_SIZE_MAX_SB; ++i) {
+        for (j = 0; j < TX_SIZE_MAX_SB - 1; ++j) {
+          if (vp9_read(r, VP9_DEF_UPDATE_PROB))
+            pc->fc.tx_probs_32x32p[i][j] =
+                vp9_read_prob_diff_update(r, pc->fc.tx_probs_32x32p[i][j]);
+        }
       }
     } else {
-      vpx_memcpy(pc->fc.tx_probs, vp9_default_tx_probs,
-                 sizeof(vp9_default_tx_probs));
+      vpx_memcpy(pc->fc.tx_probs_8x8p, vp9_default_tx_probs_8x8p,
+                 sizeof(vp9_default_tx_probs_8x8p));
+      vpx_memcpy(pc->fc.tx_probs_16x16p, vp9_default_tx_probs_16x16p,
+                 sizeof(vp9_default_tx_probs_16x16p));
+      vpx_memcpy(pc->fc.tx_probs_32x32p, vp9_default_tx_probs_32x32p,
+                 sizeof(vp9_default_tx_probs_32x32p));
     }
   }
 }
@@ -469,12 +489,21 @@
 
   if (bsize >= BLOCK_SIZE_SB8X8) {
     int pl;
+    int idx = check_bsize_coverage(pc, xd, mi_row, mi_col, bsize);
     // read the partition information
     xd->left_seg_context = pc->left_seg_context + (mi_row & MI_MASK);
     xd->above_seg_context = pc->above_seg_context + mi_col;
     pl = partition_plane_context(xd, bsize);
-    partition = treed_read(r, vp9_partition_tree,
-                           pc->fc.partition_prob[pc->frame_type][pl]);
+
+    if (idx == 0)
+      partition = treed_read(r, vp9_partition_tree,
+                             pc->fc.partition_prob[pc->frame_type][pl]);
+    else if (idx > 0 &&
+        !vp9_read(r, pc->fc.partition_prob[pc->frame_type][pl][idx]))
+      partition = (idx == 1) ? PARTITION_HORZ : PARTITION_VERT;
+    else
+      partition = PARTITION_SPLIT;
+
     pc->fc.partition_counts[pl][partition]++;
   }
 
@@ -711,34 +740,20 @@
                              : vp9_rb_read_literal(rb, 2);
 }
 
-static void read_frame_size(VP9_COMMON *cm,
-                            struct vp9_read_bit_buffer *rb,
+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(&cm->error, VPX_CODEC_CORRUPT_FRAME,
-                       "Invalid frame height");
+  const int w = vp9_rb_read_literal(rb, 16) + 1;
+  const int h = vp9_rb_read_literal(rb, 16) + 1;
   *width = w;
   *height = h;
 }
 
-static void setup_display_size(VP9D_COMP *pbi,
-                               struct vp9_read_bit_buffer *rb) {
+static void setup_display_size(VP9D_COMP *pbi, struct vp9_read_bit_buffer *rb) {
   VP9_COMMON *const cm = &pbi->common;
-  if (vp9_rb_read_bit(rb)) {
-    int width, height;
-    read_frame_size(cm, rb, &width, &height);
-    cm->display_width = width;
-    cm->display_height = height;
-  } else {
-    cm->display_width = cm->width;
-    cm->display_height = cm->height;
-  }
+  cm->display_width = cm->width;
+  cm->display_height = cm->height;
+  if (vp9_rb_read_bit(rb))
+    read_frame_size(cm, rb, &cm->display_width, &cm->display_height);
 }
 
 static void apply_frame_size(VP9D_COMP *pbi, int width, int height) {
@@ -781,6 +796,29 @@
   apply_frame_size(pbi, width, height);
 }
 
+static void setup_frame_size_with_refs(VP9D_COMP *pbi,
+                                       struct vp9_read_bit_buffer *rb) {
+  VP9_COMMON *const cm = &pbi->common;
+
+  int width, height;
+  int found = 0, i;
+  for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) {
+    if (vp9_rb_read_bit(rb)) {
+      YV12_BUFFER_CONFIG *cfg = &cm->yv12_fb[cm->active_ref_idx[i]];
+      width = cfg->y_crop_width;
+      height = cfg->y_crop_height;
+      found = 1;
+      break;
+    }
+  }
+
+  if (!found)
+    read_frame_size(cm, rb, &width, &height);
+
+  setup_display_size(pbi, rb);
+  apply_frame_size(pbi, width, height);
+}
+
 static void update_frame_context(FRAME_CONTEXT *fc) {
   vp9_copy(fc->pre_coef_probs, fc->coef_probs);
   vp9_copy(fc->pre_y_mode_prob, fc->y_mode_prob);
@@ -793,7 +831,10 @@
   fc->pre_nmvc = fc->nmvc;
   vp9_copy(fc->pre_switchable_interp_prob, fc->switchable_interp_prob);
   vp9_copy(fc->pre_inter_mode_probs, fc->inter_mode_probs);
-  vp9_copy(fc->pre_tx_probs, fc->tx_probs);
+  vp9_copy(fc->pre_tx_probs_8x8p, fc->tx_probs_8x8p);
+  vp9_copy(fc->pre_tx_probs_16x16p, fc->tx_probs_16x16p);
+  vp9_copy(fc->pre_tx_probs_32x32p, fc->tx_probs_32x32p);
+  vp9_copy(fc->pre_mbskip_probs, fc->mbskip_probs);
 
   vp9_zero(fc->coef_counts);
   vp9_zero(fc->eob_branch_counts);
@@ -810,6 +851,7 @@
   vp9_zero(fc->tx_count_8x8p);
   vp9_zero(fc->tx_count_16x16p);
   vp9_zero(fc->tx_count_32x32p);
+  vp9_zero(fc->mbskip_count);
 }
 
 static void decode_tile(VP9D_COMP *pbi, vp9_reader *r) {
@@ -919,12 +961,49 @@
   }
 }
 
+static void check_sync_code(VP9_COMMON *cm, struct vp9_read_bit_buffer *rb) {
+  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");
+  }
+}
 
 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");
 }
 
+static void setup_inter_inter(VP9_COMMON *cm) {
+  int i;
+
+  cm->allow_comp_inter_inter = 0;
+  for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) {
+    cm->allow_comp_inter_inter |= i > 0 &&
+        cm->ref_frame_sign_bias[i + 1] != cm->ref_frame_sign_bias[1];
+  }
+
+  if (cm->allow_comp_inter_inter) {
+    // which one is always-on in comp inter-inter?
+    if (cm->ref_frame_sign_bias[LAST_FRAME] ==
+        cm->ref_frame_sign_bias[GOLDEN_FRAME]) {
+      cm->comp_fixed_ref = ALTREF_FRAME;
+      cm->comp_var_ref[0] = LAST_FRAME;
+      cm->comp_var_ref[1] = GOLDEN_FRAME;
+    } else if (cm->ref_frame_sign_bias[LAST_FRAME] ==
+               cm->ref_frame_sign_bias[ALTREF_FRAME]) {
+      cm->comp_fixed_ref = GOLDEN_FRAME;
+      cm->comp_var_ref[0] = LAST_FRAME;
+      cm->comp_var_ref[1] = ALTREF_FRAME;
+    } else {
+      cm->comp_fixed_ref = LAST_FRAME;
+      cm->comp_var_ref[0] = GOLDEN_FRAME;
+      cm->comp_var_ref[1] = ALTREF_FRAME;
+    }
+  }
+}
+
 #define RESERVED \
   if (vp9_rb_read_bit(rb)) \
       vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM, \
@@ -961,12 +1040,7 @@
   if (cm->frame_type == KEY_FRAME) {
     int csp;
 
-    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");
-    }
+    check_sync_code(cm, rb);
 
     csp = vp9_rb_read_literal(rb, 3);  // colorspace
     if (csp != 7) {  // != sRGB
@@ -997,52 +1071,38 @@
 
     setup_frame_size(pbi, rb);
   } else {
+    cm->intra_only = cm->show_frame ? 0 : vp9_rb_read_bit(rb);
+
     if (cm->error_resilient_mode)
       vp9_setup_past_independence(cm, xd);
 
-    pbi->refresh_frame_flags = vp9_rb_read_literal(rb, NUM_REF_FRAMES);
+    if (cm->intra_only) {
+      check_sync_code(cm, rb);
+      pbi->refresh_frame_flags = vp9_rb_read_literal(rb, NUM_REF_FRAMES);
+      setup_frame_size(pbi, rb);
+    } else {
+       pbi->refresh_frame_flags = vp9_rb_read_literal(rb, NUM_REF_FRAMES);
 
-    for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) {
-      const int ref = vp9_rb_read_literal(rb, NUM_REF_FRAMES_LG2);
-      cm->active_ref_idx[i] = cm->ref_frame_map[ref];
-      cm->ref_frame_sign_bias[LAST_FRAME + i] = vp9_rb_read_bit(rb);
-    }
-
-    setup_frame_size(pbi, rb);
-
-    // Read the sign bias for each reference frame buffer.
-    cm->allow_comp_inter_inter = 0;
-    for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) {
-      vp9_setup_scale_factors(cm, i);
-      cm->allow_comp_inter_inter |= i > 0 &&
-          cm->ref_frame_sign_bias[i + 1] != cm->ref_frame_sign_bias[1];
-    }
-
-    if (cm->allow_comp_inter_inter) {
-      // which one is always-on in comp inter-inter?
-      if (cm->ref_frame_sign_bias[LAST_FRAME] ==
-          cm->ref_frame_sign_bias[GOLDEN_FRAME]) {
-        cm->comp_fixed_ref = ALTREF_FRAME;
-        cm->comp_var_ref[0] = LAST_FRAME;
-        cm->comp_var_ref[1] = GOLDEN_FRAME;
-      } else if (cm->ref_frame_sign_bias[LAST_FRAME] ==
-                 cm->ref_frame_sign_bias[ALTREF_FRAME]) {
-        cm->comp_fixed_ref = GOLDEN_FRAME;
-        cm->comp_var_ref[0] = LAST_FRAME;
-        cm->comp_var_ref[1] = ALTREF_FRAME;
-      } else {
-        cm->comp_fixed_ref = LAST_FRAME;
-        cm->comp_var_ref[0] = GOLDEN_FRAME;
-        cm->comp_var_ref[1] = ALTREF_FRAME;
+      for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) {
+        const int ref = vp9_rb_read_literal(rb, NUM_REF_FRAMES_LG2);
+        cm->active_ref_idx[i] = cm->ref_frame_map[ref];
+        cm->ref_frame_sign_bias[LAST_FRAME + i] = vp9_rb_read_bit(rb);
       }
-    }
 
-    xd->allow_high_precision_mv = vp9_rb_read_bit(rb);
-    cm->mcomp_filter_type = read_interp_filter_type(rb);
+      setup_frame_size_with_refs(pbi, rb);
+
+      xd->allow_high_precision_mv = vp9_rb_read_bit(rb);
+      cm->mcomp_filter_type = read_interp_filter_type(rb);
+
+      for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i)
+        vp9_setup_scale_factors(cm, i);
+
+      setup_inter_inter(cm);
+    }
   }
 
   if (!cm->error_resilient_mode) {
-    cm->reset_frame_context = vp9_rb_read_bit(rb);
+    cm->reset_frame_context = vp9_rb_read_literal(rb, 2);
     cm->refresh_frame_context = vp9_rb_read_bit(rb);
     cm->frame_parallel_decoding_mode = vp9_rb_read_bit(rb);
   } else {
@@ -1051,9 +1111,7 @@
     cm->frame_parallel_decoding_mode = 1;
   }
 
-  cm->intra_only = cm->show_frame ? 0 : vp9_rb_read_bit(rb);
   cm->frame_context_idx = vp9_rb_read_literal(rb, NUM_FRAME_CONTEXTS_LG2);
-  cm->clr_type = (YUV_TYPE)vp9_rb_read_bit(rb);
 
   setup_loopfilter(pbi, rb);
   setup_quantization(pbi, rb);
@@ -1088,10 +1146,8 @@
   xd->corrupted = 0;
   new_fb->corrupted = 0;
 
-  if ((!pbi->decoded_key_frame && !keyframe) ||
-      pc->width == 0 || pc->height == 0) {
+  if (!pbi->decoded_key_frame && !keyframe)
     return -1;
-  }
 
   vp9_setup_version(pc);
   if (!read_is_valid(data, first_partition_size, data_end))
diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c
index 2070432..ede067e 100644
--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -51,6 +51,74 @@
 #define vp9_cost_upd  ((int)(vp9_cost_one(upd) - vp9_cost_zero(upd)) >> 8)
 #define vp9_cost_upd256  ((int)(vp9_cost_one(upd) - vp9_cost_zero(upd)))
 
+#ifdef MODE_STATS
+int64_t tx_count_32x32p_stats[TX_SIZE_MAX_SB][TX_SIZE_MAX_SB];
+int64_t tx_count_16x16p_stats[TX_SIZE_MAX_SB - 1][TX_SIZE_MAX_SB - 1];
+int64_t tx_count_8x8p_stats[TX_SIZE_MAX_SB - 2][TX_SIZE_MAX_SB - 2];
+
+void init_tx_count_stats() {
+  vp9_zero(tx_count_32x32p_stats);
+  vp9_zero(tx_count_16x16p_stats);
+  vp9_zero(tx_count_8x8p_stats);
+}
+
+static void update_tx_count_stats(VP9_COMMON *cm) {
+  int i, j;
+  for (i = 0; i < TX_SIZE_MAX_SB; i++) {
+    for (j = 0; j < TX_SIZE_MAX_SB; j++) {
+      tx_count_32x32p_stats[i][j] += cm->fc.tx_count_32x32p[i][j];
+    }
+  }
+  for (i = 0; i < TX_SIZE_MAX_SB - 1; i++) {
+    for (j = 0; j < TX_SIZE_MAX_SB - 1; j++) {
+      tx_count_16x16p_stats[i][j] += cm->fc.tx_count_16x16p[i][j];
+    }
+  }
+  for (i = 0; i < TX_SIZE_MAX_SB - 2; i++) {
+    for (j = 0; j < TX_SIZE_MAX_SB - 2; j++) {
+      tx_count_8x8p_stats[i][j] += cm->fc.tx_count_8x8p[i][j];
+    }
+  }
+}
+
+void write_tx_count_stats() {
+  int i, j;
+  FILE *fp = fopen("tx_count.bin", "wb");
+  fwrite(tx_count_32x32p_stats, sizeof(tx_count_32x32p_stats), 1, fp);
+  fwrite(tx_count_16x16p_stats, sizeof(tx_count_16x16p_stats), 1, fp);
+  fwrite(tx_count_8x8p_stats, sizeof(tx_count_8x8p_stats), 1, fp);
+  fclose(fp);
+
+  printf("vp9_default_tx_count_32x32p[TX_SIZE_MAX_SB][TX_SIZE_MAX_SB] = {\n");
+  for (i = 0; i < TX_SIZE_MAX_SB; i++) {
+    printf("{ ");
+    for (j = 0; j < TX_SIZE_MAX_SB; j++) {
+      printf("%"PRId64", ", tx_count_32x32p_stats[i][j]);
+    }
+    printf("},\n");
+  }
+  printf("};\n");
+  printf("vp9_default_tx_count_16x16p[TX_SIZE_MAX_SB-1][TX_SIZE_MAX_SB-1] = {\n");
+  for (i = 0; i < TX_SIZE_MAX_SB - 1; i++) {
+    printf("{ ");
+    for (j = 0; j < TX_SIZE_MAX_SB - 1; j++) {
+      printf("%"PRId64", ", tx_count_16x16p_stats[i][j]);
+    }
+    printf("},\n");
+  }
+  printf("};\n");
+  printf("vp9_default_tx_count_8x8p[TX_SIZE_MAX_SB-2][TX_SIZE_MAX_SB-2] = {\n");
+  for (i = 0; i < TX_SIZE_MAX_SB - 2; i++) {
+    printf("{ ");
+    for (j = 0; j < TX_SIZE_MAX_SB - 2; j++) {
+      printf("%"PRId64", ", tx_count_8x8p_stats[i][j]);
+    }
+    printf("},\n");
+  }
+  printf("};\n");
+}
+#endif
+
 static int update_bits[255];
 
 static INLINE void write_le32(uint8_t *p, int value) {
@@ -334,13 +402,18 @@
                 (unsigned int *)cpi->y_mode_count[j]);
 }
 
-void vp9_update_skip_probs(VP9_COMP *cpi) {
+void vp9_update_skip_probs(VP9_COMP *cpi, vp9_writer *bc) {
   VP9_COMMON *const pc = &cpi->common;
   int k;
 
-  for (k = 0; k < MBSKIP_CONTEXTS; ++k)
-    pc->mbskip_pred_probs[k] = get_binary_prob(cpi->skip_false_count[k],
-                                               cpi->skip_true_count[k]);
+  for (k = 0; k < MBSKIP_CONTEXTS; ++k) {
+    vp9_cond_prob_diff_update(bc, &pc->fc.mbskip_probs[k],
+                              VP9_DEF_UPDATE_PROB, pc->fc.mbskip_count[k]);
+    /*
+    pc->fc.mbskip_probs[k] = get_binary_prob(pc->fc.mbskip_count[k][0],
+                                                  pc->fc.mbskip_count[k][1]);
+                                                  */
+  }
 }
 
 static void write_intra_mode(vp9_writer *bc, int m, const vp9_prob *p) {
@@ -569,12 +642,12 @@
       !(rf != INTRA_FRAME &&
         (skip_coeff || vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)))) {
     TX_SIZE sz = mi->txfm_size;
-    int tx_probs_offset = get_tx_probs_offset(mi->sb_type);
-    vp9_write(bc, sz != TX_4X4, pc->fc.tx_probs[tx_probs_offset]);
+    const vp9_prob *tx_probs = vp9_get_pred_probs(pc, xd, PRED_TX_SIZE);
+    vp9_write(bc, sz != TX_4X4, tx_probs[0]);
     if (mi->sb_type >= BLOCK_SIZE_MB16X16 && sz != TX_4X4) {
-      vp9_write(bc, sz != TX_8X8, pc->fc.tx_probs[tx_probs_offset + 1]);
+      vp9_write(bc, sz != TX_8X8, tx_probs[1]);
       if (mi->sb_type >= BLOCK_SIZE_SB32X32 && sz != TX_8X8)
-        vp9_write(bc, sz != TX_16X16, pc->fc.tx_probs[tx_probs_offset + 2]);
+        vp9_write(bc, sz != TX_16X16, tx_probs[2]);
     }
   }
 
@@ -658,10 +731,6 @@
           }
         }
       }
-
-#ifdef MODE_STATS
-      ++count_mb_seg[mi->partitioning];
-#endif
     } else if (mode == NEWMV) {
 #ifdef ENTROPY_STATS
       active_section = 5;
@@ -700,12 +769,12 @@
 
   if (m->mbmi.sb_type >= BLOCK_SIZE_SB8X8 && c->txfm_mode == TX_MODE_SELECT) {
     TX_SIZE sz = m->mbmi.txfm_size;
-    int tx_probs_offset = get_tx_probs_offset(m->mbmi.sb_type);
-    vp9_write(bc, sz != TX_4X4, c->fc.tx_probs[tx_probs_offset]);
+    const vp9_prob *tx_probs = vp9_get_pred_probs(c, xd, PRED_TX_SIZE);
+    vp9_write(bc, sz != TX_4X4, tx_probs[0]);
     if (m->mbmi.sb_type >= BLOCK_SIZE_MB16X16 && sz != TX_4X4) {
-      vp9_write(bc, sz != TX_8X8, c->fc.tx_probs[tx_probs_offset + 1]);
+      vp9_write(bc, sz != TX_8X8, tx_probs[1]);
       if (m->mbmi.sb_type >= BLOCK_SIZE_SB32X32 && sz != TX_8X8)
-        vp9_write(bc, sz != TX_16X16, c->fc.tx_probs[tx_probs_offset + 2]);
+        vp9_write(bc, sz != TX_16X16, tx_probs[2]);
     }
   }
 
@@ -803,13 +872,18 @@
 
   if (bsize >= BLOCK_SIZE_SB8X8) {
     int pl;
+    int idx = check_bsize_coverage(cm, xd, mi_row, mi_col, bsize);
     xd->left_seg_context = cm->left_seg_context + (mi_row & MI_MASK);
     xd->above_seg_context = cm->above_seg_context + mi_col;
     pl = partition_plane_context(xd, bsize);
     // encode the partition information
-    write_token(bc, vp9_partition_tree,
-                cm->fc.partition_prob[cm->frame_type][pl],
-                vp9_partition_encodings + partition);
+    if (idx == 0)
+      write_token(bc, vp9_partition_tree,
+                  cm->fc.partition_prob[cm->frame_type][pl],
+                  vp9_partition_encodings + partition);
+    else if (idx > 0)
+      vp9_write(bc, partition == PARTITION_SPLIT,
+                cm->fc.partition_prob[cm->frame_type][pl][idx]);
   }
 
   subsize = get_subsize(bsize, partition);
@@ -1221,19 +1295,46 @@
 
   // Probabilities
   if (cm->txfm_mode == TX_MODE_SELECT) {
-    int i;
-    unsigned int ct[TX_SIZE_PROBS][2];
-    tx_counts_to_branch_counts(cm->fc.tx_count_32x32p,
-                               cm->fc.tx_count_16x16p,
-                               cm->fc.tx_count_8x8p, ct);
+    int i, j;
+    unsigned int ct_8x8p[TX_SIZE_MAX_SB - 3][2];
+    unsigned int ct_16x16p[TX_SIZE_MAX_SB - 2][2];
+    unsigned int ct_32x32p[TX_SIZE_MAX_SB - 1][2];
 
-    for (i = 0; i < TX_SIZE_PROBS; i++) {
-      vp9_cond_prob_diff_update(w, &cm->fc.tx_probs[i],
-                                VP9_DEF_UPDATE_PROB, ct[i]);
+
+    for (i = 0; i < TX_SIZE_MAX_SB - 2; i++) {
+      tx_counts_to_branch_counts_8x8(cm->fc.tx_count_8x8p[i],
+                                     ct_8x8p);
+      for (j = 0; j < TX_SIZE_MAX_SB - 3; j++) {
+        vp9_cond_prob_diff_update(w, &cm->fc.tx_probs_8x8p[i][j],
+                                  VP9_DEF_UPDATE_PROB, ct_8x8p[j]);
+      }
     }
+    for (i = 0; i < TX_SIZE_MAX_SB - 1; i++) {
+      tx_counts_to_branch_counts_16x16(cm->fc.tx_count_16x16p[i],
+                                       ct_16x16p);
+      for (j = 0; j < TX_SIZE_MAX_SB - 2; j++) {
+        vp9_cond_prob_diff_update(w, &cm->fc.tx_probs_16x16p[i][j],
+                                  VP9_DEF_UPDATE_PROB, ct_16x16p[j]);
+      }
+    }
+    for (i = 0; i < TX_SIZE_MAX_SB; i++) {
+      tx_counts_to_branch_counts_32x32(cm->fc.tx_count_32x32p[i],
+                                       ct_32x32p);
+      for (j = 0; j < TX_SIZE_MAX_SB - 1; j++) {
+        vp9_cond_prob_diff_update(w, &cm->fc.tx_probs_32x32p[i][j],
+                                  VP9_DEF_UPDATE_PROB, ct_32x32p[j]);
+      }
+    }
+#ifdef MODE_STATS
+    update_tx_count_stats(cm);
+#endif
   } else {
-    vpx_memcpy(cm->fc.tx_probs, vp9_default_tx_probs,
-               sizeof(vp9_default_tx_probs));
+    vpx_memcpy(cm->fc.tx_probs_32x32p, vp9_default_tx_probs_32x32p,
+               sizeof(vp9_default_tx_probs_32x32p));
+    vpx_memcpy(cm->fc.tx_probs_16x16p, vp9_default_tx_probs_16x16p,
+               sizeof(vp9_default_tx_probs_16x16p));
+    vpx_memcpy(cm->fc.tx_probs_8x8p, vp9_default_tx_probs_8x8p,
+               sizeof(vp9_default_tx_probs_8x8p));
   }
 }
 
@@ -1329,11 +1430,50 @@
                              cm->height != cm->display_height;
   vp9_wb_write_bit(wb, scaling_active);
   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->display_width - 1, 16);
+    vp9_wb_write_literal(wb, cm->display_height - 1, 16);
   }
 }
 
+static void write_frame_size(VP9_COMP *cpi,
+                             struct vp9_write_bit_buffer *wb) {
+  VP9_COMMON *const cm = &cpi->common;
+  vp9_wb_write_literal(wb, cm->width - 1, 16);
+  vp9_wb_write_literal(wb, cm->height - 1, 16);
+
+  write_display_size(cpi, wb);
+}
+
+static void write_frame_size_with_refs(VP9_COMP *cpi,
+                                       struct vp9_write_bit_buffer *wb) {
+  VP9_COMMON *const cm = &cpi->common;
+  int refs[ALLOWED_REFS_PER_FRAME] = {cpi->lst_fb_idx, cpi->gld_fb_idx,
+                                      cpi->alt_fb_idx};
+  int i, found = 0;
+
+  for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) {
+    YV12_BUFFER_CONFIG *cfg = &cm->yv12_fb[cm->ref_frame_map[refs[i]]];
+    found = cm->width == cfg->y_crop_width &&
+            cm->height == cfg->y_crop_height;
+    vp9_wb_write_bit(wb, found);
+    if (found)
+      break;
+  }
+
+  if (!found) {
+    vp9_wb_write_literal(wb, cm->width - 1, 16);
+    vp9_wb_write_literal(wb, cm->height - 1, 16);
+  }
+
+  write_display_size(cpi, wb);
+}
+
+static void write_sync_code(struct vp9_write_bit_buffer *wb) {
+  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);
+}
+
 static void write_uncompressed_header(VP9_COMP *cpi,
                                       struct vp9_write_bit_buffer *wb) {
   VP9_COMMON *const cm = &cpi->common;
@@ -1354,9 +1494,7 @@
   vp9_wb_write_bit(wb, cm->error_resilient_mode);
 
   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);
+    write_sync_code(wb);
     // colorspaces
     // 000 - Unknown
     // 001 - BT.601
@@ -1379,48 +1517,41 @@
       vp9_wb_write_bit(wb, 0);  // has extra plane
     }
 
-    // frame size
-    vp9_wb_write_literal(wb, cm->width, 16);
-    vp9_wb_write_literal(wb, cm->height, 16);
-    write_display_size(cpi, wb);
+    write_frame_size(cpi, wb);
   } else {
-    // When there is a key frame all reference buffers are updated using the
-    // new key frame
+    const int refs[ALLOWED_REFS_PER_FRAME] = {cpi->lst_fb_idx, cpi->gld_fb_idx,
+                                              cpi->alt_fb_idx};
+    if (!cm->show_frame)
+      vp9_wb_write_bit(wb, cm->intra_only);
 
-    int i;
-    int refs[ALLOWED_REFS_PER_FRAME] = {cpi->lst_fb_idx, cpi->gld_fb_idx,
-                                        cpi->alt_fb_idx};
+    if (cm->intra_only) {
+      write_sync_code(wb);
+      vp9_wb_write_literal(wb, get_refresh_mask(cpi), NUM_REF_FRAMES);
+      write_frame_size(cpi, wb);
+    } else {
+      int i;
+      vp9_wb_write_literal(wb, get_refresh_mask(cpi), NUM_REF_FRAMES);
+      for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) {
+        vp9_wb_write_literal(wb, refs[i], NUM_REF_FRAMES_LG2);
+        vp9_wb_write_bit(wb, cm->ref_frame_sign_bias[LAST_FRAME + i]);
+      }
 
-    vp9_wb_write_literal(wb, get_refresh_mask(cpi), NUM_REF_FRAMES);
-    for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) {
-      vp9_wb_write_literal(wb, refs[i], NUM_REF_FRAMES_LG2);
-      vp9_wb_write_bit(wb, cm->ref_frame_sign_bias[LAST_FRAME + i]);
+      write_frame_size_with_refs(cpi, wb);
+
+      vp9_wb_write_bit(wb, xd->allow_high_precision_mv);
+
+      fix_mcomp_filter_type(cpi);
+      write_interp_filter_type(cm->mcomp_filter_type, wb);
     }
-
-    // frame size
-    vp9_wb_write_literal(wb, cm->width, 16);
-    vp9_wb_write_literal(wb, cm->height, 16);
-    write_display_size(cpi, wb);
-
-    // Signal whether to allow high MV precision
-    vp9_wb_write_bit(wb, xd->allow_high_precision_mv);
-
-    // Signal the type of subpel filter to use
-    fix_mcomp_filter_type(cpi);
-    write_interp_filter_type(cm->mcomp_filter_type, wb);
   }
 
   if (!cm->error_resilient_mode) {
-    vp9_wb_write_bit(wb, cm->reset_frame_context);
+    vp9_wb_write_literal(wb, cm->reset_frame_context, 2);
     vp9_wb_write_bit(wb, cm->refresh_frame_context);
     vp9_wb_write_bit(wb, cm->frame_parallel_decoding_mode);
   }
 
-  if (!cm->show_frame)
-    vp9_wb_write_bit(wb, cm->intra_only);
-
   vp9_wb_write_literal(wb, cm->frame_context_idx, NUM_FRAME_CONTEXTS_LG2);
-  vp9_wb_write_bit(wb, cm->clr_type);
 
   encode_loopfilter(cm, xd, wb);
   encode_quantization(cm, wb);
@@ -1470,7 +1601,10 @@
   vp9_copy(pc->fc.pre_comp_inter_prob, pc->fc.comp_inter_prob);
   vp9_copy(pc->fc.pre_comp_ref_prob, pc->fc.comp_ref_prob);
   vp9_copy(pc->fc.pre_single_ref_prob, pc->fc.single_ref_prob);
-  vp9_copy(pc->fc.pre_tx_probs, pc->fc.tx_probs);
+  vp9_copy(pc->fc.pre_tx_probs_8x8p, pc->fc.tx_probs_8x8p);
+  vp9_copy(pc->fc.pre_tx_probs_16x16p, pc->fc.tx_probs_16x16p);
+  vp9_copy(pc->fc.pre_tx_probs_32x32p, pc->fc.tx_probs_32x32p);
+  vp9_copy(pc->fc.pre_mbskip_probs, pc->fc.mbskip_probs);
 
   if (xd->lossless) {
     pc->txfm_mode = ONLY_4X4;
@@ -1484,9 +1618,7 @@
   active_section = 2;
 #endif
 
-  vp9_update_skip_probs(cpi);
-  for (i = 0; i < MBSKIP_CONTEXTS; ++i)
-    vp9_write_prob(&header_bc, pc->mbskip_pred_probs[i]);
+  vp9_update_skip_probs(cpi, &header_bc);
 
   if (pc->frame_type != KEY_FRAME) {
 #ifdef ENTROPY_STATS
diff --git a/vp9/encoder/vp9_bitstream.h b/vp9/encoder/vp9_bitstream.h
index f7a8ece..b3dbee1 100644
--- a/vp9/encoder/vp9_bitstream.h
+++ b/vp9/encoder/vp9_bitstream.h
@@ -12,6 +12,6 @@
 #ifndef VP9_ENCODER_VP9_BITSTREAM_H_
 #define VP9_ENCODER_VP9_BITSTREAM_H_
 
-void vp9_update_skip_probs(VP9_COMP *cpi);
+void vp9_update_skip_probs(VP9_COMP *cpi, vp9_writer *bc);
 
 #endif  // VP9_ENCODER_VP9_BITSTREAM_H_
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c
index d7810dd..1ab08bc 100644
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -1286,8 +1286,7 @@
   }
 
   // PARTITION_HORZ
-  if ((mi_col + ms <= cm->mi_cols) && (mi_row + (ms >> 1) <= cm->mi_rows) &&
-      (bsize >= BLOCK_SIZE_SB8X8)) {
+    if ((bsize >= BLOCK_SIZE_SB8X8) && (mi_col + ms <= cm->mi_cols)) {
     int r2, d2;
     int mb_skip = 0;
     subsize = get_subsize(bsize, PARTITION_HORZ);
@@ -1295,7 +1294,7 @@
     pick_sb_modes(cpi, mi_row, mi_col, tp, &r2, &d2, subsize,
                   get_block_context(x, subsize));
 
-    if (mi_row + ms <= cm->mi_rows) {
+    if (mi_row < cm->mi_rows) {
       int r = 0, d = 0;
       update_state(cpi, get_block_context(x, subsize), subsize, 0);
       encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize);
@@ -1322,15 +1321,14 @@
   }
 
   // PARTITION_VERT
-  if ((mi_row + ms <= cm->mi_rows) && (mi_col + (ms >> 1) <= cm->mi_cols) &&
-      (bsize >= BLOCK_SIZE_SB8X8)) {
+  if ((bsize >= BLOCK_SIZE_SB8X8) && (mi_row + ms <= cm->mi_rows)) {
     int r2, d2;
     int mb_skip = 0;
     subsize = get_subsize(bsize, PARTITION_VERT);
     *(get_sb_index(xd, subsize)) = 0;
     pick_sb_modes(cpi, mi_row, mi_col, tp, &r2, &d2, subsize,
                   get_block_context(x, subsize));
-    if (mi_col + ms <= cm->mi_cols) {
+    if (mi_col < cm->mi_cols) {
       int r = 0, d = 0;
       update_state(cpi, get_block_context(x, subsize), subsize, 0);
       encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize);
@@ -1404,7 +1402,7 @@
 
   // Code each SB in the row
   for (mi_col = cm->cur_tile_mi_col_start;
-       mi_col < cm->cur_tile_mi_col_end; mi_col += 8) {
+       mi_col < cm->cur_tile_mi_col_end; mi_col += 64 / MI_SIZE) {
     int dummy_rate, dummy_dist;
     if (cpi->speed < 5) {
       rd_pick_partition(cpi, tp, mi_row, mi_col, BLOCK_SIZE_SB64X64,
@@ -1464,6 +1462,7 @@
   vp9_zero(cm->fc.tx_count_32x32p);
   vp9_zero(cm->fc.tx_count_16x16p);
   vp9_zero(cm->fc.tx_count_8x8p);
+  vp9_zero(cm->fc.mbskip_count);
 
   // Note: this memset assumes above_context[0], [1] and [2]
   // are allocated as part of the same buffer.
@@ -1518,9 +1517,6 @@
   // Reset frame count of inter 0,0 motion vector usage.
   cpi->inter_zz_count = 0;
 
-  cpi->skip_true_count[0] = cpi->skip_true_count[1] = cpi->skip_true_count[2] = 0;
-  cpi->skip_false_count[0] = cpi->skip_false_count[1] = cpi->skip_false_count[2] = 0;
-
   vp9_zero(cm->fc.switchable_interp_count);
   vp9_zero(cpi->best_switchable_interp_count);
 
@@ -1868,15 +1864,34 @@
     }
 
     if (cpi->common.txfm_mode == TX_MODE_SELECT) {
-      const int count4x4 = cm->fc.tx_count_16x16p[TX_4X4] +
-                           cm->fc.tx_count_32x32p[TX_4X4] +
-                           cm->fc.tx_count_8x8p[TX_4X4];
-      const int count8x8_lp = cm->fc.tx_count_32x32p[TX_8X8] +
-                              cm->fc.tx_count_16x16p[TX_8X8];
-      const int count8x8_8x8p = cm->fc.tx_count_8x8p[TX_8X8];
-      const int count16x16_16x16p = cm->fc.tx_count_16x16p[TX_16X16];
-      const int count16x16_lp = cm->fc.tx_count_32x32p[TX_16X16];
-      const int count32x32 = cm->fc.tx_count_32x32p[TX_32X32];
+      int count4x4 = 0;
+      int count8x8_lp = 0, count8x8_8x8p = 0;
+      int count16x16_16x16p = 0, count16x16_lp = 0;
+      int count32x32 = 0;
+
+      for (i = 0; i < TX_SIZE_MAX_SB; i++)
+        count4x4 += cm->fc.tx_count_32x32p[i][TX_4X4];
+      for (i = 0; i < TX_SIZE_MAX_SB - 1; i++)
+        count4x4 += cm->fc.tx_count_16x16p[i][TX_4X4];
+      for (i = 0; i < TX_SIZE_MAX_SB - 2; i++)
+        count4x4 += cm->fc.tx_count_8x8p[i][TX_4X4];
+
+      for (i = 0; i < TX_SIZE_MAX_SB; i++)
+        count8x8_lp += cm->fc.tx_count_32x32p[i][TX_8X8];
+      for (i = 0; i < TX_SIZE_MAX_SB - 1; i++)
+        count8x8_lp += cm->fc.tx_count_16x16p[i][TX_8X8];
+
+      for (i = 0; i < TX_SIZE_MAX_SB - 2; i++)
+        count8x8_8x8p += cm->fc.tx_count_8x8p[i][TX_8X8];
+
+      for (i = 0; i < TX_SIZE_MAX_SB - 1; i++)
+        count16x16_16x16p += cm->fc.tx_count_16x16p[i][TX_16X16];
+
+      for (i = 0; i < TX_SIZE_MAX_SB; i++)
+        count16x16_lp += cm->fc.tx_count_32x32p[i][TX_16X16];
+
+      for (i = 0; i < TX_SIZE_MAX_SB; i++)
+        count32x32 += cm->fc.tx_count_32x32p[i][TX_32X32];
 
       if (count4x4 == 0 && count16x16_lp == 0 && count16x16_16x16p == 0 &&
           count32x32 == 0) {
@@ -2041,7 +2056,7 @@
 
     mbmi->mb_skip_coeff = 1;
     if (output_enabled)
-      cpi->skip_true_count[mb_skip_context]++;
+      cm->fc.mbskip_count[mb_skip_context][1]++;
     vp9_reset_sb_tokens_context(xd,
                  (bsize < BLOCK_SIZE_SB8X8) ? BLOCK_SIZE_SB8X8 : bsize);
   }
@@ -2059,12 +2074,13 @@
         mbmi->sb_type >= BLOCK_SIZE_SB8X8 &&
         !(mbmi->ref_frame[0] != INTRA_FRAME && (mbmi->mb_skip_coeff ||
           vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)))) {
+      const int context = vp9_get_pred_context(cm, xd, PRED_TX_SIZE);
       if (bsize >= BLOCK_SIZE_SB32X32) {
-        cm->fc.tx_count_32x32p[mbmi->txfm_size]++;
+        cm->fc.tx_count_32x32p[context][mbmi->txfm_size]++;
       } else if (bsize >= BLOCK_SIZE_MB16X16) {
-        cm->fc.tx_count_16x16p[mbmi->txfm_size]++;
+        cm->fc.tx_count_16x16p[context][mbmi->txfm_size]++;
       } else {
-        cm->fc.tx_count_8x8p[mbmi->txfm_size]++;
+        cm->fc.tx_count_8x8p[context][mbmi->txfm_size]++;
       }
     } else {
       int x, y;
diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c
index 65efb54..a0426ac 100644
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -96,11 +96,6 @@
 FILE *keyfile;
 #endif
 
-#if 0
-extern int skip_true_count;
-extern int skip_false_count;
-#endif
-
 
 #ifdef ENTROPY_STATS
 extern int intra_mode_stats[VP9_INTRA_MODES]
@@ -112,6 +107,10 @@
 extern void init_nmvstats();
 extern void print_nmvstats();
 #endif
+#ifdef MODE_STATS
+extern void init_tx_count_stats();
+extern void write_tx_count_stats();
+#endif
 
 #ifdef SPEEDSTATS
 unsigned int frames_at_speed[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
@@ -123,8 +122,6 @@
 
 extern void vp9_init_quantizer(VP9_COMP *cpi);
 
-static int base_skip_false_prob[QINDEX_RANGE][3];
-
 // Tables relating active max Q to active min Q
 static int kf_low_motion_minq[QINDEX_RANGE];
 static int kf_high_motion_minq[QINDEX_RANGE];
@@ -201,49 +198,6 @@
     mb->mvsadcost = mb->nmvsadcost;
   }
 }
-static void init_base_skip_probs(void) {
-  int i;
-
-  for (i = 0; i < QINDEX_RANGE; i++) {
-    const double q = vp9_convert_qindex_to_q(i);
-
-    // Exponential decay caluclation of baseline skip prob with clamping
-    // Based on crude best fit of old table.
-    const int t = (int)(564.25 * pow(2.71828, (-0.012 * q)));
-
-    base_skip_false_prob[i][1] = clip_prob(t);
-    base_skip_false_prob[i][2] = clip_prob(t * 3 / 4);
-    base_skip_false_prob[i][0] = clip_prob(t * 5 / 4);
-  }
-}
-
-static void update_base_skip_probs(VP9_COMP *cpi) {
-  VP9_COMMON *cm = &cpi->common;
-  int k;
-
-  if (cm->frame_type != KEY_FRAME) {
-    vp9_update_skip_probs(cpi);
-
-    if (cpi->refresh_alt_ref_frame) {
-      for (k = 0; k < MBSKIP_CONTEXTS; ++k)
-        cpi->last_skip_false_probs[2][k] = cm->mbskip_pred_probs[k];
-      cpi->last_skip_probs_q[2] = cm->base_qindex;
-    } else if (cpi->refresh_golden_frame) {
-      for (k = 0; k < MBSKIP_CONTEXTS; ++k)
-        cpi->last_skip_false_probs[1][k] = cm->mbskip_pred_probs[k];
-      cpi->last_skip_probs_q[1] = cm->base_qindex;
-    } else {
-      for (k = 0; k < MBSKIP_CONTEXTS; ++k)
-        cpi->last_skip_false_probs[0][k] = cm->mbskip_pred_probs[k];
-      cpi->last_skip_probs_q[0] = cm->base_qindex;
-
-      // update the baseline table for the current q
-      for (k = 0; k < MBSKIP_CONTEXTS; ++k)
-        cpi->base_skip_false_prob[cm->base_qindex][k] =
-            cm->mbskip_pred_probs[k];
-    }
-  }
-}
 
 void vp9_initialize_enc() {
   static int init_done = 0;
@@ -254,7 +208,7 @@
     vp9_init_quant_tables();
     vp9_init_me_luts();
     init_minq_luts();
-    init_base_skip_probs();
+    // init_base_skip_probs();
     init_done = 1;
   }
 }
@@ -815,7 +769,7 @@
   vpx_free(cpi->mb.pip);
 
   cpi->mb.pip = vpx_calloc((cpi->common.mode_info_stride) *
-                           (cpi->common.mi_rows + 1),
+                           (cpi->common.mi_rows + 64 / MI_SIZE),
                            sizeof(PARTITION_INFO));
   if (!cpi->mb.pip)
     return 1;
@@ -1288,7 +1242,6 @@
 
   init_config((VP9_PTR)cpi, oxcf);
 
-  memcpy(cpi->base_skip_false_prob, base_skip_false_prob, sizeof(base_skip_false_prob));
   cpi->common.current_video_frame   = 0;
   cpi->kf_overspend_bits            = 0;
   cpi->kf_bitrate_adjustment        = 0;
@@ -1338,6 +1291,9 @@
 #ifdef NMV_STATS
   init_nmvstats();
 #endif
+#ifdef MODE_STATS
+  init_tx_count_stats();
+#endif
 
   /*Initialize the feed-forward activity masking.*/
   cpi->activity_avg = 90 << 12;
@@ -1586,6 +1542,10 @@
     if (cpi->pass != 1)
       print_nmvstats();
 #endif
+#ifdef MODE_STATS
+    if (cpi->pass != 1)
+      write_tx_count_stats();
+#endif
 
 #if CONFIG_INTERNAL_STATS
 
@@ -2741,44 +2701,6 @@
     vp9_set_quantizer(cpi, q);
 
     if (loop_count == 0) {
-      int k;
-
-      // setup skip prob for costing in mode/mv decision
-      for (k = 0; k < MBSKIP_CONTEXTS; k++)
-        cm->mbskip_pred_probs[k] = cpi->base_skip_false_prob[q][k];
-
-      if (cm->frame_type != KEY_FRAME) {
-        if (cpi->refresh_alt_ref_frame) {
-          for (k = 0; k < MBSKIP_CONTEXTS; k++) {
-            if (cpi->last_skip_false_probs[2][k] != 0)
-              cm->mbskip_pred_probs[k] = cpi->last_skip_false_probs[2][k];
-          }
-        } else if (cpi->refresh_golden_frame) {
-          for (k = 0; k < MBSKIP_CONTEXTS; k++) {
-            if (cpi->last_skip_false_probs[1][k] != 0)
-              cm->mbskip_pred_probs[k] = cpi->last_skip_false_probs[1][k];
-          }
-        } else {
-          int k;
-          for (k = 0; k < MBSKIP_CONTEXTS; k++) {
-            if (cpi->last_skip_false_probs[0][k] != 0)
-              cm->mbskip_pred_probs[k] = cpi->last_skip_false_probs[0][k];
-          }
-        }
-
-        // as this is for cost estimate, let's make sure it does not
-        // get extreme either way
-        {
-          int k;
-          for (k = 0; k < MBSKIP_CONTEXTS; ++k) {
-            cm->mbskip_pred_probs[k] = clamp(cm->mbskip_pred_probs[k],
-                                             5, 250);
-
-            if (cpi->is_src_frame_alt_ref)
-              cm->mbskip_pred_probs[k] = 1;
-          }
-        }
-      }
 
       // Set up entropy depending on frame type.
       if (cm->frame_type == KEY_FRAME) {
@@ -2804,7 +2726,7 @@
 
     // Update the skip mb flag probabilities based on the distribution
     // seen in the last encoder iteration.
-    update_base_skip_probs(cpi);
+    // update_base_skip_probs(cpi);
 
     vp9_clear_system_state();  // __asm emms;
 
@@ -3170,7 +3092,7 @@
 
   // Update the skip mb flag probabilities based on the distribution seen
   // in this frame.
-  update_base_skip_probs(cpi);
+  // update_base_skip_probs(cpi);
 
 #if 0 && CONFIG_INTERNAL_STATS
   {
@@ -3385,11 +3307,11 @@
 
   if (cm->show_frame) {
     vpx_memcpy(cm->prev_mip, cm->mip,
-               cm->mode_info_stride * (cm->mi_rows + 1) *
+               cm->mode_info_stride * (cm->mi_rows + 64 / MI_SIZE) *
                sizeof(MODE_INFO));
   } else {
     vpx_memset(cm->prev_mip, 0,
-               cm->mode_info_stride * (cm->mi_rows + 1) *
+               cm->mode_info_stride * (cm->mi_rows + 64 / MI_SIZE) *
                sizeof(MODE_INFO));
   }
   // restore prev_mi
diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h
index b8a60d2..2fd6bbd 100644
--- a/vp9/encoder/vp9_onyx_int.h
+++ b/vp9/encoder/vp9_onyx_int.h
@@ -89,7 +89,10 @@
   int inter_mode_counts[INTER_MODE_CONTEXTS][VP9_INTER_MODES - 1][2];
   vp9_prob inter_mode_probs[INTER_MODE_CONTEXTS][VP9_INTER_MODES - 1];
 
-  vp9_prob tx_probs[TX_SIZE_PROBS];
+  vp9_prob tx_probs_8x8p[TX_SIZE_MAX_SB - 2][TX_SIZE_MAX_SB - 3];
+  vp9_prob tx_probs_16x16p[TX_SIZE_MAX_SB - 1][TX_SIZE_MAX_SB - 2];
+  vp9_prob tx_probs_32x32p[TX_SIZE_MAX_SB][TX_SIZE_MAX_SB - 1];
+  vp9_prob mbskip_probs[MBSKIP_CONTEXTS];
 } CODING_CONTEXT;
 
 typedef struct {
@@ -459,8 +462,6 @@
   int inter_zz_count;
   int gf_bad_count;
   int gf_update_recommended;
-  int skip_true_count[3];
-  int skip_false_count[3];
 
   unsigned char *segmentation_map;
 
@@ -480,8 +481,6 @@
   uint64_t time_pick_lpf;
   uint64_t time_encode_mb_row;
 
-  int base_skip_false_prob[QINDEX_RANGE][3];
-
   struct twopass_rc {
     unsigned int section_intra_rating;
     unsigned int next_iiratio;
diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c
index 60ca355..ae6c20e 100644
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -143,7 +143,10 @@
 
   vp9_copy(cc->coef_probs, cm->fc.coef_probs);
   vp9_copy(cc->switchable_interp_prob, cm->fc.switchable_interp_prob);
-  vp9_copy(cc->tx_probs, cm->fc.tx_probs);
+  vp9_copy(cc->tx_probs_8x8p, cm->fc.tx_probs_8x8p);
+  vp9_copy(cc->tx_probs_16x16p, cm->fc.tx_probs_16x16p);
+  vp9_copy(cc->tx_probs_32x32p, cm->fc.tx_probs_32x32p);
+  vp9_copy(cc->mbskip_probs, cm->fc.mbskip_probs);
 }
 
 void vp9_restore_coding_context(VP9_COMP *cpi) {
@@ -181,7 +184,10 @@
 
   vp9_copy(cm->fc.coef_probs, cc->coef_probs);
   vp9_copy(cm->fc.switchable_interp_prob, cc->switchable_interp_prob);
-  vp9_copy(cm->fc.tx_probs, cc->tx_probs);
+  vp9_copy(cm->fc.tx_probs_8x8p, cc->tx_probs_8x8p);
+  vp9_copy(cm->fc.tx_probs_16x16p, cc->tx_probs_16x16p);
+  vp9_copy(cm->fc.tx_probs_32x32p, cc->tx_probs_32x32p);
+  vp9_copy(cm->fc.mbskip_probs, cc->mbskip_probs);
 }
 
 void vp9_setup_key_frame(VP9_COMP *cpi) {
diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c
index cb081a3..6150746 100644
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -420,7 +420,6 @@
                                      int *d, int *distortion,
                                      int *s, int *skip,
                                      int64_t txfm_cache[NB_TXFM_MODES],
-                                     BLOCK_SIZE_TYPE bs,
                                      TX_SIZE max_txfm_size) {
   VP9_COMMON *const cm = &cpi->common;
   MACROBLOCKD *const xd = &x->e_mbd;
@@ -430,15 +429,15 @@
   int n, m;
   int s0, s1;
 
-  int tx_probs_offset = get_tx_probs_offset(bs);
+  const vp9_prob *tx_probs = vp9_get_pred_probs(cm, xd, PRED_TX_SIZE);
 
   for (n = TX_4X4; n <= max_txfm_size; n++) {
     r[n][1] = r[n][0];
     for (m = 0; m <= n - (n == max_txfm_size); m++) {
       if (m == n)
-        r[n][1] += vp9_cost_zero(cm->fc.tx_probs[tx_probs_offset + m]);
+        r[n][1] += vp9_cost_zero(tx_probs[m]);
       else
-        r[n][1] += vp9_cost_one(cm->fc.tx_probs[tx_probs_offset + m]);
+        r[n][1] += vp9_cost_one(tx_probs[m]);
     }
   }
 
@@ -612,7 +611,6 @@
   MB_MODE_INFO *const mbmi = &xd->mode_info_context->mbmi;
 
   assert(bs == mbmi->sb_type);
-
   if (mbmi->ref_frame[0] > INTRA_FRAME)
     vp9_subtract_sby(x, bs);
 
@@ -643,7 +641,7 @@
                            TX_4X4);
 
   choose_txfm_size_from_rd(cpi, x, r, rate, d, distortion, s,
-                           skip, txfm_cache, bs,
+                           skip, txfm_cache,
                            TX_32X32 - (bs < BLOCK_SIZE_SB32X32)
                            - (bs < BLOCK_SIZE_MB16X16));
 }
diff --git a/vp9/encoder/vp9_tokenize.c b/vp9/encoder/vp9_tokenize.c
index cb05219..0a290e1 100644
--- a/vp9/encoder/vp9_tokenize.c
+++ b/vp9/encoder/vp9_tokenize.c
@@ -294,7 +294,7 @@
 
   if (mbmi->mb_skip_coeff) {
     if (!dry_run)
-      cpi->skip_true_count[mb_skip_context] += skip_inc;
+      cm->fc.mbskip_count[mb_skip_context][1] += skip_inc;
     vp9_reset_sb_tokens_context(xd, bsize);
     if (dry_run)
       *t = t_backup;
@@ -302,7 +302,7 @@
   }
 
   if (!dry_run)
-    cpi->skip_false_count[mb_skip_context] += skip_inc;
+    cm->fc.mbskip_count[mb_skip_context][0] += skip_inc;
 
   foreach_transformed_block(xd, bsize, tokenize_b, &arg);