rdopt: refactor interpolation_filter_search()

The interpolation filter search used to be performed in a code block in
handle_inter_mode(). This change breaks that code out into its own
function to reduce the length of handle_inter_mode and ecapsulate its
functionality, making both functions more readable.

Attention has been paid to make as many arguments constants as can be.

Change-Id: I3fd484137fc0d16a47dba0b18ce0e2b349d24446
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index 86289a6..f5c9675 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -8010,6 +8010,129 @@
   return 0;
 }
 
+int64_t interpolation_filter_search(
+    MACROBLOCK *const x, const AV1_COMP *const cpi, BLOCK_SIZE bsize,
+    int mi_row, int mi_col, const BUFFER_SET *const tmp_dst,
+    BUFFER_SET *const orig_dst,
+    InterpFilter (*const single_filter)[TOTAL_REFS_PER_FRAME],
+    int64_t *const rd, int *const switchable_rate, int *const skip_txfm_sb,
+    int64_t *const skip_sse_sb) {
+  const AV1_COMMON *cm = &cpi->common;
+  MACROBLOCKD *const xd = &x->e_mbd;
+  MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
+  int i;
+  int tmp_rate;
+  int64_t tmp_dist;
+
+  (void)single_filter;
+
+  InterpFilter assign_filter = SWITCHABLE;
+
+  if (cm->interp_filter == SWITCHABLE) {
+#if !CONFIG_DUAL_FILTER
+    assign_filter =
+        predict_interp_filter(cpi, x, bsize, mi_row, mi_col, single_filter);
+#endif  // !CONFIG_DUAL_FILTER
+  } else {
+    assign_filter = cm->interp_filter;
+  }
+
+#if CONFIG_DUAL_FILTER
+  mbmi->interp_filter[0] =
+      assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
+  mbmi->interp_filter[1] =
+      assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
+  mbmi->interp_filter[2] =
+      assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
+  mbmi->interp_filter[3] =
+      assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
+#else
+  mbmi->interp_filter =
+      assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
+#endif  // CONFIG_DUAL_FILTER
+  *switchable_rate = av1_get_switchable_rate(cpi, xd);
+  av1_build_inter_predictors_sb(xd, mi_row, mi_col, orig_dst, bsize);
+  model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate, &tmp_dist,
+                  skip_txfm_sb, skip_sse_sb);
+  *rd = RDCOST(x->rdmult, x->rddiv, *switchable_rate + tmp_rate, tmp_dist);
+
+  if (assign_filter == SWITCHABLE) {
+    // do interp_filter search
+    if (av1_is_interp_needed(xd)) {
+#if CONFIG_DUAL_FILTER
+      const int filter_set_size = DUAL_FILTER_SET_SIZE;
+#else
+      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
+      restore_dst_buf(xd, *tmp_dst);
+      // EIGHTTAP_REGULAR mode is calculated beforehand
+      for (i = 1; i < filter_set_size; ++i) {
+        int tmp_skip_sb = 0;
+        int64_t tmp_skip_sse = INT64_MAX;
+        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];
+#else
+        mbmi->interp_filter = (InterpFilter)i;
+#endif  // CONFIG_DUAL_FILTER
+        tmp_rs = av1_get_switchable_rate(cpi, xd);
+        av1_build_inter_predictors_sb(xd, mi_row, mi_col, orig_dst, bsize);
+        model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
+                        &tmp_dist, &tmp_skip_sb, &tmp_skip_sse);
+        tmp_rd = RDCOST(x->rdmult, x->rddiv, tmp_rs + tmp_rate, tmp_dist);
+
+        if (tmp_rd < *rd) {
+          *rd = tmp_rd;
+          *switchable_rate = av1_get_switchable_rate(cpi, xd);
+#if CONFIG_DUAL_FILTER
+          av1_copy(best_filter, mbmi->interp_filter);
+#else
+          best_filter = mbmi->interp_filter;
+#endif  // CONFIG_DUAL_FILTER
+          *skip_txfm_sb = tmp_skip_sb;
+          *skip_sse_sb = tmp_skip_sse;
+          best_in_temp = !best_in_temp;
+          if (best_in_temp) {
+            restore_dst_buf(xd, *orig_dst);
+          } else {
+            restore_dst_buf(xd, *tmp_dst);
+          }
+        }
+      }
+      if (best_in_temp) {
+        restore_dst_buf(xd, *tmp_dst);
+      } 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
+    } 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
+    }
+  }
+
+  return 0;
+}
+
 // TODO(afergs): put arrays of size TOTAL_REFS_PER_FRAME in a single struct
 static int64_t handle_inter_mode(
     const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
@@ -8280,114 +8403,10 @@
       )
     return INT64_MAX;
 
-  InterpFilter assign_filter = SWITCHABLE;
-
-  if (cm->interp_filter == SWITCHABLE) {
-#if !CONFIG_DUAL_FILTER
-    assign_filter =
-        predict_interp_filter(cpi, x, bsize, mi_row, mi_col, single_filter);
-#endif  // !CONFIG_DUAL_FILTER
-  } else {
-    assign_filter = cm->interp_filter;
-  }
-
-  {  // Do interpolation filter search in the parentheses
-    int tmp_rate;
-    int64_t tmp_dist;
-#if CONFIG_DUAL_FILTER
-    mbmi->interp_filter[0] =
-        assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
-    mbmi->interp_filter[1] =
-        assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
-    mbmi->interp_filter[2] =
-        assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
-    mbmi->interp_filter[3] =
-        assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
-#else
-    mbmi->interp_filter =
-        assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
-#endif  // CONFIG_DUAL_FILTER
-    rs = av1_get_switchable_rate(cpi, xd);
-    av1_build_inter_predictors_sb(xd, mi_row, mi_col, &orig_dst, bsize);
-    model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
-                    &tmp_dist, &skip_txfm_sb, &skip_sse_sb);
-    rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist);
-
-    if (assign_filter == SWITCHABLE) {
-      // do interp_filter search
-      if (av1_is_interp_needed(xd)) {
-#if CONFIG_DUAL_FILTER
-        const int filter_set_size = DUAL_FILTER_SET_SIZE;
-#else
-        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
-        restore_dst_buf(xd, tmp_dst);
-        // EIGHTTAP_REGULAR mode is calculated beforehand
-        for (i = 1; i < filter_set_size; ++i) {
-          int tmp_skip_sb = 0;
-          int64_t tmp_skip_sse = INT64_MAX;
-          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];
-#else
-          mbmi->interp_filter = i;
-#endif  // CONFIG_DUAL_FILTER
-          tmp_rs = av1_get_switchable_rate(cpi, xd);
-          av1_build_inter_predictors_sb(xd, mi_row, mi_col, &orig_dst, bsize);
-          model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
-                          &tmp_dist, &tmp_skip_sb, &tmp_skip_sse);
-          tmp_rd = RDCOST(x->rdmult, x->rddiv, tmp_rs + tmp_rate, tmp_dist);
-
-          if (tmp_rd < rd) {
-            rd = tmp_rd;
-            rs = av1_get_switchable_rate(cpi, xd);
-#if CONFIG_DUAL_FILTER
-            av1_copy(best_filter, mbmi->interp_filter);
-#else
-            best_filter = mbmi->interp_filter;
-#endif  // CONFIG_DUAL_FILTER
-            skip_txfm_sb = tmp_skip_sb;
-            skip_sse_sb = tmp_skip_sse;
-            best_in_temp = !best_in_temp;
-            if (best_in_temp) {
-              restore_dst_buf(xd, orig_dst);
-            } else {
-              restore_dst_buf(xd, tmp_dst);
-            }
-          }
-        }
-        if (best_in_temp) {
-          restore_dst_buf(xd, tmp_dst);
-        } 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
-      } else {
-#if CONFIG_DUAL_FILTER
-        int dir;
-        for (dir = 0; dir < 4; ++dir)
-          assert(mbmi->interp_filter[dir] == EIGHTTAP_REGULAR);
-#else
-        assert(mbmi->interp_filter == EIGHTTAP_REGULAR);
-#endif  // CONFIG_DUAL_FILTER
-      }
-    }
-  }
+  int64_t ret_val = interpolation_filter_search(
+      x, cpi, bsize, mi_row, mi_col, &tmp_dst, &orig_dst, single_filter, &rd,
+      &rs, &skip_txfm_sb, &skip_sse_sb);
+  if (ret_val != 0) return ret_val;
 
 #if CONFIG_EXT_INTER
 #if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION