Merge "Cleaning up entropy probability update in encoder."
diff --git a/examples.mk b/examples.mk
index 36d20df..2600a9d 100644
--- a/examples.mk
+++ b/examples.mk
@@ -37,7 +37,7 @@
 vpxdec.GUID                  = BA5FE66F-38DD-E034-F542-B1578C5FB950
 vpxdec.DESCRIPTION           = Full featured decoder
 UTILS-$(CONFIG_ENCODERS)    += vpxenc.c
-vpxenc.SRCS                 += args.c args.h y4minput.c y4minput.h
+vpxenc.SRCS                 += args.c args.h y4minput.c y4minput.h vpxenc.h
 vpxenc.SRCS                 += ivfdec.c ivfdec.h
 vpxenc.SRCS                 += ivfenc.c ivfenc.h
 vpxenc.SRCS                 += tools_common.c tools_common.h
diff --git a/test/convolve_test.cc b/test/convolve_test.cc
index abeb4bd..9ab60b1 100644
--- a/test/convolve_test.cc
+++ b/test/convolve_test.cc
@@ -44,6 +44,8 @@
   convolve_fn_t hv8_avg_;
 };
 
+typedef std::tr1::tuple<int, int, const ConvolveFunctions*> convolve_param_t;
+
 // Reference 8-tap subpixel filter, slightly modified to fit into this test.
 #define VP9_FILTER_WEIGHT 128
 #define VP9_FILTER_SHIFT 7
@@ -169,7 +171,7 @@
                     output_width, output_height);
 }
 
-class ConvolveTest : public PARAMS(int, int, const ConvolveFunctions*) {
+class ConvolveTest : public ::testing::TestWithParam<convolve_param_t> {
  public:
   static void SetUpTestCase() {
     // Force input_ to be unaligned, output to be 16 byte aligned.
diff --git a/test/dct16x16_test.cc b/test/dct16x16_test.cc
index b61df8d..5496d0b 100644
--- a/test/dct16x16_test.cc
+++ b/test/dct16x16_test.cc
@@ -264,6 +264,9 @@
 typedef void (*iht_t) (const int16_t *in, uint8_t *out, int stride,
                        int tx_type);
 
+typedef std::tr1::tuple<fdct_t, idct_t, int> dct_16x16_param_t;
+typedef std::tr1::tuple<fht_t, iht_t, int> ht_16x16_param_t;
+
 void fdct16x16_ref(const int16_t *in, int16_t *out, int stride, int tx_type) {
   vp9_fdct16x16_c(in, out, stride);
 }
@@ -412,8 +415,9 @@
   fht_t fwd_txfm_ref;
 };
 
-class Trans16x16DCT : public Trans16x16TestBase,
-                      public PARAMS(fdct_t, idct_t, int) {
+class Trans16x16DCT
+    : public Trans16x16TestBase,
+      public ::testing::TestWithParam<dct_16x16_param_t> {
  public:
   virtual ~Trans16x16DCT() {}
 
@@ -454,8 +458,9 @@
   RunInvAccuracyCheck();
 }
 
-class Trans16x16HT : public Trans16x16TestBase,
-                     public PARAMS(fht_t, iht_t, int) {
+class Trans16x16HT
+    : public Trans16x16TestBase,
+      public ::testing::TestWithParam<ht_16x16_param_t> {
  public:
   virtual ~Trans16x16HT() {}
 
diff --git a/test/dct32x32_test.cc b/test/dct32x32_test.cc
index 1e792da..2df3b6f 100644
--- a/test/dct32x32_test.cc
+++ b/test/dct32x32_test.cc
@@ -77,7 +77,9 @@
 typedef void (*fwd_txfm_t)(const int16_t *in, int16_t *out, int stride);
 typedef void (*inv_txfm_t)(const int16_t *in, uint8_t *out, int stride);
 
-class Trans32x32Test : public PARAMS(fwd_txfm_t, inv_txfm_t, int) {
+typedef std::tr1::tuple<fwd_txfm_t, inv_txfm_t, int> trans_32x32_param_t;
+
+class Trans32x32Test : public ::testing::TestWithParam<trans_32x32_param_t> {
  public:
   virtual ~Trans32x32Test() {}
   virtual void SetUp() {
diff --git a/test/fdct4x4_test.cc b/test/fdct4x4_test.cc
index 9d8b0bd..67426eb 100644
--- a/test/fdct4x4_test.cc
+++ b/test/fdct4x4_test.cc
@@ -36,6 +36,9 @@
 typedef void (*iht_t) (const int16_t *in, uint8_t *out, int stride,
                        int tx_type);
 
+typedef std::tr1::tuple<fdct_t, idct_t, int> dct_4x4_param_t;
+typedef std::tr1::tuple<fht_t, iht_t, int> ht_4x4_param_t;
+
 void fdct4x4_ref(const int16_t *in, int16_t *out, int stride, int tx_type) {
   vp9_fdct4x4_c(in, out, stride);
 }
@@ -183,7 +186,7 @@
 
 class Trans4x4DCT
     : public Trans4x4TestBase,
-      public PARAMS(fdct_t, idct_t, int) {
+      public ::testing::TestWithParam<dct_4x4_param_t> {
  public:
   virtual ~Trans4x4DCT() {}
 
@@ -226,7 +229,7 @@
 
 class Trans4x4HT
     : public Trans4x4TestBase,
-      public PARAMS(fht_t, iht_t, int) {
+      public ::testing::TestWithParam<ht_4x4_param_t> {
  public:
   virtual ~Trans4x4HT() {}
 
diff --git a/test/fdct8x8_test.cc b/test/fdct8x8_test.cc
index 3777b11..19ffe26 100644
--- a/test/fdct8x8_test.cc
+++ b/test/fdct8x8_test.cc
@@ -35,6 +35,9 @@
 typedef void (*iht_t) (const int16_t *in, uint8_t *out, int stride,
                        int tx_type);
 
+typedef std::tr1::tuple<fdct_t, idct_t, int> dct_8x8_param_t;
+typedef std::tr1::tuple<fht_t, iht_t, int> ht_8x8_param_t;
+
 void fdct8x8_ref(const int16_t *in, int16_t *out, int stride, int tx_type) {
   vp9_fdct8x8_c(in, out, stride);
 }
@@ -215,8 +218,9 @@
   fht_t fwd_txfm_ref;
 };
 
-class FwdTrans8x8DCT : public FwdTrans8x8TestBase,
-                       public PARAMS(fdct_t, idct_t, int) {
+class FwdTrans8x8DCT
+    : public FwdTrans8x8TestBase,
+      public ::testing::TestWithParam<dct_8x8_param_t> {
  public:
   virtual ~FwdTrans8x8DCT() {}
 
@@ -254,8 +258,9 @@
   RunExtremalCheck();
 }
 
-class FwdTrans8x8HT : public FwdTrans8x8TestBase,
-                      public PARAMS(fht_t, iht_t, int) {
+class FwdTrans8x8HT
+    : public FwdTrans8x8TestBase,
+      public ::testing::TestWithParam<ht_8x8_param_t> {
  public:
   virtual ~FwdTrans8x8HT() {}
 
diff --git a/test/sixtap_predict_test.cc b/test/sixtap_predict_test.cc
index ee4faac..655146d 100644
--- a/test/sixtap_predict_test.cc
+++ b/test/sixtap_predict_test.cc
@@ -32,7 +32,10 @@
                                     uint8_t *dst_ptr,
                                     int  dst_pitch);
 
-class SixtapPredictTest : public PARAMS(int, int, sixtap_predict_fn_t) {
+typedef std::tr1::tuple<int, int, sixtap_predict_fn_t> sixtap_predict_param_t;
+
+class SixtapPredictTest
+    : public ::testing::TestWithParam<sixtap_predict_param_t> {
  public:
   static void SetUpTestCase() {
     src_ = reinterpret_cast<uint8_t*>(vpx_memalign(kDataAlignment, kSrcSize));
diff --git a/test/util.h b/test/util.h
index 4d7f3d4..3c45721 100644
--- a/test/util.h
+++ b/test/util.h
@@ -17,7 +17,6 @@
 #include "vpx/vpx_image.h"
 
 // Macros
-#define PARAMS(...) ::testing::TestWithParam< std::tr1::tuple< __VA_ARGS__ > >
 #define GET_PARAM(k) std::tr1::get< k >(GetParam())
 
 static double compute_psnr(const vpx_image_t *img1,
diff --git a/test/vp9_subtract_test.cc b/test/vp9_subtract_test.cc
index 332a839..e4c4cfe 100644
--- a/test/vp9_subtract_test.cc
+++ b/test/vp9_subtract_test.cc
@@ -41,8 +41,8 @@
   // FIXME(rbultje) split in its own file
   for (BLOCK_SIZE bsize = BLOCK_4X4; bsize < BLOCK_SIZES;
        bsize = static_cast<BLOCK_SIZE>(static_cast<int>(bsize) + 1)) {
-    const int block_width  = 4 << b_width_log2(bsize);
-    const int block_height = 4 << b_height_log2(bsize);
+    const int block_width = 4 * num_4x4_blocks_wide_lookup[bsize];
+    const int block_height = 4 * num_4x4_blocks_high_lookup[bsize];
     int16_t *diff = reinterpret_cast<int16_t *>(
         vpx_memalign(16, sizeof(*diff) * block_width * block_height * 2));
     uint8_t *pred = reinterpret_cast<uint8_t *>(
diff --git a/vp9/common/arm/neon/vp9_loopfilter_16_neon.asm b/vp9/common/arm/neon/vp9_loopfilter_16_neon.asm
new file mode 100644
index 0000000..e559272
--- /dev/null
+++ b/vp9/common/arm/neon/vp9_loopfilter_16_neon.asm
@@ -0,0 +1,198 @@
+;
+;  Copyright (c) 2013 The WebM project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license
+;  that can be found in the LICENSE file in the root of the source
+;  tree. An additional intellectual property rights grant can be found
+;  in the file PATENTS.  All contributing project authors may
+;  be found in the AUTHORS file in the root of the source tree.
+;
+
+    EXPORT  |vp9_loop_filter_horizontal_edge_16_neon|
+    ARM
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+
+;void vp9_loop_filter_horizontal_edge_16_neon(uint8_t *s, int p,
+;                                             const uint8_t *blimit0,
+;                                             const uint8_t *limit0,
+;                                             const uint8_t *thresh0,
+;                                             const uint8_t *blimit1,
+;                                             const uint8_t *limit1,
+;                                             const uint8_t *thresh1)
+; r0    uint8_t *s,
+; r1    int p,
+; r2    const uint8_t *blimit0,
+; r3    const uint8_t *limit0,
+; sp    const uint8_t *thresh0,
+; sp+4  const uint8_t *blimit1,
+; sp+8  const uint8_t *limit1,
+; sp+12 const uint8_t *thresh1,
+
+|vp9_loop_filter_horizontal_edge_16_neon| PROC
+    push        {lr}
+
+    ldr         r12, [sp, #4]              ; load thresh0
+    vld1.8      {d0}, [r2]                 ; load blimit0 to first half q
+    vld1.8      {d2}, [r3]                 ; load limit0 to first half q
+
+    add         r1, r1, r1                 ; double pitch
+    ldr         r2, [sp, #8]               ; load blimit1
+
+    vld1.8      {d4}, [r12]                ; load thresh0 to first half q
+
+    ldr         r3, [sp, #12]              ; load limit1
+    ldr         r12, [sp, #16]             ; load thresh1
+    vld1.8      {d1}, [r2]                 ; load blimit1 to 2nd half q
+
+    sub         r2, r0, r1, lsl #1         ; s[-4 * p]
+
+    vld1.8      {d3}, [r3]                 ; load limit1 to 2nd half q
+    vld1.8      {d5}, [r12]                ; load thresh1 to 2nd half q
+
+    vpush       {d8-d15}                   ; save neon registers
+
+    add         r3, r2, r1, lsr #1         ; s[-3 * p]
+
+    vld1.u8     {q3}, [r2@64], r1          ; p3
+    vld1.u8     {q4}, [r3@64], r1          ; p2
+    vld1.u8     {q5}, [r2@64], r1          ; p1
+    vld1.u8     {q6}, [r3@64], r1          ; p0
+    vld1.u8     {q7}, [r2@64], r1          ; q0
+    vld1.u8     {q8}, [r3@64], r1          ; q1
+    vld1.u8     {q9}, [r2@64]              ; q2
+    vld1.u8     {q10}, [r3@64]             ; q3
+
+    sub         r2, r2, r1, lsl #1
+    sub         r3, r3, r1, lsl #1
+
+    bl          vp9_loop_filter_neon_16
+
+    vst1.u8     {q5}, [r2@64], r1          ; store op1
+    vst1.u8     {q6}, [r3@64], r1          ; store op0
+    vst1.u8     {q7}, [r2@64], r1          ; store oq0
+    vst1.u8     {q8}, [r3@64], r1          ; store oq1
+
+    vpop        {d8-d15}                   ; restore neon registers
+
+    pop         {pc}
+    ENDP        ; |vp9_loop_filter_horizontal_edge_16_neon|
+
+; void vp9_loop_filter_neon_16();
+; This is a helper function for the loopfilters. The invidual functions do the
+; necessary load, transpose (if necessary) and store. This function uses
+; registers d8-d15, so the calling function must save those registers.
+;
+; r0-r3, r12 PRESERVE
+; q0    blimit
+; q1    limit
+; q2    thresh
+; q3    p3
+; q4    p2
+; q5    p1
+; q6    p0
+; q7    q0
+; q8    q1
+; q9    q2
+; q10   q3
+;
+; Outputs:
+; q5    op1
+; q6    op0
+; q7    oq0
+; q8    oq1
+|vp9_loop_filter_neon_16| PROC
+
+    ; filter_mask
+    vabd.u8     q11, q3, q4                 ; m1 = abs(p3 - p2)
+    vabd.u8     q12, q4, q5                 ; m2 = abs(p2 - p1)
+    vabd.u8     q13, q5, q6                 ; m3 = abs(p1 - p0)
+    vabd.u8     q14, q8, q7                 ; m4 = abs(q1 - q0)
+    vabd.u8     q3, q9, q8                  ; m5 = abs(q2 - q1)
+    vabd.u8     q4, q10, q9                 ; m6 = abs(q3 - q2)
+
+    ; only compare the largest value to limit
+    vmax.u8     q11, q11, q12               ; m1 = max(m1, m2)
+    vmax.u8     q12, q13, q14               ; m2 = max(m3, m4)
+
+    vabd.u8     q9, q6, q7                  ; abs(p0 - q0)
+
+    vmax.u8     q3, q3, q4                  ; m3 = max(m5, m6)
+
+    vmov.u8     q10, #0x80
+
+    vmax.u8     q15, q11, q12               ; m1 = max(m1, m2)
+
+    vcgt.u8     q13, q13, q2                ; (abs(p1 - p0) > thresh)*-1
+    vcgt.u8     q14, q14, q2                ; (abs(q1 - q0) > thresh)*-1
+    vmax.u8     q15, q15, q3                ; m1 = max(m1, m3)
+
+    vabd.u8     q2, q5, q8                  ; a = abs(p1 - q1)
+    vqadd.u8    q9, q9, q9                  ; b = abs(p0 - q0) * 2
+
+    veor        q7, q7, q10                 ; qs0
+
+    vcge.u8     q15, q1, q15                ; abs(m1) > limit
+
+    vshr.u8     q2, q2, #1                  ; a = a / 2
+    veor        q6, q6, q10                 ; ps0
+
+    veor        q5, q5, q10                 ; ps1
+    vqadd.u8    q9, q9, q2                  ; a = b + a
+
+    veor        q8, q8, q10                 ; qs1
+
+    vmov.u8     q4, #3
+
+    vsubl.s8    q2, d14, d12                ; ( qs0 - ps0)
+    vsubl.s8    q11, d15, d13
+
+    vcge.u8     q9, q0, q9                  ; a > blimit
+
+    vqsub.s8    q1, q5, q8                  ; filter = clamp(ps1-qs1)
+    vorr        q14, q13, q14               ; hevmask
+
+    vmul.i16    q2, q2, q4                  ; 3 * ( qs0 - ps0)
+    vmul.i16    q11, q11, q4
+
+    vand        q1, q1, q14                 ; filter &= hev
+    vand        q15, q15, q9                ; filter_mask
+
+    vaddw.s8    q2, q2, d2                  ; filter + 3 * (qs0 - ps0)
+    vaddw.s8    q11, q11, d3
+
+    vmov.u8     q9, #4
+
+    ; filter = clamp(filter + 3 * ( qs0 - ps0))
+    vqmovn.s16  d2, q2
+    vqmovn.s16  d3, q11
+    vand        q1, q1, q15                 ; filter &= mask
+
+    vqadd.s8    q2, q1, q4                  ; filter2 = clamp(filter+3)
+    vqadd.s8    q1, q1, q9                  ; filter1 = clamp(filter+4)
+    vshr.s8     q2, q2, #3                  ; filter2 >>= 3
+    vshr.s8     q1, q1, #3                  ; filter1 >>= 3
+
+
+    vqadd.s8    q11, q6, q2                 ; u = clamp(ps0 + filter2)
+    vqsub.s8    q0, q7, q1                  ; u = clamp(qs0 - filter1)
+
+    ; outer tap adjustments
+    vrshr.s8    q1, q1, #1                  ; filter = ++filter1 >> 1
+
+    veor        q6, q11, q10                ; *op0 = u^0x80
+
+    vbic        q1, q1, q14                 ; filter &= ~hev
+
+    vqadd.s8    q13, q5, q1                 ; u = clamp(ps1 + filter)
+    vqsub.s8    q12, q8, q1                 ; u = clamp(qs1 - filter)
+
+
+    veor        q7, q0,  q10                ; *oq0 = u^0x80
+    veor        q5, q13, q10                ; *op1 = u^0x80
+    veor        q8, q12, q10                ; *oq1 = u^0x80
+
+    bx          lr
+    ENDP        ; |vp9_loop_filter_neon_16|
+
+    END
diff --git a/vp9/common/vp9_blockd.h b/vp9/common/vp9_blockd.h
index 121947b..df963d1 100644
--- a/vp9/common/vp9_blockd.h
+++ b/vp9/common/vp9_blockd.h
@@ -286,16 +286,6 @@
   return bs;
 }
 
-static INLINE int plane_block_width(BLOCK_SIZE bsize,
-                                    const struct macroblockd_plane* plane) {
-  return 4 << (b_width_log2(bsize) - plane->subsampling_x);
-}
-
-static INLINE int plane_block_height(BLOCK_SIZE bsize,
-                                     const struct macroblockd_plane* plane) {
-  return 4 << (b_height_log2(bsize) - plane->subsampling_y);
-}
-
 typedef void (*foreach_transformed_block_visitor)(int plane, int block,
                                                   BLOCK_SIZE plane_bsize,
                                                   TX_SIZE tx_size,
@@ -394,21 +384,18 @@
 }
 
 static void extend_for_intra(MACROBLOCKD *xd, BLOCK_SIZE plane_bsize,
-                             int plane, int block, TX_SIZE tx_size) {
+                             int plane, int aoff, int loff) {
   struct macroblockd_plane *const pd = &xd->plane[plane];
   uint8_t *const buf = pd->dst.buf;
   const int stride = pd->dst.stride;
-
-  int x, y;
-  txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &x, &y);
-  x = x * 4 - 1;
-  y = y * 4 - 1;
+  const int x = aoff * 4 - 1;
+  const int y = loff * 4 - 1;
   // Copy a pixel into the umv if we are in a situation where the block size
   // extends into the UMV.
   // TODO(JBB): Should be able to do the full extend in place so we don't have
   // to do this multiple times.
   if (xd->mb_to_right_edge < 0) {
-    const int bw = 4 << b_width_log2(plane_bsize);
+    const int bw = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
     const int umv_border_start = bw + (xd->mb_to_right_edge >>
                                        (3 + pd->subsampling_x));
 
@@ -419,7 +406,7 @@
 
   if (xd->mb_to_bottom_edge < 0) {
     if (xd->left_available || x >= 0) {
-      const int bh = 4 << b_height_log2(plane_bsize);
+      const int bh = 4 * num_4x4_blocks_high_lookup[plane_bsize];
       const int umv_border_start =
           bh + (xd->mb_to_bottom_edge >> (3 + pd->subsampling_y));
 
diff --git a/vp9/common/vp9_entropy.c b/vp9/common/vp9_entropy.c
index 82aa77e..0f978cc 100644
--- a/vp9/common/vp9_entropy.c
+++ b/vp9/common/vp9_entropy.c
@@ -128,6 +128,20 @@
   -DCT_VAL_CATEGORY5, -DCT_VAL_CATEGORY6    /* 10 = CAT_FIVE */
 };
 
+// Unconstrained Node Tree
+const vp9_tree_index vp9_coef_con_tree[TREE_SIZE(MAX_ENTROPY_TOKENS)] = {
+  2, 6,                                     /* 0 = LOW_VAL */
+  -TWO_TOKEN, 4,                            /* 1 = TWO */
+  -THREE_TOKEN, -FOUR_TOKEN,                /* 2 = THREE */
+  8, 10,                                    /* 3 = HIGH_LOW */
+  -DCT_VAL_CATEGORY1, -DCT_VAL_CATEGORY2,   /* 4 = CAT_ONE */
+  12, 14,                                   /* 5 = CAT_THREEFOUR */
+  -DCT_VAL_CATEGORY3, -DCT_VAL_CATEGORY4,   /* 6 = CAT_THREE */
+  -DCT_VAL_CATEGORY5, -DCT_VAL_CATEGORY6    /* 7 = CAT_FIVE */
+};
+
+
+
 struct vp9_token vp9_coef_encodings[MAX_ENTROPY_TOKENS];
 
 /* Trees for extra bits.  Probabilities are constant and
@@ -158,143 +172,11 @@
 
 // beta = 8
 
-
-static const vp9_prob pareto8_probs[COEFPROB_MODELS][MODEL_NODES] = {
-  {  3,  86, 128,   6,  86,  23,  88,  29},
-  {  9,  86, 129,  17,  88,  61,  94,  76},
-  { 15,  87, 129,  28,  89,  93, 100, 110},
-  { 20,  88, 130,  38,  91, 118, 106, 136},
-  { 26,  89, 131,  48,  92, 139, 111, 156},
-  { 31,  90, 131,  58,  94, 156, 117, 171},
-  { 37,  90, 132,  66,  95, 171, 122, 184},
-  { 42,  91, 132,  75,  97, 183, 127, 194},
-  { 47,  92, 133,  83,  98, 193, 132, 202},
-  { 52,  93, 133,  90, 100, 201, 137, 208},
-  { 57,  94, 134,  98, 101, 208, 142, 214},
-  { 62,  94, 135, 105, 103, 214, 146, 218},
-  { 66,  95, 135, 111, 104, 219, 151, 222},
-  { 71,  96, 136, 117, 106, 224, 155, 225},
-  { 76,  97, 136, 123, 107, 227, 159, 228},
-  { 80,  98, 137, 129, 109, 231, 162, 231},
-  { 84,  98, 138, 134, 110, 234, 166, 233},
-  { 89,  99, 138, 140, 112, 236, 170, 235},
-  { 93, 100, 139, 145, 113, 238, 173, 236},
-  { 97, 101, 140, 149, 115, 240, 176, 238},
-  {101, 102, 140, 154, 116, 242, 179, 239},
-  {105, 103, 141, 158, 118, 243, 182, 240},
-  {109, 104, 141, 162, 119, 244, 185, 241},
-  {113, 104, 142, 166, 120, 245, 187, 242},
-  {116, 105, 143, 170, 122, 246, 190, 243},
-  {120, 106, 143, 173, 123, 247, 192, 244},
-  {123, 107, 144, 177, 125, 248, 195, 244},
-  {127, 108, 145, 180, 126, 249, 197, 245},
-  {130, 109, 145, 183, 128, 249, 199, 245},
-  {134, 110, 146, 186, 129, 250, 201, 246},
-  {137, 111, 147, 189, 131, 251, 203, 246},
-  {140, 112, 147, 192, 132, 251, 205, 247},
-  {143, 113, 148, 194, 133, 251, 207, 247},
-  {146, 114, 149, 197, 135, 252, 208, 248},
-  {149, 115, 149, 199, 136, 252, 210, 248},
-  {152, 115, 150, 201, 138, 252, 211, 248},
-  {155, 116, 151, 204, 139, 253, 213, 249},
-  {158, 117, 151, 206, 140, 253, 214, 249},
-  {161, 118, 152, 208, 142, 253, 216, 249},
-  {163, 119, 153, 210, 143, 253, 217, 249},
-  {166, 120, 153, 212, 144, 254, 218, 250},
-  {168, 121, 154, 213, 146, 254, 220, 250},
-  {171, 122, 155, 215, 147, 254, 221, 250},
-  {173, 123, 155, 217, 148, 254, 222, 250},
-  {176, 124, 156, 218, 150, 254, 223, 250},
-  {178, 125, 157, 220, 151, 254, 224, 251},
-  {180, 126, 157, 221, 152, 254, 225, 251},
-  {183, 127, 158, 222, 153, 254, 226, 251},
-  {185, 128, 159, 224, 155, 255, 227, 251},
-  {187, 129, 160, 225, 156, 255, 228, 251},
-  {189, 131, 160, 226, 157, 255, 228, 251},
-  {191, 132, 161, 227, 159, 255, 229, 251},
-  {193, 133, 162, 228, 160, 255, 230, 252},
-  {195, 134, 163, 230, 161, 255, 231, 252},
-  {197, 135, 163, 231, 162, 255, 231, 252},
-  {199, 136, 164, 232, 163, 255, 232, 252},
-  {201, 137, 165, 233, 165, 255, 233, 252},
-  {202, 138, 166, 233, 166, 255, 233, 252},
-  {204, 139, 166, 234, 167, 255, 234, 252},
-  {206, 140, 167, 235, 168, 255, 235, 252},
-  {207, 141, 168, 236, 169, 255, 235, 252},
-  {209, 142, 169, 237, 171, 255, 236, 252},
-  {210, 144, 169, 237, 172, 255, 236, 252},
-  {212, 145, 170, 238, 173, 255, 237, 252},
-  {214, 146, 171, 239, 174, 255, 237, 253},
-  {215, 147, 172, 240, 175, 255, 238, 253},
-  {216, 148, 173, 240, 176, 255, 238, 253},
-  {218, 149, 173, 241, 177, 255, 239, 253},
-  {219, 150, 174, 241, 179, 255, 239, 253},
-  {220, 152, 175, 242, 180, 255, 240, 253},
-  {222, 153, 176, 242, 181, 255, 240, 253},
-  {223, 154, 177, 243, 182, 255, 240, 253},
-  {224, 155, 178, 244, 183, 255, 241, 253},
-  {225, 156, 178, 244, 184, 255, 241, 253},
-  {226, 158, 179, 244, 185, 255, 242, 253},
-  {228, 159, 180, 245, 186, 255, 242, 253},
-  {229, 160, 181, 245, 187, 255, 242, 253},
-  {230, 161, 182, 246, 188, 255, 243, 253},
-  {231, 163, 183, 246, 189, 255, 243, 253},
-  {232, 164, 184, 247, 190, 255, 243, 253},
-  {233, 165, 185, 247, 191, 255, 244, 253},
-  {234, 166, 185, 247, 192, 255, 244, 253},
-  {235, 168, 186, 248, 193, 255, 244, 253},
-  {236, 169, 187, 248, 194, 255, 244, 253},
-  {236, 170, 188, 248, 195, 255, 245, 253},
-  {237, 171, 189, 249, 196, 255, 245, 254},
-  {238, 173, 190, 249, 197, 255, 245, 254},
-  {239, 174, 191, 249, 198, 255, 245, 254},
-  {240, 175, 192, 249, 199, 255, 246, 254},
-  {240, 177, 193, 250, 200, 255, 246, 254},
-  {241, 178, 194, 250, 201, 255, 246, 254},
-  {242, 179, 195, 250, 202, 255, 246, 254},
-  {242, 181, 196, 250, 203, 255, 247, 254},
-  {243, 182, 197, 251, 204, 255, 247, 254},
-  {244, 184, 198, 251, 205, 255, 247, 254},
-  {244, 185, 199, 251, 206, 255, 247, 254},
-  {245, 186, 200, 251, 207, 255, 247, 254},
-  {246, 188, 201, 252, 207, 255, 248, 254},
-  {246, 189, 202, 252, 208, 255, 248, 254},
-  {247, 191, 203, 252, 209, 255, 248, 254},
-  {247, 192, 204, 252, 210, 255, 248, 254},
-  {248, 194, 205, 252, 211, 255, 248, 254},
-  {248, 195, 206, 252, 212, 255, 249, 254},
-  {249, 197, 207, 253, 213, 255, 249, 254},
-  {249, 198, 208, 253, 214, 255, 249, 254},
-  {250, 200, 210, 253, 215, 255, 249, 254},
-  {250, 201, 211, 253, 215, 255, 249, 254},
-  {250, 203, 212, 253, 216, 255, 249, 254},
-  {251, 204, 213, 253, 217, 255, 250, 254},
-  {251, 206, 214, 254, 218, 255, 250, 254},
-  {252, 207, 216, 254, 219, 255, 250, 254},
-  {252, 209, 217, 254, 220, 255, 250, 254},
-  {252, 211, 218, 254, 221, 255, 250, 254},
-  {253, 213, 219, 254, 222, 255, 250, 254},
-  {253, 214, 221, 254, 223, 255, 250, 254},
-  {253, 216, 222, 254, 224, 255, 251, 254},
-  {253, 218, 224, 254, 225, 255, 251, 254},
-  {254, 220, 225, 254, 225, 255, 251, 254},
-  {254, 222, 227, 255, 226, 255, 251, 254},
-  {254, 224, 228, 255, 227, 255, 251, 254},
-  {254, 226, 230, 255, 228, 255, 251, 254},
-  {255, 228, 231, 255, 230, 255, 251, 254},
-  {255, 230, 233, 255, 231, 255, 252, 254},
-  {255, 232, 235, 255, 232, 255, 252, 254},
-  {255, 235, 237, 255, 233, 255, 252, 254},
-  {255, 238, 240, 255, 235, 255, 252, 255},
-  {255, 241, 243, 255, 236, 255, 252, 254},
-  {255, 246, 247, 255, 239, 255, 253, 255}
-};
-
-// This table is an expansion of the table : modelcoefprobs_pareto8
-// to all 255 probabilities using the code as follows to do the expansion:
-// tree_probs[i] = (model[l][i - UNCONSTRAINED_NODES] +
-//                  model[l + 1][i - UNCONSTRAINED_NODES]) >> 1;
-const vp9_prob vp9_pareto8_full[255][MODEL_NODES] = {
+// Every odd line in this table can be generated from the even lines
+// by averaging :
+// vp9_pareto8_full[l][node] = ( vp9_pareto8_full[l-1][node] +
+//                               vp9_pareto8_full[l+1][node] ) >> 1;
+const vp9_prob vp9_pareto8_full[256][MODEL_NODES] = {
     {  3, 86, 128,  6, 86, 23, 88, 29},
     {  6, 86, 128, 11, 87, 42, 91, 52},
     {  9, 86, 129, 17, 88, 61, 94, 76},
@@ -550,19 +432,12 @@
     {255, 241, 243, 255, 236, 255, 252, 254},
     {255, 243, 245, 255, 237, 255, 252, 254},
     {255, 246, 247, 255, 239, 255, 253, 255},
+    {255, 246, 247, 255, 239, 255, 253, 255},
 };
 
 static void extend_to_full_distribution(vp9_prob *probs, vp9_prob p) {
-  const int l = (p - 1) / 2;
-  if (p & 1) {
-    // Just copy
-    vpx_memcpy(probs, pareto8_probs[l], MODEL_NODES * sizeof(vp9_prob));
-  } else {
-    // Interpolate
-    int i;
-    for (i = 0; i < MODEL_NODES; ++i)
-      probs[i] = (pareto8_probs[l][i] + pareto8_probs[l + 1][i]) >> 1;
-  }
+  vpx_memcpy(probs, vp9_pareto8_full[p = 0 ? 0 : p - 1],
+             MODEL_NODES * sizeof(vp9_prob));
 }
 
 void vp9_model_to_full_probs(const vp9_prob *model, vp9_prob *full) {
diff --git a/vp9/common/vp9_entropy.h b/vp9/common/vp9_entropy.h
index 0370b32..b98bef0 100644
--- a/vp9/common/vp9_entropy.h
+++ b/vp9/common/vp9_entropy.h
@@ -46,6 +46,8 @@
 
 extern const vp9_tree_index vp9_coef_tree[TREE_SIZE(MAX_ENTROPY_TOKENS)];
 
+extern const vp9_tree_index vp9_coef_con_tree[];
+
 #define DCT_EOB_MODEL_TOKEN     3      /* EOB       Extra Bits 0+0 */
 extern const vp9_tree_index vp9_coefmodel_tree[];
 
@@ -143,7 +145,7 @@
 #define PIVOT_NODE                  2   // which node is pivot
 
 #define MODEL_NODES (ENTROPY_NODES - UNCONSTRAINED_NODES)
-extern const vp9_prob vp9_pareto8_full[255][MODEL_NODES];
+extern const vp9_prob vp9_pareto8_full[256][MODEL_NODES];
 
 typedef vp9_prob vp9_coeff_probs_model[REF_TYPES][COEF_BANDS]
                                       [PREV_COEF_CONTEXTS]
diff --git a/vp9/common/vp9_entropymv.h b/vp9/common/vp9_entropymv.h
index d843f5b..b62f7c4 100644
--- a/vp9/common/vp9_entropymv.h
+++ b/vp9/common/vp9_entropymv.h
@@ -62,6 +62,7 @@
 #define CLASS0_BITS    1  /* bits at integer precision for class 0 */
 #define CLASS0_SIZE    (1 << CLASS0_BITS)
 #define MV_OFFSET_BITS (MV_CLASSES + CLASS0_BITS - 2)
+#define MV_FP_SIZE 4
 
 #define MV_MAX_BITS    (MV_CLASSES + CLASS0_BITS + 2)
 #define MV_MAX         ((1 << MV_MAX_BITS) - 1)
@@ -80,7 +81,7 @@
 extern const vp9_tree_index vp9_mv_class0_tree[TREE_SIZE(CLASS0_SIZE)];
 extern struct vp9_token vp9_mv_class0_encodings[CLASS0_SIZE];
 
-extern const vp9_tree_index vp9_mv_fp_tree[TREE_SIZE(4)];
+extern const vp9_tree_index vp9_mv_fp_tree[TREE_SIZE(MV_FP_SIZE)];
 extern struct vp9_token vp9_mv_fp_encodings[4];
 
 typedef struct {
@@ -88,8 +89,8 @@
   vp9_prob classes[MV_CLASSES - 1];
   vp9_prob class0[CLASS0_SIZE - 1];
   vp9_prob bits[MV_OFFSET_BITS];
-  vp9_prob class0_fp[CLASS0_SIZE][4 - 1];
-  vp9_prob fp[4 - 1];
+  vp9_prob class0_fp[CLASS0_SIZE][MV_FP_SIZE - 1];
+  vp9_prob fp[MV_FP_SIZE - 1];
   vp9_prob class0_hp;
   vp9_prob hp;
 } nmv_component;
@@ -116,8 +117,8 @@
   unsigned int classes[MV_CLASSES];
   unsigned int class0[CLASS0_SIZE];
   unsigned int bits[MV_OFFSET_BITS][2];
-  unsigned int class0_fp[CLASS0_SIZE][4];
-  unsigned int fp[4];
+  unsigned int class0_fp[CLASS0_SIZE][MV_FP_SIZE];
+  unsigned int fp[MV_FP_SIZE];
   unsigned int class0_hp[2];
   unsigned int hp[2];
 } nmv_component_counts;
diff --git a/vp9/common/vp9_idct.c b/vp9/common/vp9_idct.c
index 149362a..533f7f3 100644
--- a/vp9/common/vp9_idct.c
+++ b/vp9/common/vp9_idct.c
@@ -1345,43 +1345,37 @@
   // coefficients. Use eobs to decide what to do.
   // TODO(yunqingwang): "eobs = 1" case is also handled in vp9_short_idct8x8_c.
   // Combine that with code here.
-  if (eob) {
-    if (eob == 1)
-      // DC only DCT coefficient
-      vp9_idct8x8_1_add(input, dest, stride);
-    else if (eob <= 10)
-      vp9_idct8x8_10_add(input, dest, stride);
-    else
-      vp9_idct8x8_64_add(input, dest, stride);
-  }
+  if (eob == 1)
+    // DC only DCT coefficient
+    vp9_idct8x8_1_add(input, dest, stride);
+  else if (eob <= 10)
+    vp9_idct8x8_10_add(input, dest, stride);
+  else
+    vp9_idct8x8_64_add(input, dest, stride);
 }
 
 void vp9_idct16x16_add(const int16_t *input, uint8_t *dest, int stride,
                        int eob) {
   /* The calculation can be simplified if there are not many non-zero dct
    * coefficients. Use eobs to separate different cases. */
-  if (eob) {
-    if (eob == 1)
-      /* DC only DCT coefficient. */
-      vp9_idct16x16_1_add(input, dest, stride);
-    else if (eob <= 10)
-      vp9_idct16x16_10_add(input, dest, stride);
-    else
-      vp9_idct16x16_256_add(input, dest, stride);
-  }
+  if (eob == 1)
+    /* DC only DCT coefficient. */
+    vp9_idct16x16_1_add(input, dest, stride);
+  else if (eob <= 10)
+    vp9_idct16x16_10_add(input, dest, stride);
+  else
+    vp9_idct16x16_256_add(input, dest, stride);
 }
 
 void vp9_idct32x32_add(const int16_t *input, uint8_t *dest, int stride,
                        int eob) {
-  if (eob) {
-    if (eob == 1)
-      vp9_idct32x32_1_add(input, dest, stride);
-    else if (eob <= 34)
-      // non-zero coeff only in upper-left 8x8
-      vp9_idct32x32_34_add(input, dest, stride);
-    else
-      vp9_idct32x32_1024_add(input, dest, stride);
-  }
+  if (eob == 1)
+    vp9_idct32x32_1_add(input, dest, stride);
+  else if (eob <= 34)
+    // non-zero coeff only in upper-left 8x8
+    vp9_idct32x32_34_add(input, dest, stride);
+  else
+    vp9_idct32x32_1024_add(input, dest, stride);
 }
 
 // iht
@@ -1398,9 +1392,7 @@
   if (tx_type == DCT_DCT) {
     vp9_idct8x8_add(input, dest, stride, eob);
   } else {
-    if (eob > 0) {
-      vp9_iht8x8_64_add(input, dest, stride, tx_type);
-    }
+    vp9_iht8x8_64_add(input, dest, stride, tx_type);
   }
 }
 
@@ -1409,8 +1401,6 @@
   if (tx_type == DCT_DCT) {
     vp9_idct16x16_add(input, dest, stride, eob);
   } else {
-    if (eob > 0) {
-      vp9_iht16x16_256_add(input, dest, stride, tx_type);
-    }
+    vp9_iht16x16_256_add(input, dest, stride, tx_type);
   }
 }
diff --git a/vp9/common/vp9_idct.h b/vp9/common/vp9_idct.h
index 2b3f35f..183c50a 100644
--- a/vp9/common/vp9_idct.h
+++ b/vp9/common/vp9_idct.h
@@ -77,8 +77,7 @@
 
 static INLINE int dct_const_round_shift(int input) {
   int rv = ROUND_POWER_OF_TWO(input, DCT_CONST_BITS);
-  assert(INT16_MIN <= rv && rv <= INT16_MAX);
-  return rv;
+  return (int16_t)rv;
 }
 
 typedef void (*transform_1d)(const int16_t*, int16_t*);
diff --git a/vp9/common/vp9_loopfilter.c b/vp9/common/vp9_loopfilter.c
index 8e13afb..0b48de2 100644
--- a/vp9/common/vp9_loopfilter.c
+++ b/vp9/common/vp9_loopfilter.c
@@ -323,40 +323,111 @@
   }
 }
 
-static void filter_selectively_vert(uint8_t *s, int pitch,
-                                    unsigned int mask_16x16,
-                                    unsigned int mask_8x8,
-                                    unsigned int mask_4x4,
-                                    unsigned int mask_4x4_int,
-                                    const loop_filter_info_n *lfi_n,
-                                    const uint8_t *lfl) {
+static void filter_selectively_vert_row2(PLANE_TYPE plane_type,
+                                         uint8_t *s, int pitch,
+                                         unsigned int mask_16x16_l,
+                                         unsigned int mask_8x8_l,
+                                         unsigned int mask_4x4_l,
+                                         unsigned int mask_4x4_int_l,
+                                         const loop_filter_info_n *lfi_n,
+                                         const uint8_t *lfl) {
+  const int mask_shift = plane_type ? 4 : 8;
+  const int mask_cutoff = plane_type ? 0xf : 0xff;
+  const int lfl_forward = plane_type ? 4 : 8;
+
+  unsigned int mask_16x16_0 = mask_16x16_l & mask_cutoff;
+  unsigned int mask_8x8_0 = mask_8x8_l & mask_cutoff;
+  unsigned int mask_4x4_0 = mask_4x4_l & mask_cutoff;
+  unsigned int mask_4x4_int_0 = mask_4x4_int_l & mask_cutoff;
+  unsigned int mask_16x16_1 = (mask_16x16_l >> mask_shift) & mask_cutoff;
+  unsigned int mask_8x8_1 = (mask_8x8_l >> mask_shift) & mask_cutoff;
+  unsigned int mask_4x4_1 = (mask_4x4_l >> mask_shift) & mask_cutoff;
+  unsigned int mask_4x4_int_1 = (mask_4x4_int_l >> mask_shift) & mask_cutoff;
   unsigned int mask;
 
-  for (mask = mask_16x16 | mask_8x8 | mask_4x4 | mask_4x4_int;
-       mask; mask >>= 1) {
-    const loop_filter_thresh *lfi = lfi_n->lfthr + *lfl;
+  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) {
+    const loop_filter_thresh *lfi0 = lfi_n->lfthr + *lfl;
+    const loop_filter_thresh *lfi1 = lfi_n->lfthr + *(lfl + lfl_forward);
 
+    // TODO(yunqingwang): count in loopfilter functions should be removed.
     if (mask & 1) {
-      if (mask_16x16 & 1) {
-        vp9_mb_lpf_vertical_edge_w(s, pitch, lfi->mblim, lfi->lim,
-                                   lfi->hev_thr);
-      } else if (mask_8x8 & 1) {
-        vp9_mbloop_filter_vertical_edge(s, pitch, lfi->mblim, lfi->lim,
-                                        lfi->hev_thr, 1);
-      } else if (mask_4x4 & 1) {
-        vp9_loop_filter_vertical_edge(s, pitch, lfi->mblim, lfi->lim,
-                                      lfi->hev_thr, 1);
+      if ((mask_16x16_0 | mask_16x16_1) & 1) {
+        if ((mask_16x16_0 & mask_16x16_1) & 1) {
+          // TODO(yunqingwang): Combine 2 calls as 1 wide filtering.
+          vp9_mb_lpf_vertical_edge_w(s, pitch, lfi0->mblim, lfi0->lim,
+                                     lfi0->hev_thr);
+          vp9_mb_lpf_vertical_edge_w(s + 8 *pitch, pitch, lfi1->mblim,
+                                     lfi1->lim, lfi1->hev_thr);
+        } else if (mask_16x16_0 & 1) {
+          vp9_mb_lpf_vertical_edge_w(s, pitch, lfi0->mblim, lfi0->lim,
+                                     lfi0->hev_thr);
+        } else {
+          vp9_mb_lpf_vertical_edge_w(s + 8 *pitch, pitch, lfi1->mblim,
+                                     lfi1->lim, lfi1->hev_thr);
+        }
+      }
+
+      if ((mask_8x8_0 | mask_8x8_1) & 1) {
+        if ((mask_8x8_0 & mask_8x8_1) & 1) {
+          // TODO(yunqingwang): Combine 2 calls as 1 wide filtering.
+          vp9_mbloop_filter_vertical_edge(s, pitch, lfi0->mblim, lfi0->lim,
+                                          lfi0->hev_thr, 1);
+          vp9_mbloop_filter_vertical_edge(s + 8 *pitch, pitch, lfi1->mblim,
+                                          lfi1->lim, lfi1->hev_thr, 1);
+        } else if (mask_8x8_0 & 1) {
+          vp9_mbloop_filter_vertical_edge(s, pitch, lfi0->mblim, lfi0->lim,
+                                          lfi0->hev_thr, 1);
+        } else {
+          vp9_mbloop_filter_vertical_edge(s + 8 *pitch, pitch, lfi1->mblim,
+                                          lfi1->lim, lfi1->hev_thr, 1);
+        }
+      }
+
+      if ((mask_4x4_0 | mask_4x4_1) & 1) {
+        if ((mask_4x4_0 & mask_4x4_1) & 1) {
+          // TODO(yunqingwang): Combine 2 calls as 1 wide filtering.
+          vp9_loop_filter_vertical_edge(s, pitch, lfi0->mblim, lfi0->lim,
+                                        lfi0->hev_thr, 1);
+          vp9_loop_filter_vertical_edge(s + 8 *pitch, pitch, lfi1->mblim,
+                                        lfi1->lim, lfi1->hev_thr, 1);
+        } else if (mask_4x4_0 & 1) {
+          vp9_loop_filter_vertical_edge(s, pitch, lfi0->mblim, lfi0->lim,
+                                        lfi0->hev_thr, 1);
+        } else {
+          vp9_loop_filter_vertical_edge(s + 8 *pitch, pitch, lfi1->mblim,
+                                        lfi1->lim, lfi1->hev_thr, 1);
+        }
+      }
+
+      if ((mask_4x4_int_0 | mask_4x4_int_1) & 1) {
+        if ((mask_4x4_int_0 & mask_4x4_int_1) & 1) {
+          // TODO(yunqingwang): Combine 2 calls as 1 wide filtering.
+          vp9_loop_filter_vertical_edge(s + 4, pitch, lfi0->mblim, lfi0->lim,
+                                        lfi0->hev_thr, 1);
+          vp9_loop_filter_vertical_edge(s + 8 *pitch + 4, pitch, lfi1->mblim,
+                                        lfi1->lim, lfi1->hev_thr, 1);
+        } else if (mask_4x4_int_0 & 1) {
+          vp9_loop_filter_vertical_edge(s + 4, pitch, lfi0->mblim, lfi0->lim,
+                                        lfi0->hev_thr, 1);
+        } else {
+          vp9_loop_filter_vertical_edge(s + 8 *pitch + 4, pitch, lfi1->mblim,
+                                        lfi1->lim, lfi1->hev_thr, 1);
+        }
       }
     }
-    if (mask_4x4_int & 1)
-      vp9_loop_filter_vertical_edge(s + 4, pitch, lfi->mblim, lfi->lim,
-                                    lfi->hev_thr, 1);
+
     s += 8;
     lfl += 1;
-    mask_16x16 >>= 1;
-    mask_8x8 >>= 1;
-    mask_4x4 >>= 1;
-    mask_4x4_int >>= 1;
+    mask_16x16_0 >>= 1;
+    mask_8x8_0 >>= 1;
+    mask_4x4_0 >>= 1;
+    mask_4x4_int_0 >>= 1;
+    mask_16x16_1 >>= 1;
+    mask_8x8_1 >>= 1;
+    mask_4x4_1 >>= 1;
+    mask_4x4_int_1 >>= 1;
   }
 }
 
@@ -863,6 +934,43 @@
   return filter_level;
 }
 
+static void filter_selectively_vert(uint8_t *s, int pitch,
+                                    unsigned int mask_16x16,
+                                    unsigned int mask_8x8,
+                                    unsigned int mask_4x4,
+                                    unsigned int mask_4x4_int,
+                                    const loop_filter_info_n *lfi_n,
+                                    const uint8_t *lfl) {
+  unsigned int mask;
+
+  for (mask = mask_16x16 | mask_8x8 | mask_4x4 | mask_4x4_int;
+       mask; mask >>= 1) {
+    const loop_filter_thresh *lfi = lfi_n->lfthr + *lfl;
+
+    if (mask & 1) {
+      if (mask_16x16 & 1) {
+        vp9_mb_lpf_vertical_edge_w(s, pitch, lfi->mblim, lfi->lim,
+                                   lfi->hev_thr);
+      } else if (mask_8x8 & 1) {
+        vp9_mbloop_filter_vertical_edge(s, pitch, lfi->mblim, lfi->lim,
+                                        lfi->hev_thr, 1);
+      } else if (mask_4x4 & 1) {
+        vp9_loop_filter_vertical_edge(s, pitch, lfi->mblim, lfi->lim,
+                                      lfi->hev_thr, 1);
+      }
+    }
+    if (mask_4x4_int & 1)
+      vp9_loop_filter_vertical_edge(s + 4, pitch, lfi->mblim, lfi->lim,
+                                    lfi->hev_thr, 1);
+    s += 8;
+    lfl += 1;
+    mask_16x16 >>= 1;
+    mask_8x8 >>= 1;
+    mask_4x4 >>= 1;
+    mask_4x4_int >>= 1;
+  }
+}
+
 static void filter_block_plane_non420(VP9_COMMON *cm,
                                       struct macroblockd_plane *plane,
                                       MODE_INFO **mi_8x8,
@@ -1008,7 +1116,6 @@
                                LOOP_FILTER_MASK *lfm) {
   struct buf_2d *const dst = &plane->dst;
   uint8_t* const dst0 = dst->buf;
-  unsigned int mask_4x4_int_row[MI_BLOCK_SIZE] = {0};
   int r, c;
 
   if (!plane->plane_type) {
@@ -1017,23 +1124,27 @@
     uint64_t mask_4x4 = lfm->left_y[TX_4X4];
     uint64_t mask_4x4_int = lfm->int_4x4_y;
 
-    // Vertical pass
-    for (r = 0; r < MI_BLOCK_SIZE && mi_row + r < cm->mi_rows; r++) {
-      mask_4x4_int_row[r] = mask_4x4_int & 0xff;
+    // Vertical pass: do 2 rows at one time
+    for (r = 0; r < MI_BLOCK_SIZE && mi_row + r < cm->mi_rows; r += 2) {
+      unsigned int mask_16x16_l = mask_16x16 & 0xffff;
+      unsigned int mask_8x8_l = mask_8x8 & 0xffff;
+      unsigned int mask_4x4_l = mask_4x4 & 0xffff;
+      unsigned int mask_4x4_int_l = mask_4x4_int & 0xffff;
 
       // Disable filtering on the leftmost column
-      filter_selectively_vert(dst->buf, dst->stride,
-                              mask_16x16 & 0xff,
-                              mask_8x8 & 0xff,
-                              mask_4x4 & 0xff,
-                              mask_4x4_int_row[r],
-                              &cm->lf_info, &lfm->lfl_y[r << 3]);
+      filter_selectively_vert_row2(plane->plane_type,
+                                   dst->buf, dst->stride,
+                                   mask_16x16_l,
+                                   mask_8x8_l,
+                                   mask_4x4_l,
+                                   mask_4x4_int_l,
+                                   &cm->lf_info, &lfm->lfl_y[r << 3]);
 
-      dst->buf += 8 * dst->stride;
-      mask_16x16 >>= 8;
-      mask_8x8 >>= 8;
-      mask_4x4 >>= 8;
-      mask_4x4_int >>= 8;
+      dst->buf += 16 * dst->stride;
+      mask_16x16 >>= 16;
+      mask_8x8 >>= 16;
+      mask_4x4 >>= 16;
+      mask_4x4_int >>= 16;
     }
 
     // Horizontal pass
@@ -1041,6 +1152,7 @@
     mask_16x16 = lfm->above_y[TX_16X16];
     mask_8x8 = lfm->above_y[TX_8X8];
     mask_4x4 = lfm->above_y[TX_4X4];
+    mask_4x4_int = lfm->int_4x4_y;
 
     for (r = 0; r < MI_BLOCK_SIZE && mi_row + r < cm->mi_rows; r++) {
       unsigned int mask_16x16_r;
@@ -1061,13 +1173,14 @@
                                mask_16x16_r,
                                mask_8x8_r,
                                mask_4x4_r,
-                               mask_4x4_int_row[r],
+                               mask_4x4_int & 0xff,
                                &cm->lf_info, &lfm->lfl_y[r << 3]);
 
       dst->buf += 8 * dst->stride;
       mask_16x16 >>= 8;
       mask_8x8 >>= 8;
       mask_4x4 >>= 8;
+      mask_4x4_int >>= 8;
     }
   } else {
     uint16_t mask_16x16 = lfm->left_uv[TX_16X16];
@@ -1075,27 +1188,37 @@
     uint16_t mask_4x4 = lfm->left_uv[TX_4X4];
     uint16_t mask_4x4_int = lfm->int_4x4_uv;
 
-    // Vertical pass
-    for (r = 0; r < MI_BLOCK_SIZE && mi_row + r < cm->mi_rows; r += 2) {
+    // Vertical pass: do 2 rows at one time
+    for (r = 0; r < MI_BLOCK_SIZE && mi_row + r < cm->mi_rows; r += 4) {
       if (plane->plane_type == 1) {
-        for (c = 0; c < (MI_BLOCK_SIZE >> 1); c++)
+        for (c = 0; c < (MI_BLOCK_SIZE >> 1); c++) {
           lfm->lfl_uv[(r << 1) + c] = lfm->lfl_y[(r << 3) + (c << 1)];
+          lfm->lfl_uv[((r + 2) << 1) + c] = lfm->lfl_y[((r + 2) << 3) +
+                                                       (c << 1)];
+        }
       }
 
-      mask_4x4_int_row[r] = mask_4x4_int & 0xf;
-      // Disable filtering on the leftmost column
-      filter_selectively_vert(dst->buf, dst->stride,
-                              mask_16x16 & 0xf,
-                              mask_8x8 & 0xf,
-                              mask_4x4 & 0xf,
-                              mask_4x4_int_row[r],
-                              &cm->lf_info, &lfm->lfl_uv[r << 1]);
+      {
+        unsigned int mask_16x16_l = mask_16x16 & 0xff;
+        unsigned int mask_8x8_l = mask_8x8 & 0xff;
+        unsigned int mask_4x4_l = mask_4x4 & 0xff;
+        unsigned int mask_4x4_int_l = mask_4x4_int & 0xff;
 
-      dst->buf += 8 * dst->stride;
-      mask_16x16 >>= 4;
-      mask_8x8 >>= 4;
-      mask_4x4 >>= 4;
-      mask_4x4_int >>= 4;
+        // Disable filtering on the leftmost column
+        filter_selectively_vert_row2(plane->plane_type,
+                                     dst->buf, dst->stride,
+                                     mask_16x16_l,
+                                     mask_8x8_l,
+                                     mask_4x4_l,
+                                     mask_4x4_int_l,
+                                     &cm->lf_info, &lfm->lfl_uv[r << 1]);
+
+        dst->buf += 16 * dst->stride;
+        mask_16x16 >>= 8;
+        mask_8x8 >>= 8;
+        mask_4x4 >>= 8;
+        mask_4x4_int >>= 8;
+      }
     }
 
     // Horizontal pass
@@ -1103,11 +1226,12 @@
     mask_16x16 = lfm->above_uv[TX_16X16];
     mask_8x8 = lfm->above_uv[TX_8X8];
     mask_4x4 = lfm->above_uv[TX_4X4];
+    mask_4x4_int = lfm->int_4x4_uv;
 
     for (r = 0; r < MI_BLOCK_SIZE && mi_row + r < cm->mi_rows; r += 2) {
       const int skip_border_4x4_r = mi_row + r == cm->mi_rows - 1;
       const unsigned int mask_4x4_int_r = skip_border_4x4_r ?
-          0 : (mask_4x4_int_row[r]);
+          0 : (mask_4x4_int & 0xf);
       unsigned int mask_16x16_r;
       unsigned int mask_8x8_r;
       unsigned int mask_4x4_r;
@@ -1133,6 +1257,7 @@
       mask_16x16 >>= 4;
       mask_8x8 >>= 4;
       mask_4x4 >>= 4;
+      mask_4x4_int >>= 4;
     }
   }
 }
diff --git a/vp9/common/vp9_onyx.h b/vp9/common/vp9_onyx.h
index 452dd6b..cda68a2 100644
--- a/vp9/common/vp9_onyx.h
+++ b/vp9/common/vp9_onyx.h
@@ -64,6 +64,12 @@
     FRAMEFLAGS_ALTREF = 4,
   } FRAMETYPE_FLAGS;
 
+  typedef enum {
+    NO_AQ = 0,
+    VARIANCE_AQ = 1,
+    AQ_MODES_COUNT  // This should always be the last member of the enum
+  } AQ_MODES;
+
   typedef struct {
     int version;  // 4 versions of bitstream defined:
                   //   0 - best quality/slowest decode,
@@ -128,6 +134,7 @@
     int best_allowed_q;
     int cq_level;
     int lossless;
+    int aq_mode;  // Adaptive Quantization mode
 
     // two pass datarate control
     int two_pass_vbrbias;        // two pass datarate control tweaks
diff --git a/vp9/common/vp9_reconinter.c b/vp9/common/vp9_reconinter.c
index 3add81b..aa17b85 100644
--- a/vp9/common/vp9_reconinter.c
+++ b/vp9/common/vp9_reconinter.c
@@ -106,9 +106,10 @@
                                    BLOCK_SIZE bsize, int pred_w, int pred_h,
                                    int mi_x, int mi_y) {
   struct macroblockd_plane *const pd = &xd->plane[plane];
-  const int bwl = b_width_log2(bsize) - pd->subsampling_x;
+  const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
+  const int bwl = b_width_log2(plane_bsize);
   const int bw = 4 << bwl;
-  const int bh = plane_block_height(bsize, pd);
+  const int bh = 4 * num_4x4_blocks_high_lookup[plane_bsize];
   const int x = 4 * (block & ((1 << bwl) - 1));
   const int y = 4 * (block >> bwl);
   const MODE_INFO *mi = xd->mi_8x8[0];
diff --git a/vp9/common/x86/vp9_subpixel_8t_ssse3.asm b/vp9/common/x86/vp9_subpixel_8t_ssse3.asm
index dbc17ec..634fa77 100644
--- a/vp9/common/x86/vp9_subpixel_8t_ssse3.asm
+++ b/vp9/common/x86/vp9_subpixel_8t_ssse3.asm
@@ -158,10 +158,13 @@
     pmaddubsw   xmm6, k6k7
 
     paddsw      xmm0, xmm6
-    paddsw      xmm0, xmm2
+    movdqa      xmm1, xmm2
+    pmaxsw      xmm2, xmm4
+    pminsw      xmm4, xmm1
     paddsw      xmm0, xmm4
-    paddsw      xmm0, krd
+    paddsw      xmm0, xmm2
 
+    paddsw      xmm0, krd
     psraw       xmm0, 7
     packuswb    xmm0, xmm0
 
@@ -243,10 +246,13 @@
     pmaddubsw   xmm6, k6k7
 
     paddsw      xmm0, xmm6
-    paddsw      xmm0, xmm2
+    movdqa      xmm1, xmm2
+    pmaxsw      xmm2, xmm4
+    pminsw      xmm4, xmm1
     paddsw      xmm0, xmm4
-    paddsw      xmm0, krd
+    paddsw      xmm0, xmm2
 
+    paddsw      xmm0, krd
     psraw       xmm0, 7
     packuswb    xmm0, xmm0
 %if %1
@@ -635,9 +641,13 @@
     pmaddubsw   %3,   k4k5
     pmaddubsw   %4,   k6k7
 
-    paddsw      %1,   %2
     paddsw      %1,   %4
+    movdqa      %4,   %2
+    pmaxsw      %2,   %3
+    pminsw      %3,   %4
     paddsw      %1,   %3
+    paddsw      %1,   %2
+
     paddsw      %1,   krd
     psraw       %1,   7
     packuswb    %1,   %1
@@ -783,12 +793,19 @@
     pmaddubsw   xmm6,   k4k5
     pmaddubsw   xmm7,   k6k7
 
-    paddsw      xmm0,   xmm1
     paddsw      xmm0,   xmm3
+    movdqa      xmm3,   xmm1
+    pmaxsw      xmm1,   xmm2
+    pminsw      xmm2,   xmm3
     paddsw      xmm0,   xmm2
-    paddsw      xmm4,   xmm5
+    paddsw      xmm0,   xmm1
+
     paddsw      xmm4,   xmm7
+    movdqa      xmm7,   xmm5
+    pmaxsw      xmm5,   xmm6
+    pminsw      xmm6,   xmm7
     paddsw      xmm4,   xmm6
+    paddsw      xmm4,   xmm5
 
     paddsw      xmm0,   krd
     paddsw      xmm4,   krd
@@ -839,6 +856,7 @@
     HORIZx4 0
 
     add rsp, 16 * 3
+    pop rsp
     ; begin epilog
     pop rdi
     pop rsi
@@ -952,6 +970,7 @@
     HORIZx4 1
 
     add rsp, 16 * 3
+    pop rsp
     ; begin epilog
     pop rdi
     pop rsi
diff --git a/vp9/decoder/vp9_decodeframe.c b/vp9/decoder/vp9_decodeframe.c
index dbcae76..916cb42 100644
--- a/vp9/decoder/vp9_decodeframe.c
+++ b/vp9/decoder/vp9_decodeframe.c
@@ -159,7 +159,7 @@
   int i;
   for (i = 0; i < n; ++i)
     if (vp9_read(r, NMV_UPDATE_PROB))
-       p[i] = (vp9_read_literal(r, 7) << 1) | 1;
+      p[i] = (vp9_read_literal(r, 7) << 1) | 1;
 }
 
 static void read_mv_probs(nmv_context *ctx, int allow_hp, vp9_reader *r) {
@@ -178,7 +178,7 @@
   for (i = 0; i < 2; ++i) {
     nmv_component *const comp_ctx = &ctx->comps[i];
     for (j = 0; j < CLASS0_SIZE; ++j)
-      update_mv_probs(comp_ctx->class0_fp[j], 3, r);
+      update_mv_probs(comp_ctx->class0_fp[j], MV_FP_SIZE - 1, r);
     update_mv_probs(comp_ctx->fp, 3, r);
   }
 
@@ -241,7 +241,8 @@
 }
 
 static void inverse_transform_block(MACROBLOCKD* xd, int plane, int block,
-                                    TX_SIZE tx_size, uint8_t *dst, int stride) {
+                                    TX_SIZE tx_size, uint8_t *dst, int stride,
+                                    uint8_t *token_cache) {
   struct macroblockd_plane *const pd = &xd->plane[plane];
   const int eob = pd->eobs[block];
   if (eob > 0) {
@@ -274,13 +275,20 @@
 
     if (eob == 1) {
       vpx_memset(dqcoeff, 0, 2 * sizeof(dqcoeff[0]));
+      vpx_memset(token_cache, 0, 2 * sizeof(token_cache[0]));
     } else {
-      if (tx_type == DCT_DCT && tx_size <= TX_16X16 && eob <= 10)
+      if (tx_type == DCT_DCT && tx_size <= TX_16X16 && eob <= 10) {
         vpx_memset(dqcoeff, 0, 4 * (4 << tx_size) * sizeof(dqcoeff[0]));
-      else if (tx_size == TX_32X32 && eob <= 34)
+        vpx_memset(token_cache, 0,
+                   4 * (4 << tx_size) * sizeof(token_cache[0]));
+      } else if (tx_size == TX_32X32 && eob <= 34) {
         vpx_memset(dqcoeff, 0, 256 * sizeof(dqcoeff[0]));
-      else
+        vpx_memset(token_cache, 0, 256 * sizeof(token_cache[0]));
+      } else {
         vpx_memset(dqcoeff, 0, (16 << (tx_size << 1)) * sizeof(dqcoeff[0]));
+        vpx_memset(token_cache, 0,
+                   (16 << (tx_size << 1)) * sizeof(token_cache[0]));
+      }
     }
   }
 }
@@ -310,7 +318,7 @@
   dst = &pd->dst.buf[4 * y * pd->dst.stride + 4 * x];
 
   if (xd->mb_to_right_edge < 0 || xd->mb_to_bottom_edge < 0)
-    extend_for_intra(xd, plane_bsize, plane, block, tx_size);
+    extend_for_intra(xd, plane_bsize, plane, x, y);
 
   vp9_predict_intra_block(xd, block >> (tx_size << 1),
                           b_width_log2(plane_bsize), tx_size, mode,
@@ -319,7 +327,8 @@
   if (!mi->mbmi.skip_coeff) {
     vp9_decode_block_tokens(cm, xd, plane, block, plane_bsize, x, y, tx_size,
                             args->r, args->token_cache);
-    inverse_transform_block(xd, plane, block, tx_size, dst, pd->dst.stride);
+    inverse_transform_block(xd, plane, block, tx_size, dst, pd->dst.stride,
+                            args->token_cache);
   }
 }
 
@@ -345,7 +354,7 @@
                                              args->r, args->token_cache);
   inverse_transform_block(xd, plane, block, tx_size,
                           &pd->dst.buf[4 * y * pd->dst.stride + 4 * x],
-                          pd->dst.stride);
+                          pd->dst.stride, args->token_cache);
 }
 
 static void set_offsets(VP9_COMMON *const cm, MACROBLOCKD *const xd,
@@ -946,6 +955,7 @@
     pd[i].dqcoeff = tile_data->dqcoeff[i];
     pd[i].eobs    = tile_data->eobs[i];
     vpx_memset(xd->plane[i].dqcoeff, 0, 64 * 64 * sizeof(int16_t));
+    vpx_memset(tile_data->token_cache, 0, sizeof(tile_data->token_cache));
   }
 }
 
diff --git a/vp9/decoder/vp9_detokenize.c b/vp9/decoder/vp9_detokenize.c
index 75e7e40..f6219c5 100644
--- a/vp9/decoder/vp9_detokenize.c
+++ b/vp9/decoder/vp9_detokenize.c
@@ -81,6 +81,7 @@
     INCREMENT_COUNT(token);                              \
     token_cache[scan[c]] = vp9_pt_energy_class[token];   \
     ++c;                                                 \
+    pt = get_coef_context(nb, token_cache, c);           \
     dqv = dq[1];                                          \
     continue;                                            \
   }
@@ -118,31 +119,24 @@
 
   while (c < seg_eob) {
     int val;
-    if (c)
-      pt = get_coef_context(nb, token_cache, c);
     band = *band_translate++;
     prob = coef_probs[band][pt];
     if (!cm->frame_parallel_decoding_mode)
       ++eob_branch_count[band][pt];
     if (!vp9_read(r, prob[EOB_CONTEXT_NODE]))
       break;
-    goto DECODE_ZERO;
-
-  SKIP_START:
-    if (c >= seg_eob)
-      break;
-    if (c)
-      pt = get_coef_context(nb, token_cache, c);
-    band = *band_translate++;
-    prob = coef_probs[band][pt];
 
   DECODE_ZERO:
     if (!vp9_read(r, prob[ZERO_CONTEXT_NODE])) {
       INCREMENT_COUNT(ZERO_TOKEN);
-      token_cache[scan[c]] = vp9_pt_energy_class[ZERO_TOKEN];
-      dqv = dq[1];                                          \
+      dqv = dq[1];
       ++c;
-      goto SKIP_START;
+      if (c >= seg_eob)
+        break;
+      pt = get_coef_context(nb, token_cache, c);
+      band = *band_translate++;
+      prob = coef_probs[band][pt];
+      goto DECODE_ZERO;
     }
 
     // ONE_CONTEXT_NODE_0_
diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c
index 9bd0123..e8ec61e 100644
--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -239,18 +239,8 @@
     const struct vp9_token *const a = &vp9_coef_encodings[t];
     const vp9_extra_bit *const b = &vp9_extra_bits[t];
     int i = 0;
-    const vp9_prob *pp;
     int v = a->value;
     int n = a->len;
-    vp9_prob probs[ENTROPY_NODES];
-
-    if (t >= TWO_TOKEN) {
-      vp9_model_to_full_probs(p->context_tree, probs);
-      pp = probs;
-    } else {
-      pp = p->context_tree;
-    }
-    assert(pp != 0);
 
     /* skip one or two nodes */
     if (p->skip_eob_node) {
@@ -258,11 +248,24 @@
       i = 2 * p->skip_eob_node;
     }
 
-    do {
-      const int bb = (v >> --n) & 1;
-      vp9_write(w, bb, pp[i >> 1]);
-      i = vp9_coef_tree[i + bb];
-    } while (n);
+    // TODO(jbb): expanding this can lead to big gains.  It allows
+    // much better branch prediction and would enable us to avoid numerous
+    // lookups and compares.
+
+    // If we have a token that's in the constrained set, the coefficient tree
+    // is split into two treed writes.  The first treed write takes care of the
+    // unconstrained nodes.  The second treed write takes care of the
+    // constrained nodes.
+    if (t >= TWO_TOKEN && t < DCT_EOB_TOKEN) {
+      int len = UNCONSTRAINED_NODES - p->skip_eob_node;
+      int bits = v >> (n - len);
+      treed_write(w, vp9_coef_tree, p->context_tree, bits, len, i);
+      treed_write(w, vp9_coef_con_tree,
+                  vp9_pareto8_full[p->context_tree[PIVOT_NODE] - 1], v, n - len,
+                  0);
+    } else {
+      treed_write(w, vp9_coef_tree, p->context_tree, v, n, i);
+    }
 
     if (b->base_val) {
       const int e = p->extra, l = b->len;
@@ -299,7 +302,7 @@
 static void write_segment_id(vp9_writer *w, const struct segmentation *seg,
                              int segment_id) {
   if (seg->enabled && seg->update_map)
-    treed_write(w, vp9_segment_tree, seg->tree_probs, segment_id, 3);
+    treed_write(w, vp9_segment_tree, seg->tree_probs, segment_id, 3, 0);
 }
 
 // This function encodes the reference frame
@@ -674,12 +677,6 @@
   }
 }
 
-static void build_coeff_contexts(VP9_COMP *cpi) {
-  TX_SIZE t;
-  for (t = TX_4X4; t <= TX_32X32; t++)
-    build_tree_distribution(cpi, t);
-}
-
 static void update_coef_probs_common(vp9_writer* const bc, VP9_COMP *cpi,
                                      TX_SIZE tx_size) {
   vp9_coeff_probs_model *new_frame_coef_probs = cpi->frame_coef_probs[tx_size];
@@ -853,25 +850,17 @@
   }
 }
 
-static void update_coef_probs(VP9_COMP* const cpi, vp9_writer* const bc) {
+static void update_coef_probs(VP9_COMP* cpi, vp9_writer* w) {
   const TX_MODE tx_mode = cpi->common.tx_mode;
-
+  const TX_SIZE max_tx_size = tx_mode_to_biggest_tx_size[tx_mode];
+  TX_SIZE tx_size;
   vp9_clear_system_state();
 
-  // Build the cofficient contexts based on counts collected in encode loop
-  build_coeff_contexts(cpi);
+  for (tx_size = TX_4X4; tx_size <= TX_32X32; ++tx_size)
+    build_tree_distribution(cpi, tx_size);
 
-  update_coef_probs_common(bc, cpi, TX_4X4);
-
-  // do not do this if not even allowed
-  if (tx_mode > ONLY_4X4)
-    update_coef_probs_common(bc, cpi, TX_8X8);
-
-  if (tx_mode > ALLOW_8X8)
-    update_coef_probs_common(bc, cpi, TX_16X16);
-
-  if (tx_mode > ALLOW_16X16)
-    update_coef_probs_common(bc, cpi, TX_32X32);
+  for (tx_size = TX_4X4; tx_size <= max_tx_size; ++tx_size)
+    update_coef_probs_common(w, cpi, tx_size);
 }
 
 static void encode_loopfilter(struct loopfilter *lf,
@@ -1446,53 +1435,3 @@
   *size = data - dest;
 }
 
-#ifdef ENTROPY_STATS
-static void print_tree_update_for_type(FILE *f,
-                                       vp9_coeff_stats *tree_update_hist,
-                                       int block_types, const char *header) {
-  int i, j, k, l, m;
-
-  fprintf(f, "const vp9_coeff_prob %s = {\n", header);
-  for (i = 0; i < block_types; i++) {
-    fprintf(f, "  { \n");
-    for (j = 0; j < REF_TYPES; j++) {
-      fprintf(f, "  { \n");
-      for (k = 0; k < COEF_BANDS; k++) {
-        fprintf(f, "    {\n");
-        for (l = 0; l < PREV_COEF_CONTEXTS; l++) {
-          fprintf(f, "      {");
-          for (m = 0; m < ENTROPY_NODES; m++) {
-            fprintf(f, "%3d, ",
-                    get_binary_prob(tree_update_hist[i][j][k][l][m][0],
-                                    tree_update_hist[i][j][k][l][m][1]));
-          }
-          fprintf(f, "},\n");
-        }
-        fprintf(f, "},\n");
-      }
-      fprintf(f, "    },\n");
-    }
-    fprintf(f, "  },\n");
-  }
-  fprintf(f, "};\n");
-}
-
-void print_tree_update_probs() {
-  FILE *f = fopen("coefupdprob.h", "w");
-  fprintf(f, "\n/* Update probabilities for token entropy tree. */\n\n");
-
-  print_tree_update_for_type(f, tree_update_hist[TX_4X4],   BLOCK_TYPES,
-                             "vp9_coef_update_probs_4x4[BLOCK_TYPES]");
-  print_tree_update_for_type(f, tree_update_hist[TX_8X8],   BLOCK_TYPES,
-                             "vp9_coef_update_probs_8x8[BLOCK_TYPES]");
-  print_tree_update_for_type(f, tree_update_hist[TX_16X16], BLOCK_TYPES,
-                             "vp9_coef_update_probs_16x16[BLOCK_TYPES]");
-  print_tree_update_for_type(f, tree_update_hist[TX_32X32], BLOCK_TYPES,
-                             "vp9_coef_update_probs_32x32[BLOCK_TYPES]");
-
-  fclose(f);
-  f = fopen("treeupdate.bin", "wb");
-  fwrite(tree_update_hist, sizeof(tree_update_hist), 1, f);
-  fclose(f);
-}
-#endif
diff --git a/vp9/encoder/vp9_dct.c b/vp9/encoder/vp9_dct.c
index 065992a..0f4a6bb 100644
--- a/vp9/encoder/vp9_dct.c
+++ b/vp9/encoder/vp9_dct.c
@@ -20,6 +20,12 @@
 
 #include "vp9/encoder/vp9_dct.h"
 
+static INLINE int fdct_round_shift(int input) {
+  int rv = ROUND_POWER_OF_TWO(input, DCT_CONST_BITS);
+  assert(INT16_MIN <= rv && rv <= INT16_MAX);
+  return rv;
+}
+
 static void fdct4(const int16_t *input, int16_t *output) {
   int16_t step[4];
   int temp1, temp2;
@@ -31,12 +37,12 @@
 
   temp1 = (step[0] + step[1]) * cospi_16_64;
   temp2 = (step[0] - step[1]) * cospi_16_64;
-  output[0] = dct_const_round_shift(temp1);
-  output[2] = dct_const_round_shift(temp2);
+  output[0] = fdct_round_shift(temp1);
+  output[2] = fdct_round_shift(temp2);
   temp1 = step[2] * cospi_24_64 + step[3] * cospi_8_64;
   temp2 = -step[2] * cospi_8_64 + step[3] * cospi_24_64;
-  output[1] = dct_const_round_shift(temp1);
-  output[3] = dct_const_round_shift(temp2);
+  output[1] = fdct_round_shift(temp1);
+  output[3] = fdct_round_shift(temp2);
 }
 
 void vp9_fdct4x4_c(const int16_t *input, int16_t *output, int stride) {
@@ -80,12 +86,12 @@
       step[3] = input[0] - input[3];
       temp1 = (step[0] + step[1]) * cospi_16_64;
       temp2 = (step[0] - step[1]) * cospi_16_64;
-      out[0] = dct_const_round_shift(temp1);
-      out[2] = dct_const_round_shift(temp2);
+      out[0] = fdct_round_shift(temp1);
+      out[2] = fdct_round_shift(temp2);
       temp1 = step[2] * cospi_24_64 + step[3] * cospi_8_64;
       temp2 = -step[2] * cospi_8_64 + step[3] * cospi_24_64;
-      out[1] = dct_const_round_shift(temp1);
-      out[3] = dct_const_round_shift(temp2);
+      out[1] = fdct_round_shift(temp1);
+      out[3] = fdct_round_shift(temp2);
       // Do next column (which is a transposed row in second/horizontal pass)
       in++;
       out += 4;
@@ -138,10 +144,10 @@
   s3 = x2 - x0 + x3;
 
   // 1-D transform scaling factor is sqrt(2).
-  output[0] = dct_const_round_shift(s0);
-  output[1] = dct_const_round_shift(s1);
-  output[2] = dct_const_round_shift(s2);
-  output[3] = dct_const_round_shift(s3);
+  output[0] = fdct_round_shift(s0);
+  output[1] = fdct_round_shift(s1);
+  output[2] = fdct_round_shift(s2);
+  output[3] = fdct_round_shift(s3);
 }
 
 static const transform_2d FHT_4[] = {
@@ -204,16 +210,16 @@
   t1 = (x0 - x1) * cospi_16_64;
   t2 =  x2 * cospi_24_64 + x3 *  cospi_8_64;
   t3 = -x2 * cospi_8_64  + x3 * cospi_24_64;
-  output[0] = dct_const_round_shift(t0);
-  output[2] = dct_const_round_shift(t2);
-  output[4] = dct_const_round_shift(t1);
-  output[6] = dct_const_round_shift(t3);
+  output[0] = fdct_round_shift(t0);
+  output[2] = fdct_round_shift(t2);
+  output[4] = fdct_round_shift(t1);
+  output[6] = fdct_round_shift(t3);
 
   // Stage 2
   t0 = (s6 - s5) * cospi_16_64;
   t1 = (s6 + s5) * cospi_16_64;
-  t2 = dct_const_round_shift(t0);
-  t3 = dct_const_round_shift(t1);
+  t2 = fdct_round_shift(t0);
+  t3 = fdct_round_shift(t1);
 
   // Stage 3
   x0 = s4 + t2;
@@ -226,10 +232,10 @@
   t1 = x1 * cospi_12_64 + x2 *  cospi_20_64;
   t2 = x2 * cospi_12_64 + x1 * -cospi_20_64;
   t3 = x3 * cospi_28_64 + x0 *  -cospi_4_64;
-  output[1] = dct_const_round_shift(t0);
-  output[3] = dct_const_round_shift(t2);
-  output[5] = dct_const_round_shift(t1);
-  output[7] = dct_const_round_shift(t3);
+  output[1] = fdct_round_shift(t0);
+  output[3] = fdct_round_shift(t2);
+  output[5] = fdct_round_shift(t1);
+  output[7] = fdct_round_shift(t3);
 }
 
 void vp9_fdct8x8_c(const int16_t *input, int16_t *final_output, int stride) {
@@ -264,16 +270,16 @@
       t1 = (x0 - x1) * cospi_16_64;
       t2 =  x2 * cospi_24_64 + x3 *  cospi_8_64;
       t3 = -x2 * cospi_8_64  + x3 * cospi_24_64;
-      output[0 * 8] = dct_const_round_shift(t0);
-      output[2 * 8] = dct_const_round_shift(t2);
-      output[4 * 8] = dct_const_round_shift(t1);
-      output[6 * 8] = dct_const_round_shift(t3);
+      output[0 * 8] = fdct_round_shift(t0);
+      output[2 * 8] = fdct_round_shift(t2);
+      output[4 * 8] = fdct_round_shift(t1);
+      output[6 * 8] = fdct_round_shift(t3);
 
       // Stage 2
       t0 = (s6 - s5) * cospi_16_64;
       t1 = (s6 + s5) * cospi_16_64;
-      t2 = dct_const_round_shift(t0);
-      t3 = dct_const_round_shift(t1);
+      t2 = fdct_round_shift(t0);
+      t3 = fdct_round_shift(t1);
 
       // Stage 3
       x0 = s4 + t2;
@@ -286,10 +292,10 @@
       t1 = x1 * cospi_12_64 + x2 *  cospi_20_64;
       t2 = x2 * cospi_12_64 + x1 * -cospi_20_64;
       t3 = x3 * cospi_28_64 + x0 *  -cospi_4_64;
-      output[1 * 8] = dct_const_round_shift(t0);
-      output[3 * 8] = dct_const_round_shift(t2);
-      output[5 * 8] = dct_const_round_shift(t1);
-      output[7 * 8] = dct_const_round_shift(t3);
+      output[1 * 8] = fdct_round_shift(t0);
+      output[3 * 8] = fdct_round_shift(t2);
+      output[5 * 8] = fdct_round_shift(t1);
+      output[7 * 8] = fdct_round_shift(t3);
       input++;
       output++;
     }
@@ -388,16 +394,16 @@
         t1 = (x0 - x1) * cospi_16_64;
         t2 = x3 * cospi_8_64  + x2 * cospi_24_64;
         t3 = x3 * cospi_24_64 - x2 * cospi_8_64;
-        out[0] = dct_const_round_shift(t0);
-        out[4] = dct_const_round_shift(t2);
-        out[8] = dct_const_round_shift(t1);
-        out[12] = dct_const_round_shift(t3);
+        out[0] = fdct_round_shift(t0);
+        out[4] = fdct_round_shift(t2);
+        out[8] = fdct_round_shift(t1);
+        out[12] = fdct_round_shift(t3);
 
         // Stage 2
         t0 = (s6 - s5) * cospi_16_64;
         t1 = (s6 + s5) * cospi_16_64;
-        t2 = dct_const_round_shift(t0);
-        t3 = dct_const_round_shift(t1);
+        t2 = fdct_round_shift(t0);
+        t3 = fdct_round_shift(t1);
 
         // Stage 3
         x0 = s4 + t2;
@@ -410,22 +416,22 @@
         t1 = x1 * cospi_12_64 + x2 *  cospi_20_64;
         t2 = x2 * cospi_12_64 + x1 * -cospi_20_64;
         t3 = x3 * cospi_28_64 + x0 *  -cospi_4_64;
-        out[2] = dct_const_round_shift(t0);
-        out[6] = dct_const_round_shift(t2);
-        out[10] = dct_const_round_shift(t1);
-        out[14] = dct_const_round_shift(t3);
+        out[2] = fdct_round_shift(t0);
+        out[6] = fdct_round_shift(t2);
+        out[10] = fdct_round_shift(t1);
+        out[14] = fdct_round_shift(t3);
       }
       // Work on the next eight values; step1 -> odd_results
       {
         // step 2
         temp1 = (step1[5] - step1[2]) * cospi_16_64;
         temp2 = (step1[4] - step1[3]) * cospi_16_64;
-        step2[2] = dct_const_round_shift(temp1);
-        step2[3] = dct_const_round_shift(temp2);
+        step2[2] = fdct_round_shift(temp1);
+        step2[3] = fdct_round_shift(temp2);
         temp1 = (step1[4] + step1[3]) * cospi_16_64;
         temp2 = (step1[5] + step1[2]) * cospi_16_64;
-        step2[4] = dct_const_round_shift(temp1);
-        step2[5] = dct_const_round_shift(temp2);
+        step2[4] = fdct_round_shift(temp1);
+        step2[5] = fdct_round_shift(temp2);
         // step 3
         step3[0] = step1[0] + step2[3];
         step3[1] = step1[1] + step2[2];
@@ -438,12 +444,12 @@
         // step 4
         temp1 = step3[1] *  -cospi_8_64 + step3[6] * cospi_24_64;
         temp2 = step3[2] * -cospi_24_64 - step3[5] *  cospi_8_64;
-        step2[1] = dct_const_round_shift(temp1);
-        step2[2] = dct_const_round_shift(temp2);
+        step2[1] = fdct_round_shift(temp1);
+        step2[2] = fdct_round_shift(temp2);
         temp1 = step3[2] * -cospi_8_64 + step3[5] * cospi_24_64;
         temp2 = step3[1] * cospi_24_64 + step3[6] *  cospi_8_64;
-        step2[5] = dct_const_round_shift(temp1);
-        step2[6] = dct_const_round_shift(temp2);
+        step2[5] = fdct_round_shift(temp1);
+        step2[6] = fdct_round_shift(temp2);
         // step 5
         step1[0] = step3[0] + step2[1];
         step1[1] = step3[0] - step2[1];
@@ -456,20 +462,20 @@
         // step 6
         temp1 = step1[0] * cospi_30_64 + step1[7] *  cospi_2_64;
         temp2 = step1[1] * cospi_14_64 + step1[6] * cospi_18_64;
-        out[1] = dct_const_round_shift(temp1);
-        out[9] = dct_const_round_shift(temp2);
+        out[1] = fdct_round_shift(temp1);
+        out[9] = fdct_round_shift(temp2);
         temp1 = step1[2] * cospi_22_64 + step1[5] * cospi_10_64;
         temp2 = step1[3] *  cospi_6_64 + step1[4] * cospi_26_64;
-        out[5] = dct_const_round_shift(temp1);
-        out[13] = dct_const_round_shift(temp2);
+        out[5] = fdct_round_shift(temp1);
+        out[13] = fdct_round_shift(temp2);
         temp1 = step1[3] * -cospi_26_64 + step1[4] *  cospi_6_64;
         temp2 = step1[2] * -cospi_10_64 + step1[5] * cospi_22_64;
-        out[3] = dct_const_round_shift(temp1);
-        out[11] = dct_const_round_shift(temp2);
+        out[3] = fdct_round_shift(temp1);
+        out[11] = fdct_round_shift(temp2);
         temp1 = step1[1] * -cospi_18_64 + step1[6] * cospi_14_64;
         temp2 = step1[0] *  -cospi_2_64 + step1[7] * cospi_30_64;
-        out[7] = dct_const_round_shift(temp1);
-        out[15] = dct_const_round_shift(temp2);
+        out[7] = fdct_round_shift(temp1);
+        out[15] = fdct_round_shift(temp2);
       }
       // Do next column (which is a transposed row in second/horizontal pass)
       in++;
@@ -503,14 +509,14 @@
   s6 = cospi_26_64 * x6 + cospi_6_64  * x7;
   s7 = cospi_6_64  * x6 - cospi_26_64 * x7;
 
-  x0 = dct_const_round_shift(s0 + s4);
-  x1 = dct_const_round_shift(s1 + s5);
-  x2 = dct_const_round_shift(s2 + s6);
-  x3 = dct_const_round_shift(s3 + s7);
-  x4 = dct_const_round_shift(s0 - s4);
-  x5 = dct_const_round_shift(s1 - s5);
-  x6 = dct_const_round_shift(s2 - s6);
-  x7 = dct_const_round_shift(s3 - s7);
+  x0 = fdct_round_shift(s0 + s4);
+  x1 = fdct_round_shift(s1 + s5);
+  x2 = fdct_round_shift(s2 + s6);
+  x3 = fdct_round_shift(s3 + s7);
+  x4 = fdct_round_shift(s0 - s4);
+  x5 = fdct_round_shift(s1 - s5);
+  x6 = fdct_round_shift(s2 - s6);
+  x7 = fdct_round_shift(s3 - s7);
 
   // stage 2
   s0 = x0;
@@ -526,10 +532,10 @@
   x1 = s1 + s3;
   x2 = s0 - s2;
   x3 = s1 - s3;
-  x4 = dct_const_round_shift(s4 + s6);
-  x5 = dct_const_round_shift(s5 + s7);
-  x6 = dct_const_round_shift(s4 - s6);
-  x7 = dct_const_round_shift(s5 - s7);
+  x4 = fdct_round_shift(s4 + s6);
+  x5 = fdct_round_shift(s5 + s7);
+  x6 = fdct_round_shift(s4 - s6);
+  x7 = fdct_round_shift(s5 - s7);
 
   // stage 3
   s2 = cospi_16_64 * (x2 + x3);
@@ -537,10 +543,10 @@
   s6 = cospi_16_64 * (x6 + x7);
   s7 = cospi_16_64 * (x6 - x7);
 
-  x2 = dct_const_round_shift(s2);
-  x3 = dct_const_round_shift(s3);
-  x6 = dct_const_round_shift(s6);
-  x7 = dct_const_round_shift(s7);
+  x2 = fdct_round_shift(s2);
+  x3 = fdct_round_shift(s3);
+  x6 = fdct_round_shift(s6);
+  x7 = fdct_round_shift(s7);
 
   output[0] =   x0;
   output[1] = - x4;
@@ -693,16 +699,16 @@
     t1 = (x0 - x1) * cospi_16_64;
     t2 = x3 * cospi_8_64  + x2 * cospi_24_64;
     t3 = x3 * cospi_24_64 - x2 * cospi_8_64;
-    out[0] = dct_const_round_shift(t0);
-    out[4] = dct_const_round_shift(t2);
-    out[8] = dct_const_round_shift(t1);
-    out[12] = dct_const_round_shift(t3);
+    out[0] = fdct_round_shift(t0);
+    out[4] = fdct_round_shift(t2);
+    out[8] = fdct_round_shift(t1);
+    out[12] = fdct_round_shift(t3);
 
     // Stage 2
     t0 = (s6 - s5) * cospi_16_64;
     t1 = (s6 + s5) * cospi_16_64;
-    t2 = dct_const_round_shift(t0);
-    t3 = dct_const_round_shift(t1);
+    t2 = fdct_round_shift(t0);
+    t3 = fdct_round_shift(t1);
 
     // Stage 3
     x0 = s4 + t2;
@@ -715,21 +721,21 @@
     t1 = x1 * cospi_12_64 + x2 *  cospi_20_64;
     t2 = x2 * cospi_12_64 + x1 * -cospi_20_64;
     t3 = x3 * cospi_28_64 + x0 *  -cospi_4_64;
-    out[2] = dct_const_round_shift(t0);
-    out[6] = dct_const_round_shift(t2);
-    out[10] = dct_const_round_shift(t1);
-    out[14] = dct_const_round_shift(t3);
+    out[2] = fdct_round_shift(t0);
+    out[6] = fdct_round_shift(t2);
+    out[10] = fdct_round_shift(t1);
+    out[14] = fdct_round_shift(t3);
   }
 
   // step 2
   temp1 = (step1[5] - step1[2]) * cospi_16_64;
   temp2 = (step1[4] - step1[3]) * cospi_16_64;
-  step2[2] = dct_const_round_shift(temp1);
-  step2[3] = dct_const_round_shift(temp2);
+  step2[2] = fdct_round_shift(temp1);
+  step2[3] = fdct_round_shift(temp2);
   temp1 = (step1[4] + step1[3]) * cospi_16_64;
   temp2 = (step1[5] + step1[2]) * cospi_16_64;
-  step2[4] = dct_const_round_shift(temp1);
-  step2[5] = dct_const_round_shift(temp2);
+  step2[4] = fdct_round_shift(temp1);
+  step2[5] = fdct_round_shift(temp2);
 
   // step 3
   step3[0] = step1[0] + step2[3];
@@ -744,12 +750,12 @@
   // step 4
   temp1 = step3[1] *  -cospi_8_64 + step3[6] * cospi_24_64;
   temp2 = step3[2] * -cospi_24_64 - step3[5] *  cospi_8_64;
-  step2[1] = dct_const_round_shift(temp1);
-  step2[2] = dct_const_round_shift(temp2);
+  step2[1] = fdct_round_shift(temp1);
+  step2[2] = fdct_round_shift(temp2);
   temp1 = step3[2] * -cospi_8_64 + step3[5] * cospi_24_64;
   temp2 = step3[1] * cospi_24_64 + step3[6] *  cospi_8_64;
-  step2[5] = dct_const_round_shift(temp1);
-  step2[6] = dct_const_round_shift(temp2);
+  step2[5] = fdct_round_shift(temp1);
+  step2[6] = fdct_round_shift(temp2);
 
   // step 5
   step1[0] = step3[0] + step2[1];
@@ -764,23 +770,23 @@
   // step 6
   temp1 = step1[0] * cospi_30_64 + step1[7] *  cospi_2_64;
   temp2 = step1[1] * cospi_14_64 + step1[6] * cospi_18_64;
-  out[1] = dct_const_round_shift(temp1);
-  out[9] = dct_const_round_shift(temp2);
+  out[1] = fdct_round_shift(temp1);
+  out[9] = fdct_round_shift(temp2);
 
   temp1 = step1[2] * cospi_22_64 + step1[5] * cospi_10_64;
   temp2 = step1[3] *  cospi_6_64 + step1[4] * cospi_26_64;
-  out[5] = dct_const_round_shift(temp1);
-  out[13] = dct_const_round_shift(temp2);
+  out[5] = fdct_round_shift(temp1);
+  out[13] = fdct_round_shift(temp2);
 
   temp1 = step1[3] * -cospi_26_64 + step1[4] *  cospi_6_64;
   temp2 = step1[2] * -cospi_10_64 + step1[5] * cospi_22_64;
-  out[3] = dct_const_round_shift(temp1);
-  out[11] = dct_const_round_shift(temp2);
+  out[3] = fdct_round_shift(temp1);
+  out[11] = fdct_round_shift(temp2);
 
   temp1 = step1[1] * -cospi_18_64 + step1[6] * cospi_14_64;
   temp2 = step1[0] *  -cospi_2_64 + step1[7] * cospi_30_64;
-  out[7] = dct_const_round_shift(temp1);
-  out[15] = dct_const_round_shift(temp2);
+  out[7] = fdct_round_shift(temp1);
+  out[15] = fdct_round_shift(temp2);
 }
 
 static void fadst16(const int16_t *input, int16_t *output) {
@@ -821,22 +827,22 @@
   s14 = x14 * cospi_29_64 + x15 * cospi_3_64;
   s15 = x14 * cospi_3_64  - x15 * cospi_29_64;
 
-  x0 = dct_const_round_shift(s0 + s8);
-  x1 = dct_const_round_shift(s1 + s9);
-  x2 = dct_const_round_shift(s2 + s10);
-  x3 = dct_const_round_shift(s3 + s11);
-  x4 = dct_const_round_shift(s4 + s12);
-  x5 = dct_const_round_shift(s5 + s13);
-  x6 = dct_const_round_shift(s6 + s14);
-  x7 = dct_const_round_shift(s7 + s15);
-  x8  = dct_const_round_shift(s0 - s8);
-  x9  = dct_const_round_shift(s1 - s9);
-  x10 = dct_const_round_shift(s2 - s10);
-  x11 = dct_const_round_shift(s3 - s11);
-  x12 = dct_const_round_shift(s4 - s12);
-  x13 = dct_const_round_shift(s5 - s13);
-  x14 = dct_const_round_shift(s6 - s14);
-  x15 = dct_const_round_shift(s7 - s15);
+  x0 = fdct_round_shift(s0 + s8);
+  x1 = fdct_round_shift(s1 + s9);
+  x2 = fdct_round_shift(s2 + s10);
+  x3 = fdct_round_shift(s3 + s11);
+  x4 = fdct_round_shift(s4 + s12);
+  x5 = fdct_round_shift(s5 + s13);
+  x6 = fdct_round_shift(s6 + s14);
+  x7 = fdct_round_shift(s7 + s15);
+  x8  = fdct_round_shift(s0 - s8);
+  x9  = fdct_round_shift(s1 - s9);
+  x10 = fdct_round_shift(s2 - s10);
+  x11 = fdct_round_shift(s3 - s11);
+  x12 = fdct_round_shift(s4 - s12);
+  x13 = fdct_round_shift(s5 - s13);
+  x14 = fdct_round_shift(s6 - s14);
+  x15 = fdct_round_shift(s7 - s15);
 
   // stage 2
   s0 = x0;
@@ -864,14 +870,14 @@
   x5 = s1 - s5;
   x6 = s2 - s6;
   x7 = s3 - s7;
-  x8 = dct_const_round_shift(s8 + s12);
-  x9 = dct_const_round_shift(s9 + s13);
-  x10 = dct_const_round_shift(s10 + s14);
-  x11 = dct_const_round_shift(s11 + s15);
-  x12 = dct_const_round_shift(s8 - s12);
-  x13 = dct_const_round_shift(s9 - s13);
-  x14 = dct_const_round_shift(s10 - s14);
-  x15 = dct_const_round_shift(s11 - s15);
+  x8 = fdct_round_shift(s8 + s12);
+  x9 = fdct_round_shift(s9 + s13);
+  x10 = fdct_round_shift(s10 + s14);
+  x11 = fdct_round_shift(s11 + s15);
+  x12 = fdct_round_shift(s8 - s12);
+  x13 = fdct_round_shift(s9 - s13);
+  x14 = fdct_round_shift(s10 - s14);
+  x15 = fdct_round_shift(s11 - s15);
 
   // stage 3
   s0 = x0;
@@ -895,18 +901,18 @@
   x1 = s1 + s3;
   x2 = s0 - s2;
   x3 = s1 - s3;
-  x4 = dct_const_round_shift(s4 + s6);
-  x5 = dct_const_round_shift(s5 + s7);
-  x6 = dct_const_round_shift(s4 - s6);
-  x7 = dct_const_round_shift(s5 - s7);
+  x4 = fdct_round_shift(s4 + s6);
+  x5 = fdct_round_shift(s5 + s7);
+  x6 = fdct_round_shift(s4 - s6);
+  x7 = fdct_round_shift(s5 - s7);
   x8 = s8 + s10;
   x9 = s9 + s11;
   x10 = s8 - s10;
   x11 = s9 - s11;
-  x12 = dct_const_round_shift(s12 + s14);
-  x13 = dct_const_round_shift(s13 + s15);
-  x14 = dct_const_round_shift(s12 - s14);
-  x15 = dct_const_round_shift(s13 - s15);
+  x12 = fdct_round_shift(s12 + s14);
+  x13 = fdct_round_shift(s13 + s15);
+  x14 = fdct_round_shift(s12 - s14);
+  x15 = fdct_round_shift(s13 - s15);
 
   // stage 4
   s2 = (- cospi_16_64) * (x2 + x3);
@@ -918,14 +924,14 @@
   s14 = (- cospi_16_64) * (x14 + x15);
   s15 = cospi_16_64 * (x14 - x15);
 
-  x2 = dct_const_round_shift(s2);
-  x3 = dct_const_round_shift(s3);
-  x6 = dct_const_round_shift(s6);
-  x7 = dct_const_round_shift(s7);
-  x10 = dct_const_round_shift(s10);
-  x11 = dct_const_round_shift(s11);
-  x14 = dct_const_round_shift(s14);
-  x15 = dct_const_round_shift(s15);
+  x2 = fdct_round_shift(s2);
+  x3 = fdct_round_shift(s3);
+  x6 = fdct_round_shift(s6);
+  x7 = fdct_round_shift(s7);
+  x10 = fdct_round_shift(s10);
+  x11 = fdct_round_shift(s11);
+  x14 = fdct_round_shift(s14);
+  x15 = fdct_round_shift(s15);
 
   output[0] = x0;
   output[1] = - x8;
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c
index c056bff..2a85dee 100644
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -408,7 +408,7 @@
           && (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height > y)
         xd->mi_8x8[x_idx + y * mis] = mi_addr;
 
-  if (cpi->sf.variance_adaptive_quantization) {
+  if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
     vp9_mb_init_quantizer(cpi, x);
   }
 
@@ -557,7 +557,7 @@
 
   /* segment ID */
   if (seg->enabled) {
-    if (!cpi->sf.variance_adaptive_quantization) {
+    if (!cpi->oxcf.aq_mode == VARIANCE_AQ) {
       uint8_t *map = seg->update_map ? cpi->segmentation_map
           : cm->last_frame_seg_map;
       mbmi->segment_id = vp9_get_segment_id(cm, map, bsize, mi_row, mi_col);
@@ -634,7 +634,7 @@
 
   x->source_variance = get_sby_perpixel_variance(cpi, x, bsize);
 
-  if (cpi->sf.variance_adaptive_quantization) {
+  if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
     int energy;
     if (bsize <= BLOCK_16X16) {
       energy = x->mb_energy;
@@ -650,7 +650,7 @@
   if (cpi->oxcf.tuning == VP8_TUNE_SSIM)
     vp9_activity_masking(cpi, x);
 
-  if (cpi->sf.variance_adaptive_quantization) {
+  if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
     vp9_clear_system_state();  // __asm emms;
     x->rdmult = round(x->rdmult * rdmult_ratio);
   }
@@ -669,7 +669,7 @@
                                     totaldist, bsize, ctx, best_rd);
   }
 
-  if (cpi->sf.variance_adaptive_quantization) {
+  if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
     x->rdmult = orig_rdmult;
     if (*totalrate != INT_MAX) {
       vp9_clear_system_state();  // __asm emms;
diff --git a/vp9/encoder/vp9_encodemb.c b/vp9/encoder/vp9_encodemb.c
index 0e1523b..22ab26d 100644
--- a/vp9/encoder/vp9_encodemb.c
+++ b/vp9/encoder/vp9_encodemb.c
@@ -63,13 +63,12 @@
 
 static void subtract_plane(MACROBLOCK *x, BLOCK_SIZE bsize, int plane) {
   struct macroblock_plane *const p = &x->plane[plane];
-  const MACROBLOCKD *const xd = &x->e_mbd;
-  const struct macroblockd_plane *const pd = &xd->plane[plane];
-  const int bw = plane_block_width(bsize, pd);
-  const int bh = plane_block_height(bsize, pd);
+  const struct macroblockd_plane *const pd = &x->e_mbd.plane[plane];
+  const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
+  const int bw = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
+  const int bh = 4 * num_4x4_blocks_high_lookup[plane_bsize];
 
-  vp9_subtract_block(bh, bw, p->src_diff, bw,
-                     p->src.buf, p->src.stride,
+  vp9_subtract_block(bh, bw, p->src_diff, bw, p->src.buf, p->src.stride,
                      pd->dst.buf, pd->dst.stride);
 }
 
@@ -167,7 +166,7 @@
 
   /* Now set up a Viterbi trellis to evaluate alternative roundings. */
   rdmult = mb->rdmult * err_mult;
-  if (mb->e_mbd.mi_8x8[0]->mbmi.ref_frame[0] == INTRA_FRAME)
+  if (!is_inter_block(&mb->e_mbd.mi_8x8[0]->mbmi))
     rdmult = (rdmult * 9) >> 4;
   rddiv = mb->rddiv;
   /* Initialize the sentinel node of the trellis. */
@@ -551,15 +550,19 @@
   const int16_t *scan, *iscan;
   TX_TYPE tx_type;
   MB_PREDICTION_MODE mode;
-  const int bwl = b_width_log2(plane_bsize), bw = 1 << bwl;
-  const int twl = bwl - tx_size, twmask = (1 << twl) - 1;
-  int xoff, yoff;
+  const int bwl = b_width_log2(plane_bsize);
+  const int diff_stride = 4 * (1 << bwl);
   uint8_t *src, *dst;
   int16_t *src_diff;
   uint16_t *eob = &pd->eobs[block];
+  int i, j;
+  txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &i, &j);
+  dst = &pd->dst.buf[4 * (j * pd->dst.stride + i)];
+  src = &p->src.buf[4 * (j * p->src.stride + i)];
+  src_diff = &p->src_diff[4 * (j * diff_stride + i)];
 
   if (xd->mb_to_right_edge < 0 || xd->mb_to_bottom_edge < 0)
-    extend_for_intra(xd, plane_bsize, plane, block, tx_size);
+    extend_for_intra(xd, plane_bsize, plane, i, j);
 
   // if (x->optimize)
   // vp9_optimize_b(plane, block, plane_bsize, tx_size, x, args->ctx);
@@ -570,21 +573,16 @@
       iscan = vp9_default_iscan_32x32;
       mode = plane == 0 ? mbmi->mode : mbmi->uv_mode;
       block >>= 6;
-      xoff = 32 * (block & twmask);
-      yoff = 32 * (block >> twl);
-      dst = pd->dst.buf + yoff * pd->dst.stride + xoff;
       vp9_predict_intra_block(xd, block, bwl, TX_32X32, mode,
                               dst, pd->dst.stride, dst, pd->dst.stride);
 
       if (!x->skip_recode) {
-        src = p->src.buf + yoff * p->src.stride + xoff;
-        src_diff = p->src_diff + 4 * bw * yoff + xoff;
-        vp9_subtract_block(32, 32, src_diff, bw * 4,
+        vp9_subtract_block(32, 32, src_diff, diff_stride,
                            src, p->src.stride, dst, pd->dst.stride);
         if (x->use_lp32x32fdct)
-          vp9_fdct32x32_rd(src_diff, coeff, bw * 4);
+          vp9_fdct32x32_rd(src_diff, coeff, diff_stride);
         else
-          vp9_fdct32x32(src_diff, coeff, bw * 4);
+          vp9_fdct32x32(src_diff, coeff, diff_stride);
         vp9_quantize_b_32x32(coeff, 1024, x->skip_block, p->zbin, p->round,
                              p->quant, p->quant_shift, qcoeff, dqcoeff,
                              pd->dequant, p->zbin_extra, eob, scan, iscan);
@@ -598,17 +596,12 @@
       iscan = get_iscan_16x16(tx_type);
       mode = plane == 0 ? mbmi->mode : mbmi->uv_mode;
       block >>= 4;
-      xoff = 16 * (block & twmask);
-      yoff = 16 * (block >> twl);
-      dst = pd->dst.buf + yoff * pd->dst.stride + xoff;
       vp9_predict_intra_block(xd, block, bwl, TX_16X16, mode,
                               dst, pd->dst.stride, dst, pd->dst.stride);
       if (!x->skip_recode) {
-        src = p->src.buf + yoff * p->src.stride + xoff;
-        src_diff = p->src_diff + 4 * bw * yoff + xoff;
-        vp9_subtract_block(16, 16, src_diff, bw * 4,
+        vp9_subtract_block(16, 16, src_diff, diff_stride,
                            src, p->src.stride, dst, pd->dst.stride);
-        vp9_fht16x16(tx_type, src_diff, coeff, bw * 4);
+        vp9_fht16x16(tx_type, src_diff, coeff, diff_stride);
         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);
@@ -622,17 +615,12 @@
       iscan = get_iscan_8x8(tx_type);
       mode = plane == 0 ? mbmi->mode : mbmi->uv_mode;
       block >>= 2;
-      xoff = 8 * (block & twmask);
-      yoff = 8 * (block >> twl);
-      dst = pd->dst.buf + yoff * pd->dst.stride + xoff;
       vp9_predict_intra_block(xd, block, bwl, TX_8X8, mode,
                               dst, pd->dst.stride, dst, pd->dst.stride);
       if (!x->skip_recode) {
-        src = p->src.buf + yoff * p->src.stride + xoff;
-        src_diff = p->src_diff + 4 * bw * yoff + xoff;
-        vp9_subtract_block(8, 8, src_diff, bw * 4,
+        vp9_subtract_block(8, 8, src_diff, diff_stride,
                            src, p->src.stride, dst, pd->dst.stride);
-        vp9_fht8x8(tx_type, src_diff, coeff, bw * 4);
+        vp9_fht8x8(tx_type, src_diff, coeff, diff_stride);
         vp9_quantize_b(coeff, 64, x->skip_block, p->zbin, p->round, p->quant,
                        p->quant_shift, qcoeff, dqcoeff,
                        pd->dequant, p->zbin_extra, eob, scan, iscan);
@@ -649,21 +637,16 @@
       else
         mode = plane == 0 ? mbmi->mode : mbmi->uv_mode;
 
-      xoff = 4 * (block & twmask);
-      yoff = 4 * (block >> twl);
-      dst = pd->dst.buf + yoff * pd->dst.stride + xoff;
       vp9_predict_intra_block(xd, block, bwl, TX_4X4, mode,
                               dst, pd->dst.stride, dst, pd->dst.stride);
 
       if (!x->skip_recode) {
-        src = p->src.buf + yoff * p->src.stride + xoff;
-        src_diff = p->src_diff + 4 * bw * yoff + xoff;
-        vp9_subtract_block(4, 4, src_diff, bw * 4,
+        vp9_subtract_block(4, 4, src_diff, diff_stride,
                            src, p->src.stride, dst, pd->dst.stride);
         if (tx_type != DCT_DCT)
-          vp9_short_fht4x4(src_diff, coeff, bw * 4, tx_type);
+          vp9_short_fht4x4(src_diff, coeff, diff_stride, tx_type);
         else
-          x->fwd_txm4x4(src_diff, coeff, bw * 4);
+          x->fwd_txm4x4(src_diff, coeff, diff_stride);
         vp9_quantize_b(coeff, 16, 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_encodemv.c b/vp9/encoder/vp9_encodemv.c
index bb9baff..cc4e347 100644
--- a/vp9/encoder/vp9_encodemv.c
+++ b/vp9/encoder/vp9_encodemv.c
@@ -68,7 +68,7 @@
   int i, v;
   int sign_cost[2], class_cost[MV_CLASSES], class0_cost[CLASS0_SIZE];
   int bits_cost[MV_OFFSET_BITS][2];
-  int class0_fp_cost[CLASS0_SIZE][4], fp_cost[4];
+  int class0_fp_cost[CLASS0_SIZE][MV_FP_SIZE], fp_cost[MV_FP_SIZE];
   int class0_hp_cost[2], hp_cost[2];
 
   sign_cost[0] = vp9_cost_zero(mvcomp->sign);
@@ -145,8 +145,8 @@
     unsigned int (*branch_ct_classes)[MV_CLASSES - 1][2],
     unsigned int (*branch_ct_class0)[CLASS0_SIZE - 1][2],
     unsigned int (*branch_ct_bits)[MV_OFFSET_BITS][2],
-    unsigned int (*branch_ct_class0_fp)[CLASS0_SIZE][4 - 1][2],
-    unsigned int (*branch_ct_fp)[4 - 1][2],
+    unsigned int (*branch_ct_class0_fp)[CLASS0_SIZE][MV_FP_SIZE - 1][2],
+    unsigned int (*branch_ct_fp)[MV_FP_SIZE - 1][2],
     unsigned int (*branch_ct_class0_hp)[2],
     unsigned int (*branch_ct_hp)[2]) {
   int i, j, k;
@@ -194,8 +194,8 @@
   unsigned int branch_ct_classes[2][MV_CLASSES - 1][2];
   unsigned int branch_ct_class0[2][CLASS0_SIZE - 1][2];
   unsigned int branch_ct_bits[2][MV_OFFSET_BITS][2];
-  unsigned int branch_ct_class0_fp[2][CLASS0_SIZE][4 - 1][2];
-  unsigned int branch_ct_fp[2][4 - 1][2];
+  unsigned int branch_ct_class0_fp[2][CLASS0_SIZE][MV_FP_SIZE - 1][2];
+  unsigned int branch_ct_fp[2][MV_FP_SIZE - 1][2];
   unsigned int branch_ct_class0_hp[2][2];
   unsigned int branch_ct_hp[2][2];
   nmv_context *mvc = &cpi->common.fc.nmvc;
@@ -227,12 +227,12 @@
   for (i = 0; i < 2; ++i) {
     for (j = 0; j < CLASS0_SIZE; ++j) {
       int k;
-      for (k = 0; k < 3; ++k)
+      for (k = 0; k < MV_FP_SIZE - 1; ++k)
         update_mv(bc, branch_ct_class0_fp[i][j][k],
                   &mvc->comps[i].class0_fp[j][k], NMV_UPDATE_PROB);
     }
 
-    for (j = 0; j < 3; ++j)
+    for (j = 0; j < MV_FP_SIZE - 1; ++j)
       update_mv(bc, branch_ct_fp[i][j], &mvc->comps[i].fp[j], NMV_UPDATE_PROB);
   }
 
diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c
index d80ecb1..df28410 100644
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -599,14 +599,14 @@
                      num_8x8_blocks_wide_lookup[xd->mi_8x8[0]->mbmi.sb_type],
                      cm->mi_rows, cm->mi_cols);
 
-      if (cpi->sf.variance_adaptive_quantization) {
+      if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
         int energy = vp9_block_energy(cpi, x, xd->mi_8x8[0]->mbmi.sb_type);
         error_weight = vp9_vaq_inv_q_ratio(energy);
       }
 
       // do intra 16x16 prediction
       this_error = vp9_encode_intra(x, use_dc_pred);
-      if (cpi->sf.variance_adaptive_quantization) {
+      if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
         vp9_clear_system_state();  // __asm emms;
         this_error *= error_weight;
       }
@@ -644,7 +644,7 @@
         first_pass_motion_search(cpi, x, &best_ref_mv,
                                  &mv.as_mv, lst_yv12,
                                  &motion_error, recon_yoffset);
-        if (cpi->sf.variance_adaptive_quantization) {
+        if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
           vp9_clear_system_state();  // __asm emms;
           motion_error *= error_weight;
         }
@@ -655,7 +655,7 @@
           tmp_err = INT_MAX;
           first_pass_motion_search(cpi, x, &zero_ref_mv, &tmp_mv.as_mv,
                                    lst_yv12, &tmp_err, recon_yoffset);
-          if (cpi->sf.variance_adaptive_quantization) {
+          if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
             vp9_clear_system_state();  // __asm emms;
             tmp_err *= error_weight;
           }
@@ -675,7 +675,7 @@
           first_pass_motion_search(cpi, x, &zero_ref_mv,
                                    &tmp_mv.as_mv, gld_yv12,
                                    &gf_motion_error, recon_yoffset);
-          if (cpi->sf.variance_adaptive_quantization) {
+          if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
             vp9_clear_system_state();  // __asm emms;
             gf_motion_error *= error_weight;
           }
@@ -966,19 +966,19 @@
 // (now uses the actual quantizer) but has not been tuned.
 static void adjust_maxq_qrange(VP9_COMP *cpi) {
   int i;
-  // Set the max corresponding to cpi->avg_q * 2.0
-  double q = cpi->avg_q * 2.0;
-  cpi->twopass.maxq_max_limit = cpi->worst_quality;
-  for (i = cpi->best_quality; i <= cpi->worst_quality; i++) {
+  // Set the max corresponding to cpi->rc.avg_q * 2.0
+  double q = cpi->rc.avg_q * 2.0;
+  cpi->twopass.maxq_max_limit = cpi->rc.worst_quality;
+  for (i = cpi->rc.best_quality; i <= cpi->rc.worst_quality; i++) {
     cpi->twopass.maxq_max_limit = i;
     if (vp9_convert_qindex_to_q(i) >= q)
       break;
   }
 
-  // Set the min corresponding to cpi->avg_q * 0.5
-  q = cpi->avg_q * 0.5;
-  cpi->twopass.maxq_min_limit = cpi->best_quality;
-  for (i = cpi->worst_quality; i >= cpi->best_quality; i--) {
+  // Set the min corresponding to cpi->rc.avg_q * 0.5
+  q = cpi->rc.avg_q * 0.5;
+  cpi->twopass.maxq_min_limit = cpi->rc.best_quality;
+  for (i = cpi->rc.worst_quality; i >= cpi->rc.best_quality; i--) {
     cpi->twopass.maxq_min_limit = i;
     if (vp9_convert_qindex_to_q(i) <= q)
       break;
@@ -1017,10 +1017,10 @@
 
   // Calculate a corrective factor based on a rolling ratio of bits spent
   // vs target bits
-  if (cpi->rolling_target_bits > 0 &&
-      cpi->active_worst_quality < cpi->worst_quality) {
-    double rolling_ratio = (double)cpi->rolling_actual_bits /
-                               (double)cpi->rolling_target_bits;
+  if (cpi->rc.rolling_target_bits > 0 &&
+      cpi->rc.active_worst_quality < cpi->rc.worst_quality) {
+    double rolling_ratio = (double)cpi->rc.rolling_actual_bits /
+                               (double)cpi->rc.rolling_target_bits;
 
     if (rolling_ratio < 0.95)
       cpi->twopass.est_max_qcorrection_factor -= 0.005;
@@ -1066,8 +1066,8 @@
   // average q observed in clip for non kf/gf/arf frames
   // Give average a chance to settle though.
   // PGW TODO.. This code is broken for the extended Q range
-  if (cpi->ni_frames > ((int)cpi->twopass.total_stats.count >> 8) &&
-      cpi->ni_frames > 25)
+  if (cpi->rc.ni_frames > ((int)cpi->twopass.total_stats.count >> 8) &&
+      cpi->rc.ni_frames > 25)
     adjust_maxq_qrange(cpi);
 
   return q;
@@ -1146,10 +1146,10 @@
 
   // Clip value to range "best allowed to (worst allowed - 1)"
   q = select_cq_level(q);
-  if (q >= cpi->worst_quality)
-    q = cpi->worst_quality - 1;
-  if (q < cpi->best_quality)
-    q = cpi->best_quality;
+  if (q >= cpi->rc.worst_quality)
+    q = cpi->rc.worst_quality - 1;
+  if (q < cpi->rc.best_quality)
+    q = cpi->rc.best_quality;
 
   return q;
 }
@@ -1599,13 +1599,13 @@
   if (cpi->twopass.frames_to_key <= (FIXED_ARF_GROUP_SIZE + 8)) {
     // Setup a GF group close to the keyframe.
     cpi->source_alt_ref_pending = 0;
-    cpi->baseline_gf_interval = cpi->twopass.frames_to_key;
-    schedule_frames(cpi, 0, (cpi->baseline_gf_interval - 1), 2, 0, 0);
+    cpi->rc.baseline_gf_interval = cpi->twopass.frames_to_key;
+    schedule_frames(cpi, 0, (cpi->rc.baseline_gf_interval - 1), 2, 0, 0);
   } else {
     // Setup a fixed period ARF group.
     cpi->source_alt_ref_pending = 1;
-    cpi->baseline_gf_interval = FIXED_ARF_GROUP_SIZE;
-    schedule_frames(cpi, 0, -(cpi->baseline_gf_interval - 1), 2, 1, 0);
+    cpi->rc.baseline_gf_interval = FIXED_ARF_GROUP_SIZE;
+    schedule_frames(cpi, 0, -(cpi->rc.baseline_gf_interval - 1), 2, 1, 0);
   }
 
   // Replace level indicator of -1 with correct level.
@@ -1702,10 +1702,10 @@
   // At high Q when there are few bits to spare we are better with a longer
   // interval to spread the cost of the GF.
   active_max_gf_interval =
-    12 + ((int)vp9_convert_qindex_to_q(cpi->active_worst_quality) >> 5);
+    12 + ((int)vp9_convert_qindex_to_q(cpi->rc.active_worst_quality) >> 5);
 
-  if (active_max_gf_interval > cpi->max_gf_interval)
-    active_max_gf_interval = cpi->max_gf_interval;
+  if (active_max_gf_interval > cpi->rc.max_gf_interval)
+    active_max_gf_interval = cpi->rc.max_gf_interval;
 
   i = 0;
   while (((i < cpi->twopass.static_scene_max_gf_interval) ||
@@ -1799,7 +1799,7 @@
   }
 
   // Set the interval until the next gf or arf.
-  cpi->baseline_gf_interval = i;
+  cpi->rc.baseline_gf_interval = i;
 
 #if CONFIG_MULTIPLE_ARF
   if (cpi->multi_arf_enabled) {
@@ -1825,24 +1825,25 @@
        (mv_in_out_accumulator > -2.0)) &&
       (boost_score > 100)) {
     // Alternative boost calculation for alt ref
-    cpi->gfu_boost = calc_arf_boost(cpi, 0, (i - 1), (i - 1), &f_boost,
+    cpi->rc.gfu_boost = calc_arf_boost(cpi, 0, (i - 1), (i - 1), &f_boost,
                                     &b_boost);
     cpi->source_alt_ref_pending = 1;
 
 #if CONFIG_MULTIPLE_ARF
     // Set the ARF schedule.
     if (cpi->multi_arf_enabled) {
-      schedule_frames(cpi, 0, -(cpi->baseline_gf_interval - 1), 2, 1, 0);
+      schedule_frames(cpi, 0, -(cpi->rc.baseline_gf_interval - 1), 2, 1, 0);
     }
 #endif
   } else {
-    cpi->gfu_boost = (int)boost_score;
+    cpi->rc.gfu_boost = (int)boost_score;
     cpi->source_alt_ref_pending = 0;
 #if CONFIG_MULTIPLE_ARF
     // Set the GF schedule.
     if (cpi->multi_arf_enabled) {
-      schedule_frames(cpi, 0, cpi->baseline_gf_interval - 1, 2, 0, 0);
-      assert(cpi->new_frame_coding_order_period == cpi->baseline_gf_interval);
+      schedule_frames(cpi, 0, cpi->rc.baseline_gf_interval - 1, 2, 0, 0);
+      assert(cpi->new_frame_coding_order_period ==
+             cpi->rc.baseline_gf_interval);
     }
 #endif
   }
@@ -1915,8 +1916,9 @@
   // Clip cpi->twopass.gf_group_bits based on user supplied data rate
   // variability limit (cpi->oxcf.two_pass_vbrmax_section)
   if (cpi->twopass.gf_group_bits >
-      (int64_t)max_bits * cpi->baseline_gf_interval)
-    cpi->twopass.gf_group_bits = (int64_t)max_bits * cpi->baseline_gf_interval;
+      (int64_t)max_bits * cpi->rc.baseline_gf_interval)
+    cpi->twopass.gf_group_bits =
+        (int64_t)max_bits * cpi->rc.baseline_gf_interval;
 
   // Reset the file position
   reset_fpf_position(cpi, start_pos);
@@ -1929,19 +1931,18 @@
       i <= (cpi->source_alt_ref_pending && cpi->common.frame_type != KEY_FRAME);
       ++i) {
     int allocation_chunks;
-    int q = cpi->oxcf.fixed_q < 0 ? cpi->last_q[INTER_FRAME]
-                                  : cpi->oxcf.fixed_q;
+    int q = cpi->rc.last_q[INTER_FRAME];
     int gf_bits;
 
-    int boost = (cpi->gfu_boost * vp9_gfboost_qadjust(q)) / 100;
+    int boost = (cpi->rc.gfu_boost * vp9_gfboost_qadjust(q)) / 100;
 
     // Set max and minimum boost and hence minimum allocation
-    boost = clamp(boost, 125, (cpi->baseline_gf_interval + 1) * 200);
+    boost = clamp(boost, 125, (cpi->rc.baseline_gf_interval + 1) * 200);
 
     if (cpi->source_alt_ref_pending && i == 0)
-      allocation_chunks = ((cpi->baseline_gf_interval + 1) * 100) + boost;
+      allocation_chunks = ((cpi->rc.baseline_gf_interval + 1) * 100) + boost;
     else
-      allocation_chunks = (cpi->baseline_gf_interval * 100) + (boost - 100);
+      allocation_chunks = (cpi->rc.baseline_gf_interval * 100) + (boost - 100);
 
     // Prevent overflow
     if (boost > 1023) {
@@ -1958,10 +1959,10 @@
     // If the frame that is to be boosted is simpler than the average for
     // the gf/arf group then use an alternative calculation
     // based on the error score of the frame itself
-    if (mod_frame_err < gf_group_err / (double)cpi->baseline_gf_interval) {
+    if (mod_frame_err < gf_group_err / (double)cpi->rc.baseline_gf_interval) {
       double alt_gf_grp_bits =
         (double)cpi->twopass.kf_group_bits  *
-        (mod_frame_err * (double)cpi->baseline_gf_interval) /
+        (mod_frame_err * (double)cpi->rc.baseline_gf_interval) /
         DOUBLE_DIVIDE_CHECK(cpi->twopass.kf_group_error_left);
 
       int alt_gf_bits = (int)((double)boost * (alt_gf_grp_bits /
@@ -1986,7 +1987,7 @@
       gf_bits = 0;
 
     // Add in minimum for a frame
-    gf_bits += cpi->min_frame_bandwidth;
+    gf_bits += cpi->rc.min_frame_bandwidth;
 
     if (i == 0) {
       cpi->twopass.gf_bits = gf_bits;
@@ -1994,7 +1995,7 @@
     if (i == 1 || (!cpi->source_alt_ref_pending
         && (cpi->common.frame_type != KEY_FRAME))) {
       // Per frame bit target for this frame
-      cpi->per_frame_bandwidth = gf_bits;
+      cpi->rc.per_frame_bandwidth = gf_bits;
     }
   }
 
@@ -2017,7 +2018,7 @@
       cpi->twopass.gf_group_error_left = (int64_t)gf_group_err;
 
     cpi->twopass.gf_group_bits -= cpi->twopass.gf_bits
-        - cpi->min_frame_bandwidth;
+        - cpi->rc.min_frame_bandwidth;
 
     if (cpi->twopass.gf_group_bits < 0)
       cpi->twopass.gf_group_bits = 0;
@@ -2025,8 +2026,9 @@
     // This condition could fail if there are two kfs very close together
     // despite (MIN_GF_INTERVAL) and would cause a divide by 0 in the
     // calculation of alt_extra_bits.
-    if (cpi->baseline_gf_interval >= 3) {
-      const int boost = cpi->source_alt_ref_pending ? b_boost : cpi->gfu_boost;
+    if (cpi->rc.baseline_gf_interval >= 3) {
+      const int boost = cpi->source_alt_ref_pending ?
+          b_boost : cpi->rc.gfu_boost;
 
       if (boost >= 150) {
         int alt_extra_bits;
@@ -2045,7 +2047,7 @@
     zero_stats(&sectionstats);
     reset_fpf_position(cpi, start_pos);
 
-    for (i = 0; i < cpi->baseline_gf_interval; i++) {
+    for (i = 0; i < cpi->rc.baseline_gf_interval; i++) {
       input_stats(cpi, &next_frame);
       accumulate_stats(&sectionstats, &next_frame);
     }
@@ -2102,10 +2104,10 @@
     cpi->twopass.gf_group_bits = 0;
 
   // Add in the minimum number of bits that is set aside for every frame.
-  target_frame_size += cpi->min_frame_bandwidth;
+  target_frame_size += cpi->rc.min_frame_bandwidth;
 
   // Per frame bit target for this frame.
-  cpi->per_frame_bandwidth = target_frame_size;
+  cpi->rc.per_frame_bandwidth = target_frame_size;
 }
 
 // Make a damped adjustment to the active max q.
@@ -2145,7 +2147,7 @@
   vp9_clear_system_state();
 
   if (cpi->oxcf.end_usage == USAGE_CONSTANT_QUALITY) {
-    cpi->active_worst_quality = cpi->oxcf.cq_level;
+    cpi->rc.active_worst_quality = cpi->oxcf.cq_level;
   } else {
     // Special case code for first frame.
     if (cpi->common.current_video_frame == 0) {
@@ -2169,15 +2171,15 @@
       */
 
       // guess at maxq needed in 2nd pass
-      cpi->twopass.maxq_max_limit = cpi->worst_quality;
-      cpi->twopass.maxq_min_limit = cpi->best_quality;
+      cpi->twopass.maxq_max_limit = cpi->rc.worst_quality;
+      cpi->twopass.maxq_min_limit = cpi->rc.best_quality;
 
       tmp_q = estimate_max_q(cpi, &cpi->twopass.total_left_stats,
                              section_target_bandwidth);
 
-      cpi->active_worst_quality = tmp_q;
-      cpi->ni_av_qi = tmp_q;
-      cpi->avg_q = vp9_convert_qindex_to_q(tmp_q);
+      cpi->rc.active_worst_quality = tmp_q;
+      cpi->rc.ni_av_qi = tmp_q;
+      cpi->rc.avg_q = vp9_convert_qindex_to_q(tmp_q);
 
       // Limit the maxq value returned subsequently.
       // This increases the risk of overspend or underspend if the initial
@@ -2193,7 +2195,7 @@
     // few surplus bits or get beneath the target rate.
     else if ((cpi->common.current_video_frame <
               (((unsigned int)cpi->twopass.total_stats.count * 255) >> 8)) &&
-             ((cpi->common.current_video_frame + cpi->baseline_gf_interval) <
+             ((cpi->common.current_video_frame + cpi->rc.baseline_gf_interval) <
               (unsigned int)cpi->twopass.total_stats.count)) {
       int section_target_bandwidth =
           (int)(cpi->twopass.bits_left / frames_left);
@@ -2206,8 +2208,8 @@
           section_target_bandwidth);
 
       // Make a damped adjustment to active max Q
-      cpi->active_worst_quality =
-          adjust_active_maxq(cpi->active_worst_quality, tmp_q);
+      cpi->rc.active_worst_quality =
+          adjust_active_maxq(cpi->rc.active_worst_quality, tmp_q);
     }
   }
   vp9_zero(this_frame);
@@ -2225,7 +2227,7 @@
   }
 
   // Is this a GF / ARF (Note that a KF is always also a GF)
-  if (cpi->frames_till_gf_update_due == 0) {
+  if (cpi->rc.frames_till_gf_update_due == 0) {
     // Define next gf group and assign bits to it
     this_frame_copy = this_frame;
 
@@ -2259,10 +2261,10 @@
     if (cpi->source_alt_ref_pending && (cpi->common.frame_type != KEY_FRAME)) {
       // Assign a standard frames worth of bits from those allocated
       // to the GF group
-      int bak = cpi->per_frame_bandwidth;
+      int bak = cpi->rc.per_frame_bandwidth;
       this_frame_copy = this_frame;
       assign_std_frame_bits(cpi, &this_frame_copy);
-      cpi->per_frame_bandwidth = bak;
+      cpi->rc.per_frame_bandwidth = bak;
     }
   } else {
     // Otherwise this is an ordinary frame
@@ -2283,7 +2285,7 @@
   }
 
   // Set nominal per second bandwidth for this frame
-  cpi->target_bandwidth = (int)(cpi->per_frame_bandwidth
+  cpi->target_bandwidth = (int)(cpi->rc.per_frame_bandwidth
                                 * cpi->output_framerate);
   if (cpi->target_bandwidth < 0)
     cpi->target_bandwidth = 0;
@@ -2416,7 +2418,7 @@
   cpi->source_alt_ref_active = 0;
 
   // Kf is always a gf so clear frames till next gf counter
-  cpi->frames_till_gf_update_due = 0;
+  cpi->rc.frames_till_gf_update_due = 0;
 
   cpi->twopass.frames_to_key = 1;
 
@@ -2579,7 +2581,7 @@
     }
 
     // For the first few frames collect data to decide kf boost.
-    if (i <= (cpi->max_gf_interval * 2)) {
+    if (i <= (cpi->rc.max_gf_interval * 2)) {
       if (next_frame.intra_error > cpi->twopass.kf_intra_err_min)
         r = (IIKFACTOR2 * next_frame.intra_error /
              DOUBLE_DIVIDE_CHECK(next_frame.coded_error));
@@ -2637,7 +2639,7 @@
 
     // Make a note of baseline boost and the zero motion
     // accumulator value for use elsewhere.
-    cpi->kf_boost = kf_boost;
+    cpi->rc.kf_boost = kf_boost;
     cpi->kf_zeromotion_pct = (int)(zero_motion_accumulator * 100.0);
 
     // We do three calculations for kf size.
@@ -2707,10 +2709,10 @@
 
     cpi->twopass.kf_group_bits -= cpi->twopass.kf_bits;
     // Add in the minimum frame allowance
-    cpi->twopass.kf_bits += cpi->min_frame_bandwidth;
+    cpi->twopass.kf_bits += cpi->rc.min_frame_bandwidth;
 
     // Peer frame bit target for this frame
-    cpi->per_frame_bandwidth = cpi->twopass.kf_bits;
+    cpi->rc.per_frame_bandwidth = cpi->twopass.kf_bits;
     // Convert to a per second bitrate
     cpi->target_bandwidth = (int)(cpi->twopass.kf_bits *
                                   cpi->output_framerate);
diff --git a/vp9/encoder/vp9_mbgraph.c b/vp9/encoder/vp9_mbgraph.c
index 9870738..544f130 100644
--- a/vp9/encoder/vp9_mbgraph.c
+++ b/vp9/encoder/vp9_mbgraph.c
@@ -323,8 +323,8 @@
                              1));
 
   // We are not interested in results beyond the alt ref itself.
-  if (n_frames > cpi->frames_till_gf_update_due)
-    n_frames = cpi->frames_till_gf_update_due;
+  if (n_frames > cpi->rc.frames_till_gf_update_due)
+    n_frames = cpi->rc.frames_till_gf_update_due;
 
   // defer cost to reference frames
   for (i = n_frames - 1; i >= 0; i--) {
@@ -396,7 +396,7 @@
 
   // we need to look ahead beyond where the ARF transitions into
   // being a GF - so exit if we don't look ahead beyond that
-  if (n_frames <= cpi->frames_till_gf_update_due)
+  if (n_frames <= cpi->rc.frames_till_gf_update_due)
     return;
   if (n_frames > (int)cpi->frames_till_alt_ref_frame)
     n_frames = cpi->frames_till_alt_ref_frame;
diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c
index dd4705d..585f799 100644
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -37,9 +37,6 @@
 
 #include "vpx_ports/vpx_timer.h"
 
-
-extern void print_tree_update_probs();
-
 static void set_default_lf_deltas(struct loopfilter *lf);
 
 #define DEFAULT_INTERP_FILTER SWITCHABLE
@@ -112,15 +109,6 @@
 
 extern void vp9_init_quantizer(VP9_COMP *cpi);
 
-// Tables relating active max Q to active min Q
-static int kf_low_motion_minq[QINDEX_RANGE];
-static int kf_high_motion_minq[QINDEX_RANGE];
-static int gf_low_motion_minq[QINDEX_RANGE];
-static int gf_high_motion_minq[QINDEX_RANGE];
-static int inter_minq[QINDEX_RANGE];
-static int afq_low_motion_minq[QINDEX_RANGE];
-static int afq_high_motion_minq[QINDEX_RANGE];
-
 static INLINE void Scale2Ratio(int mode, int *hr, int *hs) {
   switch (mode) {
     case NORMAL:
@@ -147,96 +135,6 @@
   }
 }
 
-// Functions to compute the active minq lookup table entries based on a
-// formulaic approach to facilitate easier adjustment of the Q tables.
-// The formulae were derived from computing a 3rd order polynomial best
-// fit to the original data (after plotting real maxq vs minq (not q index))
-static int calculate_minq_index(double maxq,
-                                double x3, double x2, double x1, double c) {
-  int i;
-  const double minqtarget = MIN(((x3 * maxq + x2) * maxq + x1) * maxq + c,
-                                maxq);
-
-  // Special case handling to deal with the step from q2.0
-  // down to lossless mode represented by q 1.0.
-  if (minqtarget <= 2.0)
-    return 0;
-
-  for (i = 0; i < QINDEX_RANGE; i++) {
-    if (minqtarget <= vp9_convert_qindex_to_q(i))
-      return i;
-  }
-
-  return QINDEX_RANGE - 1;
-}
-
-static void init_minq_luts(void) {
-  int i;
-
-  for (i = 0; i < QINDEX_RANGE; i++) {
-    const double maxq = vp9_convert_qindex_to_q(i);
-
-
-    kf_low_motion_minq[i] = calculate_minq_index(maxq,
-                                                 0.000001,
-                                                 -0.0004,
-                                                 0.15,
-                                                 0.0);
-    kf_high_motion_minq[i] = calculate_minq_index(maxq,
-                                                  0.000002,
-                                                  -0.0012,
-                                                  0.5,
-                                                  0.0);
-
-    gf_low_motion_minq[i] = calculate_minq_index(maxq,
-                                                 0.0000015,
-                                                 -0.0009,
-                                                 0.32,
-                                                 0.0);
-    gf_high_motion_minq[i] = calculate_minq_index(maxq,
-                                                  0.0000021,
-                                                  -0.00125,
-                                                  0.50,
-                                                  0.0);
-    inter_minq[i] = calculate_minq_index(maxq,
-                                         0.00000271,
-                                         -0.00113,
-                                         0.75,
-                                         0.0);
-    afq_low_motion_minq[i] = calculate_minq_index(maxq,
-                                                  0.0000015,
-                                                  -0.0009,
-                                                  0.33,
-                                                  0.0);
-    afq_high_motion_minq[i] = calculate_minq_index(maxq,
-                                                   0.0000021,
-                                                   -0.00125,
-                                                   0.55,
-                                                   0.0);
-  }
-}
-
-static int get_active_quality(int q,
-                              int gfu_boost,
-                              int low,
-                              int high,
-                              int *low_motion_minq,
-                              int *high_motion_minq) {
-  int active_best_quality;
-  if (gfu_boost > high) {
-    active_best_quality = low_motion_minq[q];
-  } else if (gfu_boost < low) {
-    active_best_quality = high_motion_minq[q];
-  } else {
-    const int gap = high - low;
-    const int offset = high - gfu_boost;
-    const int qdiff = high_motion_minq[q] - low_motion_minq[q];
-    const int adjustment = ((offset * qdiff) + (gap >> 1)) / gap;
-    active_best_quality = low_motion_minq[q] + adjustment;
-  }
-  return active_best_quality;
-}
-
 static void set_mvcost(VP9_COMP *cpi) {
   MACROBLOCK *const mb = &cpi->mb;
   if (cpi->common.allow_high_precision_mv) {
@@ -256,7 +154,7 @@
     vp9_tokenize_initialize();
     vp9_init_quant_tables();
     vp9_init_me_luts();
-    init_minq_luts();
+    vp9_init_minq_luts();
     // init_base_skip_probs();
     init_done = 1;
   }
@@ -325,18 +223,18 @@
 // target q value
 int vp9_compute_qdelta(VP9_COMP *cpi, double qstart, double qtarget) {
   int i;
-  int start_index = cpi->worst_quality;
-  int target_index = cpi->worst_quality;
+  int start_index = cpi->rc.worst_quality;
+  int target_index = cpi->rc.worst_quality;
 
   // Convert the average q value to an index.
-  for (i = cpi->best_quality; i < cpi->worst_quality; i++) {
+  for (i = cpi->rc.best_quality; i < cpi->rc.worst_quality; i++) {
     start_index = i;
     if (vp9_convert_qindex_to_q(i) >= qstart)
       break;
   }
 
   // Convert the q target to an index
-  for (i = cpi->best_quality; i < cpi->worst_quality; i++) {
+  for (i = cpi->rc.best_quality; i < cpi->rc.worst_quality; i++) {
     target_index = i;
     if (vp9_convert_qindex_to_q(i) >= qtarget)
       break;
@@ -349,7 +247,7 @@
   VP9_COMMON *cm = &cpi->common;
   struct segmentation *seg = &cm->seg;
 
-  int high_q = (int)(cpi->avg_q > 48.0);
+  int high_q = (int)(cpi->rc.avg_q > 48.0);
   int qi_delta;
 
   // Disable and clear down for KF
@@ -387,7 +285,8 @@
       seg->update_map = 1;
       seg->update_data = 1;
 
-      qi_delta = vp9_compute_qdelta(cpi, cpi->avg_q, (cpi->avg_q * 0.875));
+      qi_delta = vp9_compute_qdelta(
+          cpi, cpi->rc.avg_q, (cpi->rc.avg_q * 0.875));
       vp9_set_segdata(seg, 1, SEG_LVL_ALT_Q, (qi_delta - 2));
       vp9_set_segdata(seg, 1, SEG_LVL_ALT_LF, -2);
 
@@ -401,15 +300,15 @@
     // All other frames if segmentation has been enabled
 
     // First normal frame in a valid gf or alt ref group
-    if (cpi->frames_since_golden == 0) {
+    if (cpi->rc.frames_since_golden == 0) {
       // Set up segment features for normal frames in an arf group
       if (cpi->source_alt_ref_active) {
         seg->update_map = 0;
         seg->update_data = 1;
         seg->abs_delta = SEGMENT_DELTADATA;
 
-        qi_delta = vp9_compute_qdelta(cpi, cpi->avg_q,
-                                      (cpi->avg_q * 1.125));
+        qi_delta = vp9_compute_qdelta(cpi, cpi->rc.avg_q,
+                                      (cpi->rc.avg_q * 1.125));
         vp9_set_segdata(seg, 1, SEG_LVL_ALT_Q, (qi_delta + 2));
         vp9_enable_segfeature(seg, 1, SEG_LVL_ALT_Q);
 
@@ -467,69 +366,6 @@
   }
 }
 
-#ifdef ENTROPY_STATS
-void vp9_update_mode_context_stats(VP9_COMP *cpi) {
-  VP9_COMMON *cm = &cpi->common;
-  int i, j;
-  unsigned int (*inter_mode_counts)[INTER_MODES - 1][2] =
-      cm->fc.inter_mode_counts;
-  int64_t (*mv_ref_stats)[INTER_MODES - 1][2] = cpi->mv_ref_stats;
-  FILE *f;
-
-  // Read the past stats counters
-  f = fopen("mode_context.bin",  "rb");
-  if (!f) {
-    vpx_memset(cpi->mv_ref_stats, 0, sizeof(cpi->mv_ref_stats));
-  } else {
-    fread(cpi->mv_ref_stats, sizeof(cpi->mv_ref_stats), 1, f);
-    fclose(f);
-  }
-
-  // Add in the values for this frame
-  for (i = 0; i < INTER_MODE_CONTEXTS; i++) {
-    for (j = 0; j < INTER_MODES - 1; j++) {
-      mv_ref_stats[i][j][0] += (int64_t)inter_mode_counts[i][j][0];
-      mv_ref_stats[i][j][1] += (int64_t)inter_mode_counts[i][j][1];
-    }
-  }
-
-  // Write back the accumulated stats
-  f = fopen("mode_context.bin",  "wb");
-  fwrite(cpi->mv_ref_stats, sizeof(cpi->mv_ref_stats), 1, f);
-  fclose(f);
-}
-
-void print_mode_context(VP9_COMP *cpi) {
-  FILE *f = fopen("vp9_modecont.c", "a");
-  int i, j;
-
-  fprintf(f, "#include \"vp9_entropy.h\"\n");
-  fprintf(
-      f,
-      "const int inter_mode_probs[INTER_MODE_CONTEXTS][INTER_MODES - 1] =");
-  fprintf(f, "{\n");
-  for (j = 0; j < INTER_MODE_CONTEXTS; j++) {
-    fprintf(f, "  {/* %d */ ", j);
-    fprintf(f, "    ");
-    for (i = 0; i < INTER_MODES - 1; i++) {
-      int this_prob;
-      int64_t count = cpi->mv_ref_stats[j][i][0] + cpi->mv_ref_stats[j][i][1];
-      if (count)
-        this_prob = ((cpi->mv_ref_stats[j][i][0] * 256) + (count >> 1)) / count;
-      else
-        this_prob = 128;
-
-      // context probs
-      fprintf(f, "%5d, ", this_prob);
-    }
-    fprintf(f, "  },\n");
-  }
-
-  fprintf(f, "};\n");
-  fclose(f);
-}
-#endif  // ENTROPY_STATS
-
 // DEBUG: Print out the segment id of each MB in the current frame.
 static void print_seg_map(VP9_COMP *cpi) {
   VP9_COMMON *cm = &cpi->common;
@@ -764,8 +600,6 @@
   sf->static_segmentation = 0;
 #endif
 
-  sf->variance_adaptive_quantization = 0;
-
   switch (mode) {
     case 0:  // This is the best quality mode.
       break;
@@ -1127,33 +961,34 @@
 
   cpi->oxcf.framerate = framerate;
   cpi->output_framerate = cpi->oxcf.framerate;
-  cpi->per_frame_bandwidth = (int)(cpi->oxcf.target_bandwidth
-                             / cpi->output_framerate);
-  cpi->av_per_frame_bandwidth = (int)(cpi->oxcf.target_bandwidth
-                                / cpi->output_framerate);
-  cpi->min_frame_bandwidth = (int)(cpi->av_per_frame_bandwidth *
-                                   cpi->oxcf.two_pass_vbrmin_section / 100);
+  cpi->rc.per_frame_bandwidth = (int)(cpi->oxcf.target_bandwidth
+                                      / cpi->output_framerate);
+  cpi->rc.av_per_frame_bandwidth = (int)(cpi->oxcf.target_bandwidth
+                                         / cpi->output_framerate);
+  cpi->rc.min_frame_bandwidth = (int)(cpi->rc.av_per_frame_bandwidth *
+                                      cpi->oxcf.two_pass_vbrmin_section / 100);
 
 
-  cpi->min_frame_bandwidth = MAX(cpi->min_frame_bandwidth, FRAME_OVERHEAD_BITS);
+  cpi->rc.min_frame_bandwidth = MAX(cpi->rc.min_frame_bandwidth,
+                                    FRAME_OVERHEAD_BITS);
 
   // Set Maximum gf/arf interval
-  cpi->max_gf_interval = 16;
+  cpi->rc.max_gf_interval = 16;
 
   // Extended interval for genuinely static scenes
   cpi->twopass.static_scene_max_gf_interval = cpi->key_frame_frequency >> 1;
 
   // Special conditions when alt ref frame enabled in lagged compress mode
   if (cpi->oxcf.play_alternate && cpi->oxcf.lag_in_frames) {
-    if (cpi->max_gf_interval > cpi->oxcf.lag_in_frames - 1)
-      cpi->max_gf_interval = cpi->oxcf.lag_in_frames - 1;
+    if (cpi->rc.max_gf_interval > cpi->oxcf.lag_in_frames - 1)
+      cpi->rc.max_gf_interval = cpi->oxcf.lag_in_frames - 1;
 
     if (cpi->twopass.static_scene_max_gf_interval > cpi->oxcf.lag_in_frames - 1)
       cpi->twopass.static_scene_max_gf_interval = cpi->oxcf.lag_in_frames - 1;
   }
 
-  if (cpi->max_gf_interval > cpi->twopass.static_scene_max_gf_interval)
-    cpi->max_gf_interval = cpi->twopass.static_scene_max_gf_interval;
+  if (cpi->rc.max_gf_interval > cpi->twopass.static_scene_max_gf_interval)
+    cpi->rc.max_gf_interval = cpi->twopass.static_scene_max_gf_interval;
 }
 
 static int64_t rescale(int val, int64_t num, int denom) {
@@ -1194,21 +1029,21 @@
   vp9_change_config(ptr, oxcf);
 
   // Initialize active best and worst q and average q values.
-  cpi->active_worst_quality         = cpi->oxcf.worst_allowed_q;
-  cpi->active_best_quality          = cpi->oxcf.best_allowed_q;
-  cpi->avg_frame_qindex             = cpi->oxcf.worst_allowed_q;
+  cpi->rc.active_worst_quality         = cpi->oxcf.worst_allowed_q;
+  cpi->rc.active_best_quality          = cpi->oxcf.best_allowed_q;
+  cpi->rc.avg_frame_qindex          = cpi->oxcf.worst_allowed_q;
 
   // Initialise the starting buffer levels
-  cpi->buffer_level                 = cpi->oxcf.starting_buffer_level;
-  cpi->bits_off_target              = cpi->oxcf.starting_buffer_level;
+  cpi->rc.buffer_level              = cpi->oxcf.starting_buffer_level;
+  cpi->rc.bits_off_target           = cpi->oxcf.starting_buffer_level;
 
-  cpi->rolling_target_bits          = cpi->av_per_frame_bandwidth;
-  cpi->rolling_actual_bits          = cpi->av_per_frame_bandwidth;
-  cpi->long_rolling_target_bits     = cpi->av_per_frame_bandwidth;
-  cpi->long_rolling_actual_bits     = cpi->av_per_frame_bandwidth;
+  cpi->rc.rolling_target_bits       = cpi->rc.av_per_frame_bandwidth;
+  cpi->rc.rolling_actual_bits       = cpi->rc.av_per_frame_bandwidth;
+  cpi->rc.long_rolling_target_bits  = cpi->rc.av_per_frame_bandwidth;
+  cpi->rc.long_rolling_actual_bits  = cpi->rc.av_per_frame_bandwidth;
 
-  cpi->total_actual_bits            = 0;
-  cpi->total_target_vs_actual       = 0;
+  cpi->rc.total_actual_bits         = 0;
+  cpi->rc.total_target_vs_actual    = 0;
 
   cpi->static_mb_pct = 0;
 
@@ -1272,7 +1107,7 @@
   cpi->oxcf.lossless = oxcf->lossless;
   cpi->mb.e_mbd.itxm_add = cpi->oxcf.lossless ? vp9_iwht4x4_add
                                               : vp9_idct4x4_add;
-  cpi->baseline_gf_interval = DEFAULT_GF_INTERVAL;
+  cpi->rc.baseline_gf_interval = DEFAULT_GF_INTERVAL;
 
   cpi->ref_frame_flags = VP9_ALT_FLAG | VP9_GOLD_FLAG | VP9_LAST_FLAG;
 
@@ -1327,20 +1162,18 @@
   vp9_new_framerate(cpi, cpi->oxcf.framerate);
 
   // Set absolute upper and lower quality limits
-  cpi->worst_quality = cpi->oxcf.worst_allowed_q;
-  cpi->best_quality = cpi->oxcf.best_allowed_q;
+  cpi->rc.worst_quality = cpi->oxcf.worst_allowed_q;
+  cpi->rc.best_quality = cpi->oxcf.best_allowed_q;
 
   // active values should only be modified if out of new range
-  cpi->active_worst_quality = clamp(cpi->active_worst_quality,
+  cpi->rc.active_worst_quality = clamp(cpi->rc.active_worst_quality,
                                     cpi->oxcf.best_allowed_q,
                                     cpi->oxcf.worst_allowed_q);
 
-  cpi->active_best_quality = clamp(cpi->active_best_quality,
+  cpi->rc.active_best_quality = clamp(cpi->rc.active_best_quality,
                                    cpi->oxcf.best_allowed_q,
                                    cpi->oxcf.worst_allowed_q);
 
-  cpi->buffered_mode = cpi->oxcf.optimal_buffer_level > 0;
-
   cpi->cq_target_quality = cpi->oxcf.cq_level;
 
   cm->mcomp_filter_type = DEFAULT_INTERP_FILTER;
@@ -1365,9 +1198,9 @@
   update_frame_size(cpi);
 
   if (cpi->oxcf.fixed_q >= 0) {
-    cpi->last_q[0] = cpi->oxcf.fixed_q;
-    cpi->last_q[1] = cpi->oxcf.fixed_q;
-    cpi->last_boosted_qindex = cpi->oxcf.fixed_q;
+    cpi->rc.last_q[0] = cpi->oxcf.fixed_q;
+    cpi->rc.last_q[1] = cpi->oxcf.fixed_q;
+    cpi->rc.last_boosted_qindex = cpi->oxcf.fixed_q;
   }
 
   cpi->speed = cpi->oxcf.cpu_used;
@@ -1595,16 +1428,12 @@
   init_pick_mode_context(cpi);
 
   cm->current_video_frame   = 0;
-  cpi->kf_overspend_bits            = 0;
-  cpi->kf_bitrate_adjustment        = 0;
-  cpi->frames_till_gf_update_due    = 0;
-  cpi->gf_overspend_bits            = 0;
-  cpi->non_gf_bitrate_adjustment    = 0;
+  cpi->rc.frames_till_gf_update_due = 0;
 
   // Set reference frame sign bias for ALTREF frame to 1 (for now)
   cm->ref_frame_sign_bias[ALTREF_FRAME] = 1;
 
-  cpi->baseline_gf_interval = DEFAULT_GF_INTERVAL;
+  cpi->rc.baseline_gf_interval = DEFAULT_GF_INTERVAL;
 
   cpi->gold_is_last = 0;
   cpi->alt_is_last  = 0;
@@ -1704,19 +1533,18 @@
 
   cpi->first_time_stamp_ever = INT64_MAX;
 
-  cpi->frames_till_gf_update_due      = 0;
-  cpi->key_frame_count              = 1;
+  cpi->rc.frames_till_gf_update_due      = 0;
+  cpi->rc.key_frame_count              = 1;
 
-  cpi->ni_av_qi                     = cpi->oxcf.worst_allowed_q;
-  cpi->ni_tot_qi                    = 0;
-  cpi->ni_frames                   = 0;
-  cpi->tot_q = 0.0;
-  cpi->avg_q = vp9_convert_qindex_to_q(cpi->oxcf.worst_allowed_q);
-  cpi->total_byte_count             = 0;
+  cpi->rc.ni_av_qi                     = cpi->oxcf.worst_allowed_q;
+  cpi->rc.ni_tot_qi                    = 0;
+  cpi->rc.ni_frames                   = 0;
+  cpi->rc.tot_q = 0.0;
+  cpi->rc.avg_q = vp9_convert_qindex_to_q(cpi->oxcf.worst_allowed_q);
 
-  cpi->rate_correction_factor         = 1.0;
-  cpi->key_frame_rate_correction_factor = 1.0;
-  cpi->gf_rate_correction_factor  = 1.0;
+  cpi->rc.rate_correction_factor         = 1.0;
+  cpi->rc.key_frame_rate_correction_factor = 1.0;
+  cpi->rc.gf_rate_correction_factor  = 1.0;
   cpi->twopass.est_max_qcorrection_factor  = 1.0;
 
   cal_nmvjointsadcost(cpi->mb.nmvjointsadcost);
@@ -1733,7 +1561,7 @@
   cal_nmvsadcosts_hp(cpi->mb.nmvsadcost_hp);
 
   for (i = 0; i < KEY_FRAME_CONTEXT; i++)
-    cpi->prior_key_frame_distance[i] = (int)cpi->output_framerate;
+    cpi->rc.prior_key_frame_distance[i] = (int)cpi->output_framerate;
 
 #ifdef OUTPUT_YUV_SRC
   yuv_file = fopen("bd.yuv", "ab");
@@ -1904,14 +1732,6 @@
       vp9_end_second_pass(cpi);
     }
 
-#ifdef ENTROPY_STATS
-    if (cpi->pass != 1) {
-      print_context_counters();
-      print_tree_update_probs();
-      print_mode_context(cpi);
-    }
-#endif
-
 #ifdef MODE_STATS
     if (cpi->pass != 1) {
       write_tx_count_stats();
@@ -2391,7 +2211,7 @@
 
 static void update_alt_ref_frame_stats(VP9_COMP *cpi) {
   // this frame refreshes means next frames don't unless specified by user
-  cpi->frames_since_golden = 0;
+  cpi->rc.frames_since_golden = 0;
 
 #if CONFIG_MULTIPLE_ARF
   if (!cpi->multi_arf_enabled)
@@ -2407,7 +2227,7 @@
   if (cpi->refresh_golden_frame) {
     // this frame refreshes means next frames don't unless specified by user
     cpi->refresh_golden_frame = 0;
-    cpi->frames_since_golden = 0;
+    cpi->rc.frames_since_golden = 0;
 
     // ******** Fixed Q test code only ************
     // If we are going to use the ALT reference for the next group of frames
@@ -2415,12 +2235,12 @@
     if (cpi->oxcf.fixed_q >= 0 &&
         cpi->oxcf.play_alternate && !cpi->refresh_alt_ref_frame) {
       cpi->source_alt_ref_pending = 1;
-      cpi->frames_till_gf_update_due = cpi->baseline_gf_interval;
+      cpi->rc.frames_till_gf_update_due = cpi->rc.baseline_gf_interval;
 
       // TODO(ivan): For SVC encoder, GF automatic update is disabled by using
       // a large GF_interval.
       if (cpi->use_svc) {
-        cpi->frames_till_gf_update_due = INT_MAX;
+        cpi->rc.frames_till_gf_update_due = INT_MAX;
       }
     }
 
@@ -2428,18 +2248,18 @@
       cpi->source_alt_ref_active = 0;
 
     // Decrement count down till next gf
-    if (cpi->frames_till_gf_update_due > 0)
-      cpi->frames_till_gf_update_due--;
+    if (cpi->rc.frames_till_gf_update_due > 0)
+      cpi->rc.frames_till_gf_update_due--;
 
   } else if (!cpi->refresh_alt_ref_frame) {
     // Decrement count down till next gf
-    if (cpi->frames_till_gf_update_due > 0)
-      cpi->frames_till_gf_update_due--;
+    if (cpi->rc.frames_till_gf_update_due > 0)
+      cpi->rc.frames_till_gf_update_due--;
 
     if (cpi->frames_till_alt_ref_frame)
       cpi->frames_till_alt_ref_frame--;
 
-    cpi->frames_since_golden++;
+    cpi->rc.frames_since_golden++;
   }
 }
 
@@ -2549,21 +2369,22 @@
         cpi->refresh_golden_frame ||
         cpi->refresh_alt_ref_frame))) {
     // General over and under shoot tests
-    if (((cpi->projected_frame_size > high_limit) && (q < maxq)) ||
-        ((cpi->projected_frame_size < low_limit) && (q > minq))) {
+    if (((cpi->rc.projected_frame_size > high_limit) && (q < maxq)) ||
+        ((cpi->rc.projected_frame_size < low_limit) && (q > minq))) {
       force_recode = 1;
     } else if (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) {
       // Deal with frame undershoot and whether or not we are
       // below the automatically set cq level.
       if (q > cpi->cq_target_quality &&
-          cpi->projected_frame_size < ((cpi->this_frame_target * 7) >> 3)) {
+          cpi->rc.projected_frame_size <
+          ((cpi->rc.this_frame_target * 7) >> 3)) {
         force_recode = 1;
       } else if (q > cpi->oxcf.cq_level &&
-                 cpi->projected_frame_size < cpi->min_frame_bandwidth &&
-                 cpi->active_best_quality > cpi->oxcf.cq_level) {
+                 cpi->rc.projected_frame_size < cpi->rc.min_frame_bandwidth &&
+                 cpi->rc.active_best_quality > cpi->oxcf.cq_level) {
         // Severe undershoot and between auto and user cq level
         force_recode = 1;
-        cpi->active_best_quality = cpi->oxcf.cq_level;
+        cpi->rc.active_best_quality = cpi->oxcf.cq_level;
       }
     }
   }
@@ -2730,25 +2551,26 @@
         "%7.2f %7.2f %7.2f %7.2f %7.2f %7.2f %7.2f"
         "%6d %6d %5d %5d %5d %8.2f %10d %10.3f"
         "%10.3f %8d %10d %10d %10d\n",
-        cpi->common.current_video_frame, cpi->this_frame_target,
-        cpi->projected_frame_size, 0,
-        (cpi->projected_frame_size - cpi->this_frame_target),
-        (int)cpi->total_target_vs_actual,
-        (int)(cpi->oxcf.starting_buffer_level - cpi->bits_off_target),
-        (int)cpi->total_actual_bits, cm->base_qindex,
+        cpi->common.current_video_frame, cpi->rc.this_frame_target,
+        cpi->rc.projected_frame_size, 0,
+        (cpi->rc.projected_frame_size - cpi->rc.this_frame_target),
+        (int)cpi->rc.total_target_vs_actual,
+        (int)(cpi->oxcf.starting_buffer_level - cpi->rc.bits_off_target),
+        (int)cpi->rc.total_actual_bits, cm->base_qindex,
         vp9_convert_qindex_to_q(cm->base_qindex),
         (double)vp9_dc_quant(cm->base_qindex, 0) / 4.0,
-        vp9_convert_qindex_to_q(cpi->active_best_quality),
-        vp9_convert_qindex_to_q(cpi->active_worst_quality), cpi->avg_q,
-        vp9_convert_qindex_to_q(cpi->ni_av_qi),
+        vp9_convert_qindex_to_q(cpi->rc.active_best_quality),
+        vp9_convert_qindex_to_q(cpi->rc.active_worst_quality), cpi->rc.avg_q,
+        vp9_convert_qindex_to_q(cpi->rc.ni_av_qi),
         vp9_convert_qindex_to_q(cpi->cq_target_quality),
         cpi->refresh_last_frame, cpi->refresh_golden_frame,
-        cpi->refresh_alt_ref_frame, cm->frame_type, cpi->gfu_boost,
+        cpi->refresh_alt_ref_frame, cm->frame_type, cpi->rc.gfu_boost,
         cpi->twopass.est_max_qcorrection_factor, (int)cpi->twopass.bits_left,
         cpi->twopass.total_left_stats.coded_error,
         (double)cpi->twopass.bits_left /
             (1 + cpi->twopass.total_left_stats.coded_error),
-        cpi->tot_recode_hits, recon_err, cpi->kf_boost, cpi->kf_zeromotion_pct);
+        cpi->tot_recode_hits, recon_err, cpi->rc.kf_boost,
+        cpi->kf_zeromotion_pct);
 
   fclose(f);
 
@@ -2772,194 +2594,212 @@
 }
 #endif
 
-static int pick_q_and_adjust_q_bounds(VP9_COMP *cpi,
-                                      int * bottom_index, int * top_index) {
-  // Set an active best quality and if necessary active worst quality
-  int q = cpi->active_worst_quality;
+static void encode_with_recode_loop(VP9_COMP *cpi,
+                                    unsigned long *size,
+                                    uint8_t *dest,
+                                    int q,
+                                    int bottom_index,
+                                    int top_index,
+                                    int frame_over_shoot_limit,
+                                    int frame_under_shoot_limit) {
   VP9_COMMON *const cm = &cpi->common;
+  int loop_count = 0;
+  int loop = 0;
+  int overshoot_seen = 0;
+  int undershoot_seen = 0;
+  int active_worst_qchanged = 0;
+  int q_low = bottom_index, q_high = top_index;
+  do {
+    vp9_clear_system_state();  // __asm emms;
 
-  if (frame_is_intra_only(cm)) {
-#if !CONFIG_MULTIPLE_ARF
-    // Handle the special case for key frames forced when we have75 reached
-    // the maximum key frame interval. Here force the Q to a range
-    // based on the ambient Q to reduce the risk of popping.
-    if (cpi->this_key_frame_forced) {
-      int delta_qindex;
-      int qindex = cpi->last_boosted_qindex;
-      double last_boosted_q = vp9_convert_qindex_to_q(qindex);
+    vp9_set_quantizer(cpi, q);
 
-      delta_qindex = vp9_compute_qdelta(cpi, last_boosted_q,
-                                        (last_boosted_q * 0.75));
-
-      cpi->active_best_quality = MAX(qindex + delta_qindex,
-                                     cpi->best_quality);
-    } else {
-      int high = 5000;
-      int low = 400;
-      double q_adj_factor = 1.0;
-      double q_val;
-
-      // Baseline value derived from cpi->active_worst_quality and kf boost
-      cpi->active_best_quality = get_active_quality(q, cpi->kf_boost,
-                                                    low, high,
-                                                    kf_low_motion_minq,
-                                                    kf_high_motion_minq);
-
-      // Allow somewhat lower kf minq with small image formats.
-      if ((cm->width * cm->height) <= (352 * 288)) {
-        q_adj_factor -= 0.25;
-      }
-
-      // Make a further adjustment based on the kf zero motion measure.
-      q_adj_factor += 0.05 - (0.001 * (double)cpi->kf_zeromotion_pct);
-
-      // Convert the adjustment factor to a qindex delta
-      // on active_best_quality.
-      q_val = vp9_convert_qindex_to_q(cpi->active_best_quality);
-      cpi->active_best_quality +=
-          vp9_compute_qdelta(cpi, q_val, (q_val * q_adj_factor));
-    }
-#else
-    double current_q;
-    // Force the KF quantizer to be 30% of the active_worst_quality.
-    current_q = vp9_convert_qindex_to_q(cpi->active_worst_quality);
-    cpi->active_best_quality = cpi->active_worst_quality
-        + vp9_compute_qdelta(cpi, current_q, current_q * 0.3);
-#endif
-  } else if (!cpi->is_src_frame_alt_ref &&
-             (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) {
-    int high = 2000;
-    int low = 400;
-
-    // Use the lower of cpi->active_worst_quality and recent
-    // average Q as basis for GF/ARF best Q limit unless last frame was
-    // a key frame.
-    if (cpi->frames_since_key > 1 &&
-        cpi->avg_frame_qindex < cpi->active_worst_quality) {
-      q = cpi->avg_frame_qindex;
-    }
-    // For constrained quality dont allow Q less than the cq level
-    if (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) {
-      if (q < cpi->cq_target_quality)
-        q = cpi->cq_target_quality;
-      if (cpi->frames_since_key > 1) {
-        cpi->active_best_quality = get_active_quality(q, cpi->gfu_boost,
-                                                      low, high,
-                                                      afq_low_motion_minq,
-                                                      afq_high_motion_minq);
+    if (loop_count == 0) {
+      // Set up entropy context depending on frame type. The decoder mandates
+      // the use of the default context, index 0, for keyframes and inter
+      // frames where the error_resilient_mode or intra_only flag is set. For
+      // other inter-frames the encoder currently uses only two contexts;
+      // context 1 for ALTREF frames and context 0 for the others.
+      if (cm->frame_type == KEY_FRAME) {
+        vp9_setup_key_frame(cpi);
       } else {
-        cpi->active_best_quality = get_active_quality(q, cpi->gfu_boost,
-                                                      low, high,
-                                                      gf_low_motion_minq,
-                                                      gf_high_motion_minq);
-      }
-      // Constrained quality use slightly lower active best.
-      cpi->active_best_quality = cpi->active_best_quality * 15 / 16;
-
-    } else if (cpi->oxcf.end_usage == USAGE_CONSTANT_QUALITY) {
-      if (!cpi->refresh_alt_ref_frame) {
-        cpi->active_best_quality = cpi->cq_target_quality;
-      } else {
-        if (cpi->frames_since_key > 1) {
-          cpi->active_best_quality = get_active_quality(q, cpi->gfu_boost,
-                                                        low, high,
-                                                        afq_low_motion_minq,
-                                                        afq_high_motion_minq);
-        } else {
-          cpi->active_best_quality = get_active_quality(q, cpi->gfu_boost,
-                                                        low, high,
-                                                        gf_low_motion_minq,
-                                                        gf_high_motion_minq);
+        if (!cm->intra_only && !cm->error_resilient_mode) {
+          cpi->common.frame_context_idx = cpi->refresh_alt_ref_frame;
         }
+        vp9_setup_inter_frame(cpi);
       }
-    } else {
-        cpi->active_best_quality = get_active_quality(q, cpi->gfu_boost,
-                                                      low, high,
-                                                      gf_low_motion_minq,
-                                                      gf_high_motion_minq);
     }
-  } else {
+
+    if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
+        vp9_vaq_frame_setup(cpi);
+    }
+
+    // transform / motion compensation build reconstruction frame
+
+    vp9_encode_frame(cpi);
+
+    // Update the skip mb flag probabilities based on the distribution
+    // seen in the last encoder iteration.
+    // update_base_skip_probs(cpi);
+
+    vp9_clear_system_state();  // __asm emms;
+
+    // Dummy pack of the bitstream using up to date stats to get an
+    // accurate estimate of output frame size to determine if we need
+    // to recode.
+    vp9_save_coding_context(cpi);
+    cpi->dummy_packing = 1;
+    vp9_pack_bitstream(cpi, dest, size);
+    cpi->rc.projected_frame_size = (*size) << 3;
+    vp9_restore_coding_context(cpi);
+
+    if (frame_over_shoot_limit == 0)
+      frame_over_shoot_limit = 1;
+    active_worst_qchanged = 0;
+
     if (cpi->oxcf.end_usage == USAGE_CONSTANT_QUALITY) {
-      cpi->active_best_quality = cpi->cq_target_quality;
+      loop = 0;
     } else {
-      cpi->active_best_quality = inter_minq[q];
-      // 1-pass: for now, use the average Q for the active_best, if its lower
-      // than active_worst.
-      if (cpi->pass == 0 && (cpi->avg_frame_qindex < q))
-        cpi->active_best_quality = inter_minq[cpi->avg_frame_qindex];
+      // Special case handling for forced key frames
+      if ((cm->frame_type == KEY_FRAME) && cpi->this_key_frame_forced) {
+        int last_q = q;
+        int kf_err = vp9_calc_ss_err(cpi->Source, get_frame_new_buffer(cm));
 
-      // For the constrained quality mode we don't want
-      // q to fall below the cq level.
-      if ((cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) &&
-          (cpi->active_best_quality < cpi->cq_target_quality)) {
-        // If we are strongly undershooting the target rate in the last
-        // frames then use the user passed in cq value not the auto
-        // cq value.
-        if (cpi->rolling_actual_bits < cpi->min_frame_bandwidth)
-          cpi->active_best_quality = cpi->oxcf.cq_level;
-        else
-          cpi->active_best_quality = cpi->cq_target_quality;
+        int high_err_target = cpi->ambient_err;
+        int low_err_target = cpi->ambient_err >> 1;
+
+        // Prevent possible divide by zero error below for perfect KF
+        kf_err += !kf_err;
+
+        // The key frame is not good enough or we can afford
+        // to make it better without undue risk of popping.
+        if ((kf_err > high_err_target &&
+             cpi->rc.projected_frame_size <= frame_over_shoot_limit) ||
+            (kf_err > low_err_target &&
+             cpi->rc.projected_frame_size <= frame_under_shoot_limit)) {
+          // Lower q_high
+          q_high = q > q_low ? q - 1 : q_low;
+
+          // Adjust Q
+          q = (q * high_err_target) / kf_err;
+          q = MIN(q, (q_high + q_low) >> 1);
+        } else if (kf_err < low_err_target &&
+                   cpi->rc.projected_frame_size >= frame_under_shoot_limit) {
+          // The key frame is much better than the previous frame
+          // Raise q_low
+          q_low = q < q_high ? q + 1 : q_high;
+
+          // Adjust Q
+          q = (q * low_err_target) / kf_err;
+          q = MIN(q, (q_high + q_low + 1) >> 1);
+        }
+
+        // Clamp Q to upper and lower limits:
+        q = clamp(q, q_low, q_high);
+
+        loop = q != last_q;
+      } else if (recode_loop_test(
+          cpi, frame_over_shoot_limit, frame_under_shoot_limit,
+          q, top_index, bottom_index)) {
+        // Is the projected frame size out of range and are we allowed
+        // to attempt to recode.
+        int last_q = q;
+        int retries = 0;
+
+        // Frame size out of permitted range:
+        // Update correction factor & compute new Q to try...
+
+        // Frame is too large
+        if (cpi->rc.projected_frame_size > cpi->rc.this_frame_target) {
+          // Raise Qlow as to at least the current value
+          q_low = q < q_high ? q + 1 : q_high;
+
+          if (undershoot_seen || loop_count > 1) {
+            // Update rate_correction_factor unless
+            // cpi->rc.active_worst_quality has changed.
+            if (!active_worst_qchanged)
+              vp9_update_rate_correction_factors(cpi, 1);
+
+            q = (q_high + q_low + 1) / 2;
+          } else {
+            // Update rate_correction_factor unless
+            // cpi->rc.active_worst_quality has changed.
+            if (!active_worst_qchanged)
+              vp9_update_rate_correction_factors(cpi, 0);
+
+            q = vp9_regulate_q(cpi, cpi->rc.this_frame_target);
+
+            while (q < q_low && retries < 10) {
+              vp9_update_rate_correction_factors(cpi, 0);
+              q = vp9_regulate_q(cpi, cpi->rc.this_frame_target);
+              retries++;
+            }
+          }
+
+          overshoot_seen = 1;
+        } else {
+          // Frame is too small
+          q_high = q > q_low ? q - 1 : q_low;
+
+          if (overshoot_seen || loop_count > 1) {
+            // Update rate_correction_factor unless
+            // cpi->rc.active_worst_quality has changed.
+            if (!active_worst_qchanged)
+              vp9_update_rate_correction_factors(cpi, 1);
+
+            q = (q_high + q_low) / 2;
+          } else {
+            // Update rate_correction_factor unless
+            // cpi->rc.active_worst_quality has changed.
+            if (!active_worst_qchanged)
+              vp9_update_rate_correction_factors(cpi, 0);
+
+            q = vp9_regulate_q(cpi, cpi->rc.this_frame_target);
+
+            // Special case reset for qlow for constrained quality.
+            // This should only trigger where there is very substantial
+            // undershoot on a frame and the auto cq level is above
+            // the user passsed in value.
+            if (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY && q < q_low) {
+              q_low = q;
+            }
+
+            while (q > q_high && retries < 10) {
+              vp9_update_rate_correction_factors(cpi, 0);
+              q = vp9_regulate_q(cpi, cpi->rc.this_frame_target);
+              retries++;
+            }
+          }
+
+          undershoot_seen = 1;
+        }
+
+        // Clamp Q to upper and lower limits:
+        q = clamp(q, q_low, q_high);
+
+        loop = q != last_q;
+      } else {
+        loop = 0;
       }
     }
-  }
 
-  // Clip the active best and worst quality values to limits
-  if (cpi->active_worst_quality > cpi->worst_quality)
-    cpi->active_worst_quality = cpi->worst_quality;
+    if (cpi->is_src_frame_alt_ref)
+      loop = 0;
 
-  if (cpi->active_best_quality < cpi->best_quality)
-    cpi->active_best_quality = cpi->best_quality;
+    if (loop) {
+      loop_count++;
 
-  if (cpi->active_best_quality > cpi->worst_quality)
-    cpi->active_best_quality = cpi->worst_quality;
-
-  if (cpi->active_worst_quality < cpi->active_best_quality)
-    cpi->active_worst_quality = cpi->active_best_quality;
-
-  // Limit Q range for the adaptive loop.
-  if (cm->frame_type == KEY_FRAME && !cpi->this_key_frame_forced) {
-    *top_index =
-      (cpi->active_worst_quality + cpi->active_best_quality * 3) / 4;
-    // If this is the first (key) frame in 1-pass, active best is the user
-    // best-allowed, and leave the top_index to active_worst.
-    if (cpi->pass == 0 && cpi->common.current_video_frame == 0) {
-      cpi->active_best_quality = cpi->oxcf.best_allowed_q;
-      *top_index = cpi->oxcf.worst_allowed_q;
+#if CONFIG_INTERNAL_STATS
+      cpi->tot_recode_hits++;
+#endif
     }
-  } else if (!cpi->is_src_frame_alt_ref &&
-             (cpi->oxcf.end_usage != USAGE_STREAM_FROM_SERVER) &&
-             (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) {
-    *top_index =
-      (cpi->active_worst_quality + cpi->active_best_quality) / 2;
-  } else {
-    *top_index = cpi->active_worst_quality;
-  }
-  *bottom_index = cpi->active_best_quality;
-
-  if (cpi->oxcf.end_usage == USAGE_CONSTANT_QUALITY) {
-    q = cpi->active_best_quality;
-  // Special case code to try and match quality with forced key frames
-  } else if ((cm->frame_type == KEY_FRAME) && cpi->this_key_frame_forced) {
-    q = cpi->last_boosted_qindex;
-  } else {
-    // Determine initial Q to try.
-    if (cpi->pass == 0) {
-      // 1-pass: for now, use per-frame-bw for target size of frame, scaled
-      // by |x| for key frame.
-      int scale = (cm->frame_type == KEY_FRAME) ? 5 : 1;
-      q = vp9_regulate_q(cpi, scale * cpi->av_per_frame_bandwidth);
-    } else {
-      q = vp9_regulate_q(cpi, cpi->this_frame_target);
-    }
-    if (q > *top_index)
-      q = *top_index;
-  }
-
-  return q;
+  } while (loop);
+  cpi->rc.active_worst_qchanged = active_worst_qchanged;
 }
+
 static void encode_frame_to_data_rate(VP9_COMP *cpi,
                                       unsigned long *size,
-                                      unsigned char *dest,
+                                      uint8_t *dest,
                                       unsigned int *frame_flags) {
   VP9_COMMON *const cm = &cpi->common;
   TX_SIZE t;
@@ -2967,18 +2807,8 @@
   int frame_over_shoot_limit;
   int frame_under_shoot_limit;
 
-  int loop = 0;
-  int loop_count;
-
-  int q_low;
-  int q_high;
-
   int top_index;
   int bottom_index;
-  int active_worst_qchanged = 0;
-
-  int overshoot_seen = 0;
-  int undershoot_seen = 0;
 
   SPEED_FEATURES *const sf = &cpi->sf;
   unsigned int max_mv_def = MIN(cpi->common.width, cpi->common.height);
@@ -3001,7 +2831,7 @@
   // pass function that sets the target bandwidth so we must set it here.
   if (cpi->refresh_alt_ref_frame) {
     // Set a per frame bit target for the alt ref frame.
-    cpi->per_frame_bandwidth = cpi->twopass.gf_bits;
+    cpi->rc.per_frame_bandwidth = cpi->twopass.gf_bits;
     // Set a per second target bitrate.
     cpi->target_bandwidth = (int)(cpi->twopass.gf_bits * cpi->output_framerate);
   }
@@ -3094,10 +2924,7 @@
 
   vp9_clear_system_state();
 
-  q = pick_q_and_adjust_q_bounds(cpi, &bottom_index, &top_index);
-
-  q_high = top_index;
-  q_low  = bottom_index;
+  q = vp9_pick_q_and_adjust_q_bounds(cpi, &bottom_index, &top_index);
 
   vp9_compute_frame_size_bounds(cpi, &frame_under_shoot_limit,
                                 &frame_over_shoot_limit);
@@ -3107,24 +2934,22 @@
   if (cpi->multi_arf_enabled && (cm->frame_type != KEY_FRAME) &&
       cpi->oxcf.end_usage != USAGE_CONSTANT_QUALITY) {
     double new_q;
-    double current_q = vp9_convert_qindex_to_q(cpi->active_worst_quality);
+    double current_q = vp9_convert_qindex_to_q(cpi->rc.active_worst_quality);
     int level = cpi->this_frame_weight;
     assert(level >= 0);
 
     // Set quantizer steps at 10% increments.
     new_q = current_q * (1.0 - (0.2 * (cpi->max_arf_level - level)));
-    q = cpi->active_worst_quality + vp9_compute_qdelta(cpi, current_q, new_q);
+    q = cpi->rc.active_worst_quality +
+        vp9_compute_qdelta(cpi, current_q, new_q);
 
     bottom_index = q;
     top_index    = q;
-    q_low  = q;
-    q_high = q;
 
     printf("frame:%d q:%d\n", cm->current_video_frame, q);
   }
 #endif
 
-  loop_count = 0;
   vp9_zero(cpi->rd_tx_select_threshes);
 
   if (!frame_is_intra_only(cm)) {
@@ -3135,10 +2960,8 @@
   }
 
 #if CONFIG_VP9_POSTPROC
-
   if (cpi->oxcf.noise_sensitivity > 0) {
     int l = 0;
-
     switch (cpi->oxcf.noise_sensitivity) {
       case 1:
         l = 20;
@@ -3157,201 +2980,22 @@
         l = 150;
         break;
     }
-
     vp9_denoise(cpi->Source, cpi->Source, l);
   }
-
 #endif
 
 #ifdef OUTPUT_YUV_SRC
   vp9_write_yuv_frame(cpi->Source);
 #endif
 
-  do {
-    vp9_clear_system_state();  // __asm emms;
-
-    vp9_set_quantizer(cpi, q);
-
-    if (loop_count == 0) {
-      // Set up entropy context depending on frame type. The decoder mandates
-      // the use of the default context, index 0, for keyframes and inter
-      // frames where the error_resilient_mode or intra_only flag is set. For
-      // other inter-frames the encoder currently uses only two contexts;
-      // context 1 for ALTREF frames and context 0 for the others.
-      if (cm->frame_type == KEY_FRAME) {
-        vp9_setup_key_frame(cpi);
-      } else {
-        if (!cm->intra_only && !cm->error_resilient_mode) {
-          cpi->common.frame_context_idx = cpi->refresh_alt_ref_frame;
-        }
-        vp9_setup_inter_frame(cpi);
-      }
-    }
-
-    if (cpi->sf.variance_adaptive_quantization) {
-        vp9_vaq_frame_setup(cpi);
-    }
-
-    // transform / motion compensation build reconstruction frame
-
-    vp9_encode_frame(cpi);
-
-    // Update the skip mb flag probabilities based on the distribution
-    // seen in the last encoder iteration.
-    // update_base_skip_probs(cpi);
-
-    vp9_clear_system_state();  // __asm emms;
-
-    // Dummy pack of the bitstream using up to date stats to get an
-    // accurate estimate of output frame size to determine if we need
-    // to recode.
-    vp9_save_coding_context(cpi);
-    cpi->dummy_packing = 1;
-    vp9_pack_bitstream(cpi, dest, size);
-    cpi->projected_frame_size = (*size) << 3;
-    vp9_restore_coding_context(cpi);
-
-    if (frame_over_shoot_limit == 0)
-      frame_over_shoot_limit = 1;
-    active_worst_qchanged = 0;
-
-    if (cpi->oxcf.end_usage == USAGE_CONSTANT_QUALITY) {
-      loop = 0;
-    } else {
-      // Special case handling for forced key frames
-      if ((cm->frame_type == KEY_FRAME) && cpi->this_key_frame_forced) {
-        int last_q = q;
-        int kf_err = vp9_calc_ss_err(cpi->Source, get_frame_new_buffer(cm));
-
-        int high_err_target = cpi->ambient_err;
-        int low_err_target = cpi->ambient_err >> 1;
-
-        // Prevent possible divide by zero error below for perfect KF
-        kf_err += !kf_err;
-
-        // The key frame is not good enough or we can afford
-        // to make it better without undue risk of popping.
-        if ((kf_err > high_err_target &&
-             cpi->projected_frame_size <= frame_over_shoot_limit) ||
-            (kf_err > low_err_target &&
-             cpi->projected_frame_size <= frame_under_shoot_limit)) {
-          // Lower q_high
-          q_high = q > q_low ? q - 1 : q_low;
-
-          // Adjust Q
-          q = (q * high_err_target) / kf_err;
-          q = MIN(q, (q_high + q_low) >> 1);
-        } else if (kf_err < low_err_target &&
-                   cpi->projected_frame_size >= frame_under_shoot_limit) {
-          // The key frame is much better than the previous frame
-          // Raise q_low
-          q_low = q < q_high ? q + 1 : q_high;
-
-          // Adjust Q
-          q = (q * low_err_target) / kf_err;
-          q = MIN(q, (q_high + q_low + 1) >> 1);
-        }
-
-        // Clamp Q to upper and lower limits:
-        q = clamp(q, q_low, q_high);
-
-        loop = q != last_q;
-      } else if (recode_loop_test(
-          cpi, frame_over_shoot_limit, frame_under_shoot_limit,
-          q, top_index, bottom_index)) {
-        // Is the projected frame size out of range and are we allowed
-        // to attempt to recode.
-        int last_q = q;
-        int retries = 0;
-
-        // Frame size out of permitted range:
-        // Update correction factor & compute new Q to try...
-
-        // Frame is too large
-        if (cpi->projected_frame_size > cpi->this_frame_target) {
-          // Raise Qlow as to at least the current value
-          q_low = q < q_high ? q + 1 : q_high;
-
-          if (undershoot_seen || loop_count > 1) {
-            // Update rate_correction_factor unless
-            // cpi->active_worst_quality has changed.
-            if (!active_worst_qchanged)
-              vp9_update_rate_correction_factors(cpi, 1);
-
-            q = (q_high + q_low + 1) / 2;
-          } else {
-            // Update rate_correction_factor unless
-            // cpi->active_worst_quality has changed.
-            if (!active_worst_qchanged)
-              vp9_update_rate_correction_factors(cpi, 0);
-
-            q = vp9_regulate_q(cpi, cpi->this_frame_target);
-
-            while (q < q_low && retries < 10) {
-              vp9_update_rate_correction_factors(cpi, 0);
-              q = vp9_regulate_q(cpi, cpi->this_frame_target);
-              retries++;
-            }
-          }
-
-          overshoot_seen = 1;
-        } else {
-          // Frame is too small
-          q_high = q > q_low ? q - 1 : q_low;
-
-          if (overshoot_seen || loop_count > 1) {
-            // Update rate_correction_factor unless
-            // cpi->active_worst_quality has changed.
-            if (!active_worst_qchanged)
-              vp9_update_rate_correction_factors(cpi, 1);
-
-            q = (q_high + q_low) / 2;
-          } else {
-            // Update rate_correction_factor unless
-            // cpi->active_worst_quality has changed.
-            if (!active_worst_qchanged)
-              vp9_update_rate_correction_factors(cpi, 0);
-
-            q = vp9_regulate_q(cpi, cpi->this_frame_target);
-
-            // Special case reset for qlow for constrained quality.
-            // This should only trigger where there is very substantial
-            // undershoot on a frame and the auto cq level is above
-            // the user passsed in value.
-            if (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY && q < q_low) {
-              q_low = q;
-            }
-
-            while (q > q_high && retries < 10) {
-              vp9_update_rate_correction_factors(cpi, 0);
-              q = vp9_regulate_q(cpi, cpi->this_frame_target);
-              retries++;
-            }
-          }
-
-          undershoot_seen = 1;
-        }
-
-        // Clamp Q to upper and lower limits:
-        q = clamp(q, q_low, q_high);
-
-        loop = q != last_q;
-      } else {
-        loop = 0;
-      }
-    }
-
-    if (cpi->is_src_frame_alt_ref)
-      loop = 0;
-
-    if (loop) {
-      loop_count++;
-
-#if CONFIG_INTERNAL_STATS
-      cpi->tot_recode_hits++;
-#endif
-    }
-  } while (loop);
+  encode_with_recode_loop(cpi,
+                          size,
+                          dest,
+                          q,
+                          bottom_index,
+                          top_index,
+                          frame_over_shoot_limit,
+                          frame_under_shoot_limit);
 
   // Special case code to reduce pulsing when key frames are forced at a
   // fixed interval. Note the reconstruction error if it is the frame before
@@ -3431,28 +3075,27 @@
   cm->last_frame_type = cm->frame_type;
 
   // Update rate control heuristics
-  cpi->total_byte_count += (*size);
-  cpi->projected_frame_size = (*size) << 3;
+  cpi->rc.projected_frame_size = (*size) << 3;
 
   // Post encode loop adjustment of Q prediction.
-  if (!active_worst_qchanged)
+  if (!cpi->rc.active_worst_qchanged)
     vp9_update_rate_correction_factors(cpi, (cpi->sf.recode_loop ||
         cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) ? 2 : 0);
 
 
-  cpi->last_q[cm->frame_type] = cm->base_qindex;
+  cpi->rc.last_q[cm->frame_type] = cm->base_qindex;
 
   // Keep record of last boosted (KF/KF/ARF) Q value.
   // If the current frame is coded at a lower Q then we also update it.
   // If all mbs in this group are skipped only update if the Q value is
   // better than that already stored.
   // This is used to help set quality in forced key frames to reduce popping
-  if ((cm->base_qindex < cpi->last_boosted_qindex) ||
+  if ((cm->base_qindex < cpi->rc.last_boosted_qindex) ||
       ((cpi->static_mb_pct < 100) &&
        ((cm->frame_type == KEY_FRAME) ||
         cpi->refresh_alt_ref_frame ||
         (cpi->refresh_golden_frame && !cpi->is_src_frame_alt_ref)))) {
-    cpi->last_boosted_qindex = cm->base_qindex;
+    cpi->rc.last_boosted_qindex = cm->base_qindex;
   }
 
   if (cm->frame_type == KEY_FRAME) {
@@ -3461,7 +3104,7 @@
 
   // Keep a record of ambient average Q.
   if (cm->frame_type != KEY_FRAME)
-    cpi->avg_frame_qindex = (2 + 3 * cpi->avg_frame_qindex +
+    cpi->rc.avg_frame_qindex = (2 + 3 * cpi->rc.avg_frame_qindex +
                             cm->base_qindex) >> 2;
 
   // Keep a record from which we can calculate the average Q excluding GF
@@ -3469,61 +3112,64 @@
   if (cm->frame_type != KEY_FRAME &&
       !cpi->refresh_golden_frame &&
       !cpi->refresh_alt_ref_frame) {
-    cpi->ni_frames++;
-    cpi->tot_q += vp9_convert_qindex_to_q(q);
-    cpi->avg_q = cpi->tot_q / (double)cpi->ni_frames;
+    cpi->rc.ni_frames++;
+    cpi->rc.tot_q += vp9_convert_qindex_to_q(q);
+    cpi->rc.avg_q = cpi->rc.tot_q / (double)cpi->rc.ni_frames;
 
     // Calculate the average Q for normal inter frames (not key or GFU frames).
-    cpi->ni_tot_qi += q;
-    cpi->ni_av_qi = cpi->ni_tot_qi / cpi->ni_frames;
+    cpi->rc.ni_tot_qi += q;
+    cpi->rc.ni_av_qi = cpi->rc.ni_tot_qi / cpi->rc.ni_frames;
   }
 
   // Update the buffer level variable.
   // Non-viewable frames are a special case and are treated as pure overhead.
   if (!cm->show_frame)
-    cpi->bits_off_target -= cpi->projected_frame_size;
+    cpi->rc.bits_off_target -= cpi->rc.projected_frame_size;
   else
-    cpi->bits_off_target += cpi->av_per_frame_bandwidth -
-                            cpi->projected_frame_size;
+    cpi->rc.bits_off_target += cpi->rc.av_per_frame_bandwidth -
+                               cpi->rc.projected_frame_size;
 
   // Clip the buffer level at the maximum buffer size
-  if (cpi->bits_off_target > cpi->oxcf.maximum_buffer_size)
-    cpi->bits_off_target = cpi->oxcf.maximum_buffer_size;
+  if (cpi->rc.bits_off_target > cpi->oxcf.maximum_buffer_size)
+    cpi->rc.bits_off_target = cpi->oxcf.maximum_buffer_size;
 
   // Rolling monitors of whether we are over or underspending used to help
   // regulate min and Max Q in two pass.
   if (cm->frame_type != KEY_FRAME) {
-    cpi->rolling_target_bits =
-      ((cpi->rolling_target_bits * 3) + cpi->this_frame_target + 2) / 4;
-    cpi->rolling_actual_bits =
-      ((cpi->rolling_actual_bits * 3) + cpi->projected_frame_size + 2) / 4;
-    cpi->long_rolling_target_bits =
-      ((cpi->long_rolling_target_bits * 31) + cpi->this_frame_target + 16) / 32;
-    cpi->long_rolling_actual_bits =
-      ((cpi->long_rolling_actual_bits * 31) +
-       cpi->projected_frame_size + 16) / 32;
+    cpi->rc.rolling_target_bits =
+        ((cpi->rc.rolling_target_bits * 3) +
+         cpi->rc.this_frame_target + 2) / 4;
+    cpi->rc.rolling_actual_bits =
+        ((cpi->rc.rolling_actual_bits * 3) +
+         cpi->rc.projected_frame_size + 2) / 4;
+    cpi->rc.long_rolling_target_bits =
+        ((cpi->rc.long_rolling_target_bits * 31) +
+         cpi->rc.this_frame_target + 16) / 32;
+    cpi->rc.long_rolling_actual_bits =
+        ((cpi->rc.long_rolling_actual_bits * 31) +
+         cpi->rc.projected_frame_size + 16) / 32;
   }
 
   // Actual bits spent
-  cpi->total_actual_bits += cpi->projected_frame_size;
+  cpi->rc.total_actual_bits += cpi->rc.projected_frame_size;
 
   // Debug stats
-  cpi->total_target_vs_actual += (cpi->this_frame_target -
-                                  cpi->projected_frame_size);
+  cpi->rc.total_target_vs_actual += (cpi->rc.this_frame_target -
+                                     cpi->rc.projected_frame_size);
 
-  cpi->buffer_level = cpi->bits_off_target;
+  cpi->rc.buffer_level = cpi->rc.bits_off_target;
 
 #ifndef DISABLE_RC_LONG_TERM_MEM
   // Update bits left to the kf and gf groups to account for overshoot or
   // undershoot on these frames
   if (cm->frame_type == KEY_FRAME) {
-    cpi->twopass.kf_group_bits += cpi->this_frame_target -
-                                  cpi->projected_frame_size;
+    cpi->twopass.kf_group_bits += cpi->rc.this_frame_target -
+                                  cpi->rc.projected_frame_size;
 
     cpi->twopass.kf_group_bits = MAX(cpi->twopass.kf_group_bits, 0);
   } else if (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame) {
-    cpi->twopass.gf_group_bits += cpi->this_frame_target -
-                                  cpi->projected_frame_size;
+    cpi->twopass.gf_group_bits += cpi->rc.this_frame_target -
+                                  cpi->rc.projected_frame_size;
 
     cpi->twopass.gf_group_bits = MAX(cpi->twopass.gf_group_bits, 0);
   }
@@ -3658,7 +3304,7 @@
   encode_frame_to_data_rate(cpi, size, dest, frame_flags);
   // vp9_print_modes_and_motion_vectors(&cpi->common, "encode.stt");
 #ifdef DISABLE_RC_LONG_TERM_MEM
-  cpi->twopass.bits_left -=  cpi->this_frame_target;
+  cpi->twopass.bits_left -=  cpi->rc.this_frame_target;
 #else
   cpi->twopass.bits_left -= 8 * *size;
 #endif
@@ -3763,7 +3409,7 @@
         - cpi->next_frame_in_order;
     else
 #endif
-      frames_to_arf = cpi->frames_till_gf_update_due;
+      frames_to_arf = cpi->rc.frames_till_gf_update_due;
 
     assert(frames_to_arf < cpi->twopass.frames_to_key);
 
@@ -3778,7 +3424,7 @@
         // Produce the filtered ARF frame.
         // TODO(agrange) merge these two functions.
         configure_arnr_filter(cpi, cm->current_video_frame + frames_to_arf,
-                              cpi->gfu_boost);
+                              cpi->rc.gfu_boost);
         vp9_temporal_filter_prepare(cpi, frames_to_arf);
         vp9_extend_frame_borders(&cpi->alt_ref_buffer,
                                  cm->subsampling_x, cm->subsampling_y);
@@ -3975,7 +3621,7 @@
 
   vp9_setup_interp_filters(&cpi->mb.e_mbd, DEFAULT_INTERP_FILTER, cm);
 
-  if (cpi->sf.variance_adaptive_quantization) {
+  if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
       vp9_vaq_init();
   }
 
diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h
index 9e80212..8fa6385 100644
--- a/vp9/encoder/vp9_onyx_int.h
+++ b/vp9/encoder/vp9_onyx_int.h
@@ -248,7 +248,6 @@
   int auto_mv_step_size;
   int optimize_coefficients;
   int static_segmentation;
-  int variance_adaptive_quantization;
   int comp_inter_joint_search_thresh;
   int adaptive_rd_thresh;
   int skip_encode_sb;
@@ -290,6 +289,59 @@
   int use_fast_coef_updates;  // 0: 2-loop, 1: 1-loop, 2: 1-loop reduced
 } SPEED_FEATURES;
 
+typedef struct {
+  // Rate targetting variables
+  int this_frame_target;
+  int projected_frame_size;
+  int last_q[2];                   // Separate values for Intra/Inter
+  int last_boosted_qindex;         // Last boosted GF/KF/ARF q
+
+  int gfu_boost;
+  int last_boost;
+  int kf_boost;
+
+  double rate_correction_factor;
+  double key_frame_rate_correction_factor;
+  double gf_rate_correction_factor;
+
+  unsigned int frames_since_golden;
+  int frames_till_gf_update_due;  // Count down till next GF
+
+  int max_gf_interval;
+  int baseline_gf_interval;
+
+  int64_t key_frame_count;
+  int prior_key_frame_distance[KEY_FRAME_CONTEXT];
+  int per_frame_bandwidth;  // Current section per frame bandwidth target
+  int av_per_frame_bandwidth;  // Average frame size target for clip
+  int min_frame_bandwidth;  // Minimum allocation used for any frame
+
+  int ni_av_qi;
+  int ni_tot_qi;
+  int ni_frames;
+  int avg_frame_qindex;
+  double tot_q;
+  double avg_q;
+
+  int buffer_level;
+  int bits_off_target;
+
+  int rolling_target_bits;
+  int rolling_actual_bits;
+
+  int long_rolling_target_bits;
+  int long_rolling_actual_bits;
+
+  int64_t total_actual_bits;
+  int total_target_vs_actual;        // debug stats
+
+  int worst_quality;
+  int active_worst_quality;
+  int best_quality;
+  int active_best_quality;
+  int active_worst_qchanged;
+} RATE_CONTROL;
+
 typedef struct VP9_COMP {
   DECLARE_ALIGNED(16, int16_t, y_quant[QINDEX_RANGE][8]);
   DECLARE_ALIGNED(16, int16_t, y_quant_shift[QINDEX_RANGE][8]);
@@ -399,71 +451,17 @@
 
   CODING_CONTEXT coding_context;
 
-  // Rate targetting variables
-  int this_frame_target;
-  int projected_frame_size;
-  int last_q[2];                   // Separate values for Intra/Inter
-  int last_boosted_qindex;         // Last boosted GF/KF/ARF q
-
-  double rate_correction_factor;
-  double key_frame_rate_correction_factor;
-  double gf_rate_correction_factor;
-
-  unsigned int frames_since_golden;
-  int frames_till_gf_update_due;  // Count down till next GF
-
-  int gf_overspend_bits;  // cumulative bits overspent because of GF boost
-
-  int non_gf_bitrate_adjustment;  // Following GF to recover extra bits spent
-
-  int kf_overspend_bits;  // Bits spent on key frames to be recovered on inters
-  int kf_bitrate_adjustment;  // number of bits to recover on each inter frame.
-  int max_gf_interval;
-  int baseline_gf_interval;
+  int zbin_mode_boost;
+  int zbin_mode_boost_enabled;
   int active_arnr_frames;           // <= cpi->oxcf.arnr_max_frames
   int active_arnr_strength;         // <= cpi->oxcf.arnr_max_strength
 
-  int64_t key_frame_count;
-  int prior_key_frame_distance[KEY_FRAME_CONTEXT];
-  int per_frame_bandwidth;  // Current section per frame bandwidth target
-  int av_per_frame_bandwidth;  // Average frame size target for clip
-  int min_frame_bandwidth;  // Minimum allocation used for any frame
-  int inter_frame_target;
   double output_framerate;
   int64_t last_time_stamp_seen;
   int64_t last_end_time_stamp_seen;
   int64_t first_time_stamp_ever;
 
-  int ni_av_qi;
-  int ni_tot_qi;
-  int ni_frames;
-  int avg_frame_qindex;
-  double tot_q;
-  double avg_q;
-
-  int zbin_mode_boost;
-  int zbin_mode_boost_enabled;
-
-  int64_t total_byte_count;
-
-  int buffered_mode;
-
-  int buffer_level;
-  int bits_off_target;
-
-  int rolling_target_bits;
-  int rolling_actual_bits;
-
-  int long_rolling_target_bits;
-  int long_rolling_actual_bits;
-
-  int64_t total_actual_bits;
-  int total_target_vs_actual;        // debug stats
-
-  int worst_quality;
-  int active_worst_quality;
-  int best_quality;
-  int active_best_quality;
+  RATE_CONTROL rc;
 
   int cq_target_quality;
 
@@ -477,9 +475,6 @@
   vp9_coeff_probs_model frame_coef_probs[TX_SIZES][BLOCK_TYPES];
   vp9_coeff_stats frame_branch_ct[TX_SIZES][BLOCK_TYPES];
 
-  int gfu_boost;
-  int last_boost;
-  int kf_boost;
   int kf_zeromotion_pct;
   int gf_zeromotion_pct;
 
@@ -503,7 +498,6 @@
   int speed;
   int compressor_speed;
 
-  int auto_worst_q;
   int cpu_used;
   int pass;
 
diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c
index 0aa3a68..1293e86 100644
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -35,6 +35,84 @@
 static const unsigned int prior_key_frame_weight[KEY_FRAME_CONTEXT] =
     { 1, 2, 3, 4, 5 };
 
+// Tables relating active max Q to active min Q
+static int kf_low_motion_minq[QINDEX_RANGE];
+static int kf_high_motion_minq[QINDEX_RANGE];
+static int gf_low_motion_minq[QINDEX_RANGE];
+static int gf_high_motion_minq[QINDEX_RANGE];
+static int inter_minq[QINDEX_RANGE];
+static int afq_low_motion_minq[QINDEX_RANGE];
+static int afq_high_motion_minq[QINDEX_RANGE];
+
+// Functions to compute the active minq lookup table entries based on a
+// formulaic approach to facilitate easier adjustment of the Q tables.
+// The formulae were derived from computing a 3rd order polynomial best
+// fit to the original data (after plotting real maxq vs minq (not q index))
+static int calculate_minq_index(double maxq,
+                                double x3, double x2, double x1, double c) {
+  int i;
+  const double minqtarget = MIN(((x3 * maxq + x2) * maxq + x1) * maxq + c,
+                                maxq);
+
+  // Special case handling to deal with the step from q2.0
+  // down to lossless mode represented by q 1.0.
+  if (minqtarget <= 2.0)
+    return 0;
+
+  for (i = 0; i < QINDEX_RANGE; i++) {
+    if (minqtarget <= vp9_convert_qindex_to_q(i))
+      return i;
+  }
+
+  return QINDEX_RANGE - 1;
+}
+
+void vp9_init_minq_luts(void) {
+  int i;
+
+  for (i = 0; i < QINDEX_RANGE; i++) {
+    const double maxq = vp9_convert_qindex_to_q(i);
+
+
+    kf_low_motion_minq[i] = calculate_minq_index(maxq,
+                                                 0.000001,
+                                                 -0.0004,
+                                                 0.15,
+                                                 0.0);
+    kf_high_motion_minq[i] = calculate_minq_index(maxq,
+                                                  0.000002,
+                                                  -0.0012,
+                                                  0.5,
+                                                  0.0);
+
+    gf_low_motion_minq[i] = calculate_minq_index(maxq,
+                                                 0.0000015,
+                                                 -0.0009,
+                                                 0.32,
+                                                 0.0);
+    gf_high_motion_minq[i] = calculate_minq_index(maxq,
+                                                  0.0000021,
+                                                  -0.00125,
+                                                  0.50,
+                                                  0.0);
+    inter_minq[i] = calculate_minq_index(maxq,
+                                         0.00000271,
+                                         -0.00113,
+                                         0.75,
+                                         0.0);
+    afq_low_motion_minq[i] = calculate_minq_index(maxq,
+                                                  0.0000015,
+                                                  -0.0009,
+                                                  0.33,
+                                                  0.0);
+    afq_high_motion_minq[i] = calculate_minq_index(maxq,
+                                                   0.0000021,
+                                                   -0.00125,
+                                                   0.55,
+                                                   0.0);
+  }
+}
+
 // These functions use formulaic calculations to make playing with the
 // quantizer tables easier. If necessary they can be replaced by lookup
 // tables if and when things settle down in the experimental bitstream
@@ -118,7 +196,7 @@
   vp9_setup_past_independence(cm);
 
   // interval before next GF
-  cpi->frames_till_gf_update_due = cpi->baseline_gf_interval;
+  cpi->rc.frames_till_gf_update_due = cpi->rc.baseline_gf_interval;
   /* All buffers are implicitly updated on key frames. */
   cpi->refresh_golden_frame = 1;
   cpi->refresh_alt_ref_frame = 1;
@@ -153,17 +231,17 @@
   vp9_clear_system_state();  // __asm emms;
 
   // New Two pass RC
-  target = cpi->per_frame_bandwidth;
+  target = cpi->rc.per_frame_bandwidth;
 
   if (cpi->oxcf.rc_max_intra_bitrate_pct) {
-    int max_rate = cpi->per_frame_bandwidth
+    int max_rate = cpi->rc.per_frame_bandwidth
                  * cpi->oxcf.rc_max_intra_bitrate_pct / 100;
 
     if (target > max_rate)
       target = max_rate;
   }
 
-  cpi->this_frame_target = target;
+  cpi->rc.this_frame_target = target;
 }
 
 
@@ -174,21 +252,21 @@
 //  so we just use the interval determined in the two pass code.
 static void calc_gf_params(VP9_COMP *cpi) {
   // Set the gf interval
-  cpi->frames_till_gf_update_due = cpi->baseline_gf_interval;
+  cpi->rc.frames_till_gf_update_due = cpi->rc.baseline_gf_interval;
 }
 
 
 static void calc_pframe_target_size(VP9_COMP *cpi) {
-  const int min_frame_target = MAX(cpi->min_frame_bandwidth,
-                                   cpi->av_per_frame_bandwidth >> 5);
+  const int min_frame_target = MAX(cpi->rc.min_frame_bandwidth,
+                                   cpi->rc.av_per_frame_bandwidth >> 5);
   if (cpi->refresh_alt_ref_frame) {
     // Special alt reference frame case
     // Per frame bit target for the alt ref frame
-    cpi->per_frame_bandwidth = cpi->twopass.gf_bits;
-    cpi->this_frame_target = cpi->per_frame_bandwidth;
+    cpi->rc.per_frame_bandwidth = cpi->twopass.gf_bits;
+    cpi->rc.this_frame_target = cpi->rc.per_frame_bandwidth;
   } else {
     // Normal frames (gf,and inter)
-    cpi->this_frame_target = cpi->per_frame_bandwidth;
+    cpi->rc.this_frame_target = cpi->rc.per_frame_bandwidth;
   }
 
   // Check that the total sum of adjustments is not above the maximum allowed.
@@ -197,41 +275,26 @@
   // not capable of recovering all the extra bits we have spent in the KF or GF,
   // then the remainder will have to be recovered over a longer time span via
   // other buffer / rate control mechanisms.
-  if (cpi->this_frame_target < min_frame_target)
-    cpi->this_frame_target = min_frame_target;
-
-  if (!cpi->refresh_alt_ref_frame)
-    // Note the baseline target data rate for this inter frame.
-    cpi->inter_frame_target = cpi->this_frame_target;
+  if (cpi->rc.this_frame_target < min_frame_target)
+    cpi->rc.this_frame_target = min_frame_target;
 
   // Adjust target frame size for Golden Frames:
-  if (cpi->frames_till_gf_update_due == 0) {
-    const int q = (cpi->oxcf.fixed_q < 0) ? cpi->last_q[INTER_FRAME]
-                                          : cpi->oxcf.fixed_q;
-
+  if (cpi->rc.frames_till_gf_update_due == 0) {
     cpi->refresh_golden_frame = 1;
-
     calc_gf_params(cpi);
-
     // If we are using alternate ref instead of gf then do not apply the boost
     // It will instead be applied to the altref update
     // Jims modified boost
     if (!cpi->source_alt_ref_active) {
-      if (cpi->oxcf.fixed_q < 0) {
-        // The spend on the GF is defined in the two pass code
-        // for two pass encodes
-        cpi->this_frame_target = cpi->per_frame_bandwidth;
-      } else {
-        cpi->this_frame_target =
-          (estimate_bits_at_q(1, q, cpi->common.MBs, 1.0)
-           * cpi->last_boost) / 100;
-      }
+      // The spend on the GF is defined in the two pass code
+      // for two pass encodes
+      cpi->rc.this_frame_target = cpi->rc.per_frame_bandwidth;
     } else {
       // If there is an active ARF at this location use the minimum
       // bits on this frame even if it is a constructed arf.
       // The active maximum quantizer insures that an appropriate
       // number of bits will be spent if needed for constructed ARFs.
-      cpi->this_frame_target = 0;
+      cpi->rc.this_frame_target = 0;
     }
   }
 }
@@ -249,12 +312,12 @@
   vp9_clear_system_state();  // __asm emms;
 
   if (cpi->common.frame_type == KEY_FRAME) {
-    rate_correction_factor = cpi->key_frame_rate_correction_factor;
+    rate_correction_factor = cpi->rc.key_frame_rate_correction_factor;
   } else {
     if (cpi->refresh_alt_ref_frame || cpi->refresh_golden_frame)
-      rate_correction_factor = cpi->gf_rate_correction_factor;
+      rate_correction_factor = cpi->rc.gf_rate_correction_factor;
     else
-      rate_correction_factor = cpi->rate_correction_factor;
+      rate_correction_factor = cpi->rc.rate_correction_factor;
   }
 
   // Work out how big we would have expected the frame to be at this Q given
@@ -267,7 +330,7 @@
   // Work out a size correction factor.
   if (projected_size_based_on_q > 0)
     correction_factor =
-        (100 * cpi->projected_frame_size) / projected_size_based_on_q;
+        (100 * cpi->rc.projected_frame_size) / projected_size_based_on_q;
 
   // More heavily damped adjustment used if we have been oscillating either side
   // of target.
@@ -284,7 +347,7 @@
       break;
   }
 
-  // if ( (correction_factor > 102) && (Q < cpi->active_worst_quality) )
+  // if ( (correction_factor > 102) && (Q < cpi->rc.active_worst_quality) )
   if (correction_factor > 102) {
     // We are not already at the worst allowable quality
     correction_factor =
@@ -308,18 +371,18 @@
   }
 
   if (cpi->common.frame_type == KEY_FRAME) {
-    cpi->key_frame_rate_correction_factor = rate_correction_factor;
+    cpi->rc.key_frame_rate_correction_factor = rate_correction_factor;
   } else {
     if (cpi->refresh_alt_ref_frame || cpi->refresh_golden_frame)
-      cpi->gf_rate_correction_factor = rate_correction_factor;
+      cpi->rc.gf_rate_correction_factor = rate_correction_factor;
     else
-      cpi->rate_correction_factor = rate_correction_factor;
+      cpi->rc.rate_correction_factor = rate_correction_factor;
   }
 }
 
 
 int vp9_regulate_q(VP9_COMP *cpi, int target_bits_per_frame) {
-  int q = cpi->active_worst_quality;
+  int q = cpi->rc.active_worst_quality;
 
   int i;
   int last_error = INT_MAX;
@@ -329,12 +392,12 @@
 
   // Select the appropriate correction factor based upon type of frame.
   if (cpi->common.frame_type == KEY_FRAME) {
-    correction_factor = cpi->key_frame_rate_correction_factor;
+    correction_factor = cpi->rc.key_frame_rate_correction_factor;
   } else {
     if (cpi->refresh_alt_ref_frame || cpi->refresh_golden_frame)
-      correction_factor = cpi->gf_rate_correction_factor;
+      correction_factor = cpi->rc.gf_rate_correction_factor;
     else
-      correction_factor = cpi->rate_correction_factor;
+      correction_factor = cpi->rc.rate_correction_factor;
   }
 
   // Calculate required scaling factor based on target frame size and size of
@@ -347,7 +410,7 @@
     target_bits_per_mb =
         (target_bits_per_frame << BPER_MB_NORMBITS) / cpi->common.MBs;
 
-  i = cpi->active_best_quality;
+  i = cpi->rc.active_best_quality;
 
   do {
     bits_per_mb_at_this_q = (int)vp9_bits_per_mb(cpi->common.frame_type, i,
@@ -363,7 +426,214 @@
     } else {
       last_error = bits_per_mb_at_this_q - target_bits_per_mb;
     }
-  } while (++i <= cpi->active_worst_quality);
+  } while (++i <= cpi->rc.active_worst_quality);
+
+  return q;
+}
+
+static int get_active_quality(int q,
+                              int gfu_boost,
+                              int low,
+                              int high,
+                              int *low_motion_minq,
+                              int *high_motion_minq) {
+  int active_best_quality;
+  if (gfu_boost > high) {
+    active_best_quality = low_motion_minq[q];
+  } else if (gfu_boost < low) {
+    active_best_quality = high_motion_minq[q];
+  } else {
+    const int gap = high - low;
+    const int offset = high - gfu_boost;
+    const int qdiff = high_motion_minq[q] - low_motion_minq[q];
+    const int adjustment = ((offset * qdiff) + (gap >> 1)) / gap;
+    active_best_quality = low_motion_minq[q] + adjustment;
+  }
+  return active_best_quality;
+}
+
+int vp9_pick_q_and_adjust_q_bounds(VP9_COMP *cpi,
+                                   int * bottom_index, int * top_index) {
+  // Set an active best quality and if necessary active worst quality
+  int q = cpi->rc.active_worst_quality;
+  VP9_COMMON *const cm = &cpi->common;
+
+  if (frame_is_intra_only(cm)) {
+#if !CONFIG_MULTIPLE_ARF
+    // Handle the special case for key frames forced when we have75 reached
+    // the maximum key frame interval. Here force the Q to a range
+    // based on the ambient Q to reduce the risk of popping.
+    if (cpi->this_key_frame_forced) {
+      int delta_qindex;
+      int qindex = cpi->rc.last_boosted_qindex;
+      double last_boosted_q = vp9_convert_qindex_to_q(qindex);
+
+      delta_qindex = vp9_compute_qdelta(cpi, last_boosted_q,
+                                        (last_boosted_q * 0.75));
+
+      cpi->rc.active_best_quality = MAX(qindex + delta_qindex,
+                                     cpi->rc.best_quality);
+    } else {
+      int high = 5000;
+      int low = 400;
+      double q_adj_factor = 1.0;
+      double q_val;
+
+      // Baseline value derived from cpi->active_worst_quality and kf boost
+      cpi->rc.active_best_quality = get_active_quality(q, cpi->rc.kf_boost,
+                                                    low, high,
+                                                    kf_low_motion_minq,
+                                                    kf_high_motion_minq);
+
+      // Allow somewhat lower kf minq with small image formats.
+      if ((cm->width * cm->height) <= (352 * 288)) {
+        q_adj_factor -= 0.25;
+      }
+
+      // Make a further adjustment based on the kf zero motion measure.
+      q_adj_factor += 0.05 - (0.001 * (double)cpi->kf_zeromotion_pct);
+
+      // Convert the adjustment factor to a qindex delta
+      // on active_best_quality.
+      q_val = vp9_convert_qindex_to_q(cpi->rc.active_best_quality);
+      cpi->rc.active_best_quality +=
+          vp9_compute_qdelta(cpi, q_val, (q_val * q_adj_factor));
+    }
+#else
+    double current_q;
+    // Force the KF quantizer to be 30% of the active_worst_quality.
+    current_q = vp9_convert_qindex_to_q(cpi->rc.active_worst_quality);
+    cpi->rc.active_best_quality = cpi->rc.active_worst_quality
+        + vp9_compute_qdelta(cpi, current_q, current_q * 0.3);
+#endif
+  } else if (!cpi->is_src_frame_alt_ref &&
+             (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) {
+    int high = 2000;
+    int low = 400;
+
+    // Use the lower of cpi->rc.active_worst_quality and recent
+    // average Q as basis for GF/ARF best Q limit unless last frame was
+    // a key frame.
+    if (cpi->frames_since_key > 1 &&
+        cpi->rc.avg_frame_qindex < cpi->rc.active_worst_quality) {
+      q = cpi->rc.avg_frame_qindex;
+    }
+    // For constrained quality dont allow Q less than the cq level
+    if (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) {
+      if (q < cpi->cq_target_quality)
+        q = cpi->cq_target_quality;
+      if (cpi->frames_since_key > 1) {
+        cpi->rc.active_best_quality = get_active_quality(q, cpi->rc.gfu_boost,
+                                                      low, high,
+                                                      afq_low_motion_minq,
+                                                      afq_high_motion_minq);
+      } else {
+        cpi->rc.active_best_quality = get_active_quality(q, cpi->rc.gfu_boost,
+                                                      low, high,
+                                                      gf_low_motion_minq,
+                                                      gf_high_motion_minq);
+      }
+      // Constrained quality use slightly lower active best.
+      cpi->rc.active_best_quality = cpi->rc.active_best_quality * 15 / 16;
+
+    } else if (cpi->oxcf.end_usage == USAGE_CONSTANT_QUALITY) {
+      if (!cpi->refresh_alt_ref_frame) {
+        cpi->rc.active_best_quality = cpi->cq_target_quality;
+      } else {
+        if (cpi->frames_since_key > 1) {
+          cpi->rc.active_best_quality = get_active_quality(q, cpi->rc.gfu_boost,
+                                                        low, high,
+                                                        afq_low_motion_minq,
+                                                        afq_high_motion_minq);
+        } else {
+          cpi->rc.active_best_quality = get_active_quality(q, cpi->rc.gfu_boost,
+                                                        low, high,
+                                                        gf_low_motion_minq,
+                                                        gf_high_motion_minq);
+        }
+      }
+    } else {
+        cpi->rc.active_best_quality = get_active_quality(q, cpi->rc.gfu_boost,
+                                                         low, high,
+                                                         gf_low_motion_minq,
+                                                         gf_high_motion_minq);
+    }
+  } else {
+    if (cpi->oxcf.end_usage == USAGE_CONSTANT_QUALITY) {
+      cpi->rc.active_best_quality = cpi->cq_target_quality;
+    } else {
+      cpi->rc.active_best_quality = inter_minq[q];
+      // 1-pass: for now, use the average Q for the active_best, if its lower
+      // than active_worst.
+      if (cpi->pass == 0 && (cpi->rc.avg_frame_qindex < q))
+        cpi->rc.active_best_quality = inter_minq[cpi->rc.avg_frame_qindex];
+
+      // For the constrained quality mode we don't want
+      // q to fall below the cq level.
+      if ((cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) &&
+          (cpi->rc.active_best_quality < cpi->cq_target_quality)) {
+        // If we are strongly undershooting the target rate in the last
+        // frames then use the user passed in cq value not the auto
+        // cq value.
+        if (cpi->rc.rolling_actual_bits < cpi->rc.min_frame_bandwidth)
+          cpi->rc.active_best_quality = cpi->oxcf.cq_level;
+        else
+          cpi->rc.active_best_quality = cpi->cq_target_quality;
+      }
+    }
+  }
+
+  // Clip the active best and worst quality values to limits
+  if (cpi->rc.active_worst_quality > cpi->rc.worst_quality)
+    cpi->rc.active_worst_quality = cpi->rc.worst_quality;
+
+  if (cpi->rc.active_best_quality < cpi->rc.best_quality)
+    cpi->rc.active_best_quality = cpi->rc.best_quality;
+
+  if (cpi->rc.active_best_quality > cpi->rc.worst_quality)
+    cpi->rc.active_best_quality = cpi->rc.worst_quality;
+
+  if (cpi->rc.active_worst_quality < cpi->rc.active_best_quality)
+    cpi->rc.active_worst_quality = cpi->rc.active_best_quality;
+
+  // Limit Q range for the adaptive loop.
+  if (cm->frame_type == KEY_FRAME && !cpi->this_key_frame_forced) {
+    *top_index =
+      (cpi->rc.active_worst_quality + cpi->rc.active_best_quality * 3) / 4;
+    // If this is the first (key) frame in 1-pass, active best is the user
+    // best-allowed, and leave the top_index to active_worst.
+    if (cpi->pass == 0 && cpi->common.current_video_frame == 0) {
+      cpi->rc.active_best_quality = cpi->oxcf.best_allowed_q;
+      *top_index = cpi->oxcf.worst_allowed_q;
+    }
+  } else if (!cpi->is_src_frame_alt_ref &&
+             (cpi->oxcf.end_usage != USAGE_STREAM_FROM_SERVER) &&
+             (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) {
+    *top_index =
+      (cpi->rc.active_worst_quality + cpi->rc.active_best_quality) / 2;
+  } else {
+    *top_index = cpi->rc.active_worst_quality;
+  }
+  *bottom_index = cpi->rc.active_best_quality;
+
+  if (cpi->oxcf.end_usage == USAGE_CONSTANT_QUALITY) {
+    q = cpi->rc.active_best_quality;
+  // Special case code to try and match quality with forced key frames
+  } else if ((cm->frame_type == KEY_FRAME) && cpi->this_key_frame_forced) {
+    q = cpi->rc.last_boosted_qindex;
+  } else {
+    // Determine initial Q to try.
+    if (cpi->pass == 0) {
+      // 1-pass: for now, use per-frame-bw for target size of frame, scaled
+      // by |x| for key frame.
+      int scale = (cm->frame_type == KEY_FRAME) ? 5 : 1;
+      q = vp9_regulate_q(cpi, scale * cpi->rc.av_per_frame_bandwidth);
+    } else {
+      q = vp9_regulate_q(cpi, cpi->rc.this_frame_target);
+    }
+    if (q > *top_index)
+      q = *top_index;
+  }
 
   return q;
 }
@@ -378,7 +648,7 @@
   /* First key frame at start of sequence is a special case. We have no
    * frequency data.
    */
-  if (cpi->key_frame_count == 1) {
+  if (cpi->rc.key_frame_count == 1) {
     /* Assume a default of 1 kf every 2 seconds, or the max kf interval,
      * whichever is smaller.
      */
@@ -388,7 +658,7 @@
     if (cpi->oxcf.auto_key && av_key_frame_frequency > key_freq)
       av_key_frame_frequency = cpi->oxcf.key_freq;
 
-    cpi->prior_key_frame_distance[KEY_FRAME_CONTEXT - 1]
+    cpi->rc.prior_key_frame_distance[KEY_FRAME_CONTEXT - 1]
       = av_key_frame_frequency;
   } else {
     unsigned int total_weight = 0;
@@ -400,13 +670,13 @@
      */
     for (i = 0; i < KEY_FRAME_CONTEXT; i++) {
       if (i < KEY_FRAME_CONTEXT - 1)
-        cpi->prior_key_frame_distance[i]
-          = cpi->prior_key_frame_distance[i + 1];
+        cpi->rc.prior_key_frame_distance[i]
+          = cpi->rc.prior_key_frame_distance[i + 1];
       else
-        cpi->prior_key_frame_distance[i] = last_kf_interval;
+        cpi->rc.prior_key_frame_distance[i] = last_kf_interval;
 
       av_key_frame_frequency += prior_key_frame_weight[i]
-                                * cpi->prior_key_frame_distance[i];
+                                * cpi->rc.prior_key_frame_distance[i];
       total_weight += prior_key_frame_weight[i];
     }
 
@@ -421,33 +691,32 @@
   vp9_clear_system_state();
 
   cpi->frames_since_key = 0;
-  cpi->key_frame_count++;
+  cpi->rc.key_frame_count++;
 }
 
 
 void vp9_compute_frame_size_bounds(VP9_COMP *cpi, int *frame_under_shoot_limit,
                                    int *frame_over_shoot_limit) {
   // Set-up bounds on acceptable frame size:
-  if (cpi->oxcf.fixed_q >= 0) {
-    // Fixed Q scenario: frame size never outranges target (there is no target!)
+  if (cpi->oxcf.end_usage == USAGE_CONSTANT_QUALITY) {
     *frame_under_shoot_limit = 0;
     *frame_over_shoot_limit  = INT_MAX;
   } else {
     if (cpi->common.frame_type == KEY_FRAME) {
-      *frame_over_shoot_limit  = cpi->this_frame_target * 9 / 8;
-      *frame_under_shoot_limit = cpi->this_frame_target * 7 / 8;
+      *frame_over_shoot_limit  = cpi->rc.this_frame_target * 9 / 8;
+      *frame_under_shoot_limit = cpi->rc.this_frame_target * 7 / 8;
     } else {
       if (cpi->refresh_alt_ref_frame || cpi->refresh_golden_frame) {
-        *frame_over_shoot_limit  = cpi->this_frame_target * 9 / 8;
-        *frame_under_shoot_limit = cpi->this_frame_target * 7 / 8;
+        *frame_over_shoot_limit  = cpi->rc.this_frame_target * 9 / 8;
+        *frame_under_shoot_limit = cpi->rc.this_frame_target * 7 / 8;
       } else {
         // Stron overshoot limit for constrained quality
         if (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) {
-          *frame_over_shoot_limit  = cpi->this_frame_target * 11 / 8;
-          *frame_under_shoot_limit = cpi->this_frame_target * 2 / 8;
+          *frame_over_shoot_limit  = cpi->rc.this_frame_target * 11 / 8;
+          *frame_under_shoot_limit = cpi->rc.this_frame_target * 2 / 8;
         } else {
-          *frame_over_shoot_limit  = cpi->this_frame_target * 11 / 8;
-          *frame_under_shoot_limit = cpi->this_frame_target * 5 / 8;
+          *frame_over_shoot_limit  = cpi->rc.this_frame_target * 11 / 8;
+          *frame_under_shoot_limit = cpi->rc.this_frame_target * 5 / 8;
         }
       }
     }
diff --git a/vp9/encoder/vp9_ratectrl.h b/vp9/encoder/vp9_ratectrl.h
index ddda713..57dcd3f 100644
--- a/vp9/encoder/vp9_ratectrl.h
+++ b/vp9/encoder/vp9_ratectrl.h
@@ -27,6 +27,8 @@
                                    int *frame_under_shoot_limit,
                                    int *frame_over_shoot_limit);
 
+void vp9_init_minq_luts(void);
+
 // return of 0 means drop frame
 int vp9_pick_frame_size(VP9_COMP *cpi);
 
@@ -35,5 +37,7 @@
 int vp9_bits_per_mb(FRAME_TYPE frame_type, int qindex,
                     double correction_factor);
 void vp9_setup_inter_frame(VP9_COMP *cpi);
+int vp9_pick_q_and_adjust_q_bounds(VP9_COMP *cpi,
+                                   int * bottom_index, int * top_index);
 
 #endif  // VP9_ENCODER_VP9_RATECTRL_H_
diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c
index 5d37f83..8905225 100644
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -567,8 +567,7 @@
                                &this_sse) >> shift;
   args->sse  = this_sse >> shift;
 
-  if (x->skip_encode &&
-      xd->mi_8x8[0]->mbmi.ref_frame[0] == INTRA_FRAME) {
+  if (x->skip_encode && !is_inter_block(&xd->mi_8x8[0]->mbmi)) {
     // TODO(jingning): tune the model to better capture the distortion.
     int64_t p = (pd->dequant[1] * pd->dequant[1] *
                     (1 << ss_txfrm_size)) >> (shift + 2);
@@ -1549,9 +1548,9 @@
   struct macroblockd_plane *const pd = &xd->plane[0];
   struct macroblock_plane *const p = &x->plane[0];
   MODE_INFO *const mi = xd->mi_8x8[0];
-  const BLOCK_SIZE bsize = mi->mbmi.sb_type;
-  const int width = plane_block_width(bsize, pd);
-  const int height = plane_block_height(bsize, pd);
+  const BLOCK_SIZE plane_bsize = get_plane_block_size(mi->mbmi.sb_type, pd);
+  const int width = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
+  const int height = 4 * num_4x4_blocks_high_lookup[plane_bsize];
   int idx, idy;
 
   const uint8_t *const src = &p->src.buf[raster_block_offset(BLOCK_8X8, i,
@@ -3754,7 +3753,7 @@
 
   assert((cm->mcomp_filter_type == SWITCHABLE) ||
          (cm->mcomp_filter_type == best_mbmode.interp_filter) ||
-         (best_mbmode.ref_frame[0] == INTRA_FRAME));
+         !is_inter_block(&best_mbmode));
 
   // Updating rd_thresh_freq_fact[] here means that the different
   // partition/block sizes are handled independently based on the best
@@ -4325,8 +4324,8 @@
     }
 
     // Keep record of best inter rd with single reference
-    if (xd->mi_8x8[0]->mbmi.ref_frame[0] > INTRA_FRAME &&
-        xd->mi_8x8[0]->mbmi.ref_frame[1] == NONE &&
+    if (is_inter_block(&xd->mi_8x8[0]->mbmi) &&
+        !has_second_ref(&xd->mi_8x8[0]->mbmi) &&
         !mode_excluded &&
         this_rd < best_inter_rd) {
       best_inter_rd = this_rd;
@@ -4489,7 +4488,7 @@
 
   assert((cm->mcomp_filter_type == SWITCHABLE) ||
          (cm->mcomp_filter_type == best_mbmode.interp_filter) ||
-         (best_mbmode.ref_frame[0] == INTRA_FRAME));
+         !is_inter_block(&best_mbmode));
 
   // Updating rd_thresh_freq_fact[] here means that the different
   // partition/block sizes are handled independently based on the best
@@ -4515,7 +4514,7 @@
   // macroblock modes
   *mbmi = best_mbmode;
   x->skip |= best_skip2;
-  if (best_mbmode.ref_frame[0] == INTRA_FRAME) {
+  if (!is_inter_block(&best_mbmode)) {
     for (i = 0; i < 4; i++)
       xd->mi_8x8[0]->bmi[i].as_mode = best_bmodes[i].as_mode;
   } else {
diff --git a/vp9/encoder/vp9_temporal_filter.c b/vp9/encoder/vp9_temporal_filter.c
index 3bffb12..6d4075e 100644
--- a/vp9/encoder/vp9_temporal_filter.c
+++ b/vp9/encoder/vp9_temporal_filter.c
@@ -469,7 +469,7 @@
   // cases where the filter extends beyond the end of clip.
   // Note: this_frame->frame has been updated in the loop
   // so it now points at the ARF frame.
-  half_gf_int = cpi->baseline_gf_interval >> 1;
+  half_gf_int = cpi->rc.baseline_gf_interval >> 1;
   frames_after_arf = (int)(cpi->twopass.total_stats.count - this_frame - 1);
 
   switch (cpi->oxcf.arnr_type) {
@@ -507,7 +507,7 @@
   cpi->active_arnr_frames = frames_bwd + 1 + frames_fwd;
 
   // Adjust the strength based on active max q
-  q = ((int)vp9_convert_qindex_to_q(cpi->active_worst_quality) >> 1);
+  q = ((int)vp9_convert_qindex_to_q(cpi->rc.active_worst_quality) >> 1);
   if (q > 8) {
     cpi->active_arnr_strength = cpi->oxcf.arnr_strength;
   } else {
diff --git a/vp9/encoder/vp9_treewriter.h b/vp9/encoder/vp9_treewriter.h
index 41d1bfb..c9bf4da 100644
--- a/vp9/encoder/vp9_treewriter.h
+++ b/vp9/encoder/vp9_treewriter.h
@@ -35,9 +35,8 @@
 
 static INLINE void treed_write(vp9_writer *w,
                                vp9_tree tree, const vp9_prob *probs,
-                               int bits, int len) {
-  vp9_tree_index i = 0;
-
+                               int bits, int len,
+                               vp9_tree_index i) {
   do {
     const int bit = (bits >> --len) & 1;
     vp9_write(w, bit, probs[i >> 1]);
@@ -48,7 +47,7 @@
 static INLINE void write_token(vp9_writer *w, vp9_tree tree,
                                const vp9_prob *probs,
                                const struct vp9_token *token) {
-  treed_write(w, tree, probs, token->value, token->len);
+  treed_write(w, tree, probs, token->value, token->len, 0);
 }
 
 static INLINE int treed_cost(vp9_tree tree, const vp9_prob *probs,
diff --git a/vp9/encoder/x86/vp9_dct_sse2.c b/vp9/encoder/x86/vp9_dct_sse2.c
index fefca66..65431bd 100644
--- a/vp9/encoder/x86/vp9_dct_sse2.c
+++ b/vp9/encoder/x86/vp9_dct_sse2.c
@@ -26,24 +26,25 @@
   //    by constructing the 32 bit constant corresponding to that pair.
   const __m128i k__cospi_p16_p16 = _mm_set1_epi16(cospi_16_64);
   const __m128i k__cospi_p16_m16 = pair_set_epi16(cospi_16_64, -cospi_16_64);
-  const __m128i k__cospi_p24_p08 = pair_set_epi16(cospi_24_64, cospi_8_64);
-  const __m128i k__cospi_m08_p24 = pair_set_epi16(-cospi_8_64, cospi_24_64);
+  const __m128i k__cospi_p08_p24 = pair_set_epi16(cospi_8_64, cospi_24_64);
+  const __m128i k__cospi_p24_m08 = pair_set_epi16(cospi_24_64, -cospi_8_64);
   const __m128i k__DCT_CONST_ROUNDING = _mm_set1_epi32(DCT_CONST_ROUNDING);
   const __m128i k__nonzero_bias_a = _mm_setr_epi16(0, 1, 1, 1, 1, 1, 1, 1);
   const __m128i k__nonzero_bias_b = _mm_setr_epi16(1, 0, 0, 0, 0, 0, 0, 0);
   const __m128i kOne = _mm_set1_epi16(1);
-  __m128i in0, in1, in2, in3;
+  __m128i in0, in1;
   // Load inputs.
   {
     in0  = _mm_loadl_epi64((const __m128i *)(input +  0 * stride));
-    in1  = _mm_loadl_epi64((const __m128i *)(input +  1 * stride));
-    in2  = _mm_loadl_epi64((const __m128i *)(input +  2 * stride));
-    in3  = _mm_loadl_epi64((const __m128i *)(input +  3 * stride));
+    in0  = _mm_unpacklo_epi64(in0, _mm_loadl_epi64((const __m128i *)
+           (input +  1 * stride)));
+    in1  = _mm_loadl_epi64((const __m128i *)(input +  2 * stride));
+    in1  = _mm_unpacklo_epi64(_mm_loadl_epi64((const __m128i *)
+           (input +  3 * stride)), in1);
+
     // x = x << 4
     in0 = _mm_slli_epi16(in0, 4);
     in1 = _mm_slli_epi16(in1, 4);
-    in2 = _mm_slli_epi16(in2, 4);
-    in3 = _mm_slli_epi16(in3, 4);
     // if (i == 0 && input[0]) input[0] += 1;
     {
       // The mask will only contain wether the first value is zero, all
@@ -60,18 +61,18 @@
   // Do the two transform/transpose passes
   for (pass = 0; pass < 2; ++pass) {
     // Transform 1/2: Add/substract
-    const __m128i r0 = _mm_add_epi16(in0, in3);
-    const __m128i r1 = _mm_add_epi16(in1, in2);
-    const __m128i r2 = _mm_sub_epi16(in1, in2);
-    const __m128i r3 = _mm_sub_epi16(in0, in3);
+    const __m128i r0 = _mm_add_epi16(in0, in1);
+    const __m128i r1 = _mm_sub_epi16(in0, in1);
+    const __m128i r2 = _mm_unpacklo_epi64(r0, r1);
+    const __m128i r3 = _mm_unpackhi_epi64(r0, r1);
     // Transform 1/2: Interleave to do the multiply by constants which gets us
     //                into 32 bits.
-    const __m128i t0 = _mm_unpacklo_epi16(r0, r1);
-    const __m128i t2 = _mm_unpacklo_epi16(r2, r3);
+    const __m128i t0 = _mm_unpacklo_epi16(r2, r3);
+    const __m128i t2 = _mm_unpackhi_epi16(r2, r3);
     const __m128i u0 = _mm_madd_epi16(t0, k__cospi_p16_p16);
     const __m128i u2 = _mm_madd_epi16(t0, k__cospi_p16_m16);
-    const __m128i u4 = _mm_madd_epi16(t2, k__cospi_p24_p08);
-    const __m128i u6 = _mm_madd_epi16(t2, k__cospi_m08_p24);
+    const __m128i u4 = _mm_madd_epi16(t2, k__cospi_p08_p24);
+    const __m128i u6 = _mm_madd_epi16(t2, k__cospi_p24_m08);
     const __m128i v0 = _mm_add_epi32(u0, k__DCT_CONST_ROUNDING);
     const __m128i v2 = _mm_add_epi32(u2, k__DCT_CONST_ROUNDING);
     const __m128i v4 = _mm_add_epi32(u4, k__DCT_CONST_ROUNDING);
@@ -90,24 +91,21 @@
     // 00 10 01 11 02 12 03 13
     // 20 30 21 31 22 32 23 33
     in0 = _mm_unpacklo_epi32(tr0_0, tr0_1);
-    in2 = _mm_unpackhi_epi32(tr0_0, tr0_1);
+    in1 = _mm_unpackhi_epi32(tr0_0, tr0_1);
+    in1 = _mm_shuffle_epi32(in1, 0x4E);
     // 00 10 20 30 01 11 21 31      in0 contains 0 followed by 1
-    // 02 12 22 32 03 13 23 33      in2 contains 2 followed by 3
-    if (0 == pass) {
-      // Extract values in the high part for second pass as transform code
-      // only uses the first four values.
-      in1 = _mm_unpackhi_epi64(in0, in0);
-      in3 = _mm_unpackhi_epi64(in2, in2);
-    } else {
-      // Post-condition output and store it (v + 1) >> 2, taking advantage
-      // of the fact 1/3 are stored just after 0/2.
-      __m128i out01 = _mm_add_epi16(in0, kOne);
-      __m128i out23 = _mm_add_epi16(in2, kOne);
-      out01 = _mm_srai_epi16(out01, 2);
-      out23 = _mm_srai_epi16(out23, 2);
-      _mm_storeu_si128((__m128i *)(output + 0 * 4), out01);
-      _mm_storeu_si128((__m128i *)(output + 2 * 4), out23);
-    }
+    // 02 12 22 32 03 13 23 33      in1 contains 2 followed by 3
+  }
+  in1 = _mm_shuffle_epi32(in1, 0x4E);
+  // Post-condition output and store it (v + 1) >> 2, taking advantage
+  // of the fact 1/3 are stored just after 0/2.
+  {
+     __m128i out01 = _mm_add_epi16(in0, kOne);
+     __m128i out23 = _mm_add_epi16(in1, kOne);
+     out01 = _mm_srai_epi16(out01, 2);
+     out23 = _mm_srai_epi16(out23, 2);
+     _mm_storeu_si128((__m128i *)(output + 0 * 4), out01);
+     _mm_storeu_si128((__m128i *)(output + 2 * 4), out23);
   }
 }
 
diff --git a/vp9/vp9_common.mk b/vp9/vp9_common.mk
index c566765..6e4a498 100644
--- a/vp9/vp9_common.mk
+++ b/vp9/vp9_common.mk
@@ -124,6 +124,7 @@
 VP9_COMMON_SRCS-$(HAVE_NEON) += common/arm/neon/vp9_convolve8_neon$(ASM)
 VP9_COMMON_SRCS-$(HAVE_NEON) += common/arm/neon/vp9_convolve8_avg_neon$(ASM)
 VP9_COMMON_SRCS-$(HAVE_NEON) += common/arm/neon/vp9_loopfilter_neon$(ASM)
+#VP9_COMMON_SRCS-$(HAVE_NEON) += common/arm/neon/vp9_loopfilter_16_neon$(ASM)
 VP9_COMMON_SRCS-$(HAVE_NEON) += common/arm/neon/vp9_dc_only_idct_add_neon$(ASM)
 VP9_COMMON_SRCS-$(HAVE_NEON) += common/arm/neon/vp9_short_idct4x4_1_add_neon$(ASM)
 VP9_COMMON_SRCS-$(HAVE_NEON) += common/arm/neon/vp9_short_idct4x4_add_neon$(ASM)
diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c
index 1942039..9a23ebd 100644
--- a/vp9/vp9_cx_iface.c
+++ b/vp9/vp9_cx_iface.c
@@ -38,6 +38,7 @@
   unsigned int                rc_max_intra_bitrate_pct;
   unsigned int                lossless;
   unsigned int                frame_parallel_decoding_mode;
+  unsigned int                aq_mode;
 };
 
 struct extraconfig_map {
@@ -66,6 +67,7 @@
       0,                          /* rc_max_intra_bitrate_pct */
       0,                          /* lossless */
       0,                          /* frame_parallel_decoding_mode */
+      0,                          /* aq_mode */
     }
   }
 };
@@ -157,6 +159,7 @@
     RANGE_CHECK_HI(cfg, rc_max_quantizer, 0);
     RANGE_CHECK_HI(cfg, rc_min_quantizer, 0);
   }
+  RANGE_CHECK(vp8_cfg, aq_mode,           0, AQ_MODES_COUNT - 1);
 
   RANGE_CHECK_HI(cfg, g_threads,          64);
   RANGE_CHECK_HI(cfg, g_lag_in_frames,    MAX_LAG_BUFFERS);
@@ -335,6 +338,8 @@
   oxcf->error_resilient_mode         = cfg.g_error_resilient;
   oxcf->frame_parallel_decoding_mode = vp8_cfg.frame_parallel_decoding_mode;
 
+  oxcf->aq_mode = vp8_cfg.aq_mode;
+
   oxcf->ss_number_layers = cfg.ss_number_layers;
   /*
   printf("Current VP9 Settings: \n");
@@ -445,6 +450,7 @@
       MAP(VP8E_SET_MAX_INTRA_BITRATE_PCT,   xcfg.rc_max_intra_bitrate_pct);
       MAP(VP9E_SET_LOSSLESS,                xcfg.lossless);
       MAP(VP9E_SET_FRAME_PARALLEL_DECODING, xcfg.frame_parallel_decoding_mode);
+      MAP(VP9E_SET_AQ_MODE,                 xcfg.aq_mode);
   }
 
   res = validate_config(ctx, &ctx->cfg, &xcfg);
@@ -1071,6 +1077,7 @@
   {VP8E_SET_MAX_INTRA_BITRATE_PCT,    set_param},
   {VP9E_SET_LOSSLESS,                 set_param},
   {VP9E_SET_FRAME_PARALLEL_DECODING,  set_param},
+  {VP9E_SET_AQ_MODE,                  set_param},
   {VP9_GET_REFERENCE,                 get_reference},
   {VP9E_SET_SVC,                      vp9e_set_svc},
   {VP9E_SET_SVC_PARAMETERS,           vp9e_set_svc_parameters},
diff --git a/vpx/vp8cx.h b/vpx/vp8cx.h
index 433cc0d..c0424f1 100644
--- a/vpx/vp8cx.h
+++ b/vpx/vp8cx.h
@@ -193,6 +193,7 @@
   VP9E_SET_TILE_COLUMNS,
   VP9E_SET_TILE_ROWS,
   VP9E_SET_FRAME_PARALLEL_DECODING,
+  VP9E_SET_AQ_MODE,
 
   VP9E_SET_SVC,
   VP9E_SET_SVC_PARAMETERS
@@ -343,6 +344,8 @@
 
 VPX_CTRL_USE_TYPE(VP9E_SET_FRAME_PARALLEL_DECODING, unsigned int)
 
+VPX_CTRL_USE_TYPE(VP9E_SET_AQ_MODE, unsigned int)
+
 /*! @} - end defgroup vp8_encoder */
 #ifdef __cplusplus
 }  // extern "C"
diff --git a/vpx_ports/x86.h b/vpx_ports/x86.h
index 2990583..e5e97e7 100644
--- a/vpx_ports/x86.h
+++ b/vpx_ports/x86.h
@@ -35,51 +35,53 @@
 
 #if defined(__GNUC__) && __GNUC__ || defined(__ANDROID__)
 #if ARCH_X86_64
-#define cpuid(func,ax,bx,cx,dx)\
+#define cpuid(func, func2, ax, bx, cx, dx)\
   __asm__ __volatile__ (\
                         "cpuid           \n\t" \
                         : "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx) \
-                        : "a"  (func));
+                        : "a" (func), "c" (func2));
 #else
-#define cpuid(func,ax,bx,cx,dx)\
+#define cpuid(func, func2, ax, bx, cx, dx)\
   __asm__ __volatile__ (\
                         "mov %%ebx, %%edi   \n\t" \
                         "cpuid              \n\t" \
                         "xchg %%edi, %%ebx  \n\t" \
                         : "=a" (ax), "=D" (bx), "=c" (cx), "=d" (dx) \
-                        : "a" (func));
+                        : "a" (func), "c" (func2));
 #endif
 #elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) /* end __GNUC__ or __ANDROID__*/
 #if ARCH_X86_64
-#define cpuid(func,ax,bx,cx,dx)\
+#define cpuid(func, func2, ax, bx, cx, dx)\
   asm volatile (\
                 "xchg %rsi, %rbx \n\t" \
                 "cpuid           \n\t" \
                 "movl %ebx, %edi \n\t" \
                 "xchg %rsi, %rbx \n\t" \
                 : "=a" (ax), "=D" (bx), "=c" (cx), "=d" (dx) \
-                : "a"  (func));
+                : "a" (func), "c" (func2));
 #else
-#define cpuid(func,ax,bx,cx,dx)\
+#define cpuid(func, func2, ax, bx, cx, dx)\
   asm volatile (\
                 "pushl %ebx       \n\t" \
                 "cpuid            \n\t" \
                 "movl %ebx, %edi  \n\t" \
                 "popl %ebx        \n\t" \
                 : "=a" (ax), "=D" (bx), "=c" (cx), "=d" (dx) \
-                : "a" (func));
+                : "a" (func), "c" (func2));
 #endif
 #else /* end __SUNPRO__ */
 #if ARCH_X86_64
-void __cpuid(int CPUInfo[4], int info_type);
-#pragma intrinsic(__cpuid)
-#define cpuid(func,a,b,c,d) do{\
+void __cpuidex(int CPUInfo[4], int info_type, int ecxvalue);
+#pragma intrinsic(__cpuidex)
+#define cpuid(func, func2, a, b, c, d) do {\
     int regs[4];\
-    __cpuid(regs,func); a=regs[0];  b=regs[1];  c=regs[2];  d=regs[3];\
+    __cpuidex(regs, func, func2); \
+    a = regs[0];  b = regs[1];  c = regs[2];  d = regs[3];\
   } while(0)
 #else
-#define cpuid(func,a,b,c,d)\
+#define cpuid(func, func2, a, b, c, d)\
   __asm mov eax, func\
+  __asm mov ecx, func2\
   __asm cpuid\
   __asm mov a, eax\
   __asm mov b, ebx\
@@ -120,13 +122,13 @@
     mask = strtol(env, NULL, 0);
 
   /* Ensure that the CPUID instruction supports extended features */
-  cpuid(0, reg_eax, reg_ebx, reg_ecx, reg_edx);
+  cpuid(0, 0, reg_eax, reg_ebx, reg_ecx, reg_edx);
 
   if (reg_eax < 1)
     return 0;
 
   /* Get the standard feature flags */
-  cpuid(1, reg_eax, reg_ebx, reg_ecx, reg_edx);
+  cpuid(1, 0, reg_eax, reg_ebx, reg_ecx, reg_edx);
 
   if (reg_edx & BIT(23)) flags |= HAS_MMX;
 
@@ -142,6 +144,11 @@
 
   if (reg_ecx & BIT(28)) flags |= HAS_AVX;
 
+  /* Get the leaf 7 feature flags. Needed to check for AVX2 support */
+  reg_eax = 7;
+  reg_ecx = 0;
+  cpuid(7, 0, reg_eax, reg_ebx, reg_ecx, reg_edx);
+
   if (reg_ebx & BIT(5)) flags |= HAS_AVX2;
 
   return flags & mask;
diff --git a/vpx_ports/x86_cpuid.c b/vpx_ports/x86_cpuid.c
index fe86cfc..02d382c 100644
--- a/vpx_ports/x86_cpuid.c
+++ b/vpx_ports/x86_cpuid.c
@@ -38,7 +38,7 @@
   int i;
 
   /* Get the Vendor String from the CPU */
-  cpuid(0, reg_eax, vs[0], vs[2], vs[1]);
+  cpuid(0, 0, reg_eax, vs[0], vs[2], vs[1]);
 
   for (i = 0; i < VPX_CPU_LAST; i++) {
     if (strncmp((const char *)vs, cpuid_vendor_list[i].vendor_string, 12) == 0)
diff --git a/vpxenc.c b/vpxenc.c
index 377e38b..c35493f 100644
--- a/vpxenc.c
+++ b/vpxenc.c
@@ -8,6 +8,7 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
+#include "./vpxenc.h"
 #include "./vpx_config.h"
 
 #include <assert.h>
@@ -214,11 +215,7 @@
                                                   "Show encoder parameters");
 static const arg_def_t psnrarg          = ARG_DEF(NULL, "psnr", 0,
                                                   "Show PSNR in status line");
-enum TestDecodeFatality {
-  TEST_DECODE_OFF,
-  TEST_DECODE_FATAL,
-  TEST_DECODE_WARN,
-};
+
 static const struct arg_enum_list test_decode_enum[] = {
   {"off",   TEST_DECODE_OFF},
   {"fatal", TEST_DECODE_FATAL},
@@ -238,11 +235,16 @@
                                                   "Show quantizer histogram (n-buckets)");
 static const arg_def_t rate_hist_n         = ARG_DEF(NULL, "rate-hist", 1,
                                                      "Show rate histogram (n-buckets)");
+static const arg_def_t disable_warnings =
+    ARG_DEF(NULL, "disable-warnings", 0,
+            "Disable warnings about potentially incorrect encode settings.");
+
 static const arg_def_t *main_args[] = {
   &debugmode,
   &outputfile, &codecarg, &passes, &pass_arg, &fpf_name, &limit, &skip,
   &deadline, &best_dl, &good_dl, &rt_dl,
-  &quietarg, &verbosearg, &psnrarg, &use_ivf, &out_part, &q_hist_n, &rate_hist_n,
+  &quietarg, &verbosearg, &psnrarg, &use_ivf, &out_part, &q_hist_n,
+  &rate_hist_n, &disable_warnings,
   NULL
 };
 
@@ -380,6 +382,9 @@
 #if CONFIG_VP9_ENCODER
 static const arg_def_t frame_parallel_decoding  = ARG_DEF(
     NULL, "frame-parallel", 1, "Enable frame parallel decodability features");
+static const arg_def_t aq_mode  = ARG_DEF(
+    NULL, "aq-mode", 1,
+    "Adaptive quantization mode (0: disabled (by default), 1: variance based)");
 #endif
 
 #if CONFIG_VP8_ENCODER
@@ -404,7 +409,7 @@
   &cpu_used, &auto_altref, &noise_sens, &sharpness, &static_thresh,
   &tile_cols, &tile_rows, &arnr_maxframes, &arnr_strength, &arnr_type,
   &tune_ssim, &cq_level, &max_intra_rate_pct, &lossless,
-  &frame_parallel_decoding,
+  &frame_parallel_decoding, &aq_mode,
   NULL
 };
 static const int vp9_arg_ctrl_map[] = {
@@ -413,7 +418,7 @@
   VP9E_SET_TILE_COLUMNS, VP9E_SET_TILE_ROWS,
   VP8E_SET_ARNR_MAXFRAMES, VP8E_SET_ARNR_STRENGTH, VP8E_SET_ARNR_TYPE,
   VP8E_SET_TUNING, VP8E_SET_CQ_LEVEL, VP8E_SET_MAX_INTRA_BITRATE_PCT,
-  VP9E_SET_LOSSLESS, VP9E_SET_FRAME_PARALLEL_DECODING,
+  VP9E_SET_LOSSLESS, VP9E_SET_FRAME_PARALLEL_DECODING, VP9E_SET_AQ_MODE,
   0
 };
 #endif
@@ -853,29 +858,6 @@
                              NELEMENTS(vp9_arg_ctrl_map))
 #endif
 
-/* Configuration elements common to all streams */
-struct global_config {
-  const struct codec_item  *codec;
-  int                       passes;
-  int                       pass;
-  int                       usage;
-  int                       deadline;
-  int                       use_i420;
-  int                       quiet;
-  int                       verbose;
-  int                       limit;
-  int                       skip_frames;
-  int                       show_psnr;
-  enum TestDecodeFatality   test_decode;
-  int                       have_framerate;
-  struct vpx_rational       framerate;
-  int                       out_part;
-  int                       debug;
-  int                       show_q_hist_buckets;
-  int                       show_rate_hist_buckets;
-};
-
-
 /* Per-stream configuration */
 struct stream_config {
   struct vpx_codec_enc_cfg  cfg;
@@ -928,7 +910,7 @@
 }
 
 
-static void parse_global_config(struct global_config *global, char **argv) {
+static void parse_global_config(struct VpxEncoderConfig *global, char **argv) {
   char       **argi, **argj;
   struct arg   arg;
 
@@ -1079,7 +1061,7 @@
     y4m_input_close(&input->y4m);
 }
 
-static struct stream_state *new_stream(struct global_config *global,
+static struct stream_state *new_stream(struct VpxEncoderConfig *global,
                                        struct stream_state *prev) {
   struct stream_state *stream;
 
@@ -1128,7 +1110,7 @@
 }
 
 
-static int parse_stream_params(struct global_config *global,
+static int parse_stream_params(struct VpxEncoderConfig *global,
                                struct stream_state  *stream,
                                char **argv) {
   char                   **argi, **argj;
@@ -1274,14 +1256,13 @@
 }
 
 
-#define FOREACH_STREAM(func)\
-  do\
-  {\
-    struct stream_state  *stream;\
-    \
-    for(stream = streams; stream; stream = stream->next)\
-      func;\
-  }while(0)
+#define FOREACH_STREAM(func) \
+  do { \
+    struct stream_state *stream; \
+    for(stream = streams; stream; stream = stream->next) { \
+      func; \
+    } \
+  } while (0)
 
 
 static void validate_stream_config(struct stream_state *stream) {
@@ -1333,8 +1314,8 @@
 }
 
 
-static void set_default_kf_interval(struct stream_state  *stream,
-                                    struct global_config *global) {
+static void set_default_kf_interval(struct stream_state *stream,
+                                    struct VpxEncoderConfig *global) {
   /* Use a max keyframe interval of 5 seconds, if none was
    * specified on the command line.
    */
@@ -1346,8 +1327,8 @@
 }
 
 
-static void show_stream_config(struct stream_state  *stream,
-                               struct global_config *global,
+static void show_stream_config(struct stream_state *stream,
+                               struct VpxEncoderConfig *global,
                                struct VpxInputContext *input) {
 
 #define SHOW(field) \
@@ -1397,7 +1378,7 @@
 
 
 static void open_output_file(struct stream_state *stream,
-                             struct global_config *global) {
+                             struct VpxEncoderConfig *global) {
   const char *fn = stream->config.out_fn;
 
   stream->file = strcmp(fn, "-") ? fopen(fn, "wb") : set_binary_mode(stdout);
@@ -1437,9 +1418,9 @@
 }
 
 
-static void setup_pass(struct stream_state  *stream,
-                       struct global_config *global,
-                       int                   pass) {
+static void setup_pass(struct stream_state *stream,
+                       struct VpxEncoderConfig *global,
+                       int pass) {
   if (stream->config.stats_fn) {
     if (!stats_open_file(&stream->stats, stream->config.stats_fn,
                          pass))
@@ -1461,8 +1442,8 @@
 }
 
 
-static void initialize_encoder(struct stream_state  *stream,
-                               struct global_config *global) {
+static void initialize_encoder(struct stream_state *stream,
+                               struct VpxEncoderConfig *global) {
   int i;
   int flags = 0;
 
@@ -1496,10 +1477,10 @@
 }
 
 
-static void encode_frame(struct stream_state  *stream,
-                         struct global_config *global,
-                         struct vpx_image     *img,
-                         unsigned int          frames_in) {
+static void encode_frame(struct stream_state *stream,
+                         struct VpxEncoderConfig *global,
+                         struct vpx_image *img,
+                         unsigned int frames_in) {
   vpx_codec_pts_t frame_start, next_frame_start;
   struct vpx_codec_enc_cfg *cfg = &stream->config.cfg;
   struct vpx_usec_timer timer;
@@ -1554,9 +1535,9 @@
 }
 
 
-static void get_cx_data(struct stream_state  *stream,
-                        struct global_config *global,
-                        int                  *got_data) {
+static void get_cx_data(struct stream_state *stream,
+                        struct VpxEncoderConfig *global,
+                        int *got_data) {
   const vpx_codec_cx_pkt_t *pkt;
   const struct vpx_codec_enc_cfg *cfg = &stream->config.cfg;
   vpx_codec_iter_t iter = NULL;
@@ -1748,18 +1729,44 @@
   }
 }
 
-int main(int argc, const char **argv_) {
-  int                    pass;
-  vpx_image_t            raw;
-  int                    frame_avail, got_data;
+int continue_prompt() {
+  int c;
+  fprintf(stderr, "Continue? (y to continue) ");
+  c = getchar();
+  return c == 'y';
+}
 
-  struct VpxInputContext  input = {0};
-  struct global_config    global;
-  struct stream_state     *streams = NULL;
-  char                   **argv, **argi;
-  uint64_t                 cx_time = 0;
-  int                      stream_cnt = 0;
-  int                      res = 0;
+void check_quantizer(struct VpxEncoderConfig* config, int min_q, int max_q) {
+  int check_failed = 0;
+
+  if (config->disable_warnings)
+    return;
+
+  if (min_q == max_q || abs(max_q - min_q) < 8) {
+    check_failed = 1;
+  }
+
+  if (check_failed) {
+    warn("Bad quantizer values. Quantizer values must not be equal, and "
+         "should differ by at least 8.");
+
+    if (!continue_prompt())
+      exit(EXIT_FAILURE);
+  }
+}
+
+int main(int argc, const char **argv_) {
+  int pass;
+  vpx_image_t raw;
+  int frame_avail, got_data;
+
+  struct VpxInputContext input = {0};
+  struct VpxEncoderConfig global;
+  struct stream_state *streams = NULL;
+  char **argv, **argi;
+  uint64_t cx_time = 0;
+  int stream_cnt = 0;
+  int res = 0;
 
   exec_name = argv_[0];
 
@@ -1779,6 +1786,7 @@
   argv = argv_dup(argc - 1, argv_ + 1);
   parse_global_config(&global, argv);
 
+
   {
     /* Now parse each stream's parameters. Using a local scope here
      * due to the use of 'stream' as loop variable in FOREACH_STREAM
@@ -1799,6 +1807,10 @@
     if (argi[0][0] == '-' && argi[0][1])
       die("Error: Unrecognized option %s\n", *argi);
 
+  FOREACH_STREAM(
+      check_quantizer(&global,
+                      stream->config.cfg.rc_min_quantizer,
+                      stream->config.cfg.rc_max_quantizer););
   /* Handle non-option arguments */
   input.filename = argv[0];
 
diff --git a/vpxenc.h b/vpxenc.h
new file mode 100644
index 0000000..5cb3f85
--- /dev/null
+++ b/vpxenc.h
@@ -0,0 +1,45 @@
+/*
+ *  Copyright (c) 2013 The WebM project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef VPXENC_H_
+#define VPXENC_H_
+
+#include "vpx/vpx_encoder.h"
+
+enum TestDecodeFatality {
+  TEST_DECODE_OFF,
+  TEST_DECODE_FATAL,
+  TEST_DECODE_WARN,
+};
+
+/* Configuration elements common to all streams. */
+struct VpxEncoderConfig {
+  const struct codec_item *codec;
+  int passes;
+  int pass;
+  int usage;
+  int deadline;
+  int use_i420;
+  int quiet;
+  int verbose;
+  int limit;
+  int skip_frames;
+  int show_psnr;
+  enum TestDecodeFatality test_decode;
+  int have_framerate;
+  struct vpx_rational framerate;
+  int out_part;
+  int debug;
+  int show_q_hist_buckets;
+  int show_rate_hist_buckets;
+  int disable_warnings;
+  int disable_warning_prompt;
+};
+
+#endif  // VPXENC_H_