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.