Merge "Fix chrome valgrind warning due to the use of mismatched bsize"
diff --git a/test/convolve_test.cc b/test/convolve_test.cc
index 6af2abb..2fcb2df 100644
--- a/test/convolve_test.cc
+++ b/test/convolve_test.cc
@@ -264,7 +264,7 @@
   uint8_t* const out = output();
   DECLARE_ALIGNED(256, const int16_t, filter8[8]) = {0, 0, 0, 128, 0, 0, 0, 0};
 
-  REGISTER_STATE_CHECK(
+  ASM_REGISTER_STATE_CHECK(
       UUT_->h8_(in, kInputStride, out, kOutputStride, filter8, 16, filter8, 16,
                 Width(), Height()));
 
@@ -281,7 +281,7 @@
   uint8_t* const out = output();
   DECLARE_ALIGNED(256, const int16_t, filter8[8]) = {0, 0, 0, 128, 0, 0, 0, 0};
 
-  REGISTER_STATE_CHECK(
+  ASM_REGISTER_STATE_CHECK(
       UUT_->v8_(in, kInputStride, out, kOutputStride, filter8, 16, filter8, 16,
                 Width(), Height()));
 
@@ -298,7 +298,7 @@
   uint8_t* const out = output();
   DECLARE_ALIGNED(256, const int16_t, filter8[8]) = {0, 0, 0, 128, 0, 0, 0, 0};
 
-  REGISTER_STATE_CHECK(
+  ASM_REGISTER_STATE_CHECK(
       UUT_->hv8_(in, kInputStride, out, kOutputStride, filter8, 16, filter8, 16,
                  Width(), Height()));
 
@@ -356,17 +356,17 @@
                            Width(), Height());
 
         if (filters == eighttap_smooth || (filter_x && filter_y))
-          REGISTER_STATE_CHECK(
+          ASM_REGISTER_STATE_CHECK(
               UUT_->hv8_(in, kInputStride, out, kOutputStride,
                          filters[filter_x], 16, filters[filter_y], 16,
                          Width(), Height()));
         else if (filter_y)
-          REGISTER_STATE_CHECK(
+          ASM_REGISTER_STATE_CHECK(
               UUT_->v8_(in, kInputStride, out, kOutputStride,
                         kInvalidFilter, 16, filters[filter_y], 16,
                         Width(), Height()));
         else
-          REGISTER_STATE_CHECK(
+          ASM_REGISTER_STATE_CHECK(
               UUT_->h8_(in, kInputStride, out, kOutputStride,
                         filters[filter_x], 16, kInvalidFilter, 16,
                         Width(), Height()));
@@ -414,17 +414,17 @@
                                    Width(), Height());
 
         if (filters == eighttap_smooth || (filter_x && filter_y))
-          REGISTER_STATE_CHECK(
+          ASM_REGISTER_STATE_CHECK(
               UUT_->hv8_avg_(in, kInputStride, out, kOutputStride,
                              filters[filter_x], 16, filters[filter_y], 16,
                              Width(), Height()));
         else if (filter_y)
-          REGISTER_STATE_CHECK(
+          ASM_REGISTER_STATE_CHECK(
               UUT_->v8_avg_(in, kInputStride, out, kOutputStride,
                             filters[filter_x], 16, filters[filter_y], 16,
                             Width(), Height()));
         else
-          REGISTER_STATE_CHECK(
+          ASM_REGISTER_STATE_CHECK(
               UUT_->h8_avg_(in, kInputStride, out, kOutputStride,
                             filters[filter_x], 16, filters[filter_y], 16,
                             Width(), Height()));
@@ -494,9 +494,10 @@
    */
 
   /* Test the horizontal filter. */
-  REGISTER_STATE_CHECK(UUT_->h8_(in, kInputStride, out, kOutputStride,
-                                 kChangeFilters[kInitialSubPelOffset],
-                                 kInputPixelStep, NULL, 0, Width(), Height()));
+  ASM_REGISTER_STATE_CHECK(
+      UUT_->h8_(in, kInputStride, out, kOutputStride,
+                kChangeFilters[kInitialSubPelOffset],
+                kInputPixelStep, NULL, 0, Width(), Height()));
 
   for (int x = 0; x < Width(); ++x) {
     const int kFilterPeriodAdjust = (x >> 3) << 3;
@@ -508,9 +509,10 @@
   }
 
   /* Test the vertical filter. */
-  REGISTER_STATE_CHECK(UUT_->v8_(in, kInputStride, out, kOutputStride,
-                                 NULL, 0, kChangeFilters[kInitialSubPelOffset],
-                                 kInputPixelStep, Width(), Height()));
+  ASM_REGISTER_STATE_CHECK(
+      UUT_->v8_(in, kInputStride, out, kOutputStride,
+                NULL, 0, kChangeFilters[kInitialSubPelOffset],
+                kInputPixelStep, Width(), Height()));
 
   for (int y = 0; y < Height(); ++y) {
     const int kFilterPeriodAdjust = (y >> 3) << 3;
@@ -522,12 +524,11 @@
   }
 
   /* Test the horizontal and vertical filters in combination. */
-  REGISTER_STATE_CHECK(UUT_->hv8_(in, kInputStride, out, kOutputStride,
-                                  kChangeFilters[kInitialSubPelOffset],
-                                  kInputPixelStep,
-                                  kChangeFilters[kInitialSubPelOffset],
-                                  kInputPixelStep,
-                                  Width(), Height()));
+  ASM_REGISTER_STATE_CHECK(
+      UUT_->hv8_(in, kInputStride, out, kOutputStride,
+                 kChangeFilters[kInitialSubPelOffset], kInputPixelStep,
+                 kChangeFilters[kInitialSubPelOffset], kInputPixelStep,
+                 Width(), Height()));
 
   for (int y = 0; y < Height(); ++y) {
     const int kFilterPeriodAdjustY = (y >> 3) << 3;
@@ -560,10 +561,10 @@
   for (int frac = 0; frac < 16; ++frac) {
     for (int step = 1; step <= 32; ++step) {
       /* Test the horizontal and vertical filters in combination. */
-      REGISTER_STATE_CHECK(UUT_->hv8_(in, kInputStride, out, kOutputStride,
-                                      eighttap[frac], step,
-                                      eighttap[frac], step,
-                                      Width(), Height()));
+      ASM_REGISTER_STATE_CHECK(UUT_->hv8_(in, kInputStride, out, kOutputStride,
+                                          eighttap[frac], step,
+                                          eighttap[frac], step,
+                                          Width(), Height()));
 
       CheckGuardBlocks();
 
diff --git a/test/dct16x16_test.cc b/test/dct16x16_test.cc
index e6a20fb..b7c2dcc 100644
--- a/test/dct16x16_test.cc
+++ b/test/dct16x16_test.cc
@@ -311,9 +311,9 @@
         test_input_block[j] = src[j] - dst[j];
       }
 
-      REGISTER_STATE_CHECK(RunFwdTxfm(test_input_block,
-                                      test_temp_block, pitch_));
-      REGISTER_STATE_CHECK(RunInvTxfm(test_temp_block, dst, pitch_));
+      ASM_REGISTER_STATE_CHECK(RunFwdTxfm(test_input_block,
+                                          test_temp_block, pitch_));
+      ASM_REGISTER_STATE_CHECK(RunInvTxfm(test_temp_block, dst, pitch_));
 
       for (int j = 0; j < kNumCoeffs; ++j) {
         const uint32_t diff = dst[j] - src[j];
@@ -344,7 +344,7 @@
         input_block[j] = rnd.Rand8() - rnd.Rand8();
 
       fwd_txfm_ref(input_block, output_ref_block, pitch_, tx_type_);
-      REGISTER_STATE_CHECK(RunFwdTxfm(input_block, output_block, pitch_));
+      ASM_REGISTER_STATE_CHECK(RunFwdTxfm(input_block, output_block, pitch_));
 
       // The minimum quant value is 4.
       for (int j = 0; j < kNumCoeffs; ++j)
@@ -375,8 +375,8 @@
       }
 
       fwd_txfm_ref(input_extreme_block, output_ref_block, pitch_, tx_type_);
-      REGISTER_STATE_CHECK(RunFwdTxfm(input_extreme_block,
-                                      output_block, pitch_));
+      ASM_REGISTER_STATE_CHECK(RunFwdTxfm(input_extreme_block,
+                                          output_block, pitch_));
 
       // The minimum quant value is 4.
       for (int j = 0; j < kNumCoeffs; ++j) {
@@ -421,7 +421,7 @@
       for (int j = 1; j < kNumCoeffs; ++j)
         output_ref_block[j] = (output_ref_block[j] / ac_thred) * ac_thred;
       inv_txfm_ref(output_ref_block, ref, pitch_, tx_type_);
-      REGISTER_STATE_CHECK(RunInvTxfm(output_ref_block, dst, pitch_));
+      ASM_REGISTER_STATE_CHECK(RunInvTxfm(output_ref_block, dst, pitch_));
 
       for (int j = 0; j < kNumCoeffs; ++j)
         EXPECT_EQ(ref[j], dst[j]);
@@ -450,7 +450,7 @@
       for (int j = 0; j < kNumCoeffs; ++j)
         coeff[j] = round(out_r[j]);
 
-      REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, 16));
+      ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, 16));
 
       for (int j = 0; j < kNumCoeffs; ++j) {
         const uint32_t diff = dst[j] - src[j];
diff --git a/test/dct32x32_test.cc b/test/dct32x32_test.cc
index 501c696..02250a9 100644
--- a/test/dct32x32_test.cc
+++ b/test/dct32x32_test.cc
@@ -112,8 +112,8 @@
       test_input_block[j] = src[j] - dst[j];
     }
 
-    REGISTER_STATE_CHECK(fwd_txfm_(test_input_block, test_temp_block, 32));
-    REGISTER_STATE_CHECK(inv_txfm_(test_temp_block, dst, 32));
+    ASM_REGISTER_STATE_CHECK(fwd_txfm_(test_input_block, test_temp_block, 32));
+    ASM_REGISTER_STATE_CHECK(inv_txfm_(test_temp_block, dst, 32));
 
     for (int j = 0; j < kNumCoeffs; ++j) {
       const uint32_t diff = dst[j] - src[j];
@@ -150,7 +150,7 @@
 
     const int stride = 32;
     vp9_fdct32x32_c(input_block, output_ref_block, stride);
-    REGISTER_STATE_CHECK(fwd_txfm_(input_block, output_block, stride));
+    ASM_REGISTER_STATE_CHECK(fwd_txfm_(input_block, output_block, stride));
 
     if (version_ == 0) {
       for (int j = 0; j < kNumCoeffs; ++j)
@@ -189,7 +189,8 @@
 
     const int stride = 32;
     vp9_fdct32x32_c(input_extreme_block, output_ref_block, stride);
-    REGISTER_STATE_CHECK(fwd_txfm_(input_extreme_block, output_block, stride));
+    ASM_REGISTER_STATE_CHECK(
+        fwd_txfm_(input_extreme_block, output_block, stride));
 
     // The minimum quant value is 4.
     for (int j = 0; j < kNumCoeffs; ++j) {
@@ -230,7 +231,7 @@
     reference_32x32_dct_2d(in, out_r);
     for (int j = 0; j < kNumCoeffs; ++j)
       coeff[j] = round(out_r[j]);
-    REGISTER_STATE_CHECK(inv_txfm_(coeff, dst, 32));
+    ASM_REGISTER_STATE_CHECK(inv_txfm_(coeff, dst, 32));
     for (int j = 0; j < kNumCoeffs; ++j) {
       const int diff = dst[j] - src[j];
       const int error = diff * diff;
diff --git a/test/decode_test_driver.cc b/test/decode_test_driver.cc
index 8bea4cc..a762b03 100644
--- a/test/decode_test_driver.cc
+++ b/test/decode_test_driver.cc
@@ -32,15 +32,15 @@
                                      void *user_priv) {
   vpx_codec_err_t res_dec;
   InitOnce();
-  REGISTER_STATE_CHECK(
+  API_REGISTER_STATE_CHECK(
       res_dec = vpx_codec_decode(&decoder_,
                                  cxdata, static_cast<unsigned int>(size),
                                  user_priv, 0));
   return res_dec;
 }
 
-void DecoderTest::RunLoop(CompressedVideoSource *video) {
-  vpx_codec_dec_cfg_t dec_cfg = {0};
+void DecoderTest::RunLoop(CompressedVideoSource *video,
+                          const vpx_codec_dec_cfg_t &dec_cfg) {
   Decoder* const decoder = codec_->CreateDecoder(dec_cfg, 0);
   ASSERT_TRUE(decoder != NULL);
   const char *codec_name = decoder->GetDecoderName();
@@ -82,7 +82,12 @@
     while ((img = dec_iter.Next()))
       DecompressedFrameHook(*img, video->frame_number());
   }
-
   delete decoder;
 }
+
+void DecoderTest::RunLoop(CompressedVideoSource *video) {
+  vpx_codec_dec_cfg_t dec_cfg = {0};
+  RunLoop(video, dec_cfg);
+}
+
 }  // namespace libvpx_test
diff --git a/test/decode_test_driver.h b/test/decode_test_driver.h
index dd3593e..a3cfd3f 100644
--- a/test/decode_test_driver.h
+++ b/test/decode_test_driver.h
@@ -119,6 +119,8 @@
  public:
   // Main decoding loop
   virtual void RunLoop(CompressedVideoSource *video);
+  virtual void RunLoop(CompressedVideoSource *video,
+                       const vpx_codec_dec_cfg_t &dec_cfg);
 
   // Hook to be called before decompressing every frame.
   virtual void PreDecodeFrameHook(const CompressedVideoSource& video,
diff --git a/test/decode_to_md5.sh b/test/decode_to_md5.sh
index 28e29c6..6cb7d0e 100755
--- a/test/decode_to_md5.sh
+++ b/test/decode_to_md5.sh
@@ -39,7 +39,8 @@
     return 1
   fi
 
-  eval "${decoder}" "${input_file}" "${output_file}" ${devnull}
+  eval "${VPX_TEST_PREFIX}" "${decoder}" "${input_file}" "${output_file}" \
+      ${devnull}
 
   [ -e "${output_file}" ] || return 1
 
diff --git a/test/decode_with_drops.sh b/test/decode_with_drops.sh
index 12e17de..9b2edb6 100755
--- a/test/decode_with_drops.sh
+++ b/test/decode_with_drops.sh
@@ -39,7 +39,8 @@
     return 1
   fi
 
-  eval "${decoder}" "${input_file}" "${output_file}" "${drop_mode}" ${devnull}
+  eval "${VPX_TEST_PREFIX}" "${decoder}" "${input_file}" "${output_file}" \
+      "${drop_mode}" ${devnull}
 
   [ -e "${output_file}" ] || return 1
 }
diff --git a/test/encode_test_driver.cc b/test/encode_test_driver.cc
index 709831e..b30c3e0 100644
--- a/test/encode_test_driver.cc
+++ b/test/encode_test_driver.cc
@@ -59,7 +59,7 @@
   }
 
   // Encode the frame
-  REGISTER_STATE_CHECK(
+  API_REGISTER_STATE_CHECK(
       res = vpx_codec_encode(&encoder_,
                              video.img(), video.pts(), video.duration(),
                              frame_flags, deadline_));
diff --git a/test/fdct4x4_test.cc b/test/fdct4x4_test.cc
index ec233d3..ab636bf 100644
--- a/test/fdct4x4_test.cc
+++ b/test/fdct4x4_test.cc
@@ -79,9 +79,9 @@
         test_input_block[j] = src[j] - dst[j];
       }
 
-      REGISTER_STATE_CHECK(RunFwdTxfm(test_input_block,
-                                      test_temp_block, pitch_));
-      REGISTER_STATE_CHECK(RunInvTxfm(test_temp_block, dst, pitch_));
+      ASM_REGISTER_STATE_CHECK(RunFwdTxfm(test_input_block,
+                                          test_temp_block, pitch_));
+      ASM_REGISTER_STATE_CHECK(RunInvTxfm(test_temp_block, dst, pitch_));
 
       for (int j = 0; j < kNumCoeffs; ++j) {
         const uint32_t diff = dst[j] - src[j];
@@ -114,7 +114,7 @@
         input_block[j] = rnd.Rand8() - rnd.Rand8();
 
       fwd_txfm_ref(input_block, output_ref_block, pitch_, tx_type_);
-      REGISTER_STATE_CHECK(RunFwdTxfm(input_block, output_block, pitch_));
+      ASM_REGISTER_STATE_CHECK(RunFwdTxfm(input_block, output_block, pitch_));
 
       // The minimum quant value is 4.
       for (int j = 0; j < kNumCoeffs; ++j)
@@ -145,8 +145,8 @@
       }
 
       fwd_txfm_ref(input_extreme_block, output_ref_block, pitch_, tx_type_);
-      REGISTER_STATE_CHECK(RunFwdTxfm(input_extreme_block,
-                                      output_block, pitch_));
+      ASM_REGISTER_STATE_CHECK(RunFwdTxfm(input_extreme_block,
+                                          output_block, pitch_));
 
       // The minimum quant value is 4.
       for (int j = 0; j < kNumCoeffs; ++j) {
@@ -175,7 +175,7 @@
 
       fwd_txfm_ref(in, coeff, pitch_, tx_type_);
 
-      REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch_));
+      ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch_));
 
       for (int j = 0; j < kNumCoeffs; ++j) {
         const uint32_t diff = dst[j] - src[j];
diff --git a/test/fdct8x8_test.cc b/test/fdct8x8_test.cc
index 146aa31..3e14c24 100644
--- a/test/fdct8x8_test.cc
+++ b/test/fdct8x8_test.cc
@@ -68,7 +68,7 @@
       // Initialize a test block with input range [-255, 255].
       for (int j = 0; j < 64; ++j)
         test_input_block[j] = rnd.Rand8() - rnd.Rand8();
-      REGISTER_STATE_CHECK(
+      ASM_REGISTER_STATE_CHECK(
           RunFwdTxfm(test_input_block, test_output_block, pitch_));
 
       for (int j = 0; j < 64; ++j) {
@@ -97,7 +97,7 @@
       // Initialize a test block with input range [-15, 15].
       for (int j = 0; j < 64; ++j)
         test_input_block[j] = (rnd.Rand8() >> 4) - (rnd.Rand8() >> 4);
-      REGISTER_STATE_CHECK(
+      ASM_REGISTER_STATE_CHECK(
           RunFwdTxfm(test_input_block, test_output_block, pitch_));
 
       for (int j = 0; j < 64; ++j) {
@@ -139,7 +139,7 @@
         test_input_block[j] = src[j] - dst[j];
       }
 
-      REGISTER_STATE_CHECK(
+      ASM_REGISTER_STATE_CHECK(
           RunFwdTxfm(test_input_block, test_temp_block, pitch_));
       for (int j = 0; j < 64; ++j) {
           if (test_temp_block[j] > 0) {
@@ -152,7 +152,7 @@
             test_temp_block[j] *= 4;
           }
       }
-      REGISTER_STATE_CHECK(
+      ASM_REGISTER_STATE_CHECK(
           RunInvTxfm(test_temp_block, dst, pitch_));
 
       for (int j = 0; j < 64; ++j) {
@@ -202,11 +202,11 @@
         test_input_block[j] = src[j] - dst[j];
       }
 
-      REGISTER_STATE_CHECK(
+      ASM_REGISTER_STATE_CHECK(
           RunFwdTxfm(test_input_block, test_temp_block, pitch_));
-      REGISTER_STATE_CHECK(
+      ASM_REGISTER_STATE_CHECK(
           fwd_txfm_ref(test_input_block, ref_temp_block, pitch_, tx_type_));
-      REGISTER_STATE_CHECK(
+      ASM_REGISTER_STATE_CHECK(
           RunInvTxfm(test_temp_block, dst, pitch_));
 
       for (int j = 0; j < 64; ++j) {
diff --git a/test/idct_test.cc b/test/idct_test.cc
index 1bbf80a..c7f609d 100644
--- a/test/idct_test.cc
+++ b/test/idct_test.cc
@@ -52,7 +52,7 @@
 TEST_P(IDCTTest, TestAllZeros) {
   int i;
 
-  REGISTER_STATE_CHECK(UUT(input, output, 16, output, 16));
+  ASM_REGISTER_STATE_CHECK(UUT(input, output, 16, output, 16));
 
   for (i = 0; i < 256; i++)
     if ((i & 0xF) < 4 && i < 64)
@@ -65,7 +65,7 @@
   int i;
 
   input[0] = 4;
-  REGISTER_STATE_CHECK(UUT(input, output, 16, output, 16));
+  ASM_REGISTER_STATE_CHECK(UUT(input, output, 16, output, 16));
 
   for (i = 0; i < 256; i++)
     if ((i & 0xF) < 4 && i < 64)
@@ -79,7 +79,7 @@
 
   for (i = 0; i < 256; i++) predict[i] = i;
   input[0] = 4;
-  REGISTER_STATE_CHECK(UUT(input, predict, 16, output, 16));
+  ASM_REGISTER_STATE_CHECK(UUT(input, predict, 16, output, 16));
 
   for (i = 0; i < 256; i++)
     if ((i & 0xF) < 4 && i < 64)
@@ -93,7 +93,7 @@
 
   for (i = 0; i < 16; i++) input[i] = i;
 
-  REGISTER_STATE_CHECK(UUT(input, output, 16, output, 16));
+  ASM_REGISTER_STATE_CHECK(UUT(input, output, 16, output, 16));
 
   for (i = 0; i < 256; i++)
     if ((i & 0xF) > 3 || i > 63)
diff --git a/test/intrapred_test.cc b/test/intrapred_test.cc
index cefe192..d93251d 100644
--- a/test/intrapred_test.cc
+++ b/test/intrapred_test.cc
@@ -261,10 +261,10 @@
 
   virtual void Predict(MB_PREDICTION_MODE mode) {
     mbptr_->mode_info_context->mbmi.mode = mode;
-    REGISTER_STATE_CHECK(pred_fn_(mbptr_,
-                                  data_ptr_[0] - kStride,
-                                  data_ptr_[0] - 1, kStride,
-                                  data_ptr_[0], kStride));
+    ASM_REGISTER_STATE_CHECK(pred_fn_(mbptr_,
+                                      data_ptr_[0] - kStride,
+                                      data_ptr_[0] - 1, kStride,
+                                      data_ptr_[0], kStride));
   }
 
   intra_pred_y_fn_t pred_fn_;
diff --git a/test/invalid_file_test.cc b/test/invalid_file_test.cc
index 63c7941..8d7114f 100644
--- a/test/invalid_file_test.cc
+++ b/test/invalid_file_test.cc
@@ -25,9 +25,14 @@
 
 namespace {
 
+struct DecodeParam {
+  int threads;
+  const char *filename;
+};
+
 class InvalidFileTest
     : public ::libvpx_test::DecoderTest,
-      public ::libvpx_test::CodecTestWithParam<const char*> {
+      public ::libvpx_test::CodecTestWithParam<DecodeParam> {
  protected:
   InvalidFileTest() : DecoderTest(GET_PARAM(0)), res_file_(NULL) {}
 
@@ -66,8 +71,11 @@
 };
 
 TEST_P(InvalidFileTest, ReturnCode) {
-  const std::string filename = GET_PARAM(1);
   libvpx_test::CompressedVideoSource *video = NULL;
+  const DecodeParam input = GET_PARAM(1);
+  vpx_codec_dec_cfg_t cfg = {0};
+  cfg.threads = input.threads;
+  const std::string filename = input.filename;
 
   // Open compressed video file.
   if (filename.substr(filename.length() - 3, 3) == "ivf") {
@@ -90,24 +98,30 @@
   OpenResFile(res_filename);
 
   // Decode frame, and check the md5 matching.
-  ASSERT_NO_FATAL_FAILURE(RunLoop(video));
+  ASSERT_NO_FATAL_FAILURE(RunLoop(video, cfg));
   delete video;
 }
 
-const char *const kVP9InvalidFileTests[] = {
-  "invalid-vp90-01.webm",
-  "invalid-vp90-02.webm",
-  "invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.ivf",
-  "invalid-vp90-03.webm",
-  "invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf",
-  "invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf",
+const DecodeParam kVP9InvalidFileTests[] = {
+  {1, "invalid-vp90-01-v2.webm"},
+  {1, "invalid-vp90-02-v2.webm"},
+  {1, "invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.ivf"},
+  {1, "invalid-vp90-03-v2.webm"},
+  {1, "invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf"},
+  {1, "invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf"},
 };
 
-#define NELEMENTS(x) static_cast<int>(sizeof(x) / sizeof(x[0]))
-
 VP9_INSTANTIATE_TEST_CASE(InvalidFileTest,
-                          ::testing::ValuesIn(kVP9InvalidFileTests,
-                                              kVP9InvalidFileTests +
-                                              NELEMENTS(kVP9InvalidFileTests)));
+                          ::testing::ValuesIn(kVP9InvalidFileTests));
 
+const DecodeParam kMultiThreadedVP9InvalidFileTests[] = {
+  {4, "invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm"},
+};
+
+INSTANTIATE_TEST_CASE_P(
+    VP9MultiThreaded, InvalidFileTest,
+    ::testing::Combine(
+        ::testing::Values(
+            static_cast<const libvpx_test::CodecFactory*>(&libvpx_test::kVP9)),
+        ::testing::ValuesIn(kMultiThreadedVP9InvalidFileTests)));
 }  // namespace
diff --git a/test/partial_idct_test.cc b/test/partial_idct_test.cc
index f2171b2..fd24c75 100644
--- a/test/partial_idct_test.cc
+++ b/test/partial_idct_test.cc
@@ -118,8 +118,8 @@
                          = (output_ref_block[j] / 1828) * 1828;
     }
 
-    REGISTER_STATE_CHECK(full_itxfm_(test_coef_block1, dst1, size));
-    REGISTER_STATE_CHECK(partial_itxfm_(test_coef_block1, dst2, size));
+    ASM_REGISTER_STATE_CHECK(full_itxfm_(test_coef_block1, dst1, size));
+    ASM_REGISTER_STATE_CHECK(partial_itxfm_(test_coef_block1, dst2, size));
 
     for (int j = 0; j < block_size; ++j) {
       const int diff = dst1[j] - dst2[j];
@@ -182,8 +182,8 @@
     memcpy(test_coef_block2, test_coef_block1,
            sizeof(*test_coef_block2) * block_size);
 
-    REGISTER_STATE_CHECK(full_itxfm_(test_coef_block1, dst1, size));
-    REGISTER_STATE_CHECK(partial_itxfm_(test_coef_block2, dst2, size));
+    ASM_REGISTER_STATE_CHECK(full_itxfm_(test_coef_block1, dst1, size));
+    ASM_REGISTER_STATE_CHECK(partial_itxfm_(test_coef_block2, dst2, size));
 
     for (int j = 0; j < block_size; ++j) {
       const int diff = dst1[j] - dst2[j];
diff --git a/test/postproc.sh b/test/postproc.sh
index c9c4e58..939a3e7 100755
--- a/test/postproc.sh
+++ b/test/postproc.sh
@@ -37,7 +37,8 @@
     return 1
   fi
 
-  eval "${decoder}" "${input_file}" "${output_file}" ${devnull}
+  eval "${VPX_TEST_PREFIX}" "${decoder}" "${input_file}" "${output_file}" \
+      ${devnull}
 
   [ -e "${output_file}" ] || return 1
 }
diff --git a/test/pp_filter_test.cc b/test/pp_filter_test.cc
index 86c2b0e..1144083 100644
--- a/test/pp_filter_test.cc
+++ b/test/pp_filter_test.cc
@@ -80,8 +80,9 @@
   // Initialize pixels in the output to 99.
   (void)vpx_memset(dst_image, 99, output_size);
 
-  REGISTER_STATE_CHECK(GetParam()(src_image_ptr, dst_image_ptr, input_stride,
-                                  output_stride, block_width, flimits, 16));
+  ASM_REGISTER_STATE_CHECK(
+      GetParam()(src_image_ptr, dst_image_ptr, input_stride,
+                 output_stride, block_width, flimits, 16));
 
   static const uint8_t expected_data[block_height] = {
     4, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 4
diff --git a/test/register_state_check.h b/test/register_state_check.h
index 1ee149b..8d4beea 100644
--- a/test/register_state_check.h
+++ b/test/register_state_check.h
@@ -13,6 +13,20 @@
 
 #include "third_party/googletest/src/include/gtest/gtest.h"
 #include "./vpx_config.h"
+#include "vpx/vpx_integer.h"
+
+// ASM_REGISTER_STATE_CHECK(asm_function)
+//   Minimally validates the environment pre & post function execution. This
+//   variant should be used with assembly functions which are not expected to
+//   fully restore the system state. See platform implementations of
+//   RegisterStateCheck for details.
+//
+// API_REGISTER_STATE_CHECK(api_function)
+//   Performs all the checks done by ASM_REGISTER_STATE_CHECK() and any
+//   additional checks to ensure the environment is in a consistent state pre &
+//   post function execution. This variant should be used with API functions.
+//   See platform implementations of RegisterStateCheckXXX for details.
+//
 
 #if defined(_WIN64)
 
@@ -35,11 +49,6 @@
 // Compares the state of xmm[6-15] at construction with their state at
 // destruction. These registers should be preserved by the callee on
 // Windows x64.
-// Usage:
-// {
-//   RegisterStateCheck reg_check;
-//   FunctionToVerify();
-// }
 class RegisterStateCheck {
  public:
   RegisterStateCheck() { initialized_ = StoreRegisters(&pre_context_); }
@@ -75,9 +84,9 @@
   CONTEXT pre_context_;
 };
 
-#define REGISTER_STATE_CHECK(statement) do { \
-  libvpx_test::RegisterStateCheck reg_check; \
-  statement;                               \
+#define ASM_REGISTER_STATE_CHECK(statement) do {  \
+  libvpx_test::RegisterStateCheck reg_check;      \
+  statement;                                      \
 } while (false)
 
 }  // namespace libvpx_test
@@ -85,8 +94,6 @@
 #elif defined(CONFIG_SHARED) && defined(HAVE_NEON_ASM) && defined(CONFIG_VP9) \
       && !CONFIG_SHARED && HAVE_NEON_ASM && CONFIG_VP9
 
-#include "vpx/vpx_integer.h"
-
 extern "C" {
 // Save the d8-d15 registers into store.
 void vp9_push_neon(int64_t *store);
@@ -97,11 +104,6 @@
 // Compares the state of d8-d15 at construction with their state at
 // destruction. These registers should be preserved by the callee on
 // arm platform.
-// Usage:
-// {
-//   RegisterStateCheck reg_check;
-//   FunctionToVerify();
-// }
 class RegisterStateCheck {
  public:
   RegisterStateCheck() { initialized_ = StoreRegisters(pre_store_); }
@@ -129,9 +131,9 @@
   int64_t pre_store_[8];
 };
 
-#define REGISTER_STATE_CHECK(statement) do { \
-  libvpx_test::RegisterStateCheck reg_check; \
-  statement;                               \
+#define ASM_REGISTER_STATE_CHECK(statement) do {  \
+  libvpx_test::RegisterStateCheck reg_check;      \
+  statement;                                      \
 } while (false)
 
 }  // namespace libvpx_test
@@ -141,10 +143,54 @@
 namespace libvpx_test {
 
 class RegisterStateCheck {};
-#define REGISTER_STATE_CHECK(statement) statement
+#define ASM_REGISTER_STATE_CHECK(statement) statement
 
 }  // namespace libvpx_test
 
 #endif  // _WIN64
 
+#if ARCH_X86 || ARCH_X86_64
+#if defined(__GNUC__)
+
+namespace libvpx_test {
+
+// Checks the FPU tag word pre/post execution to ensure emms has been called.
+class RegisterStateCheckMMX {
+ public:
+  RegisterStateCheckMMX() {
+    __asm__ volatile("fstenv %0" : "=rm"(pre_fpu_env_));
+  }
+  ~RegisterStateCheckMMX() { EXPECT_TRUE(Check()); }
+
+ private:
+  // Checks the FPU tag word pre/post execution, returning false if not cleared
+  // to 0xffff.
+  bool Check() const {
+    EXPECT_EQ(0xffff, pre_fpu_env_[4])
+        << "FPU was in an inconsistent state prior to call";
+
+    uint16_t post_fpu_env[14];
+    __asm__ volatile("fstenv %0" : "=rm"(post_fpu_env));
+    EXPECT_EQ(0xffff, post_fpu_env[4])
+        << "FPU was left in an inconsistent state after call";
+    return !testing::Test::HasNonfatalFailure();
+  }
+
+  uint16_t pre_fpu_env_[14];
+};
+
+#define API_REGISTER_STATE_CHECK(statement) do {  \
+  libvpx_test::RegisterStateCheckMMX reg_check;   \
+  ASM_REGISTER_STATE_CHECK(statement);            \
+} while (false)
+
+}  // namespace libvpx_test
+
+#endif  // __GNUC__
+#endif  // ARCH_X86 || ARCH_X86_64
+
+#ifndef API_REGISTER_STATE_CHECK
+#define API_REGISTER_STATE_CHECK ASM_REGISTER_STATE_CHECK
+#endif
+
 #endif  // TEST_REGISTER_STATE_CHECK_H_
diff --git a/test/resize_util.sh b/test/resize_util.sh
index ab3dfd1..5e47271 100755
--- a/test/resize_util.sh
+++ b/test/resize_util.sh
@@ -38,7 +38,7 @@
       return 1
     fi
 
-    eval "${resizer}" "${YUV_RAW_INPUT}" \
+    eval "${VPX_TEST_PREFIX}" "${resizer}" "${YUV_RAW_INPUT}" \
         "${YUV_RAW_INPUT_WIDTH}x${YUV_RAW_INPUT_HEIGHT}" \
         "${target_dimensions}" "${output_file}" ${frames_to_resize} \
         ${devnull}
diff --git a/test/sad_test.cc b/test/sad_test.cc
index 89d8c41..7e5bcef 100644
--- a/test/sad_test.cc
+++ b/test/sad_test.cc
@@ -149,9 +149,9 @@
     const uint8_t* refs[] = {GetReference(0), GetReference(1),
                              GetReference(2), GetReference(3)};
 
-    REGISTER_STATE_CHECK(GET_PARAM(2)(source_data_, source_stride_,
-                                      refs, reference_stride_,
-                                      results));
+    ASM_REGISTER_STATE_CHECK(GET_PARAM(2)(source_data_, source_stride_,
+                                          refs, reference_stride_,
+                                          results));
   }
 
   void CheckSADs() {
@@ -178,9 +178,9 @@
     unsigned int ret;
     const uint8_t* const reference = GetReference(block_idx);
 
-    REGISTER_STATE_CHECK(ret = GET_PARAM(2)(source_data_, source_stride_,
-                                            reference, reference_stride_,
-                                            max_sad));
+    ASM_REGISTER_STATE_CHECK(ret = GET_PARAM(2)(source_data_, source_stride_,
+                                                reference, reference_stride_,
+                                                max_sad));
     return ret;
   }
 
@@ -210,8 +210,8 @@
     unsigned int ret;
     const uint8_t* const reference = GetReference(block_idx);
 
-    REGISTER_STATE_CHECK(ret = GET_PARAM(2)(source_data_, source_stride_,
-                                            reference, reference_stride_));
+    ASM_REGISTER_STATE_CHECK(ret = GET_PARAM(2)(source_data_, source_stride_,
+                                                reference, reference_stride_));
     return ret;
   }
 
diff --git a/test/simple_decoder.sh b/test/simple_decoder.sh
index 0be48e6..7eeaf71 100755
--- a/test/simple_decoder.sh
+++ b/test/simple_decoder.sh
@@ -37,7 +37,8 @@
     return 1
   fi
 
-  eval "${decoder}" "${input_file}" "${output_file}" ${devnull}
+  eval "${VPX_TEST_PREFIX}" "${decoder}" "${input_file}" "${output_file}" \
+      ${devnull}
 
   [ -e "${output_file}" ] || return 1
 }
diff --git a/test/simple_encoder.sh b/test/simple_encoder.sh
index a0b0e13..c4a6280 100755
--- a/test/simple_encoder.sh
+++ b/test/simple_encoder.sh
@@ -34,7 +34,7 @@
     return 1
   fi
 
-  eval "${encoder}" "${codec}" "${YUV_RAW_INPUT_WIDTH}" \
+  eval "${VPX_TEST_PREFIX}" "${encoder}" "${codec}" "${YUV_RAW_INPUT_WIDTH}" \
       "${YUV_RAW_INPUT_HEIGHT}" "${YUV_RAW_INPUT}" "${output_file}" 9999 \
       ${devnull}
 
diff --git a/test/sixtap_predict_test.cc b/test/sixtap_predict_test.cc
index 0c600f4..ac7aa99 100644
--- a/test/sixtap_predict_test.cc
+++ b/test/sixtap_predict_test.cc
@@ -143,8 +143,9 @@
 
   uint8_t *src = const_cast<uint8_t*>(test_data);
 
-  REGISTER_STATE_CHECK(sixtap_predict_(&src[kSrcStride * 2 + 2 + 1], kSrcStride,
-                                       2, 2, dst_, kDstStride));
+  ASM_REGISTER_STATE_CHECK(
+      sixtap_predict_(&src[kSrcStride * 2 + 2 + 1], kSrcStride,
+                      2, 2, dst_, kDstStride));
 
   for (int i = 0; i < height_; ++i)
     for (int j = 0; j < width_; ++j)
@@ -169,7 +170,7 @@
                                 xoffset, yoffset, dst_c_, kDstStride);
 
       // Run test.
-      REGISTER_STATE_CHECK(
+      ASM_REGISTER_STATE_CHECK(
           sixtap_predict_(&src_[kSrcStride * 2 + 2 + 1], kSrcStride,
                           xoffset, yoffset, dst_, kDstStride));
 
diff --git a/test/subtract_test.cc b/test/subtract_test.cc
index 63e999d..2db3dd7 100644
--- a/test/subtract_test.cc
+++ b/test/subtract_test.cc
@@ -82,7 +82,7 @@
       predictor += kDiffPredStride;
     }
 
-    REGISTER_STATE_CHECK(GetParam()(&be, &bd, kDiffPredStride));
+    ASM_REGISTER_STATE_CHECK(GetParam()(&be, &bd, kDiffPredStride));
 
     base_src = *be.base_src;
     src_diff = be.src_diff;
diff --git a/test/test-data.sha1 b/test/test-data.sha1
index 8940027..d5a1165 100644
--- a/test/test-data.sha1
+++ b/test/test-data.sha1
@@ -663,3 +663,11 @@
 456d1493e52d32a5c30edf44a27debc1fa6b253a  invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf.res
 c123d1f9f02fb4143abb5e271916e3a3080de8f6  invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf
 456d1493e52d32a5c30edf44a27debc1fa6b253a  invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf.res
+fe346136b9b8c1e6f6084cc106485706915795e4  invalid-vp90-01-v2.webm
+25751f5d3b05ff03f0719ad42cd625348eb8961e  invalid-vp90-01-v2.webm.res
+d78e2fceba5ac942246503ec8366f879c4775ca5  invalid-vp90-02-v2.webm
+8e2eff4af87d2b561cce2365713269e301457ef3  invalid-vp90-02-v2.webm.res
+df1a1453feb3c00d7d89746c7003b4163523bff3  invalid-vp90-03-v2.webm
+25dd58c22d23f75304d7ce7f69f4e5b02ef9119a  invalid-vp90-03-v2.webm.res
+d637297561dd904eb2c97a9015deeb31c4a1e8d2  invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm
+3a204bdbeaa3c6458b77bcebb8366d107267f55d  invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm.res
diff --git a/test/test.mk b/test/test.mk
index ef81ab1..f624649 100644
--- a/test/test.mk
+++ b/test/test.mk
@@ -777,18 +777,20 @@
 LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp91-2-04-yuv444.webm.md5
 
 # Invalid files for testing libvpx error checking.
-LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-01.webm
-LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-01.webm.res
-LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-02.webm
-LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-02.webm.res
-LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-03.webm
-LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-03.webm.res
+LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-01-v2.webm
+LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-01-v2.webm.res
+LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-02-v2.webm
+LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-02-v2.webm.res
+LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-03-v2.webm
+LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-03-v2.webm.res
 LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.ivf
 LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.ivf.res
 LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf
 LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf.res
 LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf
 LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf.res
+LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm
+LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm.res
 
 ifeq ($(CONFIG_DECODE_PERF_TESTS),yes)
 # BBB VP9 streams
diff --git a/test/tools_common.sh b/test/tools_common.sh
index 7f32905..3e69c36 100755
--- a/test/tools_common.sh
+++ b/test/tools_common.sh
@@ -16,6 +16,7 @@
 
 set -e
 devnull='> /dev/null 2>&1'
+VPX_TEST_PREFIX=""
 
 elog() {
   echo "$@" 1>&2
@@ -204,9 +205,12 @@
   local decoder="${LIBVPX_BIN_PATH}/vpxdec${VPX_TEST_EXE_SUFFIX}"
 
   if [ -z "${pipe_input}" ]; then
-    eval "${decoder}" "$input" --summary --noblit "$@" ${devnull}
+    eval "${VPX_TEST_PREFIX}" "${decoder}" "$input" --summary --noblit "$@" \
+        ${devnull}
   else
-    cat "${input}" | eval "${decoder}" - --summary --noblit "$@" ${devnull}
+    cat "${input}" \
+        | eval "${VPX_TEST_PREFIX}" "${decoder}" - --summary --noblit "$@" \
+            ${devnull}
   fi
 }
 
@@ -252,16 +256,14 @@
   fi
 
   if [ -z "${pipe_input}" ]; then
-    eval "${encoder}" --codec=${codec} --width=${width} --height=${height} \
-        --limit=${frames} ${use_ivf} ${extra_flags} --output="${output}" \
-        "${input}" \
-        ${devnull}
+    eval "${VPX_TEST_PREFIX}" "${encoder}" --codec=${codec} --width=${width} \
+        --height=${height} --limit=${frames} ${use_ivf} ${extra_flags} \
+        --output="${output}" "${input}" ${devnull}
   else
     cat "${input}" \
-        | eval "${encoder}" --codec=${codec} --width=${width} \
-              --height=${height} --limit=${frames} ${use_ivf} ${extra_flags} \
-              --output="${output}" - \
-              ${devnull}
+        | eval "${VPX_TEST_PREFIX}" "${encoder}" --codec=${codec} \
+            --width=${width} --height=${height} --limit=${frames} ${use_ivf} \
+            ${extra_flags} --output="${output}" - ${devnull}
   fi
 
   if [ ! -e "${output}" ]; then
@@ -351,6 +353,9 @@
     --help: Display this message and exit.
     --test-data-path <path to libvpx test data directory>
     --show-program-output: Shows output from all programs being tested.
+    --prefix: Allows for a user specified prefix to be inserted before all test
+              programs. Grants the ability, for example, to run test programs
+              within valgrind.
     --verbose: Verbose output.
 
     When the --bin-path option is not specified the script attempts to use
@@ -400,6 +405,10 @@
       LIBVPX_TEST_DATA_PATH="$2"
       shift
       ;;
+    --prefix)
+      VPX_TEST_PREFIX="$2"
+      shift
+      ;;
     --verbose)
       VPX_TEST_VERBOSE_OUTPUT=yes
       ;;
@@ -466,6 +475,7 @@
   VPX_TEST_EXE_SUFFIX=${VPX_TEST_EXE_SUFFIX}
   VPX_TEST_FILTER=${VPX_TEST_FILTER}
   VPX_TEST_OUTPUT_DIR=${VPX_TEST_OUTPUT_DIR}
+  VPX_TEST_PREFIX=${VPX_TEST_PREFIX}
   VPX_TEST_RAND=${VPX_TEST_RAND}
   VPX_TEST_RUN_DISABLED_TESTS=${VPX_TEST_RUN_DISABLED_TESTS}
   VPX_TEST_SHOW_PROGRAM_OUTPUT=${VPX_TEST_SHOW_PROGRAM_OUTPUT}
diff --git a/test/twopass_encoder.sh b/test/twopass_encoder.sh
index 95d49d6..1189e51 100755
--- a/test/twopass_encoder.sh
+++ b/test/twopass_encoder.sh
@@ -34,7 +34,7 @@
     return 1
   fi
 
-  eval "${encoder}" "${codec}" "${YUV_RAW_INPUT_WIDTH}" \
+  eval "${VPX_TEST_PREFIX}" "${encoder}" "${codec}" "${YUV_RAW_INPUT_WIDTH}" \
       "${YUV_RAW_INPUT_HEIGHT}" "${YUV_RAW_INPUT}" "${output_file}" \
       ${devnull}
 
diff --git a/test/variance_test.cc b/test/variance_test.cc
index 9985695..5469770 100644
--- a/test/variance_test.cc
+++ b/test/variance_test.cc
@@ -124,7 +124,8 @@
       memset(ref_, j, block_size_);
       unsigned int sse;
       unsigned int var;
-      REGISTER_STATE_CHECK(var = variance_(src_, width_, ref_, width_, &sse));
+      ASM_REGISTER_STATE_CHECK(
+          var = variance_(src_, width_, ref_, width_, &sse));
       EXPECT_EQ(0u, var) << "src values: " << i << "ref values: " << j;
     }
   }
@@ -139,7 +140,8 @@
     }
     unsigned int sse1, sse2;
     unsigned int var1;
-    REGISTER_STATE_CHECK(var1 = variance_(src_, width_, ref_, width_, &sse1));
+    ASM_REGISTER_STATE_CHECK(
+        var1 = variance_(src_, width_, ref_, width_, &sse1));
     const unsigned int var2 = variance_ref(src_, ref_, log2width_,
                                            log2height_, &sse2);
     EXPECT_EQ(sse1, sse2);
@@ -155,7 +157,7 @@
   memset(ref_ + half, 0, half);
   unsigned int sse;
   unsigned int var;
-  REGISTER_STATE_CHECK(var = variance_(src_, width_, ref_, width_, &sse));
+  ASM_REGISTER_STATE_CHECK(var = variance_(src_, width_, ref_, width_, &sse));
   const unsigned int expected = block_size_ * 255 * 255 / 4;
   EXPECT_EQ(expected, var);
 }
@@ -246,8 +248,8 @@
       }
       unsigned int sse1, sse2;
       unsigned int var1;
-      REGISTER_STATE_CHECK(var1 = subpel_variance_(ref_, width_ + 1, x, y,
-                                                   src_, width_, &sse1));
+      ASM_REGISTER_STATE_CHECK(var1 = subpel_variance_(ref_, width_ + 1, x, y,
+                                                       src_, width_, &sse1));
       const unsigned int var2 = subpel_variance_ref(ref_, src_, log2width_,
                                                     log2height_, x, y, &sse2);
       EXPECT_EQ(sse1, sse2) << "at position " << x << ", " << y;
@@ -269,8 +271,9 @@
       }
       unsigned int sse1, sse2;
       unsigned int var1;
-      REGISTER_STATE_CHECK(var1 = subpel_variance_(ref_, width_ + 1, x, y,
-                                                   src_, width_, &sse1, sec_));
+      ASM_REGISTER_STATE_CHECK(
+          var1 = subpel_variance_(ref_, width_ + 1, x, y,
+                                  src_, width_, &sse1, sec_));
       const unsigned int var2 = subpel_avg_variance_ref(ref_, src_, sec_,
                                                         log2width_, log2height_,
                                                         x, y, &sse2);
diff --git a/test/vp8cx_set_ref.sh b/test/vp8cx_set_ref.sh
index ee10056..5d760bc 100755
--- a/test/vp8cx_set_ref.sh
+++ b/test/vp8cx_set_ref.sh
@@ -39,9 +39,9 @@
     return 1
   fi
 
-  eval "${encoder}" "${YUV_RAW_INPUT_WIDTH}" "${YUV_RAW_INPUT_HEIGHT}" \
-      "${YUV_RAW_INPUT}" "${output_file}" "${ref_frame_num}" \
-      ${devnull}
+  eval "${VPX_TEST_PREFIX}" "${encoder}" "${YUV_RAW_INPUT_WIDTH}" \
+      "${YUV_RAW_INPUT_HEIGHT}" "${YUV_RAW_INPUT}" "${output_file}" \
+      "${ref_frame_num}" ${devnull}
 
   [ -e "${output_file}" ] || return 1
 }
diff --git a/test/vp9_spatial_svc_encoder.sh b/test/vp9_spatial_svc_encoder.sh
index 8c9d130..a5728f6 100755
--- a/test/vp9_spatial_svc_encoder.sh
+++ b/test/vp9_spatial_svc_encoder.sh
@@ -39,10 +39,9 @@
     return 1
   fi
 
-  eval "${encoder}" -w "${YUV_RAW_INPUT_WIDTH}" -h "${YUV_RAW_INPUT_HEIGHT}" \
-      -k "${max_kf}" -f "${frames_to_encode}" "$@" "${YUV_RAW_INPUT}" \
-      "${output_file}" \
-      ${devnull}
+  eval "${VPX_TEST_PREFIX}" "${encoder}" -w "${YUV_RAW_INPUT_WIDTH}" \
+      -h "${YUV_RAW_INPUT_HEIGHT}" -k "${max_kf}" -f "${frames_to_encode}" \
+      "$@" "${YUV_RAW_INPUT}" "${output_file}" ${devnull}
 
   [ -e "${output_file}" ] || return 1
 }
diff --git a/test/vp9_thread_test.cc b/test/vp9_thread_test.cc
index fa51835..d7fc4ee 100644
--- a/test/vp9_thread_test.cc
+++ b/test/vp9_thread_test.cc
@@ -35,6 +35,15 @@
     vp9_get_worker_interface()->end(&worker_);
   }
 
+  void Run(VP9Worker* worker) {
+    const bool synchronous = GetParam();
+    if (synchronous) {
+      vp9_get_worker_interface()->execute(worker);
+    } else {
+      vp9_get_worker_interface()->launch(worker);
+    }
+  }
+
   VP9Worker worker_;
 };
 
@@ -57,12 +66,7 @@
     worker_.data1 = &hook_data;
     worker_.data2 = &return_value;
 
-    const bool synchronous = GetParam();
-    if (synchronous) {
-      vp9_get_worker_interface()->execute(&worker_);
-    } else {
-      vp9_get_worker_interface()->launch(&worker_);
-    }
+    Run(&worker_);
     EXPECT_NE(vp9_get_worker_interface()->sync(&worker_), 0);
     EXPECT_FALSE(worker_.had_error);
     EXPECT_EQ(5, hook_data);
@@ -81,12 +85,7 @@
   worker_.data1 = &hook_data;
   worker_.data2 = &return_value;
 
-  const bool synchronous = GetParam();
-  if (synchronous) {
-    vp9_get_worker_interface()->execute(&worker_);
-  } else {
-    vp9_get_worker_interface()->launch(&worker_);
-  }
+  Run(&worker_);
   EXPECT_FALSE(vp9_get_worker_interface()->sync(&worker_));
   EXPECT_EQ(1, worker_.had_error);
 
@@ -99,6 +98,39 @@
   EXPECT_FALSE(worker_.had_error);
 }
 
+TEST_P(VP9WorkerThreadTest, EndWithoutSync) {
+  // Create a large number of threads to increase the chances of detecting a
+  // race. Doing more work in the hook is no guarantee as any race would occur
+  // post hook execution in the main thread loop driver.
+  static const int kNumWorkers = 64;
+  VP9Worker workers[kNumWorkers];
+  int hook_data[kNumWorkers];
+  int return_value[kNumWorkers];
+
+  for (int n = 0; n < kNumWorkers; ++n) {
+    vp9_get_worker_interface()->init(&workers[n]);
+    return_value[n] = 1;  // return successfully from the hook
+    workers[n].hook = ThreadHook;
+    workers[n].data1 = &hook_data[n];
+    workers[n].data2 = &return_value[n];
+  }
+
+  for (int i = 0; i < 2; ++i) {
+    for (int n = 0; n < kNumWorkers; ++n) {
+      EXPECT_NE(vp9_get_worker_interface()->reset(&workers[n]), 0);
+      hook_data[n] = 0;
+    }
+
+    for (int n = 0; n < kNumWorkers; ++n) {
+      Run(&workers[n]);
+    }
+
+    for (int n = kNumWorkers - 1; n >= 0; --n) {
+      vp9_get_worker_interface()->end(&workers[n]);
+    }
+  }
+}
+
 TEST(VP9WorkerThreadTest, TestInterfaceAPI) {
   EXPECT_EQ(0, vp9_set_worker_interface(NULL));
   EXPECT_TRUE(vp9_get_worker_interface() != NULL);
diff --git a/test/vpx_temporal_svc_encoder.sh b/test/vpx_temporal_svc_encoder.sh
index b2e968f..fcc8cb4 100755
--- a/test/vpx_temporal_svc_encoder.sh
+++ b/test/vpx_temporal_svc_encoder.sh
@@ -21,6 +21,10 @@
     echo "Libvpx test data must exist in LIBVPX_TEST_DATA_PATH."
     return 1
   fi
+  if [ "$(vpx_config_option_enabled CONFIG_TEMPORAL_DENOISING)" != "yes" ]; then
+    elog "Warning: Temporal denoising is disabled! Spatial denoising will be " \
+      "used instead, which is probably not what you want for this test."
+  fi
 }
 
 # Runs vpx_temporal_svc_encoder using the codec specified by $1 and output file
@@ -44,8 +48,8 @@
     return 1
   fi
 
-  eval "${encoder}" "${YUV_RAW_INPUT}" "${output_file}" "${codec}" \
-      "${YUV_RAW_INPUT_WIDTH}" "${YUV_RAW_INPUT_HEIGHT}" \
+  eval "${VPX_TEST_PREFIX}" "${encoder}" "${YUV_RAW_INPUT}" "${output_file}" \
+      "${codec}" "${YUV_RAW_INPUT_WIDTH}" "${YUV_RAW_INPUT_HEIGHT}" \
       "${timebase_num}" "${timebase_den}" "${speed}" "${frame_drop_thresh}" \
       "$@" \
       ${devnull}
diff --git a/vp8/decoder/onyxd_if.c b/vp8/decoder/onyxd_if.c
index 29fea61..1d763b6 100644
--- a/vp8/decoder/onyxd_if.c
+++ b/vp8/decoder/onyxd_if.c
@@ -386,6 +386,7 @@
 
 decode_exit:
     pbi->common.error.setjmp = 0;
+    vp8_clear_system_state();
     return retcode;
 }
 int vp8dx_get_raw_frame(VP8D_COMP *pbi, YV12_BUFFER_CONFIG *sd, int64_t *time_stamp, int64_t *time_end_stamp, vp8_ppflags_t *flags)
diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c
index 09854a5..373dbeb 100644
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -4886,6 +4886,7 @@
     if (setjmp(cpi->common.error.jmp))
     {
         cpi->common.error.setjmp = 0;
+        vp8_clear_system_state();
         return VPX_CODEC_CORRUPT_FRAME;
     }
 
diff --git a/vp8/vp8_dx_iface.c b/vp8/vp8_dx_iface.c
index 56394fb..b695ddc 100644
--- a/vp8/vp8_dx_iface.c
+++ b/vp8/vp8_dx_iface.c
@@ -409,6 +409,7 @@
                 if (setjmp(pbi->common.error.jmp))
                 {
                     pbi->common.error.setjmp = 0;
+                    vp8_clear_system_state();
                     /* same return value as used in vp8dx_receive_compressed_data */
                     return -1;
                 }
diff --git a/vp9/common/vp9_blockd.h b/vp9/common/vp9_blockd.h
index 9d5ad9c..29af98a 100644
--- a/vp9/common/vp9_blockd.h
+++ b/vp9/common/vp9_blockd.h
@@ -242,9 +242,7 @@
 
 static INLINE BLOCK_SIZE get_subsize(BLOCK_SIZE bsize,
                                      PARTITION_TYPE partition) {
-  const BLOCK_SIZE subsize = subsize_lookup[partition][bsize];
-  assert(subsize < BLOCK_SIZES);
-  return subsize;
+  return subsize_lookup[partition][bsize];
 }
 
 extern const TX_TYPE intra_mode_to_tx_type_lookup[INTRA_MODES];
@@ -288,9 +286,7 @@
 
 static INLINE BLOCK_SIZE get_plane_block_size(BLOCK_SIZE bsize,
     const struct macroblockd_plane *pd) {
-  BLOCK_SIZE bs = ss_size_lookup[bsize][pd->subsampling_x][pd->subsampling_y];
-  assert(bs < BLOCK_SIZES);
-  return bs;
+  return ss_size_lookup[bsize][pd->subsampling_x][pd->subsampling_y];
 }
 
 typedef void (*foreach_transformed_block_visitor)(int plane, int block,
diff --git a/vp9/common/vp9_loopfilter.c b/vp9/common/vp9_loopfilter.c
index d4b58b6..3b39d42 100644
--- a/vp9/common/vp9_loopfilter.c
+++ b/vp9/common/vp9_loopfilter.c
@@ -16,7 +16,7 @@
 
 #include "vp9/common/vp9_seg_common.h"
 
-// 64 bit masks for left transform size.  Each 1 represents a position where
+// 64 bit masks for left transform size. Each 1 represents a position where
 // we should apply a loop filter across the left border of an 8x8 block
 // boundary.
 //
@@ -34,13 +34,13 @@
 //
 // A loopfilter should be applied to every other 8x8 horizontally.
 static const uint64_t left_64x64_txform_mask[TX_SIZES]= {
-    0xffffffffffffffff,  // TX_4X4
-    0xffffffffffffffff,  // TX_8x8
-    0x5555555555555555,  // TX_16x16
-    0x1111111111111111,  // TX_32x32
+  0xffffffffffffffff,  // TX_4X4
+  0xffffffffffffffff,  // TX_8x8
+  0x5555555555555555,  // TX_16x16
+  0x1111111111111111,  // TX_32x32
 };
 
-// 64 bit masks for above transform size.  Each 1 represents a position where
+// 64 bit masks for above transform size. Each 1 represents a position where
 // we should apply a loop filter across the top border of an 8x8 block
 // boundary.
 //
@@ -58,15 +58,15 @@
 //
 // A loopfilter should be applied to every other 4 the row vertically.
 static const uint64_t above_64x64_txform_mask[TX_SIZES]= {
-    0xffffffffffffffff,  // TX_4X4
-    0xffffffffffffffff,  // TX_8x8
-    0x00ff00ff00ff00ff,  // TX_16x16
-    0x000000ff000000ff,  // TX_32x32
+  0xffffffffffffffff,  // TX_4X4
+  0xffffffffffffffff,  // TX_8x8
+  0x00ff00ff00ff00ff,  // TX_16x16
+  0x000000ff000000ff,  // TX_32x32
 };
 
-// 64 bit masks for prediction sizes (left).  Each 1 represents a position
-// where left border of an 8x8 block.  These are aligned to the right most
-// appropriate bit,  and then shifted into place.
+// 64 bit masks for prediction sizes (left). Each 1 represents a position
+// where left border of an 8x8 block. These are aligned to the right most
+// appropriate bit, and then shifted into place.
 //
 // In the case of TX_16x32 ->  ( low order byte first ) we end up with
 // a mask that looks like this :
@@ -80,54 +80,54 @@
 //  00000000
 //  00000000
 static const uint64_t left_prediction_mask[BLOCK_SIZES] = {
-    0x0000000000000001,  // BLOCK_4X4,
-    0x0000000000000001,  // BLOCK_4X8,
-    0x0000000000000001,  // BLOCK_8X4,
-    0x0000000000000001,  // BLOCK_8X8,
-    0x0000000000000101,  // BLOCK_8X16,
-    0x0000000000000001,  // BLOCK_16X8,
-    0x0000000000000101,  // BLOCK_16X16,
-    0x0000000001010101,  // BLOCK_16X32,
-    0x0000000000000101,  // BLOCK_32X16,
-    0x0000000001010101,  // BLOCK_32X32,
-    0x0101010101010101,  // BLOCK_32X64,
-    0x0000000001010101,  // BLOCK_64X32,
-    0x0101010101010101,  // BLOCK_64X64
+  0x0000000000000001,  // BLOCK_4X4,
+  0x0000000000000001,  // BLOCK_4X8,
+  0x0000000000000001,  // BLOCK_8X4,
+  0x0000000000000001,  // BLOCK_8X8,
+  0x0000000000000101,  // BLOCK_8X16,
+  0x0000000000000001,  // BLOCK_16X8,
+  0x0000000000000101,  // BLOCK_16X16,
+  0x0000000001010101,  // BLOCK_16X32,
+  0x0000000000000101,  // BLOCK_32X16,
+  0x0000000001010101,  // BLOCK_32X32,
+  0x0101010101010101,  // BLOCK_32X64,
+  0x0000000001010101,  // BLOCK_64X32,
+  0x0101010101010101,  // BLOCK_64X64
 };
 
 // 64 bit mask to shift and set for each prediction size.
 static const uint64_t above_prediction_mask[BLOCK_SIZES] = {
-    0x0000000000000001,  // BLOCK_4X4
-    0x0000000000000001,  // BLOCK_4X8
-    0x0000000000000001,  // BLOCK_8X4
-    0x0000000000000001,  // BLOCK_8X8
-    0x0000000000000001,  // BLOCK_8X16,
-    0x0000000000000003,  // BLOCK_16X8
-    0x0000000000000003,  // BLOCK_16X16
-    0x0000000000000003,  // BLOCK_16X32,
-    0x000000000000000f,  // BLOCK_32X16,
-    0x000000000000000f,  // BLOCK_32X32,
-    0x000000000000000f,  // BLOCK_32X64,
-    0x00000000000000ff,  // BLOCK_64X32,
-    0x00000000000000ff,  // BLOCK_64X64
+  0x0000000000000001,  // BLOCK_4X4
+  0x0000000000000001,  // BLOCK_4X8
+  0x0000000000000001,  // BLOCK_8X4
+  0x0000000000000001,  // BLOCK_8X8
+  0x0000000000000001,  // BLOCK_8X16,
+  0x0000000000000003,  // BLOCK_16X8
+  0x0000000000000003,  // BLOCK_16X16
+  0x0000000000000003,  // BLOCK_16X32,
+  0x000000000000000f,  // BLOCK_32X16,
+  0x000000000000000f,  // BLOCK_32X32,
+  0x000000000000000f,  // BLOCK_32X64,
+  0x00000000000000ff,  // BLOCK_64X32,
+  0x00000000000000ff,  // BLOCK_64X64
 };
-// 64 bit mask to shift and set for each prediction size.  A bit is set for
+// 64 bit mask to shift and set for each prediction size. A bit is set for
 // each 8x8 block that would be in the left most block of the given block
 // size in the 64x64 block.
 static const uint64_t size_mask[BLOCK_SIZES] = {
-    0x0000000000000001,  // BLOCK_4X4
-    0x0000000000000001,  // BLOCK_4X8
-    0x0000000000000001,  // BLOCK_8X4
-    0x0000000000000001,  // BLOCK_8X8
-    0x0000000000000101,  // BLOCK_8X16,
-    0x0000000000000003,  // BLOCK_16X8
-    0x0000000000000303,  // BLOCK_16X16
-    0x0000000003030303,  // BLOCK_16X32,
-    0x0000000000000f0f,  // BLOCK_32X16,
-    0x000000000f0f0f0f,  // BLOCK_32X32,
-    0x0f0f0f0f0f0f0f0f,  // BLOCK_32X64,
-    0x00000000ffffffff,  // BLOCK_64X32,
-    0xffffffffffffffff,  // BLOCK_64X64
+  0x0000000000000001,  // BLOCK_4X4
+  0x0000000000000001,  // BLOCK_4X8
+  0x0000000000000001,  // BLOCK_8X4
+  0x0000000000000001,  // BLOCK_8X8
+  0x0000000000000101,  // BLOCK_8X16,
+  0x0000000000000003,  // BLOCK_16X8
+  0x0000000000000303,  // BLOCK_16X16
+  0x0000000003030303,  // BLOCK_16X32,
+  0x0000000000000f0f,  // BLOCK_32X16,
+  0x000000000f0f0f0f,  // BLOCK_32X32,
+  0x0f0f0f0f0f0f0f0f,  // BLOCK_32X64,
+  0x00000000ffffffff,  // BLOCK_64X32,
+  0xffffffffffffffff,  // BLOCK_64X64
 };
 
 // These are used for masking the left and above borders.
@@ -136,67 +136,67 @@
 
 // 16 bit masks for uv transform sizes.
 static const uint16_t left_64x64_txform_mask_uv[TX_SIZES]= {
-    0xffff,  // TX_4X4
-    0xffff,  // TX_8x8
-    0x5555,  // TX_16x16
-    0x1111,  // TX_32x32
+  0xffff,  // TX_4X4
+  0xffff,  // TX_8x8
+  0x5555,  // TX_16x16
+  0x1111,  // TX_32x32
 };
 
 static const uint16_t above_64x64_txform_mask_uv[TX_SIZES]= {
-    0xffff,  // TX_4X4
-    0xffff,  // TX_8x8
-    0x0f0f,  // TX_16x16
-    0x000f,  // TX_32x32
+  0xffff,  // TX_4X4
+  0xffff,  // TX_8x8
+  0x0f0f,  // TX_16x16
+  0x000f,  // TX_32x32
 };
 
 // 16 bit left mask to shift and set for each uv prediction size.
 static const uint16_t left_prediction_mask_uv[BLOCK_SIZES] = {
-    0x0001,  // BLOCK_4X4,
-    0x0001,  // BLOCK_4X8,
-    0x0001,  // BLOCK_8X4,
-    0x0001,  // BLOCK_8X8,
-    0x0001,  // BLOCK_8X16,
-    0x0001,  // BLOCK_16X8,
-    0x0001,  // BLOCK_16X16,
-    0x0011,  // BLOCK_16X32,
-    0x0001,  // BLOCK_32X16,
-    0x0011,  // BLOCK_32X32,
-    0x1111,  // BLOCK_32X64
-    0x0011,  // BLOCK_64X32,
-    0x1111,  // BLOCK_64X64
+  0x0001,  // BLOCK_4X4,
+  0x0001,  // BLOCK_4X8,
+  0x0001,  // BLOCK_8X4,
+  0x0001,  // BLOCK_8X8,
+  0x0001,  // BLOCK_8X16,
+  0x0001,  // BLOCK_16X8,
+  0x0001,  // BLOCK_16X16,
+  0x0011,  // BLOCK_16X32,
+  0x0001,  // BLOCK_32X16,
+  0x0011,  // BLOCK_32X32,
+  0x1111,  // BLOCK_32X64
+  0x0011,  // BLOCK_64X32,
+  0x1111,  // BLOCK_64X64
 };
 // 16 bit above mask to shift and set for uv each prediction size.
 static const uint16_t above_prediction_mask_uv[BLOCK_SIZES] = {
-    0x0001,  // BLOCK_4X4
-    0x0001,  // BLOCK_4X8
-    0x0001,  // BLOCK_8X4
-    0x0001,  // BLOCK_8X8
-    0x0001,  // BLOCK_8X16,
-    0x0001,  // BLOCK_16X8
-    0x0001,  // BLOCK_16X16
-    0x0001,  // BLOCK_16X32,
-    0x0003,  // BLOCK_32X16,
-    0x0003,  // BLOCK_32X32,
-    0x0003,  // BLOCK_32X64,
-    0x000f,  // BLOCK_64X32,
-    0x000f,  // BLOCK_64X64
+  0x0001,  // BLOCK_4X4
+  0x0001,  // BLOCK_4X8
+  0x0001,  // BLOCK_8X4
+  0x0001,  // BLOCK_8X8
+  0x0001,  // BLOCK_8X16,
+  0x0001,  // BLOCK_16X8
+  0x0001,  // BLOCK_16X16
+  0x0001,  // BLOCK_16X32,
+  0x0003,  // BLOCK_32X16,
+  0x0003,  // BLOCK_32X32,
+  0x0003,  // BLOCK_32X64,
+  0x000f,  // BLOCK_64X32,
+  0x000f,  // BLOCK_64X64
 };
 
 // 64 bit mask to shift and set for each uv prediction size
 static const uint16_t size_mask_uv[BLOCK_SIZES] = {
-    0x0001,  // BLOCK_4X4
-    0x0001,  // BLOCK_4X8
-    0x0001,  // BLOCK_8X4
-    0x0001,  // BLOCK_8X8
-    0x0001,  // BLOCK_8X16,
-    0x0001,  // BLOCK_16X8
-    0x0001,  // BLOCK_16X16
-    0x0011,  // BLOCK_16X32,
-    0x0003,  // BLOCK_32X16,
-    0x0033,  // BLOCK_32X32,
-    0x3333,  // BLOCK_32X64,
-    0x00ff,  // BLOCK_64X32,
-    0xffff,  // BLOCK_64X64
+  0x0001,  // BLOCK_4X4
+  0x0001,  // BLOCK_4X8
+  0x0001,  // BLOCK_8X4
+  0x0001,  // BLOCK_8X8
+  0x0001,  // BLOCK_8X16,
+  0x0001,  // BLOCK_16X8
+  0x0001,  // BLOCK_16X16
+  0x0011,  // BLOCK_16X32,
+  0x0003,  // BLOCK_32X16,
+  0x0033,  // BLOCK_32X32,
+  0x3333,  // BLOCK_32X64,
+  0x00ff,  // BLOCK_64X32,
+  0xffff,  // BLOCK_64X64
 };
 static const uint16_t left_border_uv =  0x1111;
 static const uint16_t above_border_uv = 0x000f;
@@ -211,7 +211,7 @@
 
   // For each possible value for the loop filter fill out limits
   for (lvl = 0; lvl <= MAX_LOOP_FILTER; lvl++) {
-    // Set loop filter paramaeters that control sharpness.
+    // Set loop filter parameters that control sharpness.
     int block_inside_limit = lvl >> ((sharpness_lvl > 0) + (sharpness_lvl > 4));
 
     if (sharpness_lvl > 0) {
@@ -250,7 +250,7 @@
 
 void vp9_loop_filter_frame_init(VP9_COMMON *cm, int default_filt_lvl) {
   int seg_id;
-  // n_shift is the a multiplier for lf_deltas
+  // n_shift is the multiplier for lf_deltas
   // the multiplier is 1 for when filter_lvl is between 0 and 31;
   // 2 when filter_lvl is between 32 and 63
   const int scale = 1 << (default_filt_lvl >> 5);
@@ -316,8 +316,8 @@
   unsigned int mask;
 
   for (mask = mask_16x16_0 | mask_8x8_0 | mask_4x4_0 | mask_4x4_int_0 |
-      mask_16x16_1 | mask_8x8_1 | mask_4x4_1 | mask_4x4_int_1;
-      mask; mask >>= 1) {
+              mask_16x16_1 | mask_8x8_1 | mask_4x4_1 | mask_4x4_int_1;
+       mask; mask >>= 1) {
     const loop_filter_thresh *lfi0 = lfi_n->lfthr + *lfl;
     const loop_filter_thresh *lfi1 = lfi_n->lfthr + *(lfl + lfl_forward);
 
@@ -489,8 +489,8 @@
 }
 
 // This function ors into the current lfm structure, where to do loop
-// filters for the specific mi we are looking at.   It uses information
-// including the block_size_type (32x16, 32x32, etc),  the transform size,
+// filters for the specific mi we are looking at. It uses information
+// including the block_size_type (32x16, 32x32, etc.), the transform size,
 // whether there were any coefficients encoded, and the loop filter strength
 // block we are currently looking at. Shift is used to position the
 // 1's we produce.
@@ -526,7 +526,7 @@
   }
 
   // These set 1 in the current block size for the block size edges.
-  // For instance if the block size is 32x16,   we'll set :
+  // For instance if the block size is 32x16, we'll set:
   //    above =   1111
   //              0000
   //    and
@@ -535,7 +535,7 @@
   // NOTE : In this example the low bit is left most ( 1000 ) is stored as
   //        1,  not 8...
   //
-  // U and v set things on a 16 bit scale.
+  // U and V set things on a 16 bit scale.
   //
   *above_y |= above_prediction_mask[block_size] << shift_y;
   *above_uv |= above_prediction_mask_uv[block_size] << shift_uv;
@@ -547,7 +547,7 @@
   if (mbmi->skip && is_inter_block(mbmi))
     return;
 
-  // Here we are adding a mask for the transform size.  The transform
+  // Here we are adding a mask for the transform size. The transform
   // size mask is set to be correct for a 64x64 prediction block size. We
   // mask to match the size of the block we are working on and then shift it
   // into place..
@@ -573,7 +573,7 @@
 }
 
 // This function does the same thing as the one above with the exception that
-// it only affects the y masks.   It exists because for blocks < 16x16 in size,
+// it only affects the y masks. It exists because for blocks < 16x16 in size,
 // we only update u and v masks on the first block.
 static void build_y_mask(const loop_filter_info_n *const lfi_n,
                          const MODE_INFO *mi, const int shift_y,
@@ -627,8 +627,8 @@
   MODE_INFO **mip2 = mi;
 
   // These are offsets to the next mi in the 64x64 block. It is what gets
-  // added to the mi ptr as we go through each loop.  It helps us to avoids
-  // setting up special row and column counters for each index.  The last step
+  // added to the mi ptr as we go through each loop. It helps us to avoid
+  // setting up special row and column counters for each index. The last step
   // brings us out back to the starting position.
   const int offset_32[] = {4, (mode_info_stride << 2) - 4, 4,
                            -(mode_info_stride << 2) - 4};
@@ -637,7 +637,7 @@
   const int offset[] = {1, mode_info_stride - 1, 1, -mode_info_stride - 1};
 
   // Following variables represent shifts to position the current block
-  // mask over the appropriate block.   A shift of 36 to the left will move
+  // mask over the appropriate block. A shift of 36 to the left will move
   // the bits for the final 32 by 32 block in the 64x64 up 4 rows and left
   // 4 rows to the appropriate spot.
   const int shift_32_y[] = {0, 4, 32, 36};
@@ -652,6 +652,7 @@
                         cm->mi_cols - mi_col : MI_BLOCK_SIZE);
 
   vp9_zero(*lfm);
+  assert(mip[0] != NULL);
 
   // TODO(jimbankoski): Try moving most of the following code into decode
   // loop and storing lfm in the mbmi structure so that we don't have to go
@@ -767,7 +768,7 @@
   lfm->above_uv[TX_16X16] |= lfm->above_uv[TX_32X32];
 
   // We do at least 8 tap filter on every 32x32 even if the transform size
-  // is 4x4.  So if the 4x4 is set on a border pixel add it to the 8x8 and
+  // is 4x4. So if the 4x4 is set on a border pixel add it to the 8x8 and
   // remove it from the 4x4.
   lfm->left_y[TX_8X8] |= lfm->left_y[TX_4X4] & left_border;
   lfm->left_y[TX_4X4] &= ~left_border;
@@ -796,7 +797,7 @@
     lfm->int_4x4_y &= mask_y;
     lfm->int_4x4_uv &= mask_uv;
 
-    // We don't apply a wide loop filter on the last uv block row.  If set
+    // We don't apply a wide loop filter on the last uv block row. If set
     // apply the shorter one instead.
     if (rows == 1) {
       lfm->above_uv[TX_8X8] |= lfm->above_uv[TX_16X16];
@@ -830,7 +831,7 @@
     lfm->int_4x4_y &= mask_y;
     lfm->int_4x4_uv &= mask_uv_int;
 
-    // We don't apply a wide loop filter on the last uv column.  If set
+    // We don't apply a wide loop filter on the last uv column. If set
     // apply the shorter one instead.
     if (columns == 1) {
       lfm->left_uv[TX_8X8] |= lfm->left_uv[TX_16X16];
@@ -841,7 +842,8 @@
       lfm->left_uv[TX_16X16] &= ~(lfm->left_uv[TX_16X16] & 0xcccc);
     }
   }
-  // We don't a loop filter on the first column in the image.  Mask that out.
+  // We don't apply a loop filter on the first column in the image, mask that
+  // out.
   if (mi_col == 0) {
     for (i = 0; i < TX_32X32; i++) {
       lfm->left_y[i] &= 0xfefefefefefefefe;
diff --git a/vp9/common/vp9_reconinter.c b/vp9/common/vp9_reconinter.c
index 224debb..86ae648 100644
--- a/vp9/common/vp9_reconinter.c
+++ b/vp9/common/vp9_reconinter.c
@@ -151,7 +151,7 @@
   return clamped_mv;
 }
 
-static MV average_split_mvs(const struct macroblockd_plane *pd, int plane,
+static MV average_split_mvs(const struct macroblockd_plane *pd,
                             const MODE_INFO *mi, int ref, int block) {
   const int ss_idx = ((pd->subsampling_x > 0) << 1) | (pd->subsampling_y > 0);
   MV res = {0, 0};
@@ -190,7 +190,7 @@
     struct buf_2d *const dst_buf = &pd->dst;
     uint8_t *const dst = dst_buf->buf + dst_buf->stride * y + x;
     const MV mv = mi->mbmi.sb_type < BLOCK_8X8
-               ? average_split_mvs(pd, plane, mi, ref, block)
+               ? average_split_mvs(pd, mi, ref, block)
                : mi->mbmi.mv[ref].as_mv;
 
     // TODO(jkoleszar): This clamping is done in the incorrect place for the
@@ -288,7 +288,7 @@
     struct buf_2d *const dst_buf = &pd->dst;
     uint8_t *const dst = dst_buf->buf + dst_buf->stride * y + x;
     const MV mv = mi->mbmi.sb_type < BLOCK_8X8
-               ? average_split_mvs(pd, plane, mi, ref, block)
+               ? average_split_mvs(pd, mi, ref, block)
                : mi->mbmi.mv[ref].as_mv;
 
 
diff --git a/vp9/common/vp9_rtcd_defs.pl b/vp9/common/vp9_rtcd_defs.pl
index 590dcbb..99f5a89 100644
--- a/vp9/common/vp9_rtcd_defs.pl
+++ b/vp9/common/vp9_rtcd_defs.pl
@@ -789,8 +789,7 @@
 specialize qw/vp9_refining_search_sad/;
 
 add_proto qw/int vp9_diamond_search_sad/, "const struct macroblock *x, const struct search_site_config *cfg,  struct mv *ref_mv, struct mv *best_mv, int search_param, int sad_per_bit, int *num00, const struct vp9_variance_vtable *fn_ptr, const struct mv *center_mv";
-specialize qw/vp9_diamond_search_sad sse3/;
-$vp9_diamond_search_sad_sse3=vp9_diamond_search_sadx4;
+specialize qw/vp9_diamond_search_sad/;
 
 add_proto qw/int vp9_full_range_search/, "const struct macroblock *x, const struct search_site_config *cfg, struct mv *ref_mv, struct mv *best_mv, int search_param, int sad_per_bit, int *num00, const struct vp9_variance_vtable *fn_ptr, const struct mv *center_mv";
 specialize qw/vp9_full_range_search/;
diff --git a/vp9/common/vp9_thread.c b/vp9/common/vp9_thread.c
index 348bdf6..1c6aec0 100644
--- a/vp9/common/vp9_thread.c
+++ b/vp9/common/vp9_thread.c
@@ -11,7 +11,7 @@
 //
 // Original source:
 //  http://git.chromium.org/webm/libwebp.git
-//  100644 blob 08ad4e1fecba302bf1247645e84a7d2779956bc3  src/utils/thread.c
+//  100644 blob 264210ba2807e4da47eb5d18c04cf869d89b9784  src/utils/thread.c
 
 #include <assert.h>
 #include <string.h>   // for memset()
@@ -144,18 +144,19 @@
 }
 
 static void end(VP9Worker *const worker) {
-  if (worker->status_ >= OK) {
 #if CONFIG_MULTITHREAD
+  if (worker->impl_ != NULL) {
     change_state(worker, NOT_OK);
     pthread_join(worker->impl_->thread_, NULL);
     pthread_mutex_destroy(&worker->impl_->mutex_);
     pthread_cond_destroy(&worker->impl_->condition_);
-#else
-    worker->status_ = NOT_OK;
-#endif
+    vpx_free(worker->impl_);
+    worker->impl_ = NULL;
   }
-  vpx_free(worker->impl_);
-  worker->impl_ = NULL;
+#else
+  worker->status_ = NOT_OK;
+  assert(worker->impl_ == NULL);
+#endif
   assert(worker->status_ == NOT_OK);
 }
 
diff --git a/vp9/decoder/vp9_decodeframe.c b/vp9/decoder/vp9_decodeframe.c
index 55d5b4f..82d0307 100644
--- a/vp9/decoder/vp9_decodeframe.c
+++ b/vp9/decoder/vp9_decodeframe.c
@@ -858,6 +858,7 @@
           decode_partition(tile_data->cm, &tile_data->xd, &tile, mi_row, mi_col,
                            &tile_data->bit_reader, BLOCK_64X64);
         }
+        pbi->mb.corrupted |= tile_data->xd.corrupted;
       }
       // Loopfilter one row.
       if (cm->lf.filter_level) {
@@ -1411,6 +1412,9 @@
     } else {
       debug_check_frame_counts(cm);
     }
+  } else {
+    vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME,
+                       "Decode failed. Frame data is corrupted.");
   }
 
   if (cm->refresh_frame_context)
diff --git a/vp9/decoder/vp9_decoder.c b/vp9/decoder/vp9_decoder.c
index a1a78a9..e32637b 100644
--- a/vp9/decoder/vp9_decoder.c
+++ b/vp9/decoder/vp9_decoder.c
@@ -246,6 +246,7 @@
 
   if (setjmp(cm->error.jmp)) {
     cm->error.setjmp = 0;
+    vp9_clear_system_state();
 
     // We do not know if the missing frame(s) was supposed to update
     // any of the reference buffers, but we act conservative and
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c
index 83955dc..7ba7cae 100644
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -1827,7 +1827,7 @@
   int bh, bw;
   BLOCK_SIZE min_size = BLOCK_32X32;
   BLOCK_SIZE max_size = BLOCK_8X8;
-  int bsl = mi_width_log2_lookup[BLOCK_64X64];
+  int bsl = mi_width_log2(BLOCK_64X64);
   const int search_range_ctrl = (((mi_row + mi_col) >> bsl) +
                                      get_chessboard_index(cm)) % 2;
   // Trap case where we do not have a prediction.
@@ -1976,8 +1976,8 @@
           pc_tree->partitioning = PARTITION_NONE;
 
         // Adjust threshold according to partition size.
-        stop_thresh >>= 8 - (b_width_log2_lookup[bsize] +
-            b_height_log2_lookup[bsize]);
+        stop_thresh >>= 8 - (b_width_log2(bsize) +
+            b_height_log2(bsize));
 
         stop_thresh_rd = RDCOST(x->rdmult, x->rddiv, 0, stop_thresh);
         // If obtained distortion is very small, choose current partition
@@ -2548,8 +2548,8 @@
           pc_tree->partitioning = PARTITION_NONE;
 
         // Adjust threshold according to partition size.
-        stop_thresh >>= 8 - (b_width_log2_lookup[bsize] +
-            b_height_log2_lookup[bsize]);
+        stop_thresh >>= 8 - (b_width_log2(bsize) +
+            b_height_log2(bsize));
 
         stop_thresh_rd = RDCOST(x->rdmult, x->rddiv, 0, stop_thresh);
         // If obtained distortion is very small, choose current partition
diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c
index a240622..dc572aa 100644
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -2096,7 +2096,7 @@
   cm->lf.mode_ref_delta_update = 0;
 
   // Initialize cpi->mv_step_param to default based on max resolution.
-  cpi->mv_step_param = vp9_init_search_range(sf, max_mv_def);
+  cpi->mv_step_param = vp9_init_search_range(max_mv_def);
   // Initialize cpi->max_mv_magnitude and cpi->mv_step_param if appropriate.
   if (sf->mv.auto_mv_step_size) {
     if (frame_is_intra_only(cm)) {
@@ -2108,7 +2108,7 @@
         // Allow mv_steps to correspond to twice the max mv magnitude found
         // in the previous frame, capped by the default max_mv_magnitude based
         // on resolution.
-        cpi->mv_step_param = vp9_init_search_range(sf, MIN(max_mv_def, 2 *
+        cpi->mv_step_param = vp9_init_search_range(MIN(max_mv_def, 2 *
                                  cpi->max_mv_magnitude));
       cpi->max_mv_magnitude = 0;
     }
@@ -2574,9 +2574,7 @@
 
       if (cpi->oxcf.arnr_max_frames > 0) {
         // Produce the filtered ARF frame.
-        // TODO(agrange) merge these two functions.
-        vp9_configure_arnr_filter(cpi, arf_src_index, rc->gfu_boost);
-        vp9_temporal_filter_prepare(cpi, arf_src_index);
+        vp9_temporal_filter(cpi, arf_src_index);
         vp9_extend_frame_borders(&cpi->alt_ref_buffer);
         force_src_buffer = &cpi->alt_ref_buffer;
       }
diff --git a/vp9/encoder/vp9_mcomp.c b/vp9/encoder/vp9_mcomp.c
index 287e5f7..ae924d5 100644
--- a/vp9/encoder/vp9_mcomp.c
+++ b/vp9/encoder/vp9_mcomp.c
@@ -51,9 +51,8 @@
     x->mv_row_max = row_max;
 }
 
-int vp9_init_search_range(const SPEED_FEATURES *sf, int size) {
+int vp9_init_search_range(int size) {
   int sr = 0;
-
   // Minimum search size no matter what the passed in value.
   size = MAX(16, size);
 
@@ -851,94 +850,6 @@
 
 int vp9_diamond_search_sad_c(const MACROBLOCK *x,
                              const search_site_config *cfg,
-                             MV *ref_mv, MV *best_mv,
-                             int search_param, int sad_per_bit, int *num00,
-                             const vp9_variance_fn_ptr_t *fn_ptr,
-                             const MV *center_mv) {
-  const MACROBLOCKD *const xd = &x->e_mbd;
-  const struct buf_2d *const what = &x->plane[0].src;
-  const struct buf_2d *const in_what = &xd->plane[0].pre[0];
-  // search_param determines the length of the initial step and hence the number
-  // of iterations
-  // 0 = initial step (MAX_FIRST_STEP) pel : 1 = (MAX_FIRST_STEP/2) pel, 2 =
-  // (MAX_FIRST_STEP/4) pel... etc.
-  const search_site *const ss = &cfg->ss[search_param * cfg->searches_per_step];
-  const int tot_steps = (cfg->ss_count / cfg->searches_per_step) - search_param;
-  const MV fcenter_mv = {center_mv->row >> 3, center_mv->col >> 3};
-  const uint8_t *best_address, *in_what_ref;
-  int best_sad = INT_MAX;
-  int best_site = 0;
-  int last_site = 0;
-  int i, j, step;
-
-  clamp_mv(ref_mv, x->mv_col_min, x->mv_col_max, x->mv_row_min, x->mv_row_max);
-  in_what_ref = get_buf_from_mv(in_what, ref_mv);
-  best_address = in_what_ref;
-  *num00 = 0;
-  *best_mv = *ref_mv;
-
-  // Check the starting position
-  best_sad = fn_ptr->sdf(what->buf, what->stride,
-                         best_address, in_what->stride) +
-      mvsad_err_cost(x, best_mv, &fcenter_mv, sad_per_bit);
-
-  i = 1;
-
-  for (step = 0; step < tot_steps; step++) {
-    for (j = 0; j < cfg->searches_per_step; j++) {
-      const MV mv = {best_mv->row + ss[i].mv.row,
-                     best_mv->col + ss[i].mv.col};
-      if (is_mv_in(x, &mv)) {
-       int sad = fn_ptr->sdf(what->buf, what->stride,
-                             best_address + ss[i].offset, in_what->stride);
-        if (sad < best_sad) {
-          sad += mvsad_err_cost(x, &mv, &fcenter_mv, sad_per_bit);
-          if (sad < best_sad) {
-            best_sad = sad;
-            best_site = i;
-          }
-        }
-      }
-
-      i++;
-    }
-
-    if (best_site != last_site) {
-      best_mv->row += ss[best_site].mv.row;
-      best_mv->col += ss[best_site].mv.col;
-      best_address += ss[best_site].offset;
-      last_site = best_site;
-#if defined(NEW_DIAMOND_SEARCH)
-      while (1) {
-        const MV this_mv = {best_mv->row + ss[best_site].mv.row,
-                            best_mv->col + ss[best_site].mv.col};
-        if (is_mv_in(x, &this_mv)) {
-          int sad = fn_ptr->sdf(what->buf, what->stride,
-                                best_address + ss[best_site].offset,
-                                in_what->stride);
-          if (sad < best_sad) {
-            sad += mvsad_err_cost(x, &this_mv, &fcenter_mv, sad_per_bit);
-            if (sad < best_sad) {
-              best_sad = sad;
-              best_mv->row += ss[best_site].mv.row;
-              best_mv->col += ss[best_site].mv.col;
-              best_address += ss[best_site].offset;
-              continue;
-            }
-          }
-        }
-        break;
-      };
-#endif
-    } else if (best_address == in_what_ref) {
-      (*num00)++;
-    }
-  }
-  return best_sad;
-}
-
-int vp9_diamond_search_sadx4(const MACROBLOCK *x,
-                             const search_site_config *cfg,
                              MV *ref_mv, MV *best_mv, int search_param,
                              int sad_per_bit, int *num00,
                              const vp9_variance_fn_ptr_t *fn_ptr,
@@ -1059,8 +970,7 @@
           unsigned int thissad = fn_ptr->sdf(what, what_stride, check_here,
                                              in_what_stride);
           if (thissad < bestsad) {
-            thissad += mvsad_err_cost(&this_mv, &fcenter_mv,
-                                      mvjsadcost, mvsadcost, sad_per_bit);
+            thissad += mvsad_err_cost(x, &this_mv, &fcenter_mv, sad_per_bit);
             if (thissad < bestsad) {
               bestsad = thissad;
               best_mv->row += ss[best_site].mv.row;
diff --git a/vp9/encoder/vp9_mcomp.h b/vp9/encoder/vp9_mcomp.h
index 366f9af..298fbb6 100644
--- a/vp9/encoder/vp9_mcomp.h
+++ b/vp9/encoder/vp9_mcomp.h
@@ -64,7 +64,7 @@
 struct VP9_COMP;
 struct SPEED_FEATURES;
 
-int vp9_init_search_range(const struct SPEED_FEATURES *sf, int size);
+int vp9_init_search_range(int size);
 
 // Runs sequence of diamond searches in smaller steps for RD
 int vp9_full_pixel_diamond(const struct VP9_COMP *cpi, MACROBLOCK *x,
diff --git a/vp9/encoder/vp9_pickmode.c b/vp9/encoder/vp9_pickmode.c
index 31e6fcb..99f4897 100644
--- a/vp9/encoder/vp9_pickmode.c
+++ b/vp9/encoder/vp9_pickmode.c
@@ -127,6 +127,10 @@
   int rv = 0;
   const YV12_BUFFER_CONFIG *scaled_ref_frame = vp9_get_scaled_ref_frame(cpi,
                                                                         ref);
+  if (cpi->common.show_frame &&
+      (x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[LAST_FRAME])
+    return rv;
+
   if (scaled_ref_frame) {
     int i;
     // Swap out the reference frame for a version that's been scaled to
@@ -138,16 +142,6 @@
   }
   vp9_set_mv_search_range(x, &ref_mv);
 
-  if (cpi->common.show_frame &&
-      (x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[LAST_FRAME]) {
-    tmp_mv->as_int = INVALID_MV;
-    if (scaled_ref_frame) {
-      int i;
-      for (i = 0; i < MAX_MB_PLANE; i++)
-        xd->plane[i].pre[0] = backup_yv12[i];
-    }
-    return rv;
-  }
   assert(x->mv_best_ref_index[ref] <= 2);
   if (x->mv_best_ref_index[ref] < 2)
     mvp_full = mbmi->ref_mvs[ref][x->mv_best_ref_index[ref]].as_mv;
@@ -293,7 +287,7 @@
 
     // Adjust ac threshold according to partition size.
     thresh_ac >>=
-        8 - (b_width_log2_lookup[bsize] + b_height_log2_lookup[bsize]);
+        8 - (b_width_log2(bsize) + b_height_log2(bsize));
 
     thresh_dc = (xd->plane[0].dequant[0] * xd->plane[0].dequant[0] >> 6);
   } else {
@@ -393,7 +387,7 @@
   // Mode index conversion form THR_MODES to PREDICTION_MODE for a ref frame.
   int mode_idx[MB_MODE_COUNT] = {0};
   INTERP_FILTER filter_ref = cm->interp_filter;
-  int bsl = mi_width_log2_lookup[bsize];
+  int bsl = mi_width_log2(bsize);
   const int pred_filter_search = cm->interp_filter == SWITCHABLE ?
       (((mi_row + mi_col) >> bsl) + get_chessboard_index(cm)) % 2 : 0;
   int const_motion[MAX_REF_FRAMES] = { 0 };
diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c
index 998fb3c..eae469d 100644
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -1367,7 +1367,7 @@
             // Take wtd average of the step_params based on the last frame's
             // max mv magnitude and the best ref mvs of the current block for
             // the given reference.
-            step_param = (vp9_init_search_range(&cpi->sf, max_mv) +
+            step_param = (vp9_init_search_range(max_mv) +
                               cpi->mv_step_param) / 2;
           } else {
             step_param = cpi->mv_step_param;
@@ -1779,7 +1779,7 @@
     // Take wtd average of the step_params based on the last frame's
     // max mv magnitude and that based on the best ref mvs of the current
     // block for the given reference.
-    step_param = (vp9_init_search_range(&cpi->sf, x->max_mv_context[ref]) +
+    step_param = (vp9_init_search_range(x->max_mv_context[ref]) +
                     cpi->mv_step_param) / 2;
   } else {
     step_param = cpi->mv_step_param;
@@ -1793,8 +1793,8 @@
   }
 
   if (cpi->sf.adaptive_motion_search) {
-    int bwl = b_width_log2_lookup[bsize];
-    int bhl = b_height_log2_lookup[bsize];
+    int bwl = b_width_log2(bsize);
+    int bhl = b_height_log2(bsize);
     int i;
     int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
 
@@ -2266,8 +2266,8 @@
         thresh_ac = clamp(thresh_ac, min_thresh, max_thresh);
 
         // Adjust threshold according to partition size.
-        thresh_ac >>= 8 - (b_width_log2_lookup[bsize] +
-            b_height_log2_lookup[bsize]);
+        thresh_ac >>= 8 - (b_width_log2(bsize) +
+            b_height_log2(bsize));
         thresh_dc = (xd->plane[0].dequant[0] * xd->plane[0].dequant[0] >> 6);
       } else {
         thresh_ac = 0;
diff --git a/vp9/encoder/vp9_temporal_filter.c b/vp9/encoder/vp9_temporal_filter.c
index bcea100..caa831c 100644
--- a/vp9/encoder/vp9_temporal_filter.c
+++ b/vp9/encoder/vp9_temporal_filter.c
@@ -355,150 +355,32 @@
     mbd->plane[i].pre[0].buf = input_buffer[i];
 }
 
-void vp9_temporal_filter_prepare(VP9_COMP *cpi, int distance) {
-  VP9_COMMON *const cm = &cpi->common;
-  int frame = 0;
-  int frames_to_blur_backward = 0;
-  int frames_to_blur_forward = 0;
-  int frames_to_blur = 0;
-  int start_frame = 0;
-  int strength = cpi->active_arnr_strength;
-  int blur_type = cpi->oxcf.arnr_type;
-  int max_frames = cpi->active_arnr_frames;
-  const int num_frames_backward = distance;
-  const int num_frames_forward = vp9_lookahead_depth(cpi->lookahead)
-                               - (num_frames_backward + 1);
-  struct scale_factors sf;
-
-  switch (blur_type) {
-    case 1:
-      // Backward Blur
-      frames_to_blur_backward = num_frames_backward;
-
-      if (frames_to_blur_backward >= max_frames)
-        frames_to_blur_backward = max_frames - 1;
-
-      frames_to_blur = frames_to_blur_backward + 1;
-      break;
-
-    case 2:
-      // Forward Blur
-      frames_to_blur_forward = num_frames_forward;
-
-      if (frames_to_blur_forward >= max_frames)
-        frames_to_blur_forward = max_frames - 1;
-
-      frames_to_blur = frames_to_blur_forward + 1;
-      break;
-
-    case 3:
-    default:
-      // Center Blur
-      frames_to_blur_forward = num_frames_forward;
-      frames_to_blur_backward = num_frames_backward;
-
-      if (frames_to_blur_forward > frames_to_blur_backward)
-        frames_to_blur_forward = frames_to_blur_backward;
-
-      if (frames_to_blur_backward > frames_to_blur_forward)
-        frames_to_blur_backward = frames_to_blur_forward;
-
-      // When max_frames is even we have 1 more frame backward than forward
-      if (frames_to_blur_forward > (max_frames - 1) / 2)
-        frames_to_blur_forward = ((max_frames - 1) / 2);
-
-      if (frames_to_blur_backward > (max_frames / 2))
-        frames_to_blur_backward = (max_frames / 2);
-
-      frames_to_blur = frames_to_blur_backward + frames_to_blur_forward + 1;
-      break;
-  }
-
-  start_frame = distance + frames_to_blur_forward;
-
-#ifdef DEBUGFWG
-  // DEBUG FWG
-  printf(
-      "max:%d FBCK:%d FFWD:%d ftb:%d ftbbck:%d ftbfwd:%d sei:%d lasei:%d "
-      "start:%d",
-      max_frames, num_frames_backward, num_frames_forward, frames_to_blur,
-      frames_to_blur_backward, frames_to_blur_forward, cpi->source_encode_index,
-      cpi->last_alt_ref_sei, start_frame);
-#endif
-
-  // Setup scaling factors. Scaling on each of the arnr frames is not supported
-  vp9_setup_scale_factors_for_frame(&sf,
-      get_frame_new_buffer(cm)->y_crop_width,
-      get_frame_new_buffer(cm)->y_crop_height,
-      cm->width, cm->height);
-
-  // Setup frame pointers, NULL indicates frame not included in filter
-  vp9_zero(cpi->frames);
-  for (frame = 0; frame < frames_to_blur; frame++) {
-    int which_buffer = start_frame - frame;
-    struct lookahead_entry *buf = vp9_lookahead_peek(cpi->lookahead,
-                                                     which_buffer);
-    cpi->frames[frames_to_blur - 1 - frame] = &buf->img;
-  }
-
-  temporal_filter_iterate_c(cpi, frames_to_blur, frames_to_blur_backward,
-                            strength, &sf);
-}
-
-void vp9_configure_arnr_filter(VP9_COMP *cpi,
-                               const unsigned int frames_to_arnr,
-                               const int group_boost) {
-  int half_gf_int;
-  int frames_after_arf;
-  int frames_bwd = cpi->oxcf.arnr_max_frames - 1;
-  int frames_fwd = cpi->oxcf.arnr_max_frames - 1;
+// Apply buffer limits and context specific adjustments to arnr filter.
+static void adjust_arnr_filter(VP9_COMP *cpi,
+                               int distance, int group_boost) {
+  const int frames_after_arf =
+            vp9_lookahead_depth(cpi->lookahead) - distance - 1;
+  int frames_fwd = (cpi->oxcf.arnr_max_frames - 1) >> 1;
+  int frames_bwd;
   int q;
 
-  // Define the arnr filter width for this group of frames. We only
-  // filter frames that lie within a distance of half the GF interval
-  // from the ARF frame. We also have to trap cases where the filter
-  // extends beyond the end of the lookahead buffer.
-  // Note: frames_to_arnr parameter is the offset of the arnr
-  // frame from the current frame.
-  half_gf_int = cpi->rc.baseline_gf_interval >> 1;
-  frames_after_arf = vp9_lookahead_depth(cpi->lookahead)
-      - frames_to_arnr - 1;
+  // Define the forward and backwards filter limits for this arnr group.
+  if (frames_fwd > frames_after_arf)
+    frames_fwd = frames_after_arf;
+  if (frames_fwd > distance)
+    frames_fwd = distance;
 
-  switch (cpi->oxcf.arnr_type) {
-    case 1:  // Backward filter
-      frames_fwd = 0;
-      if (frames_bwd > half_gf_int)
-        frames_bwd = half_gf_int;
-      break;
+  frames_bwd = frames_fwd;
 
-    case 2:  // Forward filter
-      if (frames_fwd > half_gf_int)
-        frames_fwd = half_gf_int;
-      if (frames_fwd > frames_after_arf)
-        frames_fwd = frames_after_arf;
-      frames_bwd = 0;
-      break;
+  // For even length filter there is one more frame backward
+  // than forward: e.g. len=6 ==> bbbAff, len=7 ==> bbbAfff.
+  if (frames_bwd < distance)
+    frames_bwd += (cpi->oxcf.arnr_max_frames + 1) & 0x1;
 
-    case 3:  // Centered filter
-    default:
-      frames_fwd >>= 1;
-      if (frames_fwd > frames_after_arf)
-        frames_fwd = frames_after_arf;
-      if (frames_fwd > half_gf_int)
-        frames_fwd = half_gf_int;
-
-      frames_bwd = frames_fwd;
-
-      // For even length filter there is one more frame backward
-      // than forward: e.g. len=6 ==> bbbAff, len=7 ==> bbbAfff.
-      if (frames_bwd < half_gf_int)
-        frames_bwd += (cpi->oxcf.arnr_max_frames + 1) & 0x1;
-      break;
-  }
-
+  // Set the baseline active filter size.
   cpi->active_arnr_frames = frames_bwd + 1 + frames_fwd;
 
-  // Adjust the strength based on active max q
+  // Adjust the strength based on active max q.
   if (cpi->common.current_video_frame > 1)
     q = ((int)vp9_convert_qindex_to_q(
         cpi->rc.avg_frame_qindex[INTER_FRAME]));
@@ -521,4 +403,50 @@
   if (cpi->active_arnr_strength > (group_boost / 300)) {
     cpi->active_arnr_strength = (group_boost / 300);
   }
+
+  // Adjustments for second level arf in multi arf case.
+  if (cpi->pass == 2 && cpi->multi_arf_allowed) {
+    const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
+    if (gf_group->rf_level[gf_group->index] != GF_ARF_STD) {
+      cpi->active_arnr_strength >>= 1;
+    }
+  }
+}
+
+void vp9_temporal_filter(VP9_COMP *cpi, int distance) {
+  VP9_COMMON *const cm = &cpi->common;
+  RATE_CONTROL *const rc = &cpi->rc;
+  int frame;
+  int frames_to_blur;
+  int start_frame;
+  int strength;
+  int frames_to_blur_backward;
+  int frames_to_blur_forward;
+  struct scale_factors sf;
+
+  // Apply context specific adjustments to the arnr filter parameters.
+  adjust_arnr_filter(cpi, distance, rc->gfu_boost);
+  strength = cpi->active_arnr_strength;
+  frames_to_blur = cpi->active_arnr_frames;
+  frames_to_blur_backward = (frames_to_blur / 2);
+  frames_to_blur_forward = ((frames_to_blur - 1) / 2);
+  start_frame = distance + frames_to_blur_forward;
+
+  // Setup scaling factors. Scaling on each of the arnr frames not supported.
+  vp9_setup_scale_factors_for_frame(&sf,
+      get_frame_new_buffer(cm)->y_crop_width,
+      get_frame_new_buffer(cm)->y_crop_height,
+      cm->width, cm->height);
+
+  // Setup frame pointers, NULL indicates frame not included in filter.
+  vp9_zero(cpi->frames);
+  for (frame = 0; frame < frames_to_blur; ++frame) {
+    const int which_buffer = start_frame - frame;
+    struct lookahead_entry *buf = vp9_lookahead_peek(cpi->lookahead,
+                                                     which_buffer);
+    cpi->frames[frames_to_blur - 1 - frame] = &buf->img;
+  }
+
+  temporal_filter_iterate_c(cpi, frames_to_blur, frames_to_blur_backward,
+                            strength, &sf);
 }
diff --git a/vp9/encoder/vp9_temporal_filter.h b/vp9/encoder/vp9_temporal_filter.h
index 9453dc1..a971e0a 100644
--- a/vp9/encoder/vp9_temporal_filter.h
+++ b/vp9/encoder/vp9_temporal_filter.h
@@ -16,10 +16,7 @@
 #endif
 
 void vp9_temporal_filter_init();
-void vp9_temporal_filter_prepare(VP9_COMP *cpi, int distance);
-void vp9_configure_arnr_filter(VP9_COMP *cpi,
-                               const unsigned int frames_to_arnr,
-                               const int group_boost);
+void vp9_temporal_filter(VP9_COMP *cpi, int distance);
 
 #ifdef __cplusplus
 }  // extern "C"
diff --git a/vpxenc.c b/vpxenc.c
index fce6807..60ba547 100644
--- a/vpxenc.c
+++ b/vpxenc.c
@@ -1686,7 +1686,6 @@
                   fps >= 1.0 ? fps : fps * 60,
                   fps >= 1.0 ? "fps" : "fpm");
           print_time("ETA", estimated_time_left);
-          fprintf(stderr, "\033[K");
         }
 
       } else
@@ -1737,6 +1736,8 @@
       }
 
       fflush(stdout);
+      if (!global.quiet)
+        fprintf(stderr, "\033[K");
     }
 
     if (stream_cnt > 1)