Merge "dkboolwriter.c: change copyright notice" into nextgenv2
diff --git a/av1/common/blockd.c b/av1/common/blockd.c
index c5eb85d..27c874a 100644
--- a/av1/common/blockd.c
+++ b/av1/common/blockd.c
@@ -49,32 +49,35 @@
   // transform size varies per plane, look it up in a common way.
   const TX_SIZE tx_size = plane ? get_uv_tx_size(mbmi, pd) : mbmi->tx_size;
   const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
-  const int num_4x4_w = num_4x4_blocks_wide_lookup[plane_bsize];
-  const int num_4x4_h = num_4x4_blocks_high_lookup[plane_bsize];
-  const uint8_t num_4x4_tw = num_4x4_blocks_wide_txsize_lookup[tx_size];
-  const uint8_t num_4x4_th = num_4x4_blocks_high_txsize_lookup[tx_size];
-  const int step = num_4x4_tw * num_4x4_th;
+  const int num_4x4_w = block_size_wide[plane_bsize];
+  const int num_4x4_h = block_size_high[plane_bsize];
+  const uint8_t txw_unit = tx_size_wide_unit[tx_size];
+  const uint8_t txh_unit = tx_size_high_unit[tx_size];
+  const int step = txw_unit * txh_unit;
   int i = 0, r, c;
 
   // If mb_to_right_edge is < 0 we are in a situation in which
   // the current block size extends into the UMV and we won't
   // visit the sub blocks that are wholly within the UMV.
-  const int max_blocks_wide =
+  int max_blocks_wide =
       num_4x4_w + (xd->mb_to_right_edge >= 0 ? 0 : xd->mb_to_right_edge >>
-                                                       (5 + pd->subsampling_x));
-  const int max_blocks_high =
+                                                       (3 + pd->subsampling_x));
+  int max_blocks_high =
       num_4x4_h + (xd->mb_to_bottom_edge >= 0
                        ? 0
-                       : xd->mb_to_bottom_edge >> (5 + pd->subsampling_y));
-  const int extra_step = ((num_4x4_w - max_blocks_wide) >>
-                          num_4x4_blocks_wide_txsize_log2_lookup[tx_size]) *
-                         step;
+                       : xd->mb_to_bottom_edge >> (3 + pd->subsampling_y));
+  const int extra_step =
+      ((num_4x4_w - max_blocks_wide) >> tx_size_wide_log2[tx_size]) * step;
+
+  // Scale to the transform block unit.
+  max_blocks_wide >>= tx_size_wide_log2[0];
+  max_blocks_high >>= tx_size_high_log2[0];
 
   // Keep track of the row and column of the blocks we use so that we know
   // if we are in the unrestricted motion border.
-  for (r = 0; r < max_blocks_high; r += num_4x4_th) {
+  for (r = 0; r < max_blocks_high; r += txh_unit) {
     // Skip visiting the sub blocks that are wholly within the UMV.
-    for (c = 0; c < max_blocks_wide; c += num_4x4_tw) {
+    for (c = 0; c < max_blocks_wide; c += txw_unit) {
       visit(plane, i, r, c, plane_bsize, tx_size, arg);
       i += step;
     }
diff --git a/av1/common/common_data.h b/av1/common/common_data.h
index 88bfb0a..9d851e2 100644
--- a/av1/common/common_data.h
+++ b/av1/common/common_data.h
@@ -480,6 +480,22 @@
 #endif
 };
 
+// Transform block width in log2
+static const int tx_size_wide_log2[TX_SIZES_ALL] = {
+  2, 3, 4, 5,
+#if CONFIG_EXT_TX
+  2, 3, 3, 4, 4, 5,
+#endif
+};
+
+// Transform block height in log2
+static const int tx_size_high_log2[TX_SIZES_ALL] = {
+  2, 3, 4, 5,
+#if CONFIG_EXT_TX
+  3, 2, 4, 3, 5, 4,
+#endif
+};
+
 static const int tx_size_2d[TX_SIZES_ALL] = {
   16, 64, 256, 1024,
 #if CONFIG_EXT_TX
diff --git a/av1/common/entropy.c b/av1/common/entropy.c
index 91a61aa..870632d 100644
--- a/av1/common/entropy.c
+++ b/av1/common/entropy.c
@@ -12,6 +12,7 @@
 #include "av1/common/entropy.h"
 #include "av1/common/blockd.h"
 #include "av1/common/onyxc_int.h"
+#include "av1/common/scan.h"
 #include "av1/common/entropymode.h"
 #include "aom_mem/aom_mem.h"
 #include "aom/aom_integer.h"
@@ -2842,6 +2843,10 @@
 #endif  // CONFIG_RANS
 }
 
+#if CONFIG_ADAPT_SCAN
+#define ADAPT_SCAN_UPDATE_RATE_16 (1 << 13)
+#endif
+
 static void adapt_coef_probs(AV1_COMMON *cm, TX_SIZE tx_size,
                              unsigned int count_sat,
                              unsigned int update_factor) {
@@ -2881,11 +2886,15 @@
 }
 
 void av1_adapt_coef_probs(AV1_COMMON *cm) {
-  TX_SIZE t;
+  TX_SIZE tx_size;
   unsigned int count_sat, update_factor;
 
+#if CONFIG_ADAPT_SCAN
+  TX_TYPE tx_type;
+#endif
+
 #if CONFIG_ENTROPY
-  if (cm->last_frame_type == KEY_FRAME) {
+  if (!frame_is_intra_only(cm) && cm->last_frame_type == KEY_FRAME) {
     update_factor = COEF_MAX_UPDATE_FACTOR_AFTER_KEY_BITS; /* adapt quickly */
     count_sat = COEF_COUNT_SAT_AFTER_KEY_BITS;
   } else {
@@ -2896,7 +2905,7 @@
     update_factor = COEF_MAX_UPDATE_FACTOR_BITS;
   }
 #else
-  if (cm->last_frame_type == KEY_FRAME) {
+  if (!frame_is_intra_only(cm) && cm->last_frame_type == KEY_FRAME) {
     update_factor = COEF_MAX_UPDATE_FACTOR_AFTER_KEY; /* adapt quickly */
     count_sat = COEF_COUNT_SAT_AFTER_KEY;
   } else {
@@ -2904,11 +2913,19 @@
     count_sat = COEF_COUNT_SAT;
   }
 #endif  // CONFIG_ENTROPY
-  for (t = TX_4X4; t <= TX_32X32; t++)
-    adapt_coef_probs(cm, t, count_sat, update_factor);
+  for (tx_size = TX_4X4; tx_size <= TX_32X32; tx_size++)
+    adapt_coef_probs(cm, tx_size, count_sat, update_factor);
 #if CONFIG_RANS
   av1_coef_pareto_cdfs(cm->fc);
 #endif  // CONFIG_RANS
+
+#if CONFIG_ADAPT_SCAN
+  for (tx_size = TX_4X4; tx_size < TX_SIZES; ++tx_size)
+    for (tx_type = TX_4X4; tx_type < TX_TYPES; ++tx_type) {
+      av1_update_scan_prob(cm, tx_size, tx_type, ADAPT_SCAN_UPDATE_RATE_16);
+      av1_update_scan_order_facade(cm, tx_size, tx_type);
+    }
+#endif
 }
 
 #if CONFIG_ENTROPY
diff --git a/av1/common/entropy.h b/av1/common/entropy.h
index b475bc5..469b484 100644
--- a/av1/common/entropy.h
+++ b/av1/common/entropy.h
@@ -290,6 +290,10 @@
 
 #endif  // CONFIG_ENTROPY
 
+#if CONFIG_ADAPT_SCAN
+#define ADAPT_SCAN_UPDATE_RATE_16 (1 << 13)
+#endif
+
 static INLINE aom_prob av1_merge_probs(aom_prob pre_prob,
                                        const unsigned int ct[2],
                                        unsigned int count_sat,
diff --git a/av1/common/entropymode.c b/av1/common/entropymode.c
index e812f15..e25dcf8 100644
--- a/av1/common/entropymode.c
+++ b/av1/common/entropymode.c
@@ -12,6 +12,7 @@
 #include "aom_mem/aom_mem.h"
 
 #include "av1/common/reconinter.h"
+#include "av1/common/scan.h"
 #include "av1/common/onyxc_int.h"
 #include "av1/common/seg_common.h"
 
@@ -1755,6 +1756,9 @@
   av1_default_coef_probs(cm);
   init_mode_probs(cm->fc);
   av1_init_mv_probs(cm);
+#if CONFIG_ADAPT_SCAN
+  av1_init_scan_order(cm);
+#endif
   cm->fc->initialized = 1;
 
   if (cm->frame_type == KEY_FRAME || cm->error_resilient_mode ||
diff --git a/av1/common/filter.c b/av1/common/filter.c
index bf30fa8..21526fc 100644
--- a/av1/common/filter.c
+++ b/av1/common/filter.c
@@ -144,11 +144,20 @@
   { -1, 2, -2, 4, -8, 18, 124, -13, 6, -3, 2, -1 },
   { 0, 1, -1, 2, -4, 8, 127, -7, 3, -2, 1, 0 },
 };
-#else   // CONFIG_EXT_INTERP
+#else  // CONFIG_EXT_INTERP
 
 DECLARE_ALIGNED(256, static const InterpKernel,
                 sub_pel_filters_8[SUBPEL_SHIFTS]) = {
-  // Lagrangian interpolation filter
+#if CONFIG_FILTER_7BIT
+  { 0, 0, 0, 128, 0, 0, 0, 0 },      { 0, 2, -6, 126, 8, -2, 0, 0 },
+  { 0, 2, -10, 122, 18, -4, 0, 0 },  { 0, 2, -12, 116, 28, -8, 2, 0 },
+  { 0, 2, -14, 110, 38, -10, 2, 0 }, { 0, 2, -14, 102, 48, -12, 2, 0 },
+  { 0, 2, -16, 94, 58, -12, 2, 0 },  { 0, 2, -14, 84, 66, -12, 2, 0 },
+  { 0, 2, -14, 76, 76, -14, 2, 0 },  { 0, 2, -12, 66, 84, -14, 2, 0 },
+  { 0, 2, -12, 58, 94, -16, 2, 0 },  { 0, 2, -12, 48, 102, -14, 2, 0 },
+  { 0, 2, -10, 38, 110, -14, 2, 0 }, { 0, 2, -8, 28, 116, -12, 2, 0 },
+  { 0, 0, -4, 18, 122, -10, 2, 0 },  { 0, 0, -2, 8, 126, -6, 2, 0 }
+#else
   { 0, 0, 0, 128, 0, 0, 0, 0 },        { 0, 1, -5, 126, 8, -3, 1, 0 },
   { -1, 3, -10, 122, 18, -6, 2, 0 },   { -1, 4, -13, 118, 27, -9, 3, -1 },
   { -1, 4, -16, 112, 37, -11, 4, -1 }, { -1, 5, -18, 105, 48, -14, 4, -1 },
@@ -157,11 +166,21 @@
   { -1, 5, -16, 58, 97, -19, 5, -1 },  { -1, 4, -14, 48, 105, -18, 5, -1 },
   { -1, 4, -11, 37, 112, -16, 4, -1 }, { -1, 3, -9, 27, 118, -13, 4, -1 },
   { 0, 2, -6, 18, 122, -10, 3, -1 },   { 0, 1, -3, 8, 126, -5, 1, 0 }
+#endif
 };
 
 DECLARE_ALIGNED(256, static const InterpKernel,
                 sub_pel_filters_8sharp[SUBPEL_SHIFTS]) = {
-  // DCT based filter
+#if CONFIG_FILTER_7BIT
+  { 0, 0, 0, 128, 0, 0, 0, 0 },         { -2, 2, -6, 126, 8, -2, 2, 0 },
+  { -2, 6, -12, 124, 16, -6, 4, -2 },   { -2, 8, -18, 120, 26, -10, 6, -2 },
+  { -4, 10, -22, 116, 38, -14, 6, -2 }, { -4, 10, -22, 108, 48, -18, 8, -2 },
+  { -4, 10, -24, 100, 60, -20, 8, -2 }, { -4, 10, -24, 90, 70, -22, 10, -2 },
+  { -4, 12, -24, 80, 80, -24, 12, -4 }, { -2, 10, -22, 70, 90, -24, 10, -4 },
+  { -2, 8, -20, 60, 100, -24, 10, -4 }, { -2, 8, -18, 48, 108, -22, 10, -4 },
+  { -2, 6, -14, 38, 116, -22, 10, -4 }, { -2, 6, -10, 26, 120, -18, 8, -2 },
+  { -2, 4, -6, 16, 124, -12, 6, -2 },   { 0, 2, -2, 8, 126, -6, 2, -2 }
+#else
   { 0, 0, 0, 128, 0, 0, 0, 0 },         { -1, 3, -7, 127, 8, -3, 1, 0 },
   { -2, 5, -13, 125, 17, -6, 3, -1 },   { -3, 7, -17, 121, 27, -10, 5, -2 },
   { -4, 9, -20, 115, 37, -13, 6, -2 },  { -4, 10, -23, 108, 48, -16, 8, -3 },
@@ -170,11 +189,21 @@
   { -3, 9, -19, 59, 100, -24, 10, -4 }, { -3, 8, -16, 48, 108, -23, 10, -4 },
   { -2, 6, -13, 37, 115, -20, 9, -4 },  { -2, 5, -10, 27, 121, -17, 7, -3 },
   { -1, 3, -6, 17, 125, -13, 5, -2 },   { 0, 1, -3, 8, 127, -7, 3, -1 }
+#endif
 };
 
 DECLARE_ALIGNED(256, static const InterpKernel,
                 sub_pel_filters_8smooth[SUBPEL_SHIFTS]) = {
-  // freqmultiplier = 0.5
+#if CONFIG_FILTER_7BIT
+  { 0, 0, 0, 128, 0, 0, 0, 0 },     { 0, 2, 28, 62, 34, 2, 0, 0 },
+  { 0, 0, 26, 62, 36, 4, 0, 0 },    { 0, 0, 22, 62, 40, 4, 0, 0 },
+  { 0, 0, 20, 60, 42, 6, 0, 0 },    { 0, 0, 18, 58, 44, 8, 0, 0 },
+  { 0, 0, 16, 56, 46, 10, 0, 0 },   { 0, -2, 16, 54, 48, 12, 0, 0 },
+  { 0, -2, 14, 52, 52, 14, -2, 0 }, { 0, 0, 12, 48, 54, 16, -2, 0 },
+  { 0, 0, 10, 46, 56, 16, 0, 0 },   { 0, 0, 8, 44, 58, 18, 0, 0 },
+  { 0, 0, 6, 42, 60, 20, 0, 0 },    { 0, 0, 4, 40, 62, 22, 0, 0 },
+  { 0, 0, 4, 36, 62, 26, 0, 0 },    { 0, 0, 2, 34, 62, 28, 2, 0 }
+#else
   { 0, 0, 0, 128, 0, 0, 0, 0 },       { -3, -1, 32, 64, 38, 1, -3, 0 },
   { -2, -2, 29, 63, 41, 2, -3, 0 },   { -2, -2, 26, 63, 43, 4, -4, 0 },
   { -2, -3, 24, 62, 46, 5, -4, 0 },   { -2, -3, 21, 60, 49, 7, -4, 0 },
@@ -183,6 +212,7 @@
   { 0, -4, 9, 51, 59, 18, -4, -1 },   { 0, -4, 7, 49, 60, 21, -3, -2 },
   { 0, -4, 5, 46, 62, 24, -3, -2 },   { 0, -4, 4, 43, 63, 26, -2, -2 },
   { 0, -3, 2, 41, 63, 29, -2, -2 },   { 0, -3, 1, 38, 64, 32, -1, -3 }
+#endif
 };
 #endif  // CONFIG_EXT_INTERP
 
diff --git a/av1/common/filter.h b/av1/common/filter.h
index 0ac52a9..15fc806 100644
--- a/av1/common/filter.h
+++ b/av1/common/filter.h
@@ -33,8 +33,12 @@
 
 #define SUPPORT_NONINTERPOLATING_FILTERS 0 /* turn on for experimentation */
 #define SWITCHABLE_FILTERS 5               /* Number of switchable filters */
+#define LOG_SWITCHABLE_FILTERS \
+  3 /* (1 << LOG_SWITCHABLE_FILTERS) > SWITCHABLE_FILTERS */
 #else
 #define SWITCHABLE_FILTERS 3 /* Number of switchable filters */
+#define LOG_SWITCHABLE_FILTERS \
+  2 /* (1 << LOG_SWITCHABLE_FILTERS) > SWITCHABLE_FILTERS */
 #endif                       // CONFIG_EXT_INTERP
 
 #define USE_TEMPORALFILTER_12TAP 1
diff --git a/av1/common/idct.c b/av1/common/idct.c
index eedbc79..4f33f9b 100644
--- a/av1/common/idct.c
+++ b/av1/common/idct.c
@@ -837,8 +837,10 @@
   if (eob == 1)
     // DC only DCT coefficient
     aom_idct8x8_1_add(input, dest, stride);
+#if !CONFIG_ADAPT_SCAN
   else if (eob <= 12)
     aom_idct8x8_12_add(input, dest, stride);
+#endif
   else
     aom_idct8x8_64_add(input, dest, stride);
 }
@@ -849,19 +851,22 @@
    * coefficients. Use eobs to separate different cases. */
   if (eob == 1) /* DC only DCT coefficient. */
     aom_idct16x16_1_add(input, dest, stride);
+#if !CONFIG_ADAPT_SCAN
   else if (eob <= 10)
     aom_idct16x16_10_add(input, dest, stride);
+#endif
   else
     aom_idct16x16_256_add(input, dest, stride);
 }
 
 void av1_idct32x32_add(const tran_low_t *input, uint8_t *dest, int stride,
                        int eob) {
-  if (eob == 1)
-    aom_idct32x32_1_add(input, dest, stride);
+  if (eob == 1) aom_idct32x32_1_add(input, dest, stride);
+#if !CONFIG_ADAPT_SCAN
   else if (eob <= 34)
     // non-zero coeff only in upper-left 8x8
     aom_idct32x32_34_add(input, dest, stride);
+#endif
   else
     aom_idct32x32_1024_add(input, dest, stride);
 }
@@ -1659,13 +1664,13 @@
   // TODO(yunqingwang): "eobs = 1" case is also handled in av1_short_idct8x8_c.
   // Combine that with code here.
   // DC only DCT coefficient
-  if (eob == 1) {
-    aom_highbd_idct8x8_1_add(input, dest, stride, bd);
-  } else if (eob <= 10) {
+  if (eob == 1) aom_highbd_idct8x8_1_add(input, dest, stride, bd);
+#if !CONFIG_ADAPT_SCAN
+  else if (eob <= 10)
     aom_highbd_idct8x8_10_add(input, dest, stride, bd);
-  } else {
+#endif
+  else
     aom_highbd_idct8x8_64_add(input, dest, stride, bd);
-  }
 }
 
 void av1_highbd_idct16x16_add(const tran_low_t *input, uint8_t *dest,
@@ -1673,25 +1678,25 @@
   // The calculation can be simplified if there are not many non-zero dct
   // coefficients. Use eobs to separate different cases.
   // DC only DCT coefficient.
-  if (eob == 1) {
-    aom_highbd_idct16x16_1_add(input, dest, stride, bd);
-  } else if (eob <= 10) {
+  if (eob == 1) aom_highbd_idct16x16_1_add(input, dest, stride, bd);
+#if !CONFIG_ADAPT_SCAN
+  else if (eob <= 10)
     aom_highbd_idct16x16_10_add(input, dest, stride, bd);
-  } else {
+#endif
+  else
     aom_highbd_idct16x16_256_add(input, dest, stride, bd);
-  }
 }
 
 void av1_highbd_idct32x32_add(const tran_low_t *input, uint8_t *dest,
                               int stride, int eob, int bd) {
   // Non-zero coeff only in upper-left 8x8
-  if (eob == 1) {
-    aom_highbd_idct32x32_1_add(input, dest, stride, bd);
-  } else if (eob <= 34) {
+  if (eob == 1) aom_highbd_idct32x32_1_add(input, dest, stride, bd);
+#if !CONFIG_ADAPT_SCAN
+  else if (eob <= 34)
     aom_highbd_idct32x32_34_add(input, dest, stride, bd);
-  } else {
+#endif
+  else
     aom_highbd_idct32x32_1024_add(input, dest, stride, bd);
-  }
 }
 
 void av1_highbd_inv_txfm_add_4x4(const tran_low_t *input, uint8_t *dest,
diff --git a/av1/common/reconinter.c b/av1/common/reconinter.c
index ad9b462..6c4ae2a 100644
--- a/av1/common/reconinter.c
+++ b/av1/common/reconinter.c
@@ -546,6 +546,7 @@
   struct macroblockd_plane *const pd = &xd->plane[plane];
 #if CONFIG_MOTION_VAR
   const MODE_INFO *mi = xd->mi[mi_col_offset + xd->mi_stride * mi_row_offset];
+  const int build_for_obmc = !(mi_col_offset == 0 && mi_row_offset == 0);
 #else
   const MODE_INFO *mi = xd->mi[0];
 #endif  // CONFIG_MOTION_VAR
@@ -567,7 +568,11 @@
 // TODO(sarahparker) enable the use of DUAL_FILTER in warped motion functions
 // in order to allow GLOBAL_MOTION and DUAL_FILTER to work together
 #if CONFIG_DUAL_FILTER
+#if CONFIG_MOTION_VAR
+  if (mi->mbmi.sb_type < BLOCK_8X8 && plane > 0 && !build_for_obmc) {
+#else
   if (mi->mbmi.sb_type < BLOCK_8X8 && plane > 0) {
+#endif  // CONFIG_MOTION_VAR
     // block size in log2
     const int b4_wl = b_width_log2_lookup[mi->mbmi.sb_type];
     const int b4_hl = b_height_log2_lookup[mi->mbmi.sb_type];
@@ -648,7 +653,11 @@
 #endif
 
 #if CONFIG_SUB8X8_MC
+#if CONFIG_MOTION_VAR
+  if (mi->mbmi.sb_type < BLOCK_8X8 && plane > 0 && !build_for_obmc) {
+#else
   if (mi->mbmi.sb_type < BLOCK_8X8 && plane > 0) {
+#endif  // CONFIG_MOTION_VAR
     // block size in log2
     const int b4_wl = b_width_log2_lookup[mi->mbmi.sb_type];
     const int b4_hl = b_height_log2_lookup[mi->mbmi.sb_type];
@@ -734,7 +743,12 @@
     struct buf_2d *const dst_buf = &pd->dst;
     uint8_t *const dst = dst_buf->buf + dst_buf->stride * y + x;
     const MV mv = mi->mbmi.sb_type < BLOCK_8X8
+#if CONFIG_MOTION_VAR
+                      ? (build_for_obmc ? mi->bmi[block].as_mv[ref].as_mv
+                                        : average_split_mvs(pd, mi, ref, block))
+#else
                       ? average_split_mvs(pd, mi, ref, block)
+#endif  // CONFIG_MOTION_VAR
                       : mi->mbmi.mv[ref].as_mv;
 
     // TODO(jkoleszar): This clamping is done in the incorrect place for the
@@ -1371,9 +1385,11 @@
   const TileInfo *const tile = &xd->tile;
   BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
   int i, j, mi_step, ref;
+  int mb_to_right_edge_base = xd->mb_to_right_edge;
 
   if (mi_row <= tile->mi_row_start) return;
 
+  xd->mb_to_bottom_edge += xd->n8_h * 32;
   for (i = 0; i < AOMMIN(xd->n8_w, cm->mi_cols - mi_col); i += mi_step) {
     int mi_row_offset = -1;
     int mi_col_offset = i;
@@ -1412,6 +1428,8 @@
     }
 
     xd->mb_to_left_edge = -(((mi_col + i) * MI_SIZE) * 8);
+    xd->mb_to_right_edge =
+        mb_to_right_edge_base + (xd->n8_w - i - mi_step) * 64;
     mi_x = (mi_col + i) << MI_SIZE_LOG2;
     mi_y = mi_row << MI_SIZE_LOG2;
 
@@ -1425,19 +1443,19 @@
         const PARTITION_TYPE bp = BLOCK_8X8 - above_mbmi->sb_type;
         const int have_vsplit = bp != PARTITION_HORZ;
         const int have_hsplit = bp != PARTITION_VERT;
-        const int num_4x4_w = 2 >> ((!have_vsplit) | pd->subsampling_x);
-        const int num_4x4_h = 2 >> ((!have_hsplit) | pd->subsampling_y);
-        const int pw = 8 >> (have_vsplit | pd->subsampling_x);
+        const int num_4x4_w = 2 >> !have_vsplit;
+        const int num_4x4_h = 2 >> !have_hsplit;
+        const int pw = 8 >> (have_vsplit + pd->subsampling_x);
         int x, y;
 
         for (y = 0; y < num_4x4_h; ++y)
           for (x = 0; x < num_4x4_w; ++x) {
-            if ((bp == PARTITION_HORZ || bp == PARTITION_SPLIT) && y == 0 &&
-                !pd->subsampling_y)
+            if ((bp == PARTITION_HORZ || bp == PARTITION_SPLIT) && y == 0)
               continue;
 
             build_inter_predictors(xd, j, mi_col_offset, mi_row_offset,
-                                   y * 2 + x, bw, bh, 4 * x, 0, pw, bh,
+                                   y * 2 + x, bw, bh,
+                                   (4 * x) >> pd->subsampling_x, 0, pw, bh,
 #if CONFIG_SUPERTX && CONFIG_EXT_INTER
                                    0, 0,
 #endif  // CONFIG_SUPERTX && CONFIG_EXT_INTER
@@ -1457,6 +1475,8 @@
 #endif  // CONFIG_EXT_INTER
   }
   xd->mb_to_left_edge = -((mi_col * MI_SIZE) * 8);
+  xd->mb_to_right_edge = mb_to_right_edge_base;
+  xd->mb_to_bottom_edge -= xd->n8_h * 32;
 }
 
 void av1_build_prediction_by_left_preds(const AV1_COMMON *cm, MACROBLOCKD *xd,
@@ -1468,9 +1488,11 @@
   const TileInfo *const tile = &xd->tile;
   BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
   int i, j, mi_step, ref;
+  int mb_to_bottom_edge_base = xd->mb_to_bottom_edge;
 
   if (mi_col == 0 || (mi_col - 1 < tile->mi_col_start)) return;
 
+  xd->mb_to_right_edge += xd->n8_w * 32;
   for (i = 0; i < AOMMIN(xd->n8_h, cm->mi_rows - mi_row); i += mi_step) {
     int mi_row_offset = i;
     int mi_col_offset = -1;
@@ -1509,6 +1531,8 @@
     }
 
     xd->mb_to_top_edge = -(((mi_row + i) * MI_SIZE) * 8);
+    xd->mb_to_bottom_edge =
+        mb_to_bottom_edge_base + (xd->n8_h - i - mi_step) * 64;
     mi_x = mi_col << MI_SIZE_LOG2;
     mi_y = (mi_row + i) << MI_SIZE_LOG2;
 
@@ -1522,19 +1546,19 @@
         const PARTITION_TYPE bp = BLOCK_8X8 - left_mbmi->sb_type;
         const int have_vsplit = bp != PARTITION_HORZ;
         const int have_hsplit = bp != PARTITION_VERT;
-        const int num_4x4_w = 2 >> ((!have_vsplit) | pd->subsampling_x);
-        const int num_4x4_h = 2 >> ((!have_hsplit) | pd->subsampling_y);
-        const int ph = 8 >> (have_hsplit | pd->subsampling_y);
+        const int num_4x4_w = 2 >> !have_vsplit;
+        const int num_4x4_h = 2 >> !have_hsplit;
+        const int ph = 8 >> (have_hsplit + pd->subsampling_y);
         int x, y;
 
         for (y = 0; y < num_4x4_h; ++y)
           for (x = 0; x < num_4x4_w; ++x) {
-            if ((bp == PARTITION_VERT || bp == PARTITION_SPLIT) && x == 0 &&
-                !pd->subsampling_x)
+            if ((bp == PARTITION_VERT || bp == PARTITION_SPLIT) && x == 0)
               continue;
 
             build_inter_predictors(xd, j, mi_col_offset, mi_row_offset,
-                                   y * 2 + x, bw, bh, 0, 4 * y, bw, ph,
+                                   y * 2 + x, bw, bh, 0,
+                                   (4 * y) >> pd->subsampling_y, bw, ph,
 #if CONFIG_SUPERTX && CONFIG_EXT_INTER
                                    0, 0,
 #endif  // CONFIG_SUPERTX && CONFIG_EXT_INTER
@@ -1554,6 +1578,54 @@
 #endif  // CONFIG_EXT_INTER
   }
   xd->mb_to_top_edge = -((mi_row * MI_SIZE) * 8);
+  xd->mb_to_bottom_edge = mb_to_bottom_edge_base;
+  xd->mb_to_right_edge -= xd->n8_w * 32;
+}
+
+void av1_build_obmc_inter_predictors_sb(const AV1_COMMON *cm, MACROBLOCKD *xd,
+                                        int mi_row, int mi_col) {
+#if CONFIG_AOM_HIGHBITDEPTH
+  DECLARE_ALIGNED(16, uint8_t, tmp_buf1[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
+  DECLARE_ALIGNED(16, uint8_t, tmp_buf2[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
+#else
+  DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * MAX_SB_SQUARE]);
+  DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * MAX_SB_SQUARE]);
+#endif  // CONFIG_AOM_HIGHBITDEPTH
+  uint8_t *dst_buf1[MAX_MB_PLANE], *dst_buf2[MAX_MB_PLANE];
+  int dst_stride1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
+  int dst_stride2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
+  int dst_width1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
+  int dst_width2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
+  int dst_height1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
+  int dst_height2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
+
+#if CONFIG_AOM_HIGHBITDEPTH
+  if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
+    int len = sizeof(uint16_t);
+    dst_buf1[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
+    dst_buf1[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * len);
+    dst_buf1[2] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * 2 * len);
+    dst_buf2[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
+    dst_buf2[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * len);
+    dst_buf2[2] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * 2 * len);
+  } else {
+#endif  // CONFIG_AOM_HIGHBITDEPTH
+    dst_buf1[0] = tmp_buf1;
+    dst_buf1[1] = tmp_buf1 + MAX_SB_SQUARE;
+    dst_buf1[2] = tmp_buf1 + MAX_SB_SQUARE * 2;
+    dst_buf2[0] = tmp_buf2;
+    dst_buf2[1] = tmp_buf2 + MAX_SB_SQUARE;
+    dst_buf2[2] = tmp_buf2 + MAX_SB_SQUARE * 2;
+#if CONFIG_AOM_HIGHBITDEPTH
+  }
+#endif  // CONFIG_AOM_HIGHBITDEPTH
+  av1_build_prediction_by_above_preds(cm, xd, mi_row, mi_col, dst_buf1,
+                                      dst_width1, dst_height1, dst_stride1);
+  av1_build_prediction_by_left_preds(cm, xd, mi_row, mi_col, dst_buf2,
+                                     dst_width2, dst_height2, dst_stride2);
+  av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
+  av1_build_obmc_inter_prediction(cm, xd, mi_row, mi_col, dst_buf1, dst_stride1,
+                                  dst_buf2, dst_stride2);
 }
 #endif  // CONFIG_MOTION_VAR
 
diff --git a/av1/common/reconinter.h b/av1/common/reconinter.h
index 5f62f0a..3eec384 100644
--- a/av1/common/reconinter.h
+++ b/av1/common/reconinter.h
@@ -535,6 +535,8 @@
                                         int tmp_width[MAX_MB_PLANE],
                                         int tmp_height[MAX_MB_PLANE],
                                         int tmp_stride[MAX_MB_PLANE]);
+void av1_build_obmc_inter_predictors_sb(const AV1_COMMON *cm, MACROBLOCKD *xd,
+                                        int mi_row, int mi_col);
 #endif  // CONFIG_MOTION_VAR
 
 #if CONFIG_EXT_INTER
diff --git a/av1/common/scan.h b/av1/common/scan.h
index 407c9ec..af39993 100644
--- a/av1/common/scan.h
+++ b/av1/common/scan.h
@@ -82,6 +82,10 @@
 
 static INLINE const SCAN_ORDER *get_scan(const AV1_COMMON *cm, TX_SIZE tx_size,
                                          TX_TYPE tx_type, int is_inter) {
+#if CONFIG_ADAPT_SCAN
+  (void)is_inter;
+  return &cm->fc->sc[tx_size][tx_type];
+#else  // CONFIG_ADAPT_SCAN
   (void)cm;
 #if CONFIG_EXT_TX
   return is_inter ? &av1_inter_scan_orders[tx_size][tx_type]
@@ -90,6 +94,7 @@
   (void)is_inter;
   return &av1_intra_scan_orders[tx_size][tx_type];
 #endif  // CONFIG_EXT_TX
+#endif  // CONFIG_ADAPT_SCAN
 }
 
 #ifdef __cplusplus
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index 9576b7c..8ab549b 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -303,6 +303,9 @@
     const int eob =
         av1_decode_block_tokens(xd, plane, scan_order, col, row, tx_size,
                                 tx_type, &max_scan_line, r, mbmi->segment_id);
+#if CONFIG_ADAPT_SCAN
+    av1_update_scan_count_facade(cm, tx_size, tx_type, pd->dqcoeff, eob);
+#endif
     if (eob)
       inverse_transform_block(xd, plane, tx_type, tx_size, dst, pd->dst.stride,
                               max_scan_line, eob);
@@ -384,6 +387,9 @@
   const int eob =
       av1_decode_block_tokens(xd, plane, scan_order, col, row, tx_size, tx_type,
                               &max_scan_line, r, segment_id);
+#if CONFIG_ADAPT_SCAN
+  av1_update_scan_count_facade(cm, tx_size, tx_type, pd->dqcoeff, eob);
+#endif
   if (eob)
     inverse_transform_block(xd, plane, tx_type, tx_size,
                             &pd->dst.buf[4 * row * pd->dst.stride + 4 * col],
@@ -1264,49 +1270,7 @@
     av1_build_inter_predictors_sb(xd, mi_row, mi_col, AOMMAX(bsize, BLOCK_8X8));
 #if CONFIG_MOTION_VAR
     if (mbmi->motion_mode == OBMC_CAUSAL) {
-#if CONFIG_AOM_HIGHBITDEPTH
-      DECLARE_ALIGNED(16, uint8_t, tmp_buf1[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
-      DECLARE_ALIGNED(16, uint8_t, tmp_buf2[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
-#else
-      DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * MAX_SB_SQUARE]);
-      DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * MAX_SB_SQUARE]);
-#endif  // CONFIG_AOM_HIGHBITDEPTH
-      uint8_t *dst_buf1[MAX_MB_PLANE], *dst_buf2[MAX_MB_PLANE];
-      int dst_width1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
-      int dst_width2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
-      int dst_height1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
-      int dst_height2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
-      int dst_stride1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
-      int dst_stride2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
-
-      assert(mbmi->sb_type >= BLOCK_8X8);
-#if CONFIG_AOM_HIGHBITDEPTH
-      if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
-        int len = sizeof(uint16_t);
-        dst_buf1[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
-        dst_buf1[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * len);
-        dst_buf1[2] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * 2 * len);
-        dst_buf2[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
-        dst_buf2[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * len);
-        dst_buf2[2] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * 2 * len);
-      } else {
-#endif  // CONFIG_AOM_HIGHBITDEPTH
-        dst_buf1[0] = tmp_buf1;
-        dst_buf1[1] = tmp_buf1 + MAX_SB_SQUARE;
-        dst_buf1[2] = tmp_buf1 + MAX_SB_SQUARE * 2;
-        dst_buf2[0] = tmp_buf2;
-        dst_buf2[1] = tmp_buf2 + MAX_SB_SQUARE;
-        dst_buf2[2] = tmp_buf2 + MAX_SB_SQUARE * 2;
-#if CONFIG_AOM_HIGHBITDEPTH
-      }
-#endif  // CONFIG_AOM_HIGHBITDEPTH
-      av1_build_prediction_by_above_preds(cm, xd, mi_row, mi_col, dst_buf1,
-                                          dst_width1, dst_height1, dst_stride1);
-      av1_build_prediction_by_left_preds(cm, xd, mi_row, mi_col, dst_buf2,
-                                         dst_width2, dst_height2, dst_stride2);
-      av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
-      av1_build_obmc_inter_prediction(cm, xd, mi_row, mi_col, dst_buf1,
-                                      dst_stride1, dst_buf2, dst_stride2);
+      av1_build_obmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
     }
 #endif  // CONFIG_MOTION_VAR
 
@@ -2275,7 +2239,7 @@
 
 static InterpFilter read_interp_filter(struct aom_read_bit_buffer *rb) {
   return aom_rb_read_bit(rb) ? SWITCHABLE
-                             : aom_rb_read_literal(rb, 2 + CONFIG_EXT_INTERP);
+                             : aom_rb_read_literal(rb, LOG_SWITCHABLE_FILTERS);
 }
 
 static void setup_render_size(AV1_COMMON *cm, struct aom_read_bit_buffer *rb) {
@@ -2814,9 +2778,9 @@
 #endif
 #if CONFIG_ACCOUNTING
       if (pbi->acct_enabled) {
-        tile_data->bit_reader.accounting = &pbi->accounting;
+        td->bit_reader.accounting = &pbi->accounting;
       } else {
-        tile_data->bit_reader.accounting = NULL;
+        td->bit_reader.accounting = NULL;
       }
 #endif
       av1_init_macroblockd(cm, &td->xd, td->dqcoeff);
@@ -2839,8 +2803,8 @@
       TileData *const td = pbi->tile_data + tile_cols * row + col;
 #if CONFIG_ACCOUNTING
       if (pbi->acct_enabled) {
-        tile_data->bit_reader.accounting->last_tell_frac =
-            aom_reader_tell_frac(&tile_data->bit_reader);
+        td->bit_reader.accounting->last_tell_frac =
+            aom_reader_tell_frac(&td->bit_reader);
       }
 #endif
 
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index 0759b91..377af50 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -2884,7 +2884,7 @@
                                 struct aom_write_bit_buffer *wb) {
   aom_wb_write_bit(wb, filter == SWITCHABLE);
   if (filter != SWITCHABLE)
-    aom_wb_write_literal(wb, filter, 2 + CONFIG_EXT_INTERP);
+    aom_wb_write_literal(wb, filter, LOG_SWITCHABLE_FILTERS);
 }
 
 static void fix_interp_filter(AV1_COMMON *cm, FRAME_COUNTS *counts) {
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index 5060e45..ffb5d46 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -1327,8 +1327,8 @@
 #if CONFIG_DUAL_FILTER
       update_filter_type_count(td->counts, xd, mbmi);
 #else
-      const int ctx = av1_get_pred_context_switchable_interp(xd);
-      ++td->counts->switchable_interp[ctx][mbmi->interp_filter];
+      const int pred_ctx = av1_get_pred_context_switchable_interp(xd);
+      ++td->counts->switchable_interp[pred_ctx][mbmi->interp_filter];
 #endif
     }
 
@@ -5177,50 +5177,7 @@
 
 #if CONFIG_MOTION_VAR
     if (mbmi->motion_mode == OBMC_CAUSAL) {
-#if CONFIG_AOM_HIGHBITDEPTH
-      DECLARE_ALIGNED(16, uint8_t, tmp_buf1[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
-      DECLARE_ALIGNED(16, uint8_t, tmp_buf2[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
-#else
-      DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * MAX_SB_SQUARE]);
-      DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * MAX_SB_SQUARE]);
-#endif  // CONFIG_AOM_HIGHBITDEPTH
-      uint8_t *dst_buf1[MAX_MB_PLANE], *dst_buf2[MAX_MB_PLANE];
-      int dst_stride1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
-      int dst_stride2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
-      int dst_width1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
-      int dst_width2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
-      int dst_height1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
-      int dst_height2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
-
-      assert(mbmi->sb_type >= BLOCK_8X8);
-
-#if CONFIG_AOM_HIGHBITDEPTH
-      if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
-        int len = sizeof(uint16_t);
-        dst_buf1[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
-        dst_buf1[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * len);
-        dst_buf1[2] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * 2 * len);
-        dst_buf2[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
-        dst_buf2[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * len);
-        dst_buf2[2] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * 2 * len);
-      } else {
-#endif  // CONFIG_AOM_HIGHBITDEPTH
-        dst_buf1[0] = tmp_buf1;
-        dst_buf1[1] = tmp_buf1 + MAX_SB_SQUARE;
-        dst_buf1[2] = tmp_buf1 + MAX_SB_SQUARE * 2;
-        dst_buf2[0] = tmp_buf2;
-        dst_buf2[1] = tmp_buf2 + MAX_SB_SQUARE;
-        dst_buf2[2] = tmp_buf2 + MAX_SB_SQUARE * 2;
-#if CONFIG_AOM_HIGHBITDEPTH
-      }
-#endif  // CONFIG_AOM_HIGHBITDEPTH
-      av1_build_prediction_by_above_preds(cm, xd, mi_row, mi_col, dst_buf1,
-                                          dst_width1, dst_height1, dst_stride1);
-      av1_build_prediction_by_left_preds(cm, xd, mi_row, mi_col, dst_buf2,
-                                         dst_width2, dst_height2, dst_stride2);
-      av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
-      av1_build_obmc_inter_prediction(cm, xd, mi_row, mi_col, dst_buf1,
-                                      dst_stride1, dst_buf2, dst_stride2);
+      av1_build_obmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
     }
 #endif  // CONFIG_MOTION_VAR
 
diff --git a/av1/encoder/firstpass.c b/av1/encoder/firstpass.c
index dc97ddf..0f7fcca 100644
--- a/av1/encoder/firstpass.c
+++ b/av1/encoder/firstpass.c
@@ -535,6 +535,9 @@
   }
 
   av1_init_mv_probs(cm);
+#if CONFIG_ADAPT_SCAN
+  av1_init_scan_order(cm);
+#endif
   av1_initialize_rd_consts(cpi);
 
   // Tiling is ignored in the first pass.
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index fdf9b51..569df1f 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -992,7 +992,7 @@
   if (cpi->sf.use_transform_domain_distortion) {
     // Transform domain distortion computation is more accurate as it does
     // not involve an inverse transform, but it is less accurate.
-    const int ss_txfrm_size = num_4x4_blocks_txsize_log2_lookup[tx_size];
+    const int buffer_length = tx_size_2d[tx_size];
     int64_t this_sse;
     int tx_type = get_tx_type(pd->plane_type, xd, block, tx_size);
     int shift = (MAX_TX_SCALE - get_tx_scale(xd, tx_type, tx_size)) * 2;
@@ -1000,23 +1000,25 @@
     tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
 #if CONFIG_AOM_HIGHBITDEPTH
     const int bd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? xd->bd : 8;
-    *out_dist = av1_highbd_block_error(coeff, dqcoeff, 16 << ss_txfrm_size,
-                                       &this_sse, bd) >>
-                shift;
+    *out_dist =
+        av1_highbd_block_error(coeff, dqcoeff, buffer_length, &this_sse, bd) >>
+        shift;
 #else
     *out_dist =
-        av1_block_error(coeff, dqcoeff, 16 << ss_txfrm_size, &this_sse) >>
-        shift;
+        av1_block_error(coeff, dqcoeff, buffer_length, &this_sse) >> shift;
 #endif  // CONFIG_AOM_HIGHBITDEPTH
     *out_sse = this_sse >> shift;
   } else {
     const BLOCK_SIZE tx_bsize = txsize_to_bsize[tx_size];
-    const int bsw = 4 * num_4x4_blocks_wide_lookup[tx_bsize];
-    const int bsh = 4 * num_4x4_blocks_high_lookup[tx_bsize];
+    const int bsw = block_size_wide[tx_bsize];
+    const int bsh = block_size_high[tx_bsize];
     const int src_stride = x->plane[plane].src.stride;
     const int dst_stride = xd->plane[plane].dst.stride;
-    const int src_idx = 4 * (blk_row * src_stride + blk_col);
-    const int dst_idx = 4 * (blk_row * dst_stride + blk_col);
+    // Scale the transform block index to pixel unit.
+    const int src_idx = (blk_row * src_stride + blk_col)
+                        << tx_size_wide_log2[0];
+    const int dst_idx = (blk_row * dst_stride + blk_col)
+                        << tx_size_wide_log2[0];
     const uint8_t *src = &x->plane[plane].src.buf[src_idx];
     const uint8_t *dst = &xd->plane[plane].dst.buf[dst_idx];
     const tran_low_t *dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
@@ -1025,6 +1027,7 @@
     unsigned int tmp;
 
     assert(cpi != NULL);
+    assert(tx_size_wide_log2[0] == tx_size_high_log2[0]);
 
     cpi->fn_ptr[tx_bsize].vf(src, src_stride, dst, dst_stride, &tmp);
     *out_sse = (int64_t)tmp * 16;
@@ -7017,14 +7020,11 @@
     int64_t tmp_dist_sum = 0;
 
 #if CONFIG_DUAL_FILTER
-#if CONFIG_EXT_INTERP
-    for (i = 0; i < 25; ++i) {
+    for (i = 0; i < SWITCHABLE_FILTERS * SWITCHABLE_FILTERS; ++i)
 #else
-    for (i = 0; i < 9; ++i) {
+    for (i = 0; i < SWITCHABLE_FILTERS; ++i)
 #endif
-#else
-    for (i = 0; i < SWITCHABLE_FILTERS; ++i) {
-#endif
+    {
       int j;
       int64_t rs_rd;
       int tmp_skip_sb = 0;
@@ -7047,14 +7047,6 @@
       } else {
         int rate_sum = 0;
         int64_t dist_sum = 0;
-
-        if (i > 0 && cpi->sf.adaptive_interp_filter_search &&
-            (cpi->sf.interp_filter_search_mask & (1 << i))) {
-          rate_sum = INT_MAX;
-          dist_sum = INT64_MAX;
-          continue;
-        }
-
         if ((cm->interp_filter == SWITCHABLE && (!i || best_needs_copy)) ||
 #if CONFIG_EXT_INTER
             is_comp_interintra_pred ||
@@ -7086,13 +7078,6 @@
           tmp_dist_sum = dist_sum;
         }
       }
-
-      if (i == 0 && cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) {
-        if (rd / 2 > ref_best_rd) {
-          restore_dst_buf(xd, orig_dst, orig_dst_stride);
-          return INT64_MAX;
-        }
-      }
       newbest = i == 0 || rd < best_rd;
 
       if (newbest) {
@@ -7113,10 +7098,11 @@
       if ((cm->interp_filter == SWITCHABLE && newbest) ||
           (cm->interp_filter != SWITCHABLE &&
 #if CONFIG_DUAL_FILTER
-           cm->interp_filter == mbmi->interp_filter[0])) {
+           cm->interp_filter == mbmi->interp_filter[0]
 #else
-           cm->interp_filter == mbmi->interp_filter)) {
+           cm->interp_filter == mbmi->interp_filter
 #endif
+           )) {
         pred_exists = 1;
         tmp_rd = best_rd;
 
diff --git a/av1/encoder/tokenize.c b/av1/encoder/tokenize.c
index 6927382..43ed837 100644
--- a/av1/encoder/tokenize.c
+++ b/av1/encoder/tokenize.c
@@ -504,6 +504,14 @@
 
   *tp = t;
 
+#if CONFIG_ADAPT_SCAN
+  // Since dqcoeff is not available here, we pass qcoeff into
+  // av1_update_scan_count_facade(). The update behavior should be the same
+  // because av1_update_scan_count_facade() only cares if coefficients are zero
+  // or not.
+  av1_update_scan_count_facade((AV1_COMMON *)cm, tx_size, tx_type, qcoeff, c);
+#endif
+
   av1_set_contexts(xd, pd, tx_size, c > 0, blk_col, blk_row);
 }
 
diff --git a/configure b/configure
index 2659d37..5bfce04 100755
--- a/configure
+++ b/configure
@@ -288,6 +288,7 @@
     frame_size
     delta_q
     adapt_scan
+    filter_7bit
 "
 CONFIG_LIST="
     dependency_tracking
diff --git a/test/av1_inv_txfm_test.cc b/test/av1_inv_txfm_test.cc
index ff358b6..84e2402 100644
--- a/test/av1_inv_txfm_test.cc
+++ b/test/av1_inv_txfm_test.cc
@@ -137,6 +137,7 @@
   InvTxfmFunc partial_itxfm_;
 };
 
+#if !CONFIG_ADAPT_SCAN
 TEST_P(AV1PartialIDctTest, RunQuantCheck) {
   int size;
   switch (tx_size_) {
@@ -256,6 +257,7 @@
   EXPECT_EQ(0, max_error)
       << "Error: partial inverse transform produces different results";
 }
+#endif
 using std::tr1::make_tuple;
 
 INSTANTIATE_TEST_CASE_P(
diff --git a/test/test.mk b/test/test.mk
index 61ea1d0..2d18f69 100644
--- a/test/test.mk
+++ b/test/test.mk
@@ -113,6 +113,7 @@
 #LIBAOM_TEST_SRCS-yes                   += encoder_parms_get_to_decoder.cc
 endif
 
+LIBAOM_TEST_SRCS-$(CONFIG_ADAPT_SCAN)  += scan_test.cc
 #LIBAOM_TEST_SRCS-yes                   += convolve_test.cc
 LIBAOM_TEST_SRCS-yes                   += lpf_8_test.cc
 LIBAOM_TEST_SRCS-$(CONFIG_CLPF)        += clpf_test.cc