rtc: Abstract code related to skip inter mode

Abstracted inter mode skip logics that work based on mode
statistics and speed feature settings in skip_inter_mode_nonrd()
function.

Change-Id: Ica5286589a7ba1eaa04b9c46a3255c7ddfa01027
diff --git a/av1/encoder/nonrd_pickmode.c b/av1/encoder/nonrd_pickmode.c
index 9f7c50e..4e6b3a9 100644
--- a/av1/encoder/nonrd_pickmode.c
+++ b/av1/encoder/nonrd_pickmode.c
@@ -2323,6 +2323,8 @@
   struct aom_usec_timer bsize_timer;
 } mode_search_stat;
 
+static mode_search_stat ms_stat;
+
 static AOM_INLINE void print_stage_time(const char *stage_name,
                                         int64_t stage_time,
                                         int64_t total_time) {
@@ -3385,6 +3387,164 @@
   }
 }
 
+// Function to check the inter mode can be skipped based on mode statistics and
+// speed features settings.
+static AOM_FORCE_INLINE bool skip_inter_mode_nonrd(
+    AV1_COMP *cpi, MACROBLOCK *x, InterModeSearchStateNonrd *search_state,
+    int64_t *thresh_sad_pred, int *force_mv_inter_layer, int *comp_pred,
+    PREDICTION_MODE *this_mode, MV_REFERENCE_FRAME *last_comp_ref_frame,
+    MV_REFERENCE_FRAME *ref_frame, MV_REFERENCE_FRAME *ref_frame2, int idx,
+    int svc_mv_col, int svc_mv_row, int force_skip_low_temp_var,
+    unsigned int sse_zeromv_norm, const int num_inter_modes,
+    const unsigned char segment_id, BLOCK_SIZE bsize,
+    bool comp_use_zero_zeromv_only, bool check_globalmv) {
+  AV1_COMMON *const cm = &cpi->common;
+  const struct segmentation *const seg = &cm->seg;
+  const SVC *const svc = &cpi->svc;
+  MACROBLOCKD *const xd = &x->e_mbd;
+  MB_MODE_INFO *const mi = xd->mi[0];
+
+  if (idx >= num_inter_modes) {
+    const int comp_index = idx - num_inter_modes;
+    if (!setup_compound_params_from_comp_idx(
+            cpi, x, search_state->yv12_mb, this_mode, ref_frame, ref_frame2,
+            search_state->frame_mv, search_state->use_ref_frame_mask,
+            comp_index, comp_use_zero_zeromv_only, last_comp_ref_frame)) {
+      return true;
+    }
+    *comp_pred = 1;
+  } else {
+    *this_mode = ref_mode_set[idx].pred_mode;
+    *ref_frame = ref_mode_set[idx].ref_frame;
+    *ref_frame2 = NONE_FRAME;
+  }
+
+  if (!*comp_pred && search_state->mode_checked[*this_mode][*ref_frame]) {
+    return true;
+  }
+
+  if (!check_globalmv && *this_mode == GLOBALMV) {
+    return true;
+  }
+
+#if COLLECT_PICK_MODE_STAT
+  aom_usec_timer_start(&ms_stat.timer1);
+  ms_stat.num_searches[bsize][*this_mode]++;
+#endif
+  mi->mode = *this_mode;
+  mi->ref_frame[0] = *ref_frame;
+  mi->ref_frame[1] = *ref_frame2;
+
+  if (!search_state->use_ref_frame_mask[*ref_frame]) return true;
+
+  if (x->force_zeromv_skip_for_blk &&
+      ((!(*this_mode == NEARESTMV &&
+          search_state->frame_mv[*this_mode][*ref_frame].as_int == 0) &&
+        *this_mode != GLOBALMV) ||
+       *ref_frame != LAST_FRAME))
+    return true;
+
+  if (cpi->sf.rt_sf.prune_compoundmode_with_singlemode_var && *comp_pred &&
+      prune_compoundmode_with_singlemode_var(
+          *this_mode, *ref_frame, *ref_frame2, search_state->frame_mv,
+          search_state->mode_checked, search_state->vars,
+          search_state->uv_dist)) {
+    return true;
+  }
+
+  *force_mv_inter_layer = 0;
+  if (cpi->ppi->use_svc && svc->spatial_layer_id > 0 &&
+      ((*ref_frame == LAST_FRAME && svc->skip_mvsearch_last) ||
+       (*ref_frame == GOLDEN_FRAME && svc->skip_mvsearch_gf) ||
+       (*ref_frame == ALTREF_FRAME && svc->skip_mvsearch_altref))) {
+    // Only test mode if NEARESTMV/NEARMV is (svc_mv_col, svc_mv_row),
+    // otherwise set NEWMV to (svc_mv_col, svc_mv_row).
+    // Skip newmv and filter search.
+    *force_mv_inter_layer = 1;
+    if (*this_mode == NEWMV) {
+      search_state->frame_mv[*this_mode][*ref_frame].as_mv.col = svc_mv_col;
+      search_state->frame_mv[*this_mode][*ref_frame].as_mv.row = svc_mv_row;
+    } else if (search_state->frame_mv[*this_mode][*ref_frame].as_mv.col !=
+                   svc_mv_col ||
+               search_state->frame_mv[*this_mode][*ref_frame].as_mv.row !=
+                   svc_mv_row) {
+      return true;
+    }
+  }
+
+  // If the segment reference frame feature is enabled then do nothing if the
+  // current ref frame is not allowed.
+  if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
+      get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)(*ref_frame))
+    return true;
+
+  // For screen content: for base spatial layer only for now.
+  if (cpi->oxcf.tune_cfg.content == AOM_CONTENT_SCREEN &&
+      cpi->svc.spatial_layer_id == 0) {
+    // If source_sad is computed: skip non-zero motion
+    // check for stationary (super)blocks. Otherwise if superblock
+    // has motion skip the modes with zero motion for flat blocks,
+    // and color is not set.
+    // For the latter condition: the same condition should apply
+    // to newmv if (0, 0), so this latter condition is repeated
+    // below after search_new_mv.
+    if (cpi->sf.rt_sf.source_metrics_sb_nonrd) {
+      if ((search_state->frame_mv[*this_mode][*ref_frame].as_int != 0 &&
+           x->content_state_sb.source_sad_nonrd == kZeroSad) ||
+          (search_state->frame_mv[*this_mode][*ref_frame].as_int == 0 &&
+           x->content_state_sb.source_sad_nonrd != kZeroSad &&
+           ((x->color_sensitivity[0] == 0 && x->color_sensitivity[1] == 0) ||
+            cpi->rc.high_source_sad) &&
+           x->source_variance == 0))
+        return true;
+    }
+    // Skip NEWMV search for flat blocks.
+    if (*this_mode == NEWMV && x->source_variance < 100) return true;
+    // Skip non-LAST for color on flat blocks.
+    if (*ref_frame > LAST_FRAME && x->source_variance == 0 &&
+        (x->color_sensitivity[0] == 1 || x->color_sensitivity[1] == 1))
+      return true;
+  }
+
+  if (skip_mode_by_bsize_and_ref_frame(
+          *this_mode, *ref_frame, bsize, x->nonrd_prune_ref_frame_search,
+          sse_zeromv_norm, cpi->sf.rt_sf.nonrd_aggressive_skip))
+    return true;
+
+  if (skip_mode_by_low_temp(*this_mode, *ref_frame, bsize, x->content_state_sb,
+                            search_state->frame_mv[*this_mode][*ref_frame],
+                            force_skip_low_temp_var))
+    return true;
+
+  // Disable this drop out case if the ref frame segment level feature is
+  // enabled for this segment. This is to prevent the possibility that we
+  // end up unable to pick any mode.
+  if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
+    // Check for skipping GOLDEN and ALTREF based pred_mv_sad.
+    if (cpi->sf.rt_sf.nonrd_prune_ref_frame_search > 0 &&
+        x->pred_mv_sad[*ref_frame] != INT_MAX && *ref_frame != LAST_FRAME) {
+      if ((int64_t)(x->pred_mv_sad[*ref_frame]) > *thresh_sad_pred) return true;
+    }
+  }
+
+  // Check for skipping NEARMV based on pred_mv_sad.
+  if (*this_mode == NEARMV && x->pred_mv1_sad[*ref_frame] != INT_MAX &&
+      x->pred_mv1_sad[*ref_frame] > (x->pred_mv0_sad[*ref_frame] << 1))
+    return true;
+
+  if (!*comp_pred) {
+    if (skip_mode_by_threshold(
+            *this_mode, *ref_frame,
+            search_state->frame_mv[*this_mode][*ref_frame],
+            cpi->rc.frames_since_golden, cpi->rd.threshes[segment_id][bsize],
+            x->thresh_freq_fact[bsize], search_state->best_rdc.rdcost,
+            search_state->best_pickmode.best_mode_skip_txfm,
+            (cpi->sf.rt_sf.nonrd_aggressive_skip ? 1 : 0)))
+      return true;
+  }
+  return false;
+}
+
 void av1_nonrd_pick_inter_mode_sb(AV1_COMP *cpi, TileDataEnc *tile_data,
                                   MACROBLOCK *x, RD_STATS *rd_cost,
                                   BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx) {
@@ -3396,13 +3556,8 @@
   const MB_MODE_INFO_EXT *const mbmi_ext = &x->mbmi_ext;
   const InterpFilter filter_ref = cm->features.interp_filter;
   const InterpFilter default_interp_filter = EIGHTTAP_REGULAR;
-#if COLLECT_PICK_MODE_STAT
-  static mode_search_stat ms_stat;
-#endif
   MV_REFERENCE_FRAME ref_frame, ref_frame2;
   const unsigned char segment_id = mi->segment_id;
-  const int *const rd_threshes = cpi->rd.threshes[segment_id][bsize];
-  const int *const rd_thresh_freq_fact = x->thresh_freq_fact[bsize];
   int best_early_term = 0;
   int force_skip_low_temp_var = 0;
   unsigned int sse_zeromv_norm = UINT_MAX;
@@ -3548,8 +3703,6 @@
       break;
     }
 
-    const struct segmentation *const seg = &cm->seg;
-
     int rate_mv = 0;
     int is_skippable;
     int this_early_term = 0;
@@ -3562,142 +3715,15 @@
     memset(txfm_info->blk_skip, 0,
            sizeof(txfm_info->blk_skip[0]) * num_8x8_blocks);
 
-    if (idx >= num_inter_modes) {
-      const int comp_index = idx - num_inter_modes;
-      if (!setup_compound_params_from_comp_idx(
-              cpi, x, search_state.yv12_mb, &this_mode, &ref_frame, &ref_frame2,
-              search_state.frame_mv, search_state.use_ref_frame_mask,
-              comp_index, comp_use_zero_zeromv_only, &last_comp_ref_frame)) {
-        continue;
-      }
-      comp_pred = 1;
-    } else {
-      this_mode = ref_mode_set[idx].pred_mode;
-      ref_frame = ref_mode_set[idx].ref_frame;
-      ref_frame2 = NONE_FRAME;
-    }
-
-    if (!comp_pred && search_state.mode_checked[this_mode][ref_frame]) {
+    // Check the inter mode can be skipped based on mode statistics and speed
+    // features settings.
+    if (skip_inter_mode_nonrd(
+            cpi, x, &search_state, &thresh_sad_pred, &force_mv_inter_layer,
+            &comp_pred, &this_mode, &last_comp_ref_frame, &ref_frame,
+            &ref_frame2, idx, svc_mv_col, svc_mv_row, force_skip_low_temp_var,
+            sse_zeromv_norm, num_inter_modes, segment_id, bsize,
+            comp_use_zero_zeromv_only, check_globalmv))
       continue;
-    }
-
-    if (!check_globalmv && this_mode == GLOBALMV) {
-      continue;
-    }
-
-#if COLLECT_PICK_MODE_STAT
-    aom_usec_timer_start(&ms_stat.timer1);
-    ms_stat.num_searches[bsize][this_mode]++;
-#endif
-    mi->mode = this_mode;
-    mi->ref_frame[0] = ref_frame;
-    mi->ref_frame[1] = ref_frame2;
-
-    if (!search_state.use_ref_frame_mask[ref_frame]) continue;
-
-    if (x->force_zeromv_skip_for_blk &&
-        ((!(this_mode == NEARESTMV &&
-            search_state.frame_mv[this_mode][ref_frame].as_int == 0) &&
-          this_mode != GLOBALMV) ||
-         ref_frame != LAST_FRAME))
-      continue;
-
-    if (cpi->sf.rt_sf.prune_compoundmode_with_singlemode_var && comp_pred &&
-        prune_compoundmode_with_singlemode_var(
-            this_mode, ref_frame, ref_frame2, search_state.frame_mv,
-            search_state.mode_checked, search_state.vars,
-            search_state.uv_dist)) {
-      continue;
-    }
-
-    force_mv_inter_layer = 0;
-    if (cpi->ppi->use_svc && svc->spatial_layer_id > 0 &&
-        ((ref_frame == LAST_FRAME && svc->skip_mvsearch_last) ||
-         (ref_frame == GOLDEN_FRAME && svc->skip_mvsearch_gf) ||
-         (ref_frame == ALTREF_FRAME && svc->skip_mvsearch_altref))) {
-      // Only test mode if NEARESTMV/NEARMV is (svc_mv_col, svc_mv_row),
-      // otherwise set NEWMV to (svc_mv_col, svc_mv_row).
-      // Skip newmv and filter search.
-      force_mv_inter_layer = 1;
-      if (this_mode == NEWMV) {
-        search_state.frame_mv[this_mode][ref_frame].as_mv.col = svc_mv_col;
-        search_state.frame_mv[this_mode][ref_frame].as_mv.row = svc_mv_row;
-      } else if (search_state.frame_mv[this_mode][ref_frame].as_mv.col !=
-                     svc_mv_col ||
-                 search_state.frame_mv[this_mode][ref_frame].as_mv.row !=
-                     svc_mv_row) {
-        continue;
-      }
-    }
-
-    // If the segment reference frame feature is enabled then do nothing if the
-    // current ref frame is not allowed.
-    if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
-        get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame)
-      continue;
-
-    // For screen content: for base spatial layer only for now.
-    if (cpi->oxcf.tune_cfg.content == AOM_CONTENT_SCREEN &&
-        cpi->svc.spatial_layer_id == 0) {
-      // If source_sad is computed: skip non-zero motion
-      // check for stationary (super)blocks. Otherwise if superblock
-      // has motion skip the modes with zero motion for flat blocks,
-      // and color is not set.
-      // For the latter condition: the same condition should apply
-      // to newmv if (0, 0), so this latter condition is repeated
-      // below after search_new_mv.
-      if (cpi->sf.rt_sf.source_metrics_sb_nonrd) {
-        if ((search_state.frame_mv[this_mode][ref_frame].as_int != 0 &&
-             x->content_state_sb.source_sad_nonrd == kZeroSad) ||
-            (search_state.frame_mv[this_mode][ref_frame].as_int == 0 &&
-             x->content_state_sb.source_sad_nonrd != kZeroSad &&
-             ((x->color_sensitivity[0] == 0 && x->color_sensitivity[1] == 0) ||
-              cpi->rc.high_source_sad) &&
-             x->source_variance == 0))
-          continue;
-      }
-      // Skip NEWMV search for flat blocks.
-      if (this_mode == NEWMV && x->source_variance < 100) continue;
-      // Skip non-LAST for color on flat blocks.
-      if (ref_frame > LAST_FRAME && x->source_variance == 0 &&
-          (x->color_sensitivity[0] == 1 || x->color_sensitivity[1] == 1))
-        continue;
-    }
-
-    if (skip_mode_by_bsize_and_ref_frame(
-            this_mode, ref_frame, bsize, x->nonrd_prune_ref_frame_search,
-            sse_zeromv_norm, cpi->sf.rt_sf.nonrd_aggressive_skip))
-      continue;
-
-    if (skip_mode_by_low_temp(this_mode, ref_frame, bsize, x->content_state_sb,
-                              search_state.frame_mv[this_mode][ref_frame],
-                              force_skip_low_temp_var))
-      continue;
-
-    // Disable this drop out case if the ref frame segment level feature is
-    // enabled for this segment. This is to prevent the possibility that we
-    // end up unable to pick any mode.
-    if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
-      // Check for skipping GOLDEN and ALTREF based pred_mv_sad.
-      if (cpi->sf.rt_sf.nonrd_prune_ref_frame_search > 0 &&
-          x->pred_mv_sad[ref_frame] != INT_MAX && ref_frame != LAST_FRAME) {
-        if ((int64_t)(x->pred_mv_sad[ref_frame]) > thresh_sad_pred) continue;
-      }
-    }
-    // Check for skipping NEARMV based on pred_mv_sad.
-    if (this_mode == NEARMV && x->pred_mv1_sad[ref_frame] != INT_MAX &&
-        x->pred_mv1_sad[ref_frame] > (x->pred_mv0_sad[ref_frame] << 1))
-      continue;
-
-    if (!comp_pred) {
-      if (skip_mode_by_threshold(
-              this_mode, ref_frame, search_state.frame_mv[this_mode][ref_frame],
-              cpi->rc.frames_since_golden, rd_threshes, rd_thresh_freq_fact,
-              search_state.best_rdc.rdcost,
-              search_state.best_pickmode.best_mode_skip_txfm,
-              (cpi->sf.rt_sf.nonrd_aggressive_skip ? 1 : 0)))
-        continue;
-    }
 
     // Select prediction reference frames.
     for (int i = 0; i < MAX_MB_PLANE; i++) {