Add short_filter experiment

Reduce the motion interpolation filter taps for inter prediction
blocks with widths or heights smaller than or equal to 4 to alleviate the memory
bandwidth increase.

AWCY HL: 0.01% Y, -0.20% U, -0.29% V (positive number means loss)

Change-Id: Ic454340e20aea2f1aae622336990f24a9e5b54d8
diff --git a/av1/common/convolve.c b/av1/common/convolve.c
index 1aa08a4..cc3a873 100644
--- a/av1/common/convolve.c
+++ b/av1/common/convolve.c
@@ -634,8 +634,13 @@
   (void)dst_stride;
 
   InterpFilterParams filter_params_x, filter_params_y;
+#if CONFIG_SHORT_FILTER
+  av1_get_convolve_filter_params(interp_filters, 1, &filter_params_x,
+                                 &filter_params_y, w, h);
+#else
   av1_get_convolve_filter_params(interp_filters, 1, &filter_params_x,
                                  &filter_params_y);
+#endif
 
   if (filter_params_y.taps < filter_params_x.taps) {
     uint8_t tr_src[(MAX_SB_SIZE + MAX_FILTER_TAP - 1) *
@@ -959,8 +964,13 @@
   (void)dst_stride;
 
   InterpFilterParams filter_params_x, filter_params_y;
+#if CONFIG_SHORT_FILTER
+  av1_get_convolve_filter_params(interp_filters, 1, &filter_params_x,
+                                 &filter_params_y, w, h);
+#else
   av1_get_convolve_filter_params(interp_filters, 1, &filter_params_x,
                                  &filter_params_y);
+#endif
 
   const uint16_t *src = CONVERT_TO_SHORTPTR(src8);
   if (filter_params_y.taps < filter_params_x.taps) {
@@ -1026,8 +1036,13 @@
   int ignore_vert = y_step_q4 == SUBPEL_SHIFTS && subpel_y_q4 == 0;
 
   InterpFilterParams filter_params_x, filter_params_y;
+#if CONFIG_SHORT_FILTER
+  av1_get_convolve_filter_params(interp_filters, 0, &filter_params_x,
+                                 &filter_params_y, w, h);
+#else
   av1_get_convolve_filter_params(interp_filters, 0, &filter_params_x,
                                  &filter_params_y);
+#endif
 
   assert(conv_params->round == CONVOLVE_OPT_ROUND);
 
@@ -1123,9 +1138,14 @@
   int ignore_vert = y_step_qn == SCALE_SUBPEL_SHIFTS && subpel_y_qn == 0;
 
   InterpFilterParams filter_params_x, filter_params_y;
+
+#if CONFIG_SHORT_FILTER
+  av1_get_convolve_filter_params(interp_filters, 0, &filter_params_x,
+                                 &filter_params_y, w, h);
+#else
   av1_get_convolve_filter_params(interp_filters, 0, &filter_params_x,
                                  &filter_params_y);
-
+#endif
   assert(conv_params->round == CONVOLVE_OPT_ROUND);
 
   assert(w <= MAX_BLOCK_WIDTH);
@@ -1515,8 +1535,13 @@
   }
 
   InterpFilterParams filter_params_x, filter_params_y;
+#if CONFIG_SHORT_FILTER
+  av1_get_convolve_filter_params(interp_filters, 0, &filter_params_x,
+                                 &filter_params_y, w, h);
+#else
   av1_get_convolve_filter_params(interp_filters, 0, &filter_params_x,
                                  &filter_params_y);
+#endif
 
   if (ignore_vert) {
     av1_highbd_convolve_horiz_facade(src8, src_stride, dst8, dst_stride, w, h,
@@ -1535,7 +1560,6 @@
     uint8_t *temp8 = CONVERT_TO_BYTEPTR(temp);
     int max_intermediate_size = ((MAX_SB_SIZE * 2 + 16) + 16);
     int filter_size;
-
 #if CONFIG_DUAL_FILTER && USE_EXTRA_FILTER
     av1_convolve_filter_params_fixup_1212(&filter_params_x, &filter_params_y);
 
@@ -1609,8 +1633,13 @@
   }
 
   InterpFilterParams filter_params_x, filter_params_y;
+#if CONFIG_SHORT_FILTER
+  av1_get_convolve_filter_params(interp_filters, 0, &filter_params_x,
+                                 &filter_params_y, w, h);
+#else
   av1_get_convolve_filter_params(interp_filters, 0, &filter_params_x,
                                  &filter_params_y);
+#endif
 
   if (ignore_vert) {
     av1_highbd_convolve_horiz_facade_scale(src8, src_stride, dst8, dst_stride,
diff --git a/av1/common/convolve.h b/av1/common/convolve.h
index 61f290a..c9f6785 100644
--- a/av1/common/convolve.h
+++ b/av1/common/convolve.h
@@ -64,9 +64,15 @@
 }
 #endif
 
-static INLINE void av1_get_convolve_filter_params(
-    InterpFilters interp_filters, int avoid_1212, InterpFilterParams *params_x,
-    InterpFilterParams *params_y) {
+static INLINE void av1_get_convolve_filter_params(InterpFilters interp_filters,
+                                                  int avoid_1212,
+                                                  InterpFilterParams *params_x,
+                                                  InterpFilterParams *params_y
+#if CONFIG_SHORT_FILTER
+                                                  ,
+                                                  int w, int h
+#endif
+                                                  ) {
 #if CONFIG_DUAL_FILTER
   InterpFilter filter_x = av1_extract_interp_filter(interp_filters, 1);
   InterpFilter filter_y = av1_extract_interp_filter(interp_filters, 0);
@@ -74,9 +80,13 @@
   InterpFilter filter_x = av1_extract_interp_filter(interp_filters, 0);
   InterpFilter filter_y = av1_extract_interp_filter(interp_filters, 0);
 #endif
-
+#if CONFIG_SHORT_FILTER
+  *params_x = av1_get_interp_filter_params_with_block_size(filter_x, w);
+  *params_y = av1_get_interp_filter_params_with_block_size(filter_y, h);
+#else
   *params_x = av1_get_interp_filter_params(filter_x);
   *params_y = av1_get_interp_filter_params(filter_y);
+#endif
 
   if (avoid_1212) {
 #if CONFIG_DUAL_FILTER && USE_EXTRA_FILTER
diff --git a/av1/common/filter.c b/av1/common/filter.c
index d766f65..4d0a8bd 100644
--- a/av1/common/filter.c
+++ b/av1/common/filter.c
@@ -259,6 +259,39 @@
 };
 #endif  // USE_TEMPORALFILTER_12TAP
 
+#if CONFIG_SHORT_FILTER
+
+DECLARE_ALIGNED(256, static const InterpKernel,
+                sub_pel_filters_4[SUBPEL_SHIFTS]) = {
+  { 0, 0, 0, 128, 0, 0, 0, 0 },     { 0, 0, -4, 126, 8, -2, 0, 0 },
+  { 0, 0, -8, 122, 18, -4, 0, 0 },  { 0, 0, -10, 116, 28, -6, 0, 0 },
+  { 0, 0, -12, 110, 38, -8, 0, 0 }, { 0, 0, -12, 102, 48, -10, 0, 0 },
+  { 0, 0, -14, 94, 58, -10, 0, 0 }, { 0, 0, -12, 84, 66, -10, 0, 0 },
+  { 0, 0, -12, 76, 76, -12, 0, 0 }, { 0, 0, -10, 66, 84, -12, 0, 0 },
+  { 0, 0, -10, 58, 94, -14, 0, 0 }, { 0, 0, -10, 48, 102, -12, 0, 0 },
+  { 0, 0, -8, 38, 110, -12, 0, 0 }, { 0, 0, -6, 28, 116, -10, 0, 0 },
+  { 0, 0, -4, 18, 122, -8, 0, 0 },  { 0, 0, -2, 8, 126, -4, 0, 0 }
+};
+DECLARE_ALIGNED(256, static const InterpKernel,
+                sub_pel_filters_4smooth[SUBPEL_SHIFTS]) = {
+  { 0, 0, 0, 128, 0, 0, 0, 0 },   { 0, 0, 30, 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, 0, 14, 54, 48, 12, 0, 0 },
+  { 0, 0, 12, 52, 52, 12, 0, 0 }, { 0, 0, 12, 48, 54, 14, 0, 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, 30, 0, 0 }
+};
+
+static const InterpFilterParams av1_interp_4tap[2] = {
+  { (const int16_t *)sub_pel_filters_4, SUBPEL_TAPS, SUBPEL_SHIFTS,
+    FOURTAP_REGULAR },
+  { (const int16_t *)sub_pel_filters_4smooth, SUBPEL_TAPS, SUBPEL_SHIFTS,
+    FOURTAP_SMOOTH },
+};
+#endif
+
 InterpFilterParams av1_get_interp_filter_params(
     const InterpFilter interp_filter) {
 #if USE_TEMPORALFILTER_12TAP
@@ -268,6 +301,24 @@
   return av1_interp_filter_params_list[interp_filter];
 }
 
+#if CONFIG_SHORT_FILTER
+InterpFilterParams av1_get_interp_filter_params_with_block_size(
+    const InterpFilter interp_filter, const int w) {
+#if USE_TEMPORALFILTER_12TAP
+  if (interp_filter == TEMPORALFILTER_12TAP)
+    return av1_interp_temporalfilter_12tap;
+#endif  // USE_TEMPORALFILTER_12TAP
+
+  if (w <= 4 &&
+      (interp_filter == MULTITAP_SHARP || interp_filter == EIGHTTAP_REGULAR))
+    return av1_interp_4tap[0];
+  else if (w <= 4 && interp_filter == EIGHTTAP_SMOOTH)
+    return av1_interp_4tap[1];
+
+  return av1_interp_filter_params_list[interp_filter];
+}
+#endif
+
 const int16_t *av1_get_interp_filter_kernel(const InterpFilter interp_filter) {
 #if USE_TEMPORALFILTER_12TAP
   if (interp_filter == TEMPORALFILTER_12TAP)
diff --git a/av1/common/filter.h b/av1/common/filter.h
index 2f1689a..19caf7c 100644
--- a/av1/common/filter.h
+++ b/av1/common/filter.h
@@ -44,6 +44,10 @@
   FILTER_SHARP_UV,
   FILTER_SMOOTH2_UV,
 #endif  // USE_EXTRA_FILTER
+#if CONFIG_SHORT_FILTER
+  FOURTAP_REGULAR,
+  FOURTAP_SMOOTH,
+#endif
   INTERP_FILTERS_ALL,
   SWITCHABLE_FILTERS = BILINEAR,
   SWITCHABLE = SWITCHABLE_FILTERS + 1, /* the last switchable one */
@@ -125,6 +129,11 @@
 
 const int16_t *av1_get_interp_filter_kernel(const InterpFilter interp_filter);
 
+#if CONFIG_SHORT_FILTER
+InterpFilterParams av1_get_interp_filter_params_with_block_size(
+    const InterpFilter interp_filter, const int w);
+#endif
+
 static INLINE const int16_t *av1_get_interp_filter_subpel_kernel(
     const InterpFilterParams filter_params, const int subpel) {
   return filter_params.filter_ptr + filter_params.taps * subpel;
diff --git a/av1/common/reconinter.h b/av1/common/reconinter.h
index 7fbd8c3..094d42c 100644
--- a/av1/common/reconinter.h
+++ b/av1/common/reconinter.h
@@ -86,9 +86,15 @@
       assert(conv_params->round == CONVOLVE_OPT_ROUND);
 
       InterpFilterParams filter_params_x, filter_params_y;
+#if CONFIG_SHORT_FILTER
+      av1_get_convolve_filter_params(interp_filters, 0, &filter_params_x,
+                                     &filter_params_y, w, h);
+#else
       av1_get_convolve_filter_params(interp_filters, 0, &filter_params_x,
                                      &filter_params_y);
 
+#endif
+
       if (w <= 2 || h <= 2) {
         av1_convolve_c(src, src_stride, dst, dst_stride, w, h, interp_filters,
                        subpel_x, xs, subpel_y, ys, conv_params);
@@ -154,8 +160,13 @@
 #endif  // CONFIG_CONVOLVE_ROUND
     } else {
       InterpFilterParams filter_params_x, filter_params_y;
+#if CONFIG_SHORT_FILTER
+      av1_get_convolve_filter_params(interp_filters, 0, &filter_params_x,
+                                     &filter_params_y, w, h);
+#else
       av1_get_convolve_filter_params(interp_filters, 0, &filter_params_x,
                                      &filter_params_y);
+#endif
 
       if (filter_params_x.taps == SUBPEL_TAPS &&
           filter_params_y.taps == SUBPEL_TAPS && w > 2 && h > 2) {
diff --git a/build/cmake/aom_config_defaults.cmake b/build/cmake/aom_config_defaults.cmake
index df7cab2..9c550d3 100644
--- a/build/cmake/aom_config_defaults.cmake
+++ b/build/cmake/aom_config_defaults.cmake
@@ -191,6 +191,7 @@
 set(CONFIG_REFERENCE_BUFFER 1 CACHE NUMBER "AV1 experiment flag.")
 set(CONFIG_REF_ADAPT 0 CACHE NUMBER "AV1 experiment flag.")
 set(CONFIG_SEGMENT_ZEROMV 0 CACHE NUMBER "AV1 experiment flag.")
+set(CONFIG_SHORT_FILTER 0 CACHE NUMBER "AV1 experiment flag.")
 set(CONFIG_SIMPLE_BWD_ADAPT 0 CACHE NUMBER "AV1 experiment flag.")
 set(CONFIG_SMOOTH_HV 1 CACHE NUMBER "AV1 experiment flag.")
 set(CONFIG_STRIPED_LOOP_RESTORATION 0 CACHE NUMBER "AV1 experiment flag.")
diff --git a/configure b/configure
index 0c6e8ed..984a58b 100755
--- a/configure
+++ b/configure
@@ -252,6 +252,7 @@
     rect_tx
     rect_tx_ext
     tpl_mv
+    short_filter
     dual_filter
     convolve_round
     compound_round