Merge "Removing unused struct member mvcount[MV_VALS]."
diff --git a/examples/decoder_tmpl.c b/examples/decoder_tmpl.c
index 597fea2..3e55352 100644
--- a/examples/decoder_tmpl.c
+++ b/examples/decoder_tmpl.c
@@ -12,14 +12,14 @@
 /*
 @*INTRODUCTION
  */
-#include "vpx_config.h"
+#include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <stdarg.h>
 #include <string.h>
 #define VPX_CODEC_DISABLE_COMPAT 1
-#include "vpx/vpx_decoder.h"
+#include "./vpx_config.h"
 #include "vpx/vp8dx.h"
+#include "vpx/vpx_decoder.h"
 #define interface (vpx_codec_vp8_dx())
 @EXTRA_INCLUDES
 
diff --git a/test/dct16x16_test.cc b/test/dct16x16_test.cc
index 3d61d40..b990bf8 100644
--- a/test/dct16x16_test.cc
+++ b/test/dct16x16_test.cc
@@ -395,8 +395,7 @@
       for (int j = 0; j < kNumCoeffs; ++j)
         coeff[j] = round(out_r[j]);
 
-      const int pitch = 32;
-      REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch));
+      REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, 16));
 
       for (int j = 0; j < kNumCoeffs; ++j) {
         const uint32_t diff = dst[j] - src[j];
@@ -421,7 +420,7 @@
     fwd_txfm_ = GET_PARAM(0);
     inv_txfm_ = GET_PARAM(1);
     tx_type_  = GET_PARAM(2);
-    pitch_    = 32;
+    pitch_    = 16;
     fwd_txfm_ref = fdct16x16_ref;
   }
   virtual void TearDown() { libvpx_test::ClearSystemState(); }
@@ -431,7 +430,7 @@
     fwd_txfm_(in, out, stride);
   }
   void RunInvTxfm(int16_t *out, uint8_t *dst, int stride) {
-    inv_txfm_(out, dst, stride >> 1);
+    inv_txfm_(out, dst, stride);
   }
 
   fdct_t fwd_txfm_;
diff --git a/vp9/common/vp9_common_data.c b/vp9/common/vp9_common_data.c
index dc41efd..f858900 100644
--- a/vp9/common/vp9_common_data.c
+++ b/vp9/common/vp9_common_data.c
@@ -115,6 +115,16 @@
   TX_16X16, TX_16X16, TX_16X16, TX_32X32
 };
 
+const TX_SIZE tx_mode_to_biggest_tx_size[TX_MODES] = {
+  TX_4X4,  // ONLY_4X4
+  TX_8X8,  // ALLOW_8X8
+  TX_16X16,  // ALLOW_16X16
+  TX_32X32,  // ALLOW_32X32
+  TX_32X32,  // TX_MODE_SELECT
+};
+
+
+
 const BLOCK_SIZE ss_size_lookup[BLOCK_SIZES][2][2] = {
 //  ss_x == 0    ss_x == 0        ss_x == 1      ss_x == 1
 //  ss_y == 0    ss_y == 1        ss_y == 0      ss_y == 1
@@ -133,3 +143,4 @@
   {{BLOCK_64X64, BLOCK_64X32},   {BLOCK_32X64,   BLOCK_32X32}},
 };
 
+
diff --git a/vp9/common/vp9_common_data.h b/vp9/common/vp9_common_data.h
index 2945cd2..c1f6405 100644
--- a/vp9/common/vp9_common_data.h
+++ b/vp9/common/vp9_common_data.h
@@ -27,6 +27,7 @@
 extern const BLOCK_SIZE subsize_lookup[PARTITION_TYPES][BLOCK_SIZES];
 extern const TX_SIZE max_txsize_lookup[BLOCK_SIZES];
 extern const TX_SIZE max_uv_txsize_lookup[BLOCK_SIZES];
+extern const TX_SIZE tx_mode_to_biggest_tx_size[TX_MODES];
 extern const BLOCK_SIZE ss_size_lookup[BLOCK_SIZES][2][2];
 
 #endif  // VP9_COMMON_VP9_COMMON_DATA_H
diff --git a/vp9/common/vp9_entropymv.c b/vp9/common/vp9_entropymv.c
index e851181..f70b571 100644
--- a/vp9/common/vp9_entropymv.c
+++ b/vp9/common/vp9_entropymv.c
@@ -175,17 +175,18 @@
   }
 }
 
+void vp9_inc_mv(const MV *mv, nmv_context_counts *counts) {
+  if (counts != NULL) {
+    const MV_JOINT_TYPE j = vp9_get_mv_joint(mv);
+    ++counts->joints[j];
 
-void vp9_inc_mv(const MV *mv,  nmv_context_counts *counts) {
-  const MV_JOINT_TYPE j = vp9_get_mv_joint(mv);
-  ++counts->joints[j];
+    if (mv_joint_vertical(j)) {
+      inc_mv_component(mv->row, &counts->comps[0], 1, 1);
+    }
 
-  if (mv_joint_vertical(j)) {
-    inc_mv_component(mv->row, &counts->comps[0], 1, 1);
-  }
-
-  if (mv_joint_horizontal(j)) {
-    inc_mv_component(mv->col, &counts->comps[1], 1, 1);
+    if (mv_joint_horizontal(j)) {
+      inc_mv_component(mv->col, &counts->comps[1], 1, 1);
+    }
   }
 }
 
diff --git a/vp9/common/vp9_pred_common.c b/vp9/common/vp9_pred_common.c
index 9453d02..be42c56 100644
--- a/vp9/common/vp9_pred_common.c
+++ b/vp9/common/vp9_pred_common.c
@@ -16,12 +16,20 @@
 #include "vp9/common/vp9_seg_common.h"
 #include "vp9/common/vp9_treecoder.h"
 
+static INLINE const MB_MODE_INFO *get_above_mbmi(const MODE_INFO *const above) {
+  return (above != NULL) ? &above->mbmi : NULL;
+}
+
+static INLINE const MB_MODE_INFO *get_left_mbmi(const MODE_INFO *const left) {
+  return (left != NULL) ? &left->mbmi : NULL;
+}
+
 // Returns a context number for the given MB prediction signal
 unsigned char vp9_get_pred_context_switchable_interp(const MACROBLOCKD *xd) {
-  const MODE_INFO * const above_mi = xd->mi_8x8[-xd->mode_info_stride];
-  const MODE_INFO * const left_mi = xd->mi_8x8[-1];
-  const int left_in_image = xd->left_available && left_mi;
-  const int above_in_image = xd->up_available && above_mi;
+  const MODE_INFO *const above_mi = get_above_mi(xd);
+  const MODE_INFO *const left_mi = get_left_mi(xd);
+  const int above_in_image = above_mi != NULL;
+  const int left_in_image = left_mi != NULL;
   // Note:
   // The mode info data structure has a one element border above and to the
   // left of the entries correpsonding to real macroblocks.
@@ -53,14 +61,14 @@
 }
 // Returns a context number for the given MB prediction signal
 unsigned char vp9_get_pred_context_intra_inter(const MACROBLOCKD *xd) {
-  const MODE_INFO * const above_mi = xd->mi_8x8[-xd->mode_info_stride];
-  const MODE_INFO * const left_mi = xd->mi_8x8[-1];
-  const MB_MODE_INFO *const above_mbmi = above_mi ? &above_mi->mbmi : 0;
-  const MB_MODE_INFO *const left_mbmi = left_mi ? &left_mi->mbmi : 0;
-  const int left_in_image = xd->left_available && left_mi;
-  const int above_in_image = xd->up_available && above_mi;
-  const int left_intra = left_in_image ? !is_inter_block(left_mbmi) : 1;
+  const MODE_INFO *const above_mi = get_above_mi(xd);
+  const MODE_INFO *const left_mi = get_left_mi(xd);
+  const MB_MODE_INFO *const above_mbmi = get_above_mbmi(above_mi);
+  const MB_MODE_INFO *const left_mbmi = get_left_mbmi(left_mi);
+  const int above_in_image = above_mi != NULL;
+  const int left_in_image = left_mi != NULL;
   const int above_intra = above_in_image ? !is_inter_block(above_mbmi) : 1;
+  const int left_intra = left_in_image ? !is_inter_block(left_mbmi) : 1;
 
   // The mode info data structure has a one element border above and to the
   // left of the entries corresponding to real macroblocks.
@@ -81,12 +89,12 @@
 unsigned char vp9_get_pred_context_comp_inter_inter(const VP9_COMMON *cm,
                                                     const MACROBLOCKD *xd) {
   int pred_context;
-  const MODE_INFO * const above_mi = xd->mi_8x8[-xd->mode_info_stride];
-  const MODE_INFO * const left_mi = xd->mi_8x8[-1];
-  const MB_MODE_INFO *const above_mbmi = above_mi ? &above_mi->mbmi : 0;
-  const MB_MODE_INFO *const left_mbmi = left_mi ? &left_mi->mbmi : 0;
-  const int left_in_image = xd->left_available && left_mi;
-  const int above_in_image = xd->up_available && above_mi;
+  const MODE_INFO *const above_mi = get_above_mi(xd);
+  const MODE_INFO *const left_mi = get_left_mi(xd);
+  const MB_MODE_INFO *const above_mbmi = get_above_mbmi(above_mi);
+  const MB_MODE_INFO *const left_mbmi = get_left_mbmi(left_mi);
+  const int above_in_image = above_mi != NULL;
+  const int left_in_image = left_mi != NULL;
   // Note:
   // The mode info data structure has a one element border above and to the
   // left of the entries correpsonding to real macroblocks.
@@ -126,14 +134,14 @@
 unsigned char vp9_get_pred_context_comp_ref_p(const VP9_COMMON *cm,
                                               const MACROBLOCKD *xd) {
   int pred_context;
-  const MODE_INFO * const above_mi = xd->mi_8x8[-cm->mode_info_stride];
-  const MODE_INFO * const left_mi = xd->mi_8x8[-1];
-  const MB_MODE_INFO *const above_mbmi = above_mi ? &above_mi->mbmi : 0;
-  const MB_MODE_INFO *const left_mbmi = left_mi ? &left_mi->mbmi : 0;
-  const int left_in_image = xd->left_available && left_mi;
-  const int above_in_image = xd->up_available && above_mi;
-  const int left_intra = left_in_image ? !is_inter_block(left_mbmi) : 1;
+  const MODE_INFO *const above_mi = get_above_mi(xd);
+  const MODE_INFO *const left_mi = get_left_mi(xd);
+  const MB_MODE_INFO *const above_mbmi = get_above_mbmi(above_mi);
+  const MB_MODE_INFO *const left_mbmi = get_left_mbmi(left_mi);
+  const int above_in_image = above_mi != NULL;
+  const int left_in_image = left_mi != NULL;
   const int above_intra = above_in_image ? !is_inter_block(above_mbmi) : 1;
+  const int left_intra = left_in_image ? !is_inter_block(left_mbmi) : 1;
   // Note:
   // The mode info data structure has a one element border above and to the
   // left of the entries correpsonding to real macroblocks.
@@ -206,14 +214,14 @@
 }
 unsigned char vp9_get_pred_context_single_ref_p1(const MACROBLOCKD *xd) {
   int pred_context;
-  const MODE_INFO * const above_mi = xd->mi_8x8[-xd->mode_info_stride];
-  const MODE_INFO * const left_mi = xd->mi_8x8[-1];
-  const MB_MODE_INFO *const above_mbmi = above_mi ? &above_mi->mbmi : 0;
-  const MB_MODE_INFO *const left_mbmi = left_mi ? &left_mi->mbmi : 0;
-  const int left_in_image = xd->left_available && left_mi;
-  const int above_in_image = xd->up_available && above_mi;
-  const int left_intra = left_in_image ? !is_inter_block(left_mbmi) : 1;
+  const MODE_INFO *const above_mi = get_above_mi(xd);
+  const MODE_INFO *const left_mi = get_left_mi(xd);
+  const MB_MODE_INFO *const above_mbmi = get_above_mbmi(above_mi);
+  const MB_MODE_INFO *const left_mbmi = get_left_mbmi(left_mi);
+  const int above_in_image = above_mi != NULL;
+  const int left_in_image = left_mi != NULL;
   const int above_intra = above_in_image ? !is_inter_block(above_mbmi) : 1;
+  const int left_intra = left_in_image ? !is_inter_block(left_mbmi) : 1;
   // Note:
   // The mode info data structure has a one element border above and to the
   // left of the entries correpsonding to real macroblocks.
@@ -272,14 +280,14 @@
 
 unsigned char vp9_get_pred_context_single_ref_p2(const MACROBLOCKD *xd) {
   int pred_context;
-  const MODE_INFO * const above_mi = xd->mi_8x8[-xd->mode_info_stride];
-  const MODE_INFO * const left_mi = xd->mi_8x8[-1];
-  const MB_MODE_INFO *const above_mbmi = above_mi ? &above_mi->mbmi : 0;
-  const MB_MODE_INFO *const left_mbmi = left_mi ? &left_mi->mbmi : 0;
-  const int left_in_image = xd->left_available && left_mi;
-  const int above_in_image = xd->up_available && above_mi;
-  const int left_intra = left_in_image ? !is_inter_block(left_mbmi) : 1;
+  const MODE_INFO *const above_mi = get_above_mi(xd);
+  const MODE_INFO *const left_mi = get_left_mi(xd);
+  const MB_MODE_INFO *const above_mbmi = get_above_mbmi(above_mi);
+  const MB_MODE_INFO *const left_mbmi = get_left_mbmi(left_mi);
+  const int above_in_image = above_mi != NULL;
+  const int left_in_image = left_mi != NULL;
   const int above_intra = above_in_image ? !is_inter_block(above_mbmi) : 1;
+  const int left_intra = left_in_image ? !is_inter_block(left_mbmi) : 1;
 
   // Note:
   // The mode info data structure has a one element border above and to the
@@ -361,12 +369,12 @@
 // left of the entries corresponding to real blocks.
 // The prediction flags in these dummy entries are initialized to 0.
 unsigned char vp9_get_pred_context_tx_size(const MACROBLOCKD *xd) {
-  const MODE_INFO * const above_mi = xd->mi_8x8[-xd->mode_info_stride];
-  const MODE_INFO * const left_mi = xd->mi_8x8[-1];
-  const MB_MODE_INFO *const above_mbmi = above_mi ? &above_mi->mbmi : 0;
-  const MB_MODE_INFO *const left_mbmi = left_mi ? &left_mi->mbmi : 0;
-  const int left_in_image = xd->left_available && left_mi;
-  const int above_in_image = xd->up_available && above_mi;
+  const MODE_INFO *const above_mi = get_above_mi(xd);
+  const MODE_INFO *const left_mi = get_left_mi(xd);
+  const MB_MODE_INFO *const above_mbmi = get_above_mbmi(above_mi);
+  const MB_MODE_INFO *const left_mbmi = get_left_mbmi(left_mi);
+  const int above_in_image = above_mi != NULL;
+  const int left_in_image = left_mi != NULL;
   const int max_tx_size = max_txsize_lookup[xd->mi_8x8[0]->mbmi.sb_type];
   int above_context = max_tx_size;
   int left_context = max_tx_size;
diff --git a/vp9/common/vp9_pred_common.h b/vp9/common/vp9_pred_common.h
index 1fdd4da..a869dc0 100644
--- a/vp9/common/vp9_pred_common.h
+++ b/vp9/common/vp9_pred_common.h
@@ -14,17 +14,25 @@
 #include "vp9/common/vp9_blockd.h"
 #include "vp9/common/vp9_onyxc_int.h"
 
+static INLINE const MODE_INFO *get_above_mi(const MACROBLOCKD *const xd) {
+  return xd->up_available ? xd->mi_8x8[-xd->mode_info_stride] : NULL;
+}
+
+static INLINE const MODE_INFO *get_left_mi(const MACROBLOCKD *const xd) {
+  return xd->left_available ? xd->mi_8x8[-1] : NULL;
+}
+
 int vp9_get_segment_id(VP9_COMMON *cm, const uint8_t *segment_ids,
                        BLOCK_SIZE bsize, int mi_row, int mi_col);
 
-
 static INLINE int vp9_get_pred_context_seg_id(const MACROBLOCKD *xd) {
-  const MODE_INFO * const above_mi = xd->mi_8x8[-xd->mode_info_stride];
-  const MODE_INFO * const left_mi = xd->mi_8x8[-1];
-  const int above_sip = above_mi ? above_mi->mbmi.seg_id_predicted : 0;
-  const int left_sip = left_mi ? left_mi->mbmi.seg_id_predicted : 0;
+  const MODE_INFO *const above_mi = get_above_mi(xd);
+  const MODE_INFO *const left_mi = get_left_mi(xd);
+  const int above_sip = (above_mi != NULL) ?
+                        above_mi->mbmi.seg_id_predicted : 0;
+  const int left_sip = (left_mi != NULL) ? left_mi->mbmi.seg_id_predicted : 0;
 
-  return above_sip + (xd->left_available ? left_sip : 0);
+  return above_sip + left_sip;
 }
 
 static INLINE vp9_prob vp9_get_pred_prob_seg_id(struct segmentation *seg,
@@ -35,12 +43,13 @@
 void vp9_set_pred_flag_seg_id(MACROBLOCKD *xd, uint8_t pred_flag);
 
 static INLINE int vp9_get_pred_context_mbskip(const MACROBLOCKD *xd) {
-  const MODE_INFO * const above_mi = xd->mi_8x8[-xd->mode_info_stride];
-  const MODE_INFO * const left_mi = xd->mi_8x8[-1];
-  const int above_skip_coeff = above_mi ? above_mi->mbmi.skip_coeff : 0;
-  const int left_skip_coeff = left_mi ? left_mi->mbmi.skip_coeff : 0;
+  const MODE_INFO *const above_mi = get_above_mi(xd);
+  const MODE_INFO *const left_mi = get_left_mi(xd);
+  const int above_skip_coeff = (above_mi != NULL) ?
+                               above_mi->mbmi.skip_coeff : 0;
+  const int left_skip_coeff = (left_mi != NULL) ? left_mi->mbmi.skip_coeff : 0;
 
-  return above_skip_coeff + (xd->left_available ? left_skip_coeff : 0);
+  return above_skip_coeff + left_skip_coeff;
 }
 
 static INLINE vp9_prob vp9_get_pred_prob_mbskip(const VP9_COMMON *cm,
diff --git a/vp9/common/vp9_rtcd_defs.sh b/vp9/common/vp9_rtcd_defs.sh
index af96bb3..d3f944c 100644
--- a/vp9/common/vp9_rtcd_defs.sh
+++ b/vp9/common/vp9_rtcd_defs.sh
@@ -31,7 +31,7 @@
 # RECON
 #
 prototype void vp9_d207_predictor_4x4 "uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left"
-specialize vp9_d207_predictor_4x4 $ssse3_x86inc
+specialize vp9_d207_predictor_4x4
 
 prototype void vp9_d45_predictor_4x4 "uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left"
 specialize vp9_d45_predictor_4x4 $ssse3_x86inc
@@ -70,7 +70,7 @@
 specialize vp9_dc_128_predictor_4x4
 
 prototype void vp9_d207_predictor_8x8 "uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left"
-specialize vp9_d207_predictor_8x8 $ssse3_x86inc
+specialize vp9_d207_predictor_8x8
 
 prototype void vp9_d45_predictor_8x8 "uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left"
 specialize vp9_d45_predictor_8x8 $ssse3_x86inc
@@ -109,7 +109,7 @@
 specialize vp9_dc_128_predictor_8x8
 
 prototype void vp9_d207_predictor_16x16 "uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left"
-specialize vp9_d207_predictor_16x16 $ssse3_x86inc
+specialize vp9_d207_predictor_16x16
 
 prototype void vp9_d45_predictor_16x16 "uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left"
 specialize vp9_d45_predictor_16x16 $ssse3_x86inc
@@ -148,7 +148,7 @@
 specialize vp9_dc_128_predictor_16x16
 
 prototype void vp9_d207_predictor_32x32 "uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left"
-specialize vp9_d207_predictor_32x32 $ssse3_x86inc
+specialize vp9_d207_predictor_32x32
 
 prototype void vp9_d45_predictor_32x32 "uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left"
 specialize vp9_d45_predictor_32x32 $ssse3_x86inc
@@ -707,7 +707,7 @@
 prototype void vp9_short_fdct32x32_rd "int16_t *InputData, int16_t *OutputData, int stride"
 specialize vp9_short_fdct32x32_rd sse2
 
-prototype void vp9_short_fdct16x16 "int16_t *InputData, int16_t *OutputData, int pitch"
+prototype void vp9_short_fdct16x16 "int16_t *InputData, int16_t *OutputData, int stride"
 specialize vp9_short_fdct16x16 sse2
 
 prototype void vp9_short_walsh4x4 "int16_t *InputData, int16_t *OutputData, int pitch"
diff --git a/vp9/decoder/vp9_decodemv.c b/vp9/decoder/vp9_decodemv.c
index 6cf4f15..6615530 100644
--- a/vp9/decoder/vp9_decodemv.c
+++ b/vp9/decoder/vp9_decodemv.c
@@ -34,7 +34,8 @@
                                             int size_group) {
   const MB_PREDICTION_MODE y_mode = read_intra_mode(r,
                                         cm->fc.y_mode_prob[size_group]);
-  ++cm->counts.y_mode[size_group][y_mode];
+  if (!cm->frame_parallel_decoding_mode)
+    ++cm->counts.y_mode[size_group][y_mode];
   return y_mode;
 }
 
@@ -42,7 +43,8 @@
                                              MB_PREDICTION_MODE y_mode) {
   const MB_PREDICTION_MODE uv_mode = read_intra_mode(r,
                                          cm->fc.uv_mode_prob[y_mode]);
-  ++cm->counts.uv_mode[y_mode][uv_mode];
+  if (!cm->frame_parallel_decoding_mode)
+    ++cm->counts.uv_mode[y_mode][uv_mode];
   return uv_mode;
 }
 
@@ -50,7 +52,8 @@
                                           uint8_t context) {
   const MB_PREDICTION_MODE mode = treed_read(r, vp9_inter_mode_tree,
                                              cm->fc.inter_mode_probs[context]);
-  ++cm->counts.inter_mode[context][inter_mode_offset(mode)];
+  if (!cm->frame_parallel_decoding_mode)
+    ++cm->counts.inter_mode[context][inter_mode_offset(mode)];
   return mode;
 }
 
@@ -69,26 +72,21 @@
       tx_size += vp9_read(r, tx_probs[2]);
   }
 
-  update_tx_counts(bsize, context, tx_size, &cm->counts.tx);
+  if (!cm->frame_parallel_decoding_mode)
+    update_tx_counts(bsize, context, tx_size, &cm->counts.tx);
   return tx_size;
 }
 
-static TX_SIZE read_tx_size(VP9D_COMP *pbi, TX_MODE tx_mode,
-                            BLOCK_SIZE bsize, int allow_select,
+static TX_SIZE read_tx_size(VP9_COMMON *const cm, MACROBLOCKD *const xd,
+                            TX_MODE tx_mode, BLOCK_SIZE bsize, int allow_select,
                             vp9_reader *r) {
-  VP9_COMMON *const cm = &pbi->common;
-  MACROBLOCKD *const xd = &pbi->mb;
-
-  if (allow_select && tx_mode == TX_MODE_SELECT && bsize >= BLOCK_8X8)
+  if (allow_select && tx_mode == TX_MODE_SELECT && bsize >= BLOCK_8X8) {
     return read_selected_tx_size(cm, xd, bsize, r);
-  else if (tx_mode >= ALLOW_32X32 && bsize >= BLOCK_32X32)
-    return TX_32X32;
-  else if (tx_mode >= ALLOW_16X16 && bsize >= BLOCK_16X16)
-    return TX_16X16;
-  else if (tx_mode >= ALLOW_8X8 && bsize >= BLOCK_8X8)
-    return TX_8X8;
-  else
-    return TX_4X4;
+  } else {
+    const TX_SIZE max_tx_size_block = max_txsize_lookup[bsize];
+    const TX_SIZE max_tx_size_txmode = tx_mode_to_biggest_tx_size[tx_mode];
+    return MIN(max_tx_size_block, max_tx_size_txmode);
+  }
 }
 
 static void set_segment_id(VP9_COMMON *cm, BLOCK_SIZE bsize,
@@ -107,10 +105,10 @@
       cm->last_frame_seg_map[mi_offset + y * cm->mi_cols + x] = segment_id;
 }
 
-static int read_intra_segment_id(VP9D_COMP *pbi, int mi_row, int mi_col,
+static int read_intra_segment_id(VP9_COMMON *const cm, MACROBLOCKD *const xd,
+                                 int mi_row, int mi_col,
                                  vp9_reader *r) {
-  MACROBLOCKD *const xd = &pbi->mb;
-  struct segmentation *const seg = &pbi->common.seg;
+  struct segmentation *const seg = &cm->seg;
   const BLOCK_SIZE bsize = xd->mi_8x8[0]->mbmi.sb_type;
   int segment_id;
 
@@ -121,14 +119,12 @@
     return 0;
 
   segment_id = read_segment_id(r, seg);
-  set_segment_id(&pbi->common, bsize, mi_row, mi_col, segment_id);
+  set_segment_id(cm, bsize, mi_row, mi_col, segment_id);
   return segment_id;
 }
 
-static int read_inter_segment_id(VP9D_COMP *pbi, int mi_row, int mi_col,
-                                 vp9_reader *r) {
-  VP9_COMMON *const cm = &pbi->common;
-  MACROBLOCKD *const xd = &pbi->mb;
+static int read_inter_segment_id(VP9_COMMON *const cm, MACROBLOCKD *const xd,
+                                 int mi_row, int mi_col, vp9_reader *r) {
   struct segmentation *const seg = &cm->seg;
   const BLOCK_SIZE bsize = xd->mi_8x8[0]->mbmi.sb_type;
   int pred_segment_id, segment_id;
@@ -154,37 +150,37 @@
   return segment_id;
 }
 
-static uint8_t read_skip_coeff(VP9D_COMP *pbi, int segment_id, vp9_reader *r) {
-  VP9_COMMON *const cm = &pbi->common;
-  MACROBLOCKD *const xd = &pbi->mb;
+static uint8_t read_skip_coeff(VP9_COMMON *const cm, MACROBLOCKD *const xd,
+                               int segment_id, vp9_reader *r) {
   int skip_coeff = vp9_segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP);
   if (!skip_coeff) {
     const int ctx = vp9_get_pred_context_mbskip(xd);
     skip_coeff = vp9_read(r, vp9_get_pred_prob_mbskip(cm, xd));
-    cm->counts.mbskip[ctx][skip_coeff]++;
+    if (!cm->frame_parallel_decoding_mode)
+      ++cm->counts.mbskip[ctx][skip_coeff];
   }
   return skip_coeff;
 }
 
-static void read_intra_frame_mode_info(VP9D_COMP *pbi, MODE_INFO *m,
+static void read_intra_frame_mode_info(VP9_COMMON *const cm,
+                                       MACROBLOCKD *const xd,
+                                       MODE_INFO *const m,
                                        int mi_row, int mi_col, vp9_reader *r) {
-  VP9_COMMON *const cm = &pbi->common;
-  MACROBLOCKD *const xd = &pbi->mb;
   MB_MODE_INFO *const mbmi = &m->mbmi;
   const BLOCK_SIZE bsize = mbmi->sb_type;
   const MODE_INFO *above_mi = xd->mi_8x8[-cm->mode_info_stride];
-  const MODE_INFO *left_mi = xd->mi_8x8[-1];
 
-  mbmi->segment_id = read_intra_segment_id(pbi, mi_row, mi_col, r);
-  mbmi->skip_coeff = read_skip_coeff(pbi, mbmi->segment_id, r);
-  mbmi->tx_size = read_tx_size(pbi, cm->tx_mode, bsize, 1, r);
+  mbmi->segment_id = read_intra_segment_id(cm, xd, mi_row, mi_col, r);
+  mbmi->skip_coeff = read_skip_coeff(cm, xd, mbmi->segment_id, r);
+  mbmi->tx_size = read_tx_size(cm, xd, cm->tx_mode, bsize, 1, r);
   mbmi->ref_frame[0] = INTRA_FRAME;
   mbmi->ref_frame[1] = NONE;
 
   if (bsize >= BLOCK_8X8) {
     const MB_PREDICTION_MODE A = above_block_mode(m, above_mi, 0);
-    const MB_PREDICTION_MODE L = xd->left_available ?
-                                  left_block_mode(m, left_mi, 0) : DC_PRED;
+    const MB_PREDICTION_MODE L = xd->left_available
+                               ? left_block_mode(m, xd->mi_8x8[-1], 0)
+                               : DC_PRED;
     mbmi->mode = read_intra_mode(r, vp9_kf_y_mode_prob[A][L]);
   } else {
     // Only 4x4, 4x8, 8x4 blocks
@@ -196,8 +192,9 @@
       for (idx = 0; idx < 2; idx += num_4x4_w) {
         const int ib = idy * 2 + idx;
         const MB_PREDICTION_MODE A = above_block_mode(m, above_mi, ib);
-        const MB_PREDICTION_MODE L = (xd->left_available || idx) ?
-                                     left_block_mode(m, left_mi, ib) : DC_PRED;
+        const MB_PREDICTION_MODE L = (xd->left_available || idx)
+                                   ? left_block_mode(m, xd->mi_8x8[-1], ib)
+                                   : DC_PRED;
         const MB_PREDICTION_MODE b_mode = read_intra_mode(r,
                                               vp9_kf_y_mode_prob[A][L]);
         m->bmi[ib].as_mode = b_mode;
@@ -312,10 +309,9 @@
 }
 
 // Read the referncence frame
-static void read_ref_frames(VP9D_COMP *pbi, vp9_reader *r,
+static void read_ref_frames(VP9_COMMON *const cm, MACROBLOCKD *const xd,
+                            vp9_reader *r,
                             int segment_id, MV_REFERENCE_FRAME ref_frame[2]) {
-  VP9_COMMON *const cm = &pbi->common;
-  MACROBLOCKD *const xd = &pbi->mb;
   FRAME_CONTEXT *const fc = &cm->fc;
   FRAME_COUNTS *const counts = &cm->counts;
 
@@ -328,7 +324,8 @@
 
     if (cm->comp_pred_mode == HYBRID_PREDICTION) {
       is_comp = vp9_read(r, fc->comp_inter_prob[comp_ctx]);
-      counts->comp_inter[comp_ctx][is_comp]++;
+      if (!cm->frame_parallel_decoding_mode)
+        ++counts->comp_inter[comp_ctx][is_comp];
     } else {
       is_comp = cm->comp_pred_mode == COMP_PREDICTION_ONLY;
     }
@@ -338,18 +335,21 @@
       const int fix_ref_idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref];
       const int ref_ctx = vp9_get_pred_context_comp_ref_p(cm, xd);
       const int b = vp9_read(r, fc->comp_ref_prob[ref_ctx]);
-      counts->comp_ref[ref_ctx][b]++;
+      if (!cm->frame_parallel_decoding_mode)
+        ++counts->comp_ref[ref_ctx][b];
       ref_frame[fix_ref_idx] = cm->comp_fixed_ref;
       ref_frame[!fix_ref_idx] = cm->comp_var_ref[b];
     } else {
       const int ctx0 = vp9_get_pred_context_single_ref_p1(xd);
       const int bit0 = vp9_read(r, fc->single_ref_prob[ctx0][0]);
-      ++counts->single_ref[ctx0][0][bit0];
+      if (!cm->frame_parallel_decoding_mode)
+        ++counts->single_ref[ctx0][0][bit0];
       if (bit0) {
         const int ctx1 = vp9_get_pred_context_single_ref_p2(xd);
         const int bit1 = vp9_read(r, fc->single_ref_prob[ctx1][1]);
         ref_frame[0] = bit1 ? ALTREF_FRAME : GOLDEN_FRAME;
-        ++counts->single_ref[ctx1][1][bit1];
+        if (!cm->frame_parallel_decoding_mode)
+          ++counts->single_ref[ctx1][1][bit1];
       } else {
         ref_frame[0] = LAST_FRAME;
       }
@@ -381,19 +381,17 @@
 }
 
 static INLINE INTERPOLATIONFILTERTYPE read_switchable_filter_type(
-    VP9D_COMP *pbi, vp9_reader *r) {
-  VP9_COMMON *const cm = &pbi->common;
-  MACROBLOCKD *const xd = &pbi->mb;
+    VP9_COMMON *const cm, MACROBLOCKD *const xd, vp9_reader *r) {
   const int ctx = vp9_get_pred_context_switchable_interp(xd);
   const int type = treed_read(r, vp9_switchable_interp_tree,
                               cm->fc.switchable_interp_prob[ctx]);
-  ++cm->counts.switchable_interp[ctx][type];
+  if (!cm->frame_parallel_decoding_mode)
+    ++cm->counts.switchable_interp[ctx][type];
   return type;
 }
 
-static void read_intra_block_mode_info(VP9D_COMP *pbi, MODE_INFO *mi,
-                                  vp9_reader *r) {
-  VP9_COMMON *const cm = &pbi->common;
+static void read_intra_block_mode_info(VP9_COMMON *const cm, MODE_INFO *mi,
+                                       vp9_reader *r) {
   MB_MODE_INFO *const mbmi = &mi->mbmi;
   const BLOCK_SIZE bsize = mi->mbmi.sb_type;
 
@@ -425,64 +423,68 @@
   mbmi->uv_mode = read_intra_mode_uv(cm, r, mbmi->mode);
 }
 
-static INLINE void assign_mv(VP9_COMMON *cm, MB_PREDICTION_MODE mode,
+static INLINE int assign_mv(VP9_COMMON *cm, MB_PREDICTION_MODE mode,
                              int_mv mv[2], int_mv best_mv[2],
                              int_mv nearest_mv[2], int_mv near_mv[2],
                              int is_compound, int allow_hp, vp9_reader *r) {
   int i;
+  int ret = 1;
 
   switch (mode) {
-    case NEWMV:
-       read_mv(r, &mv[0].as_mv, &best_mv[0].as_mv,
-               &cm->fc.nmvc, &cm->counts.mv, allow_hp);
-       if (is_compound)
-         read_mv(r, &mv[1].as_mv, &best_mv[1].as_mv,
-                 &cm->fc.nmvc, &cm->counts.mv, allow_hp);
-       break;
-    case NEARESTMV:
+    case NEWMV: {
+      nmv_context_counts *const mv_counts = cm->frame_parallel_decoding_mode ?
+                                            NULL : &cm->counts.mv;
+      read_mv(r, &mv[0].as_mv, &best_mv[0].as_mv,
+              &cm->fc.nmvc, mv_counts, allow_hp);
+      if (is_compound)
+        read_mv(r, &mv[1].as_mv, &best_mv[1].as_mv,
+                &cm->fc.nmvc, mv_counts, allow_hp);
+      for (i = 0; i < 1 + is_compound; ++i) {
+        ret = ret && mv[i].as_mv.row < MV_UPP && mv[i].as_mv.row > MV_LOW;
+        ret = ret && mv[i].as_mv.col < MV_UPP && mv[i].as_mv.col > MV_LOW;
+      }
+      break;
+    }
+    case NEARESTMV: {
       mv[0].as_int = nearest_mv[0].as_int;
-      if (is_compound)
-        mv[1].as_int = nearest_mv[1].as_int;
+      if (is_compound) mv[1].as_int = nearest_mv[1].as_int;
       break;
-    case NEARMV:
+    }
+    case NEARMV: {
       mv[0].as_int = near_mv[0].as_int;
-      if (is_compound)
-        mv[1].as_int = near_mv[1].as_int;
+      if (is_compound) mv[1].as_int = near_mv[1].as_int;
       break;
-    case ZEROMV:
+    }
+    case ZEROMV: {
       mv[0].as_int = 0;
-      if (is_compound)
-        mv[1].as_int = 0;
+      if (is_compound) mv[1].as_int = 0;
       break;
-    default:
-      assert(!"Invalid inter mode value.");
+    }
+    default: {
+      return 0;
+    }
   }
-
-  for (i = 0; i < 1 + is_compound; ++i) {
-    assert(mv[i].as_mv.row < MV_UPP && mv[i].as_mv.row > MV_LOW);
-    assert(mv[i].as_mv.col < MV_UPP && mv[i].as_mv.col > MV_LOW);
-  }
+  return ret;
 }
 
-static int read_is_inter_block(VP9D_COMP *pbi, int segment_id, vp9_reader *r) {
-  VP9_COMMON *const cm = &pbi->common;
-  MACROBLOCKD *const xd = &pbi->mb;
-
+static int read_is_inter_block(VP9_COMMON *const cm, MACROBLOCKD *const xd,
+                               int segment_id, vp9_reader *r) {
   if (vp9_segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME)) {
     return vp9_get_segdata(&cm->seg, segment_id, SEG_LVL_REF_FRAME) !=
            INTRA_FRAME;
   } else {
     const int ctx = vp9_get_pred_context_intra_inter(xd);
     const int is_inter = vp9_read(r, vp9_get_pred_prob_intra_inter(cm, xd));
-    ++cm->counts.intra_inter[ctx][is_inter];
+    if (!cm->frame_parallel_decoding_mode)
+      ++cm->counts.intra_inter[ctx][is_inter];
     return is_inter;
   }
 }
 
-static void read_inter_block_mode_info(VP9D_COMP *pbi, MODE_INFO *mi,
+static void read_inter_block_mode_info(VP9_COMMON *const cm,
+                                       MACROBLOCKD *const xd,
+                                       MODE_INFO *const mi,
                                        int mi_row, int mi_col, vp9_reader *r) {
-  VP9_COMMON *const cm = &pbi->common;
-  MACROBLOCKD *const xd = &pbi->mb;
   MB_MODE_INFO *const mbmi = &mi->mbmi;
   const BLOCK_SIZE bsize = mbmi->sb_type;
   const int allow_hp = xd->allow_high_precision_mv;
@@ -493,7 +495,7 @@
   int is_compound;
 
   mbmi->uv_mode = DC_PRED;
-  read_ref_frames(pbi, r, mbmi->segment_id, mbmi->ref_frame);
+  read_ref_frames(cm, xd, r, mbmi->segment_id, mbmi->ref_frame);
   ref0 = mbmi->ref_frame[0];
   is_compound = has_second_ref(mbmi);
 
@@ -531,9 +533,9 @@
     }
   }
 
-  mbmi->interp_filter = cm->mcomp_filter_type == SWITCHABLE
-                              ? read_switchable_filter_type(pbi, r)
-                              : cm->mcomp_filter_type;
+  mbmi->interp_filter = (cm->mcomp_filter_type == SWITCHABLE)
+                      ? read_switchable_filter_type(cm, xd, r)
+                      : cm->mcomp_filter_type;
 
   if (bsize < BLOCK_8X8) {
     const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];  // 1 or 2
@@ -557,8 +559,12 @@
                                           mi_row, mi_col);
         }
 
-        assign_mv(cm, b_mode, block, best, nearest, nearmv,
-                  is_compound, allow_hp, r);
+        if (!assign_mv(cm, b_mode, block, best, nearest, nearmv,
+                       is_compound, allow_hp, r)) {
+          xd->corrupted |= 1;
+          break;
+        };
+
 
         mi->bmi[j].as_mv[0].as_int = block[0].as_int;
         if (is_compound)
@@ -576,29 +582,31 @@
     mbmi->mv[0].as_int = mi->bmi[3].as_mv[0].as_int;
     mbmi->mv[1].as_int = mi->bmi[3].as_mv[1].as_int;
   } else {
-    assign_mv(cm, mbmi->mode, mbmi->mv, best, nearest, nearmv,
-              is_compound, allow_hp, r);
+    xd->corrupted |= !assign_mv(cm, mbmi->mode, mbmi->mv,
+                                best, nearest, nearmv,
+                                is_compound, allow_hp, r);
   }
 }
 
-static void read_inter_frame_mode_info(VP9D_COMP *pbi, MODE_INFO *mi,
+static void read_inter_frame_mode_info(VP9_COMMON *const cm,
+                                       MACROBLOCKD *const xd,
+                                       MODE_INFO *const mi,
                                        int mi_row, int mi_col, vp9_reader *r) {
-  VP9_COMMON *const cm = &pbi->common;
   MB_MODE_INFO *const mbmi = &mi->mbmi;
   int inter_block;
 
   mbmi->mv[0].as_int = 0;
   mbmi->mv[1].as_int = 0;
-  mbmi->segment_id = read_inter_segment_id(pbi, mi_row, mi_col, r);
-  mbmi->skip_coeff = read_skip_coeff(pbi, mbmi->segment_id, r);
-  inter_block = read_is_inter_block(pbi, mbmi->segment_id, r);
-  mbmi->tx_size = read_tx_size(pbi, cm->tx_mode, mbmi->sb_type,
+  mbmi->segment_id = read_inter_segment_id(cm, xd, mi_row, mi_col, r);
+  mbmi->skip_coeff = read_skip_coeff(cm, xd, mbmi->segment_id, r);
+  inter_block = read_is_inter_block(cm, xd, mbmi->segment_id, r);
+  mbmi->tx_size = read_tx_size(cm, xd, cm->tx_mode, mbmi->sb_type,
                                !mbmi->skip_coeff || !inter_block, r);
 
   if (inter_block)
-    read_inter_block_mode_info(pbi, mi, mi_row, mi_col, r);
+    read_inter_block_mode_info(cm, xd, mi, mi_row, mi_col, r);
   else
-    read_intra_block_mode_info(pbi, mi, r);
+    read_intra_block_mode_info(cm, mi, r);
 }
 
 static void read_comp_pred(VP9_COMMON *cm, vp9_reader *r) {
@@ -658,10 +666,9 @@
   }
 }
 
-void vp9_read_mode_info(VP9D_COMP* pbi, int mi_row, int mi_col, vp9_reader *r) {
-  VP9_COMMON *const cm = &pbi->common;
-  MACROBLOCKD *const xd = &pbi->mb;
-  MODE_INFO *mi = xd->mi_8x8[0];
+void vp9_read_mode_info(VP9_COMMON *cm, MACROBLOCKD *xd,
+                        int mi_row, int mi_col, vp9_reader *r) {
+  MODE_INFO *const mi = xd->mi_8x8[0];
   const BLOCK_SIZE bsize = mi->mbmi.sb_type;
   const int bw = 1 << mi_width_log2(bsize);
   const int bh = 1 << mi_height_log2(bsize);
@@ -670,12 +677,13 @@
   int x, y, z;
 
   if (frame_is_intra_only(cm))
-    read_intra_frame_mode_info(pbi, mi, mi_row, mi_col, r);
+    read_intra_frame_mode_info(cm, xd, mi, mi_row, mi_col, r);
   else
-    read_inter_frame_mode_info(pbi, mi, mi_row, mi_col, r);
+    read_inter_frame_mode_info(cm, xd, mi, mi_row, mi_col, r);
 
-  for (y = 0, z = 0; y < y_mis; y++, z += cm->mode_info_stride)
+  for (y = 0, z = 0; y < y_mis; y++, z += cm->mode_info_stride) {
     for (x = !y; x < x_mis; x++) {
-        xd->mi_8x8[z + x] = mi;
-      }
+      xd->mi_8x8[z + x] = mi;
+    }
+  }
 }
diff --git a/vp9/decoder/vp9_decodemv.h b/vp9/decoder/vp9_decodemv.h
index 462d2e3..7f2517c 100644
--- a/vp9/decoder/vp9_decodemv.h
+++ b/vp9/decoder/vp9_decodemv.h
@@ -14,8 +14,9 @@
 #include "vp9/decoder/vp9_onyxd_int.h"
 #include "vp9/decoder/vp9_dboolhuff.h"
 
-void vp9_prepare_read_mode_info(VP9D_COMP* pbi, vp9_reader *r);
+void vp9_prepare_read_mode_info(VP9D_COMP *pbi, vp9_reader *r);
 
-void vp9_read_mode_info(VP9D_COMP* pbi, int mi_row, int mi_col, vp9_reader *r);
+void vp9_read_mode_info(VP9_COMMON *cm, MACROBLOCKD *xd,
+                        int mi_row, int mi_col, vp9_reader *r);
 
 #endif  // VP9_DECODER_VP9_DECODEMV_H_
diff --git a/vp9/decoder/vp9_decodframe.c b/vp9/decoder/vp9_decodframe.c
index ec310f4..6984562 100644
--- a/vp9/decoder/vp9_decodframe.c
+++ b/vp9/decoder/vp9_decodframe.c
@@ -155,9 +155,8 @@
     decode_block(plane, block, plane_bsize, tx_size, arg);
 }
 
-static int decode_tokens(VP9D_COMP *pbi, BLOCK_SIZE bsize, vp9_reader *r) {
-  VP9_COMMON *const cm = &pbi->common;
-  MACROBLOCKD *const xd = &pbi->mb;
+static int decode_tokens(VP9_COMMON *const cm, MACROBLOCKD *const xd,
+                         BLOCK_SIZE bsize, vp9_reader *r) {
   MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi;
 
   if (mbmi->skip_coeff) {
@@ -169,7 +168,7 @@
                                                   cm->base_qindex));
 
     // TODO(dkovalev) if (!vp9_reader_has_error(r))
-    return vp9_decode_tokens(pbi, r, bsize);
+    return vp9_decode_tokens(cm, xd, &cm->seg, r, bsize);
   }
 }
 
@@ -206,25 +205,25 @@
   setup_dst_planes(xd, &cm->yv12_fb[cm->new_fb_idx], mi_row, mi_col);
 }
 
-static void set_ref(VP9D_COMP *pbi, int i, int mi_row, int mi_col) {
-  VP9_COMMON *const cm = &pbi->common;
-  MACROBLOCKD *const xd = &pbi->mb;
+static void set_ref(VP9_COMMON *const cm, MACROBLOCKD *const xd,
+                    int idx, int mi_row, int mi_col) {
   MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi;
-  const int ref = mbmi->ref_frame[i] - LAST_FRAME;
+  const int ref = mbmi->ref_frame[idx] - LAST_FRAME;
   const YV12_BUFFER_CONFIG *cfg = &cm->yv12_fb[cm->active_ref_idx[ref]];
   const struct scale_factors *sf = &cm->active_ref_scale[ref];
   if (!vp9_is_valid_scale(sf))
     vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
                        "Invalid scale factors");
 
-  xd->scale_factor[i] = *sf;
-  setup_pre_planes(xd, i, cfg, mi_row, mi_col, sf);
+  xd->scale_factor[idx] = *sf;
+  setup_pre_planes(xd, idx, cfg, mi_row, mi_col, sf);
   xd->corrupted |= cfg->corrupted;
 }
 
 static void decode_modes_b(VP9D_COMP *pbi, int tile_col,
                            int mi_row, int mi_col,
                            vp9_reader *r, BLOCK_SIZE bsize, int index) {
+  VP9_COMMON *const cm = &pbi->common;
   MACROBLOCKD *const xd = &pbi->mb;
   const int less8x8 = bsize < BLOCK_8X8;
   MB_MODE_INFO *mbmi;
@@ -235,14 +234,14 @@
       return;
 
   set_offsets(pbi, bsize, tile_col, mi_row, mi_col);
-  vp9_read_mode_info(pbi, mi_row, mi_col, r);
+  vp9_read_mode_info(cm, xd, mi_row, mi_col, r);
 
   if (less8x8)
     bsize = BLOCK_8X8;
 
   // Has to be called after set_offsets
   mbmi = &xd->mi_8x8[0]->mbmi;
-  eobtotal = decode_tokens(pbi, bsize, r);
+  eobtotal = decode_tokens(cm, xd, bsize, r);
 
   if (!is_inter_block(mbmi)) {
     // Intra reconstruction
@@ -257,9 +256,9 @@
         mbmi->skip_coeff = 1;  // skip loopfilter
     }
 
-    set_ref(pbi, 0, mi_row, mi_col);
+    set_ref(cm, xd, 0, mi_row, mi_col);
     if (has_second_ref(mbmi))
-      set_ref(pbi, 1, mi_row, mi_col);
+      set_ref(cm, xd, 1, mi_row, mi_col);
 
     xd->subpix.filter_x = xd->subpix.filter_y =
         vp9_get_filter_kernel(mbmi->interp_filter);
@@ -271,7 +270,6 @@
   xd->corrupted |= vp9_reader_has_error(r);
 }
 
-
 static void decode_modes_sb(VP9D_COMP *pbi, int tile_col,
                             int mi_row, int mi_col,
                             vp9_reader* r, BLOCK_SIZE bsize, int index) {
@@ -303,7 +301,8 @@
     else
       partition = PARTITION_SPLIT;
 
-    cm->counts.partition[pl][partition]++;
+    if (!cm->frame_parallel_decoding_mode)
+      ++cm->counts.partition[pl][partition];
   }
 
   subsize = get_subsize(bsize, partition);
@@ -342,21 +341,20 @@
   }
 }
 
-static void setup_token_decoder(VP9D_COMP *pbi,
-                                const uint8_t *data, size_t read_size,
+static void setup_token_decoder(const uint8_t *data,
+                                const uint8_t *data_end,
+                                size_t read_size,
+                                struct vpx_internal_error_info *error_info,
                                 vp9_reader *r) {
-  VP9_COMMON *cm = &pbi->common;
-  const uint8_t *data_end = pbi->source + pbi->source_sz;
-
   // Validate the calculated partition length. If the buffer
   // described by the partition can't be fully read, then restrict
   // it to the portion that can be (for EC mode) or throw an error.
   if (!read_is_valid(data, read_size, data_end))
-    vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME,
+    vpx_internal_error(error_info, VPX_CODEC_CORRUPT_FRAME,
                        "Truncated packet or corrupt tile length");
 
   if (vp9_reader_init(r, data, read_size))
-    vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
+    vpx_internal_error(error_info, VPX_CODEC_MEM_ERROR,
                        "Failed to allocate bool decoder %d", 1);
 }
 
@@ -707,9 +705,9 @@
       vp9_get_tile_row_offsets(cm, tile_row);
       for (tile_col = tile_cols - 1; tile_col >= 0; tile_col--) {
         vp9_get_tile_col_offsets(cm, tile_col);
-        setup_token_decoder(pbi, data_ptr2[tile_row][tile_col],
+        setup_token_decoder(data_ptr2[tile_row][tile_col], data_end,
                             data_end - data_ptr2[tile_row][tile_col],
-                            &residual_bc);
+                            &cm->error, &residual_bc);
         decode_tile(pbi, &residual_bc, tile_col);
         if (tile_row == tile_rows - 1 && tile_col == tile_cols - 1)
           bc_bak = residual_bc;
@@ -738,7 +736,7 @@
           size = data_end - data;
         }
 
-        setup_token_decoder(pbi, data, size, &residual_bc);
+        setup_token_decoder(data, data_end, size, &cm->error, &residual_bc);
         decode_tile(pbi, &residual_bc, tile_col);
         data += size;
       }
diff --git a/vp9/decoder/vp9_detokenize.c b/vp9/decoder/vp9_detokenize.c
index 58976ec..2f5b136 100644
--- a/vp9/decoder/vp9_detokenize.c
+++ b/vp9/decoder/vp9_detokenize.c
@@ -113,7 +113,8 @@
       pt = get_coef_context(nb, token_cache, c);
     band = get_coef_band(band_translate, c);
     prob = coef_probs[band][pt];
-    counts->eob_branch[tx_size][type][ref][band][pt]++;
+    if (!cm->frame_parallel_decoding_mode)
+      ++counts->eob_branch[tx_size][type][ref][band][pt];
     if (!vp9_read(r, prob[EOB_CONTEXT_NODE]))
       break;
 
@@ -198,14 +199,18 @@
     WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY6);
   }
 
-  if (c < seg_eob)
-    coef_counts[type][ref][band][pt][DCT_EOB_MODEL_TOKEN]++;
+  if (c < seg_eob) {
+    if (!cm->frame_parallel_decoding_mode)
+      ++coef_counts[type][ref][band][pt][DCT_EOB_MODEL_TOKEN];
+  }
 
   return c;
 }
 
 struct decode_block_args {
-  VP9D_COMP *pbi;
+  VP9_COMMON *cm;
+  MACROBLOCKD *xd;
+  struct segmentation *seg;
   vp9_reader *r;
   int *eobtotal;
 };
@@ -215,8 +220,8 @@
   const struct decode_block_args* const arg = argv;
 
   // find the maximum eob for this transform size, adjusted by segment
-  MACROBLOCKD *xd = &arg->pbi->mb;
-  struct segmentation *seg = &arg->pbi->common.seg;
+  MACROBLOCKD *xd = arg->xd;
+  const struct segmentation *seg = arg->seg;
   struct macroblockd_plane* pd = &xd->plane[plane];
   const int segment_id = xd->mi_8x8[0]->mbmi.segment_id;
   const int seg_eob = get_tx_eob(seg, segment_id, tx_size);
@@ -226,7 +231,7 @@
   pt = get_entropy_context(tx_size, pd->above_context + aoff,
                                     pd->left_context + loff);
 
-  eob = decode_coefs(&arg->pbi->common, xd, arg->r, block,
+  eob = decode_coefs(arg->cm, xd, arg->r, block,
                      pd->plane_type, seg_eob, BLOCK_OFFSET(pd->qcoeff, block),
                      tx_size, pd->dequant, pt);
 
@@ -236,9 +241,11 @@
   *arg->eobtotal += eob;
 }
 
-int vp9_decode_tokens(VP9D_COMP *pbi, vp9_reader *r, BLOCK_SIZE bsize) {
+int vp9_decode_tokens(VP9_COMMON *cm, MACROBLOCKD *xd,
+                      struct segmentation *seg,
+                      vp9_reader *r, BLOCK_SIZE bsize) {
   int eobtotal = 0;
-  struct decode_block_args args = {pbi, r, &eobtotal};
-  foreach_transformed_block(&pbi->mb, bsize, decode_block, &args);
+  struct decode_block_args args = {cm, xd, seg, r, &eobtotal};
+  foreach_transformed_block(xd, bsize, decode_block, &args);
   return eobtotal;
 }
diff --git a/vp9/decoder/vp9_detokenize.h b/vp9/decoder/vp9_detokenize.h
index cf07c56..0fb4c3c 100644
--- a/vp9/decoder/vp9_detokenize.h
+++ b/vp9/decoder/vp9_detokenize.h
@@ -15,6 +15,8 @@
 #include "vp9/decoder/vp9_onyxd_int.h"
 #include "vp9/decoder/vp9_dboolhuff.h"
 
-int vp9_decode_tokens(VP9D_COMP* pbi, vp9_reader *r, BLOCK_SIZE bsize);
+int vp9_decode_tokens(VP9_COMMON *cm, MACROBLOCKD *xd,
+                      struct segmentation *seg,
+                      vp9_reader *r, BLOCK_SIZE bsize);
 
 #endif  // VP9_DECODER_VP9_DETOKENIZE_H_
diff --git a/vp9/encoder/vp9_dct.c b/vp9/encoder/vp9_dct.c
index 00a2903..23c652d 100644
--- a/vp9/encoder/vp9_dct.c
+++ b/vp9/encoder/vp9_dct.c
@@ -302,14 +302,13 @@
   }
 }
 
-void vp9_short_fdct16x16_c(int16_t *input, int16_t *output, int pitch) {
+void vp9_short_fdct16x16_c(int16_t *input, int16_t *output, int stride) {
   // The 2D transform is done with two passes which are actually pretty
   // similar. In the first one, we transform the columns and transpose
   // the results. In the second one, we transform the rows. To achieve that,
   // as the first pass results are transposed, we tranpose the columns (that
   // is the transposed rows) and transpose the results (so that it goes back
   // in normal/row positions).
-  const int stride = pitch >> 1;
   int pass;
   // We need an intermediate buffer between passes.
   int16_t intermediate[256];
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c
index 2f6d458..6e8e1d1 100644
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -30,7 +30,6 @@
 #include "vp9/common/vp9_reconinter.h"
 #include "vp9/common/vp9_seg_common.h"
 #include "vp9/common/vp9_tile_common.h"
-
 #include "vp9/encoder/vp9_encodeframe.h"
 #include "vp9/encoder/vp9_encodeintra.h"
 #include "vp9/encoder/vp9_encodemb.h"
@@ -46,14 +45,6 @@
 #define DBG_PRNT_SEGMAP 0
 
 
-static const TX_SIZE tx_mode_to_biggest_tx_size[TX_MODES] = {
-  TX_4X4,  // ONLY_4X4
-  TX_8X8,  // ONLY_8X8
-  TX_16X16,  // ONLY_16X16
-  TX_32X32,  // ONLY_32X32
-  TX_32X32,  // TX_MODE_SELECT
-};
-
 // #define ENC_DEBUG
 #ifdef ENC_DEBUG
 int enc_debug = 0;
diff --git a/vp9/encoder/vp9_encodemb.c b/vp9/encoder/vp9_encodemb.c
index 2b5451b..13d8aa8 100644
--- a/vp9/encoder/vp9_encodemb.c
+++ b/vp9/encoder/vp9_encodemb.c
@@ -379,7 +379,7 @@
       xoff = 16 * (block & twmask);
       yoff = 16 * (block >> twl);
       src_diff = p->src_diff + 4 * bw * yoff + xoff;
-      vp9_short_fdct16x16(src_diff, coeff, bw * 8);
+      vp9_short_fdct16x16(src_diff, coeff, bw * 4);
       vp9_quantize_b(coeff, 256, x->skip_block, p->zbin, p->round,
                      p->quant, p->quant_shift, qcoeff, dqcoeff,
                      pd->dequant, p->zbin_extra, eob, scan, iscan);
@@ -559,7 +559,7 @@
       if (tx_type != DCT_DCT)
         vp9_short_fht16x16(src_diff, coeff, bw * 4, tx_type);
       else
-        vp9_short_fdct16x16(src_diff, coeff, bw * 8);
+        vp9_short_fdct16x16(src_diff, coeff, bw * 4);
       vp9_quantize_b(coeff, 256, x->skip_block, p->zbin, p->round,
                      p->quant, p->quant_shift, qcoeff, dqcoeff,
                      pd->dequant, p->zbin_extra, eob, scan, iscan);
diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c
index 7add494..30cdb3f 100644
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -715,22 +715,12 @@
                                      BLOCK_SIZE bs) {
   const TX_SIZE max_tx_size = max_txsize_lookup[bs];
   VP9_COMMON *const cm = &cpi->common;
+  const TX_SIZE largest_tx_size = tx_mode_to_biggest_tx_size[cm->tx_mode];
   MACROBLOCKD *const xd = &x->e_mbd;
   MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi;
-  if (max_tx_size == TX_32X32 &&
-      (cm->tx_mode == ALLOW_32X32 ||
-       cm->tx_mode == TX_MODE_SELECT)) {
-    mbmi->tx_size = TX_32X32;
-  } else if (max_tx_size >= TX_16X16 &&
-             (cm->tx_mode == ALLOW_16X16 ||
-              cm->tx_mode == ALLOW_32X32 ||
-              cm->tx_mode == TX_MODE_SELECT)) {
-    mbmi->tx_size = TX_16X16;
-  } else if (cm->tx_mode != ONLY_4X4) {
-    mbmi->tx_size = TX_8X8;
-  } else {
-    mbmi->tx_size = TX_4X4;
-  }
+
+  mbmi->tx_size = MIN(max_tx_size, largest_tx_size);
+
   txfm_rd_in_plane(x, &cpi->rdcost_stack, rate, distortion, skip,
                    &sse[mbmi->tx_size], ref_best_rd, 0, bs,
                    mbmi->tx_size);
diff --git a/vp9/encoder/x86/vp9_dct_sse2.c b/vp9/encoder/x86/vp9_dct_sse2.c
index 5e1e5ed..457883f 100644
--- a/vp9/encoder/x86/vp9_dct_sse2.c
+++ b/vp9/encoder/x86/vp9_dct_sse2.c
@@ -1056,14 +1056,13 @@
   write_buffer_8x8(output, in, 8);
 }
 
-void vp9_short_fdct16x16_sse2(int16_t *input, int16_t *output, int pitch) {
+void vp9_short_fdct16x16_sse2(int16_t *input, int16_t *output, int stride) {
   // The 2D transform is done with two passes which are actually pretty
   // similar. In the first one, we transform the columns and transpose
   // the results. In the second one, we transform the rows. To achieve that,
   // as the first pass results are transposed, we tranpose the columns (that
   // is the transposed rows) and transpose the results (so that it goes back
   // in normal/row positions).
-  const int stride = pitch >> 1;
   int pass;
   // We need an intermediate buffer between passes.
   DECLARE_ALIGNED_ARRAY(16, int16_t, intermediate, 256);
diff --git a/vpx/vp8.h b/vpx/vp8.h
index ff71503..57d3cae 100644
--- a/vpx/vp8.h
+++ b/vpx/vp8.h
@@ -8,7 +8,6 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-
 /*!\defgroup vp8 VP8
  * \ingroup codecs
  * VP8 is vpx's newest video compression algorithm that uses motion
@@ -31,6 +30,9 @@
 #ifndef VP8_H
 #define VP8_H
 
+#include "./vpx_codec.h"
+#include "./vpx_image.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif