Pack InterpFilters into a single integer

Before this patch, if CONFIG_DUAL_FILTER was true then an MB_MODE_INFO
stored its filter choices as an array of four numbers, each of which
was between 0 and 10. It also seems that elements 2 and 3 of the array
were always the same as elements 0 and 1 when used.

This patch defines a new type(def) called InterpFilters together with
constructor and extractor functions. When CONFIG_DUAL_FILTER is zero,
InterpFilters is a synonym for InterpFilter and the constructor and
extractor functions should compile away to nothing. When it is
nonzero, InterpFilters is a uint32_t which stores the x filter in the
high part and the y filter in the low part (this looks strange, but
matches the old numbering).

Making this change allows us to get rid of lots of special case code
that was dependent on CONFIG_DUAL_FILTER. The uniform
extract/make/broadcast interface also actually shortens code in
general.

Change-Id: I6b24a61bac3e4b220d8d46d0b27cfe865dcfba81
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index 955f4de..f3d0f61 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -6432,7 +6432,7 @@
 #else   // !(CONFIG_COMPOUND_SINGLEREF)
           &frame_mv[refs[!id]].as_mv,
 #endif  // CONFIG_COMPOUND_SINGLEREF
-          &sf, pw, ph, 0, mbmi->interp_filter,
+          &sf, pw, ph, 0, mbmi->interp_filters,
 #if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
           &warp_types, p_col, p_row,
 #endif  // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
@@ -6447,7 +6447,7 @@
 #else   // !(CONFIG_COMPOUND_SINGLEREF)
         &frame_mv[refs[!id]].as_mv,
 #endif  // CONFIG_COMPOUND_SINGLEREF
-          &sf, pw, ph, &conv_params, mbmi->interp_filter,
+          &sf, pw, ph, &conv_params, mbmi->interp_filters,
 #if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
           &warp_types, p_col, p_row, plane, !id,
 #endif  // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
@@ -7224,7 +7224,7 @@
   if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
     av1_highbd_build_inter_predictor(
         ref_yv12.buf, ref_yv12.stride, second_pred, pw, other_mv, &sf, pw, ph,
-        0, mbmi->interp_filter,
+        0, mbmi->interp_filters,
 #if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
         &warp_types, p_col, p_row,
 #endif  // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
@@ -7233,7 +7233,7 @@
 #endif  // CONFIG_HIGHBITDEPTH
     av1_build_inter_predictor(
         ref_yv12.buf, ref_yv12.stride, second_pred, pw, other_mv, &sf, pw, ph,
-        &conv_params, mbmi->interp_filter,
+        &conv_params, mbmi->interp_filters,
 #if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
         &warp_types, p_col, p_row, plane, !ref_idx,
 #endif  // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
@@ -7590,8 +7590,11 @@
                   (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
   if (pred_filter_search) {
     InterpFilter af = SWITCHABLE, lf = SWITCHABLE;
-    if (xd->up_available) af = xd->mi[-xd->mi_stride]->mbmi.interp_filter;
-    if (xd->left_available) lf = xd->mi[-1]->mbmi.interp_filter;
+    if (xd->up_available)
+      af = av1_extract_interp_filter(
+          xd->mi[-xd->mi_stride]->mbmi.interp_filters, 0);
+    if (xd->left_available)
+      lf = av1_extract_interp_filter(xd->mi[-1]->mbmi.interp_filters, 0);
 
     if ((this_mode != NEWMV && this_mode != NEW_NEWMV) || (af == lf))
       best_filter = af;
@@ -8275,12 +8278,7 @@
       const int filter_set_size = SWITCHABLE_FILTERS;
 #endif  // CONFIG_DUAL_FILTER
       int best_in_temp = 0;
-#if CONFIG_DUAL_FILTER
-      InterpFilter best_filter[4];
-      av1_copy(best_filter, mbmi->interp_filter);
-#else
-      InterpFilter best_filter = mbmi->interp_filter;
-#endif  // CONFIG_DUAL_FILTER
+      InterpFilters best_filters = mbmi->interp_filters;
       restore_dst_buf(xd, *tmp_dst);
       // EIGHTTAP_REGULAR mode is calculated beforehand
       for (i = 1; i < filter_set_size; ++i) {
@@ -8289,12 +8287,10 @@
         int tmp_rs;
         int64_t tmp_rd;
 #if CONFIG_DUAL_FILTER
-        mbmi->interp_filter[0] = filter_sets[i][0];
-        mbmi->interp_filter[1] = filter_sets[i][1];
-        mbmi->interp_filter[2] = filter_sets[i][0];
-        mbmi->interp_filter[3] = filter_sets[i][1];
+        mbmi->interp_filters =
+            av1_make_interp_filters(filter_sets[i][0], filter_sets[i][1]);
 #else
-        mbmi->interp_filter = (InterpFilter)i;
+        mbmi->interp_filters = av1_broadcast_interp_filter((InterpFilter)i);
 #endif  // CONFIG_DUAL_FILTER
         tmp_rs = av1_get_switchable_rate(cm, x, xd);
         av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, orig_dst, bsize);
@@ -8305,11 +8301,7 @@
         if (tmp_rd < *rd) {
           *rd = tmp_rd;
           *switchable_rate = av1_get_switchable_rate(cm, x, xd);
-#if CONFIG_DUAL_FILTER
-          av1_copy(best_filter, mbmi->interp_filter);
-#else
-          best_filter = mbmi->interp_filter;
-#endif  // CONFIG_DUAL_FILTER
+          best_filters = mbmi->interp_filters;
           *skip_txfm_sb = tmp_skip_sb;
           *skip_sse_sb = tmp_skip_sse;
           best_in_temp = !best_in_temp;
@@ -8325,24 +8317,29 @@
       } else {
         restore_dst_buf(xd, *orig_dst);
       }
-#if CONFIG_DUAL_FILTER
-      av1_copy(mbmi->interp_filter, best_filter);
-#else
-      mbmi->interp_filter = best_filter;
-#endif  // CONFIG_DUAL_FILTER
+      mbmi->interp_filters = best_filters;
     } else {
-#if CONFIG_DUAL_FILTER
-      for (i = 0; i < 4; ++i)
-        assert(mbmi->interp_filter[i] == EIGHTTAP_REGULAR);
-#else
-      assert(mbmi->interp_filter == EIGHTTAP_REGULAR);
-#endif  // CONFIG_DUAL_FILTER
+      assert(mbmi->interp_filters ==
+             av1_broadcast_interp_filter(EIGHTTAP_REGULAR));
     }
   }
 
   return 0;
 }
 
+#if CONFIG_DUAL_FILTER
+static InterpFilters condition_interp_filters_on_mv(
+    InterpFilters interp_filters, const MACROBLOCKD *xd) {
+  InterpFilter filters[2];
+  for (int i = 0; i < 2; ++i)
+    filters[i] = (has_subpel_mv_component(xd->mi[0], xd, i))
+                     ? av1_extract_interp_filter(interp_filters, i)
+                     : EIGHTTAP_REGULAR;
+
+  return av1_make_interp_filters(filters[0], filters[1]);
+}
+#endif
+
 // TODO(afergs): Refactor the MBMI references in here - there's four
 // TODO(afergs): Refactor optional args - add them to a struct or remove
 static int64_t motion_mode_rd(
@@ -8464,10 +8461,8 @@
         }
         tmp_rate2 = rate2_bmc_nocoeff - rate_mv_bmc + tmp_rate_mv;
 #if CONFIG_DUAL_FILTER
-        if (!has_subpel_mv_component(xd->mi[0], xd, 0))
-          mbmi->interp_filter[0] = EIGHTTAP_REGULAR;
-        if (!has_subpel_mv_component(xd->mi[0], xd, 1))
-          mbmi->interp_filter[1] = EIGHTTAP_REGULAR;
+        mbmi->interp_filters =
+            condition_interp_filters_on_mv(mbmi->interp_filters, xd);
 #endif  // CONFIG_DUAL_FILTER
         av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, orig_dst, bsize);
       } else {
@@ -8489,15 +8484,8 @@
       *mbmi = *best_bmc_mbmi;
       mbmi->motion_mode = WARPED_CAUSAL;
       mbmi->wm_params[0].wmtype = DEFAULT_WMTYPE;
-#if CONFIG_DUAL_FILTER
-      for (int dir = 0; dir < 4; ++dir)
-        mbmi->interp_filter[dir] = cm->interp_filter == SWITCHABLE
-                                       ? EIGHTTAP_REGULAR
-                                       : cm->interp_filter;
-#else
-      mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR
-                                                            : cm->interp_filter;
-#endif  // CONFIG_DUAL_FILTER
+      mbmi->interp_filters = av1_broadcast_interp_filter(
+          av1_unswitchable_filter(cm->interp_filter));
 
 #if WARPED_MOTION_SORT_SAMPLES
       memcpy(pts, pts0, total_samples * 2 * sizeof(*pts0));
@@ -8552,10 +8540,8 @@
 #endif  // WARPED_MOTION_SORT_SAMPLES
             tmp_rate2 = rate2_bmc_nocoeff - rate_mv_bmc + tmp_rate_mv;
 #if CONFIG_DUAL_FILTER
-            if (!has_subpel_mv_component(xd->mi[0], xd, 0))
-              mbmi->interp_filter[0] = EIGHTTAP_REGULAR;
-            if (!has_subpel_mv_component(xd->mi[0], xd, 1))
-              mbmi->interp_filter[1] = EIGHTTAP_REGULAR;
+            mbmi->interp_filters =
+                condition_interp_filters_on_mv(mbmi->interp_filters, xd);
 #endif  // CONFIG_DUAL_FILTER
           } else {
             // Restore the old MV and WM parameters.
@@ -8714,18 +8700,8 @@
     if (this_mode == ZEROMV || this_mode == ZERO_ZEROMV) {
       if (is_nontrans_global_motion(xd)) {
         rd_stats->rate -= rs;
-#if CONFIG_DUAL_FILTER
-        mbmi->interp_filter[0] = cm->interp_filter == SWITCHABLE
-                                     ? EIGHTTAP_REGULAR
-                                     : cm->interp_filter;
-        mbmi->interp_filter[1] = cm->interp_filter == SWITCHABLE
-                                     ? EIGHTTAP_REGULAR
-                                     : cm->interp_filter;
-#else
-        mbmi->interp_filter = cm->interp_filter == SWITCHABLE
-                                  ? EIGHTTAP_REGULAR
-                                  : cm->interp_filter;
-#endif  // CONFIG_DUAL_FILTER
+        mbmi->interp_filters = av1_broadcast_interp_filter(
+            av1_unswitchable_filter(cm->interp_filter));
       }
     }
 #endif  // CONFIG_GLOBAL_MOTION
@@ -9394,11 +9370,8 @@
   }
 
   if (!is_comp_pred)
-#if CONFIG_DUAL_FILTER
-    args->single_filter[this_mode][refs[0]] = mbmi->interp_filter[0];
-#else
-    args->single_filter[this_mode][refs[0]] = mbmi->interp_filter;
-#endif  // CONFIG_DUAL_FILTER
+    args->single_filter[this_mode][refs[0]] =
+        av1_extract_interp_filter(mbmi->interp_filters, 0);
 
   if (args->modelled_rd != NULL) {
     if (is_comp_pred) {
@@ -9558,11 +9531,7 @@
     mbmi->mode = DC_PRED;
     mbmi->uv_mode = UV_DC_PRED;
     mbmi->mv[0].as_mv = dv;
-#if CONFIG_DUAL_FILTER
-    for (int idx = 0; idx < 4; ++idx) mbmi->interp_filter[idx] = BILINEAR;
-#else
-    mbmi->interp_filter = BILINEAR;
-#endif
+    mbmi->interp_filters = av1_broadcast_interp_filter(BILINEAR);
     mbmi->skip = 0;
     x->skip = 0;
     av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, bsize);
@@ -11744,24 +11713,14 @@
     return;
   }
 
+  assert((cm->interp_filter == SWITCHABLE) ||
+         (cm->interp_filter ==
+          av1_extract_interp_filter(best_mbmode.interp_filters, 0)) ||
+         !is_inter_block(&best_mbmode));
 #if CONFIG_DUAL_FILTER
   assert((cm->interp_filter == SWITCHABLE) ||
-         (cm->interp_filter == best_mbmode.interp_filter[0]) ||
-         !is_inter_block(&best_mbmode));
-  assert((cm->interp_filter == SWITCHABLE) ||
-         (cm->interp_filter == best_mbmode.interp_filter[1]) ||
-         !is_inter_block(&best_mbmode));
-  if (best_mbmode.ref_frame[1] > INTRA_FRAME) {
-    assert((cm->interp_filter == SWITCHABLE) ||
-           (cm->interp_filter == best_mbmode.interp_filter[2]) ||
-           !is_inter_block(&best_mbmode));
-    assert((cm->interp_filter == SWITCHABLE) ||
-           (cm->interp_filter == best_mbmode.interp_filter[3]) ||
-           !is_inter_block(&best_mbmode));
-  }
-#else
-  assert((cm->interp_filter == SWITCHABLE) ||
-         (cm->interp_filter == best_mbmode.interp_filter) ||
+         (cm->interp_filter ==
+          av1_extract_interp_filter(best_mbmode.interp_filters, 1)) ||
          !is_inter_block(&best_mbmode));
 #endif  // CONFIG_DUAL_FILTER
 
@@ -11791,17 +11750,8 @@
 
     // Correct the interpolation filter for ZEROMV
     if (is_nontrans_global_motion(xd)) {
-#if CONFIG_DUAL_FILTER
-      mbmi->interp_filter[0] = cm->interp_filter == SWITCHABLE
-                                   ? EIGHTTAP_REGULAR
-                                   : cm->interp_filter;
-      mbmi->interp_filter[1] = cm->interp_filter == SWITCHABLE
-                                   ? EIGHTTAP_REGULAR
-                                   : cm->interp_filter;
-#else
-      mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR
-                                                            : cm->interp_filter;
-#endif  // CONFIG_DUAL_FILTER
+      mbmi->interp_filters = av1_broadcast_interp_filter(
+          av1_unswitchable_filter(cm->interp_filter));
     }
   }
 #endif  // CONFIG_GLOBAL_MOTION
@@ -11934,30 +11884,17 @@
       int rs;
       int best_rs = INT_MAX;
       for (i = 0; i < SWITCHABLE_FILTERS; ++i) {
-#if CONFIG_DUAL_FILTER
-        int k;
-        for (k = 0; k < 4; ++k) mbmi->interp_filter[k] = i;
-#else
-        mbmi->interp_filter = i;
-#endif  // CONFIG_DUAL_FILTER
+        mbmi->interp_filters = av1_broadcast_interp_filter(i);
         rs = av1_get_switchable_rate(cm, x, xd);
         if (rs < best_rs) {
           best_rs = rs;
-#if CONFIG_DUAL_FILTER
-          best_filter = mbmi->interp_filter[0];
-#else
-          best_filter = mbmi->interp_filter;
-#endif  // CONFIG_DUAL_FILTER
+          best_filter = av1_extract_interp_filter(mbmi->interp_filters, 0);
         }
       }
     }
   }
-// Set the appropriate filter
-#if CONFIG_DUAL_FILTER
-  for (i = 0; i < 4; ++i) mbmi->interp_filter[i] = best_filter;
-#else
-  mbmi->interp_filter = best_filter;
-#endif  // CONFIG_DUAL_FILTER
+  // Set the appropriate filter
+  mbmi->interp_filters = av1_broadcast_interp_filter(best_filter);
   rate2 += av1_get_switchable_rate(cm, x, xd);
 
   if (cm->reference_mode == REFERENCE_MODE_SELECT)
@@ -11978,13 +11915,9 @@
     return;
   }
 
-#if CONFIG_DUAL_FILTER
   assert((cm->interp_filter == SWITCHABLE) ||
-         (cm->interp_filter == mbmi->interp_filter[0]));
-#else
-  assert((cm->interp_filter == SWITCHABLE) ||
-         (cm->interp_filter == mbmi->interp_filter));
-#endif  // CONFIG_DUAL_FILTER
+         (cm->interp_filter ==
+          av1_extract_interp_filter(mbmi->interp_filters, 0)));
 
   av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
                             cpi->sf.adaptive_rd_thresh, bsize, THR_ZEROMV);