Reduce entropy cost update frequency for mv

Introduced a speed feature option to reduce entropy cost update
frequency for mv. This change is applicable for speed preset 6.

          Instruction Count          BD-Rate Loss(%)
cpu-used    Reduction(%)    avg.psnr  ovr.psnr  ssim
   6          0.981         0.0175    0.0174    0.0628

Change-Id: I7eaa48ed2381de048933d03e164ede5cbd84021d
diff --git a/av1/encoder/encodeframe_utils.c b/av1/encoder/encodeframe_utils.c
index bbae592..fc3bdd8 100644
--- a/av1/encoder/encodeframe_utils.c
+++ b/av1/encoder/encodeframe_utils.c
@@ -1245,6 +1245,46 @@
 #endif  // CONFIG_INTERNAL_STATS
 }
 
+// Checks for skip status of mv cost update.
+static int skip_mv_cost_update(AV1_COMP *cpi, const TileInfo *const tile_info,
+                               const int mi_row, const int mi_col) {
+  // mv_cost_upd_level=0: update happens at each sb,
+  //                      so return skip status as 0.
+  // mv_cost_upd_level=1: update happens once for each sb row,
+  //                      so return skip status as 1 for
+  //                      mi_col != tile_info->mi_col_start.
+  // mv_cost_upd_level=2: update happens once for a set of rows,
+  //                      so return skip status as 1 appropriately.
+  if (!cpi->sf.inter_sf.mv_cost_upd_level) return 0;
+  if (mi_col != tile_info->mi_col_start) return 1;
+  if (cpi->sf.inter_sf.mv_cost_upd_level == 2) {
+    AV1_COMMON *const cm = &cpi->common;
+    const int mib_size_log2 = cm->seq_params.mib_size_log2;
+    const int sb_row = (mi_row - tile_info->mi_row_start) >> mib_size_log2;
+    const int sb_size = cm->seq_params.mib_size * MI_SIZE;
+    const int tile_height =
+        (tile_info->mi_row_end - tile_info->mi_row_start) * MI_SIZE;
+    // When mv_cost_upd_level = 2, the cost update happens once for 2, 4 sb
+    // rows for sb size 128, sb size 64 respectively. However, as the update
+    // will not be equally spaced in smaller resolutions making it equally
+    // spaced by calculating (mv_num_rows_cost_update) the number of rows
+    // after which the cost update should happen.
+    const int sb_size_update_freq_map[2] = { 2, 4 };
+    const int update_freq_sb_rows =
+        sb_size_update_freq_map[sb_size != MAX_SB_SIZE];
+    const int update_freq_num_rows = sb_size * update_freq_sb_rows;
+    // Round-up the division result to next integer.
+    const int num_updates_per_tile =
+        (tile_height + update_freq_num_rows - 1) / update_freq_num_rows;
+    const int num_rows_update_per_tile = num_updates_per_tile * sb_size;
+    // Round-up the division result to next integer.
+    const int num_sb_rows_per_update =
+        (tile_height + num_rows_update_per_tile - 1) / num_rows_update_per_tile;
+    if ((sb_row % num_sb_rows_per_update) != 0) return 1;
+  }
+  return 0;
+}
+
 // Update the rate costs of some symbols according to the frequency directed
 // by speed features
 void av1_set_cost_upd_freq(AV1_COMP *cpi, ThreadData *td,
@@ -1294,9 +1334,8 @@
       if (mi_col != tile_info->mi_col_start) break;
       AOM_FALLTHROUGH_INTENDED;
     case COST_UPD_SB:  // SB level
-      if (cpi->sf.inter_sf.disable_sb_level_mv_cost_upd &&
-          mi_col != tile_info->mi_col_start)
-        break;
+      // Checks for skip status of mv cost update.
+      if (skip_mv_cost_update(cpi, tile_info, mi_row, mi_col)) break;
       av1_fill_mv_costs(xd->tile_ctx, cm->features.cur_frame_force_integer_mv,
                         cm->features.allow_high_precision_mv, &x->mv_costs);
       break;
diff --git a/av1/encoder/speed_features.c b/av1/encoder/speed_features.c
index 566f277..14dc52c 100644
--- a/av1/encoder/speed_features.c
+++ b/av1/encoder/speed_features.c
@@ -288,6 +288,10 @@
       sf->inter_sf.disable_masked_comp = 1;
     }
 
+    if (!is_720p_or_larger) {
+      sf->inter_sf.mv_cost_upd_level = 2;
+    }
+
     // TODO(yunqing): use BLOCK_32X32 for >= 4k.
     if (is_4k_or_larger) {
       sf->part_sf.use_square_partition_only_threshold = BLOCK_64X64;
@@ -519,7 +523,7 @@
     sf->mv_sf.subpel_search_method = SUBPEL_TREE_PRUNED;
     sf->mv_sf.search_method = DIAMOND;
 
-    sf->inter_sf.disable_sb_level_mv_cost_upd = 1;
+    sf->inter_sf.mv_cost_upd_level = 1;
     // TODO(yunqing): evaluate this speed feature for speed 1 & 2, and combine
     // it with cpi->sf.disable_wedge_search_var_thresh.
     sf->inter_sf.disable_wedge_interintra_search = 1;
@@ -821,7 +825,7 @@
     // sf->mv_sf.adaptive_motion_search = 1;
 
     sf->inter_sf.adaptive_rd_thresh = 2;
-    sf->inter_sf.disable_sb_level_mv_cost_upd = 1;
+    sf->inter_sf.mv_cost_upd_level = 1;
     // TODO(yunqing): evaluate this speed feature for speed 1 & 2, and combine
     // it with cpi->sf.disable_wedge_search_var_thresh.
     sf->inter_sf.disable_wedge_interintra_search = 1;
@@ -1093,7 +1097,7 @@
   inter_sf->use_dist_wtd_comp_flag = DIST_WTD_COMP_ENABLED;
   inter_sf->reuse_inter_intra_mode = 0;
   inter_sf->disable_sb_level_coeff_cost_upd = 0;
-  inter_sf->disable_sb_level_mv_cost_upd = 0;
+  inter_sf->mv_cost_upd_level = 0;
   inter_sf->prune_inter_modes_based_on_tpl = 0;
   inter_sf->prune_comp_search_by_single_result = 0;
   inter_sf->skip_repeated_ref_mv = 0;
diff --git a/av1/encoder/speed_features.h b/av1/encoder/speed_features.h
index eac36d6..7a0f762 100644
--- a/av1/encoder/speed_features.h
+++ b/av1/encoder/speed_features.h
@@ -709,10 +709,12 @@
   // cpi->oxcf.cost_upd_freq.coeff = COST_UPD_SB (i.e. set at SB level)
   int disable_sb_level_coeff_cost_upd;
 
-  // Whether to override and disable sb level mv cost updates, if
-  // cpi->oxcf.cost_upd_freq.coeff = COST_UPD_SB (i.e. set at SB level)
-  int disable_sb_level_mv_cost_upd;
-
+  // To skip cost update for mv.
+  // mv_cost_upd_level indicates the aggressiveness of skipping.
+  // 0: update happens at each sb level.
+  // 1: update happens once for each sb row.
+  // 2: update happens once for a set of rows.
+  int mv_cost_upd_level;
   // Prune inter modes based on tpl stats
   // 0 : no pruning
   // 1 - 3 indicate increasing aggressiveness in order.