Reorganize code to test various convolve options

Reorganize code to faciliate setting rounding parameters based
on bit-depth, and to faciliate testing.

After this patch this wil be the behavior for config flags as far
as round_0 and round_1 choices are concerned for 8- and 10-bit:

0. CONFIG_LOWPRECISION_BLEND=0 CONFIG_HIGHPRECISION_INTBUF=0:
round_0 = 5, round_1 = None (baseline)

1. CONFIG_LOWPRECISION_BLEND=0 CONFIG_HIGHPRECISION_INTBUF=1:
round_0 = 3, round_1 = None (to test impact of increase in precision
of intermediate buffer)

2. CONFIG_LOWPRECISION_BLEND=1 CONFIG_HIGHPRECISION_INTBUF=0:
round_0 = 5, round_1 = 4

3. CONFIG_LOWPRECISION_BLEND=2 CONFIG_HIGHPRECISION_INTBUF=0:
round_0 = 5, round_1 = 5

4. CONFIG_LOWPRECISION_BLEND=1 CONFIG_HIGHPRECISION_INTBUF=1:
round_0 = 3, round_1 = 6 (ARM proposal except clipping)

5. CONFIG_LOWPRECISION_BLEND=2 CONFIG_HIGHPRECISION_INTBUF=1:
round_0 = 3, round_1 = 7 (Google variation proposal)

Change-Id: I615348332f5692135352085ca923662f9d52f696
diff --git a/av1/common/convolve.h b/av1/common/convolve.h
index 1a19933..f9ee3e3 100644
--- a/av1/common/convolve.h
+++ b/av1/common/convolve.h
@@ -43,6 +43,16 @@
 #endif
 } ConvolveParams;
 
+#define ROUND0_BITS (5 - 2 * (CONFIG_HIGHPRECISION_INTBUF))
+
+#if CONFIG_LOWPRECISION_BLEND == 1
+#define COMPOUND_ROUND1_BITS (4 + 2 * (CONFIG_HIGHPRECISION_INTBUF))
+#elif CONFIG_LOWPRECISION_BLEND == 2
+#define COMPOUND_ROUND1_BITS (5 + 2 * (CONFIG_HIGHPRECISION_INTBUF))
+#else
+#define COMPOUND_ROUND1_BITS 0
+#endif  // CONFIG_LOWPRECISION_BLEND
+
 typedef void (*aom_convolve_fn_t)(const uint8_t *src, int src_stride,
                                   uint8_t *dst, int dst_stride, int w, int h,
                                   InterpFilterParams *filter_params_x,
@@ -50,19 +60,24 @@
                                   const int subpel_x_q4, const int subpel_y_q4,
                                   ConvolveParams *conv_params);
 
-static INLINE ConvolveParams get_conv_params(int ref, int do_average,
-                                             int plane) {
+static INLINE ConvolveParams get_conv_params(int ref, int do_average, int plane,
+                                             int bd) {
   ConvolveParams conv_params;
   conv_params.ref = ref;
   conv_params.do_average = do_average;
   conv_params.round = CONVOLVE_OPT_ROUND;
   conv_params.plane = plane;
   conv_params.do_post_rounding = 0;
-  conv_params.round_0 = 5;
+  conv_params.round_0 = ROUND0_BITS;
   conv_params.round_1 = 0;
   conv_params.is_compound = 0;
   conv_params.dst = NULL;
   conv_params.dst_stride = 0;
+  const int intbufrange = bd + FILTER_BITS - conv_params.round_0 + 2;
+  if (bd < 12) assert(intbufrange <= 16);
+  if (intbufrange > 16) {
+    conv_params.round_0 += intbufrange - 16;
+  }
   return conv_params;
 }
 
@@ -102,14 +117,25 @@
 static INLINE ConvolveParams get_conv_params_no_round(int ref, int do_average,
                                                       int plane, int32_t *dst,
                                                       int dst_stride,
-                                                      int is_compound) {
+                                                      int is_compound, int bd) {
   ConvolveParams conv_params;
   conv_params.ref = ref;
   conv_params.do_average = do_average;
   conv_params.round = CONVOLVE_OPT_NO_ROUND;
-  conv_params.round_0 = 5;
-  conv_params.round_1 = 0;
   conv_params.is_compound = is_compound;
+  conv_params.round_0 = ROUND0_BITS;
+#if CONFIG_LOWPRECISION_BLEND
+  conv_params.round_1 = is_compound ? COMPOUND_ROUND1_BITS : 0;
+#else
+  conv_params.round_1 = 0;
+#endif
+  const int intbufrange = bd + FILTER_BITS - conv_params.round_0 + 2;
+  if (bd < 12) assert(intbufrange <= 16);
+  if (intbufrange > 16) {
+    conv_params.round_0 += intbufrange - 16;
+    if (is_compound && conv_params.round_1 > 0)
+      conv_params.round_1 -= intbufrange - 16;
+  }
   // TODO(yunqing): The following dst should only be valid while
   // is_compound = 1;
   conv_params.dst = dst;
diff --git a/av1/common/reconinter.c b/av1/common/reconinter.c
index bd3493f..98597ea 100644
--- a/av1/common/reconinter.c
+++ b/av1/common/reconinter.c
@@ -26,10 +26,6 @@
 #include "av1/common/onyxc_int.h"
 #include "av1/common/obmc.h"
 
-#if CONFIG_LOWPRECISION_BLEND
-#define LOWPRECISION_BLEND_BITS 4  // reduction in precision bits
-#endif                             // CONFIG_LOWPRECISION_BLEND
-
 // This function will determine whether or not to create a warped
 // prediction.
 static INLINE int allow_warp(const MODE_INFO *const mi,
@@ -829,7 +825,7 @@
   mv.row += SCALE_EXTRA_OFF;
   const int subpel_x = mv.col & SCALE_SUBPEL_MASK;
   const int subpel_y = mv.row & SCALE_SUBPEL_MASK;
-  ConvolveParams conv_params = get_conv_params(ref, ref, plane);
+  ConvolveParams conv_params = get_conv_params(ref, ref, plane, xd->bd);
 
   src += (mv.row >> SCALE_SUBPEL_BITS) * src_stride +
          (mv.col >> SCALE_SUBPEL_BITS);
@@ -994,13 +990,7 @@
         int tmp_dst_stride = 8;
         assert(w <= 8 && h <= 8);
         ConvolveParams conv_params = get_conv_params_no_round(
-            0, 0, plane, tmp_dst, tmp_dst_stride, is_compound);
-#if CONFIG_LOWPRECISION_BLEND == 1  // for masked compound modes only
-        if (is_masked_compound_type(mi->mbmi.interinter_compound_type))
-          conv_params.round_1 = LOWPRECISION_BLEND_BITS;
-#elif CONFIG_LOWPRECISION_BLEND == 2  // for all compound modes
-        if (is_compound) conv_params.round_1 = LOWPRECISION_BLEND_BITS;
-#endif                                // CONFIG_LOWPRECISION_BLEND
+            0, 0, plane, tmp_dst, tmp_dst_stride, is_compound, xd->bd);
 #if CONFIG_JNT_COMP
         conv_params.use_jnt_comp_avg = 0;
 #endif  // CONFIG_JNT_COMP
@@ -1200,13 +1190,7 @@
     }
 
     ConvolveParams conv_params = get_conv_params_no_round(
-        ref, ref, plane, tmp_dst, MAX_SB_SIZE, is_compound);
-#if CONFIG_LOWPRECISION_BLEND == 1  // for masked compound modes only
-    if (is_masked_compound_type(mi->mbmi.interinter_compound_type))
-      conv_params.round_1 = LOWPRECISION_BLEND_BITS;
-#elif CONFIG_LOWPRECISION_BLEND == 2  // for all compound modes
-    if (is_compound) conv_params.round_1 = LOWPRECISION_BLEND_BITS;
-#endif                                // CONFIG_LOWPRECISION_BLEND
+        ref, ref, plane, tmp_dst, MAX_SB_SIZE, is_compound, xd->bd);
 #if CONFIG_JNT_COMP
     av1_jnt_comp_weight_assign(cm, &mi->mbmi, 0, &conv_params.fwd_offset,
                                &conv_params.bck_offset,
@@ -2034,7 +2018,7 @@
   uint8_t *pre;
   int xs, ys, subpel_x, subpel_y;
   const int is_scaled = av1_is_scaled(sf);
-  ConvolveParams conv_params = get_conv_params(ref, 0, plane);
+  ConvolveParams conv_params = get_conv_params(ref, 0, plane, xd->bd);
   WarpTypesAllowed warp_types;
   const WarpedMotionParams *const wm =
       &xd->global_motion[mi->mbmi.ref_frame[ref]];
diff --git a/av1/common/warped_motion.c b/av1/common/warped_motion.c
index 3b3eb8c..5daa2cf 100644
--- a/av1/common/warped_motion.c
+++ b/av1/common/warped_motion.c
@@ -598,7 +598,7 @@
   const int error_bsize_h = AOMMIN(p_height, WARP_ERROR_BLOCK);
   uint16_t tmp[WARP_ERROR_BLOCK * WARP_ERROR_BLOCK];
 
-  ConvolveParams conv_params = get_conv_params(0, 0, 0);
+  ConvolveParams conv_params = get_conv_params(0, 0, 0, bd);
 #if CONFIG_JNT_COMP
   conv_params.use_jnt_comp_avg = 0;
 #endif
@@ -896,7 +896,7 @@
   int error_bsize_w = AOMMIN(p_width, WARP_ERROR_BLOCK);
   int error_bsize_h = AOMMIN(p_height, WARP_ERROR_BLOCK);
   uint8_t tmp[WARP_ERROR_BLOCK * WARP_ERROR_BLOCK];
-  ConvolveParams conv_params = get_conv_params(0, 0, 0);
+  ConvolveParams conv_params = get_conv_params(0, 0, 0, 8);
 #if CONFIG_JNT_COMP
   conv_params.use_jnt_comp_avg = 0;
 #endif
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index 3250ebe..c7b3d04 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -5973,7 +5973,7 @@
                        // odd iterations search in the second. The predictor
                        // found for the 'other' reference frame is factored in.
     const int plane = 0;
-    ConvolveParams conv_params = get_conv_params(!id, 0, plane);
+    ConvolveParams conv_params = get_conv_params(!id, 0, plane, xd->bd);
 #if CONFIG_JNT_COMP
     conv_params.use_jnt_comp_avg = 0;
 #endif
@@ -6631,7 +6631,7 @@
   struct buf_2d ref_yv12;
 
   const int plane = 0;
-  ConvolveParams conv_params = get_conv_params(!ref_idx, 0, plane);
+  ConvolveParams conv_params = get_conv_params(!ref_idx, 0, plane, xd->bd);
   WarpTypesAllowed warp_types;
   warp_types.global_warp_allowed = is_global;
   warp_types.local_warp_allowed = mbmi->motion_mode == WARPED_CAUSAL;
diff --git a/av1/encoder/temporal_filter.c b/av1/encoder/temporal_filter.c
index 987f34c..a7377d5 100644
--- a/av1/encoder/temporal_filter.c
+++ b/av1/encoder/temporal_filter.c
@@ -41,7 +41,7 @@
   enum mv_precision mv_precision_uv;
   int uv_stride;
   // TODO(angiebird): change plane setting accordingly
-  ConvolveParams conv_params = get_conv_params(which_mv, which_mv, 0);
+  ConvolveParams conv_params = get_conv_params(which_mv, which_mv, 0, xd->bd);
   const InterpFilters interp_filters = xd->mi[0]->mbmi.interp_filters;
   WarpTypesAllowed warp_types;
   memset(&warp_types, 0, sizeof(WarpTypesAllowed));
diff --git a/build/cmake/aom_config_defaults.cmake b/build/cmake/aom_config_defaults.cmake
index a48d42f..13a02a3 100644
--- a/build/cmake/aom_config_defaults.cmake
+++ b/build/cmake/aom_config_defaults.cmake
@@ -120,6 +120,7 @@
 set(CONFIG_FRAME_SIZE 1 CACHE NUMBER "AV1 experiment flag.")
 set(CONFIG_FWD_KF 0 CACHE NUMBER "AV1 experiment flag.")
 set(CONFIG_HASH_ME 0 CACHE NUMBER "AV1 experiment flag.")
+set(CONFIG_HIGHPRECISION_INTBUF 0 CACHE NUMBER "AV1 experiment flag.")
 set(CONFIG_HORZONLY_FRAME_SUPERRES 1 CACHE NUMBER "AV1 experiment flag.")
 set(CONFIG_INTER_STATS_ONLY 0 CACHE NUMBER "AV1 experiment flag.")
 set(CONFIG_INTRABC 1 CACHE NUMBER "AV1 experiment flag.")
diff --git a/test/av1_convolve_2d_test_util.cc b/test/av1_convolve_2d_test_util.cc
index cce9922..e18fc6f 100644
--- a/test/av1_convolve_2d_test_util.cc
+++ b/test/av1_convolve_2d_test_util.cc
@@ -63,9 +63,9 @@
             av1_get_interp_filter_params((InterpFilter)vfilter);
         for (int do_average = 0; do_average <= 1; ++do_average) {
           ConvolveParams conv_params1 = get_conv_params_no_round(
-              0, do_average, 0, output, MAX_SB_SIZE, 1);
+              0, do_average, 0, output, MAX_SB_SIZE, 1, 8);
           ConvolveParams conv_params2 = get_conv_params_no_round(
-              0, do_average, 0, output2, MAX_SB_SIZE, 1);
+              0, do_average, 0, output2, MAX_SB_SIZE, 1, 8);
 
           const int subx_range = has_subx ? 16 : 1;
           const int suby_range = has_suby ? 16 : 1;
@@ -121,7 +121,7 @@
       av1_get_interp_filter_params((InterpFilter)vfilter);
   const int do_average = 0;
   ConvolveParams conv_params2 =
-      get_conv_params_no_round(0, do_average, 0, output, MAX_SB_SIZE, 1);
+      get_conv_params_no_round(0, do_average, 0, output, MAX_SB_SIZE, 1, 8);
 
   for (int block_idx = BLOCK_4X4; block_idx < BLOCK_SIZES_ALL; ++block_idx) {
     const int out_w = block_size_wide[block_idx];
@@ -184,9 +184,9 @@
               av1_get_interp_filter_params((InterpFilter)vfilter);
           for (int do_average = 0; do_average <= 1; ++do_average) {
             ConvolveParams conv_params1 =
-                get_conv_params_no_round(0, do_average, 0, NULL, 0, 1);
+                get_conv_params_no_round(0, do_average, 0, NULL, 0, 1, 8);
             ConvolveParams conv_params2 =
-                get_conv_params_no_round(0, do_average, 0, NULL, 0, 1);
+                get_conv_params_no_round(0, do_average, 0, NULL, 0, 1, 8);
 
             const int subx_range = has_subx ? 16 : 1;
             const int suby_range = has_suby ? 16 : 1;
@@ -246,7 +246,7 @@
       av1_get_interp_filter_params((InterpFilter)vfilter);
   const int do_average = 0;
   ConvolveParams conv_params2 =
-      get_conv_params_no_round(0, do_average, 0, NULL, 0, 1);
+      get_conv_params_no_round(0, do_average, 0, NULL, 0, 1, 8);
 
   for (int block_idx = BLOCK_4X4; block_idx < BLOCK_SIZES_ALL; ++block_idx) {
     // Make sure that sizes 2xN and Nx2 are also tested for chroma.
@@ -310,9 +310,9 @@
             av1_get_interp_filter_params((InterpFilter)vfilter);
         for (int do_average = 0; do_average <= 1; ++do_average) {
           ConvolveParams conv_params1 = get_conv_params_no_round(
-              0, do_average, 0, output, MAX_SB_SIZE, 1);
+              0, do_average, 0, output, MAX_SB_SIZE, 1, 8);
           ConvolveParams conv_params2 = get_conv_params_no_round(
-              0, do_average, 0, output2, MAX_SB_SIZE, 1);
+              0, do_average, 0, output2, MAX_SB_SIZE, 1, 8);
 
           // Test special case where jnt_comp_avg is not used
           conv_params1.use_jnt_comp_avg = 0;
@@ -436,9 +436,9 @@
             av1_get_interp_filter_params((InterpFilter)vfilter);
         for (int do_average = 0; do_average <= 1; ++do_average) {
           ConvolveParams conv_params1 = get_conv_params_no_round(
-              0, do_average, 0, output, MAX_SB_SIZE, 1);
+              0, do_average, 0, output, MAX_SB_SIZE, 1, bd);
           ConvolveParams conv_params2 = get_conv_params_no_round(
-              0, do_average, 0, output2, MAX_SB_SIZE, 1);
+              0, do_average, 0, output2, MAX_SB_SIZE, 1, bd);
 
           for (subx = 0; subx < 16; ++subx) {
             for (suby = 0; suby < 16; ++suby) {
@@ -506,9 +506,9 @@
             av1_get_interp_filter_params((InterpFilter)vfilter);
         for (int do_average = 0; do_average <= 1; ++do_average) {
           ConvolveParams conv_params1 = get_conv_params_no_round(
-              0, do_average, 0, output, MAX_SB_SIZE, 1);
+              0, do_average, 0, output, MAX_SB_SIZE, 1, bd);
           ConvolveParams conv_params2 = get_conv_params_no_round(
-              0, do_average, 0, output2, MAX_SB_SIZE, 1);
+              0, do_average, 0, output2, MAX_SB_SIZE, 1, bd);
 
           // Test special case where jnt_comp_avg is not used
           conv_params1.use_jnt_comp_avg = 0;
diff --git a/test/av1_convolve_optimz_test.cc b/test/av1_convolve_optimz_test.cc
index 188fa2d..288daeb 100644
--- a/test/av1_convolve_optimz_test.cc
+++ b/test/av1_convolve_optimz_test.cc
@@ -66,7 +66,7 @@
     subpel_ = GET_PARAM(4);
     int ref = GET_PARAM(5);
     const int plane = 0;
-    conv_params_ = get_conv_params(ref, ref, plane);
+    conv_params_ = get_conv_params(ref, ref, plane, 8);
 
     alloc_ = new uint8_t[maxBlockSize * 4];
     src_ = alloc_ + (vertiOffset * maxWidth);
diff --git a/test/av1_convolve_scale_test.cc b/test/av1_convolve_scale_test.cc
index f776f36..99382e0 100644
--- a/test/av1_convolve_scale_test.cc
+++ b/test/av1_convolve_scale_test.cc
@@ -256,7 +256,7 @@
     filter_x_.set(ntaps_x_, false);
     filter_y_.set(ntaps_y_, true);
     convolve_params_ =
-        get_conv_params_no_round(0, avg_ != false, 0, NULL, 0, 1);
+        get_conv_params_no_round(0, avg_ != false, 0, NULL, 0, 1, bd);
 
     delete image_;
     image_ = new TestImage<SrcPixel>(width_, height_, bd_);
diff --git a/test/av1_convolve_test.cc b/test/av1_convolve_test.cc
index 9ccd7ea..cb58289 100644
--- a/test/av1_convolve_test.cc
+++ b/test/av1_convolve_test.cc
@@ -149,7 +149,7 @@
 
 TEST_P(Av1ConvolveTest, av1_convolve_vert) {
   const int y_step_q4 = 16;
-  ConvolveParams conv_params = get_conv_params(0, 0, 0);
+  ConvolveParams conv_params = get_conv_params(0, 0, 0, 8);
 
   int in_stride, out_stride, ref_out_stride, avg_out_stride, ref_avg_out_stride;
   uint8_t *in = add_input(MAX_SB_SIZE, MAX_SB_SIZE, &in_stride);
@@ -202,7 +202,7 @@
 
 TEST_P(Av1ConvolveTest, av1_convolve_horiz) {
   const int x_step_q4 = 16;
-  ConvolveParams conv_params = get_conv_params(0, 0, 0);
+  ConvolveParams conv_params = get_conv_params(0, 0, 0, 8);
 
   int in_stride, out_stride, ref_out_stride, avg_out_stride, ref_avg_out_stride;
   uint8_t *in = add_input(MAX_SB_SIZE, MAX_SB_SIZE, &in_stride);
diff --git a/test/warp_filter_test_util.cc b/test/warp_filter_test_util.cc
index 9b51a24..c418855 100644
--- a/test/warp_filter_test_util.cc
+++ b/test/warp_filter_test_util.cc
@@ -101,6 +101,7 @@
   const int out_w = GET_PARAM(0), out_h = GET_PARAM(1);
   const int num_iters = GET_PARAM(2);
   int i, j, sub_x, sub_y;
+  const int bd = 8;
 
   uint8_t *input_ = new uint8_t[h * stride];
   uint8_t *input = input_ + border;
@@ -112,7 +113,7 @@
   uint8_t *output2 = new uint8_t[output_n];
   int32_t mat[8];
   int16_t alpha, beta, gamma, delta;
-  ConvolveParams conv_params = get_conv_params(0, 0, 0);
+  ConvolveParams conv_params = get_conv_params(0, 0, 0, bd);
   int32_t *dsta = new int32_t[output_n];
   int32_t *dstb = new int32_t[output_n];
 
@@ -140,9 +141,10 @@
                 dsta[j] = v;
                 dstb[j] = v;
               }
-              conv_params = get_conv_params_no_round(0, 0, 0, dsta, out_w, 1);
+              conv_params =
+                  get_conv_params_no_round(0, 0, 0, dsta, out_w, 1, bd);
             } else {
-              conv_params = get_conv_params(0, 0, 0);
+              conv_params = get_conv_params(0, 0, 0, bd);
             }
 #if CONFIG_JNT_COMP
             if (jj >= 4) {
@@ -158,7 +160,8 @@
                               out_h, out_w, sub_x, sub_y, &conv_params, alpha,
                               beta, gamma, delta);
             if (use_no_round) {
-              conv_params = get_conv_params_no_round(0, 0, 0, dstb, out_w, 1);
+              conv_params =
+                  get_conv_params_no_round(0, 0, 0, dstb, out_w, 1, bd);
             }
 #if CONFIG_JNT_COMP
             if (jj >= 4) {
@@ -241,7 +244,7 @@
   uint16_t *output2 = new uint16_t[output_n];
   int32_t mat[8];
   int16_t alpha, beta, gamma, delta;
-  ConvolveParams conv_params = get_conv_params(0, 0, 0);
+  ConvolveParams conv_params = get_conv_params(0, 0, 0, bd);
   int32_t *dsta = new int32_t[output_n];
   int32_t *dstb = new int32_t[output_n];
 
@@ -270,9 +273,10 @@
                 dsta[j] = v;
                 dstb[j] = v;
               }
-              conv_params = get_conv_params_no_round(0, 0, 0, dsta, out_w, 1);
+              conv_params =
+                  get_conv_params_no_round(0, 0, 0, dsta, out_w, 1, bd);
             } else {
-              conv_params = get_conv_params(0, 0, 0);
+              conv_params = get_conv_params(0, 0, 0, bd);
             }
 #if CONFIG_JNT_COMP
             if (jj >= 4) {
@@ -289,7 +293,8 @@
             if (use_no_round) {
               // TODO(angiebird): Change this to test_impl once we have SIMD
               // implementation
-              conv_params = get_conv_params_no_round(0, 0, 0, dstb, out_w, 1);
+              conv_params =
+                  get_conv_params_no_round(0, 0, 0, dstb, out_w, 1, bd);
             }
 #if CONFIG_JNT_COMP
             if (jj >= 4) {