Commit f5d16c2318 for aom
commit f5d16c23184d985278b3984fe38181e12b8d3fe2
Author: Ranjit Kumar Tulabandu <ranjit.tulabandu@ittiam.com>
Date: Mon Mar 23 23:29:51 2026 +0530
Extend the sf that skips compound modes to speed=1
In parent version, compound mode evaluation is skipped using top N
estimated RD Costs of compound average (N=2 for speed >= 2). In this CL,
the speed feature is renamed as skip_cmp_using_top_cmp_avg_est_rd_lvl
and extended to speed=1 by setting N=5 for <= 480p resolutions and 4 for
> 480p resolutions.
The encoder performance results averaged over all resolutions are
as below:
Instruction Count BD-Rate Loss(%)
cpu Reduction(%) avg.psnr ovr.psnr ssim vmaf vmaf_neg
1 2.144 0.0102 0.0109 0.0240 -0.0016 0.0048
The CL is bit-exact for speed>=2.
STATS_CHANGED
Change-Id: Ie8566d56e520004e2f22262e0e9032ed8fc6e62f
diff --git a/av1/encoder/block.h b/av1/encoder/block.h
index f36f8cc6a6..7055379b3b 100644
--- a/av1/encoder/block.h
+++ b/av1/encoder/block.h
@@ -874,7 +874,7 @@ typedef struct SetOffsetsLoc {
/*!\endcond */
//! Maximum number of estimated RD Cost records for compound average.
-#define TOP_COMP_AVG_EST_RD_COUNT 2
+#define TOP_COMP_AVG_EST_RD_COUNT 5
/*! \brief Encoder's parameters related to the current coding block.
*
diff --git a/av1/encoder/compound_type.c b/av1/encoder/compound_type.c
index da895f3238..7c462e2a07 100644
--- a/av1/encoder/compound_type.c
+++ b/av1/encoder/compound_type.c
@@ -24,6 +24,11 @@ typedef int64_t (*pick_interinter_mask_type)(
const int16_t *const residual1, const int16_t *const diff10,
uint64_t *best_sse);
+// look-up table for number of top compound average estimated RD Costs that
+// should be considered based on skip_cmp_using_top_cmp_avg_est_rd_lvl
+// speed feature.
+static const int num_comp_mode_skip_cand[3] = { 5, 4, 2 };
+
// Checks if characteristics of search match
static inline int is_comp_rd_match(const AV1_COMP *const cpi,
const MACROBLOCK *const x,
@@ -733,13 +738,18 @@ static int handle_wedge_inter_intra_mode(
// Store the estimated RD Cost of compound average.
static inline void push_comp_avg_est_rd(
int64_t *top_comp_avg_est_rd, int64_t tmp_rd,
- bool skip_comp_eval_using_top_comp_avg_est_rd) {
- if (!skip_comp_eval_using_top_comp_avg_est_rd) return;
+ int skip_cmp_using_top_cmp_avg_est_rd_lvl) {
+ if (!skip_cmp_using_top_cmp_avg_est_rd_lvl) return;
+ assert(skip_cmp_using_top_cmp_avg_est_rd_lvl <= 3);
+
+ const int num_top_cand =
+ num_comp_mode_skip_cand[skip_cmp_using_top_cmp_avg_est_rd_lvl - 1];
+ assert(num_top_cand <= TOP_COMP_AVG_EST_RD_COUNT);
// Insert the RD Cost in sorted order
- for (int i = 0; i < TOP_COMP_AVG_EST_RD_COUNT; i++) {
+ for (int i = 0; i < num_top_cand; i++) {
if (tmp_rd < top_comp_avg_est_rd[i]) {
- for (int j = TOP_COMP_AVG_EST_RD_COUNT - 1; j > i; j--) {
+ for (int j = num_top_cand - 1; j > i; j--) {
top_comp_avg_est_rd[j] = top_comp_avg_est_rd[j - 1];
}
top_comp_avg_est_rd[i] = tmp_rd;
@@ -752,15 +762,20 @@ static inline void push_comp_avg_est_rd(
// compound average.
static inline bool prune_comp_eval_using_comp_avg_est_rd(
const int64_t *top_comp_avg_est_rd, int64_t tmp_rd, int64_t ref_best_rd,
- bool skip_comp_eval_using_top_comp_avg_est_rd) {
- if (!skip_comp_eval_using_top_comp_avg_est_rd) return false;
+ int skip_cmp_using_top_cmp_avg_est_rd_lvl) {
+ if (!skip_cmp_using_top_cmp_avg_est_rd_lvl) return false;
+ assert(skip_cmp_using_top_cmp_avg_est_rd_lvl <= 3);
+
+ const int num_top_cand =
+ num_comp_mode_skip_cand[skip_cmp_using_top_cmp_avg_est_rd_lvl - 1];
+ assert(num_top_cand <= TOP_COMP_AVG_EST_RD_COUNT);
// Do not prune if there is no valid top RD Cost for comparison
- if (top_comp_avg_est_rd[TOP_COMP_AVG_EST_RD_COUNT - 1] == INT64_MAX ||
+ if (top_comp_avg_est_rd[num_top_cand - 1] == INT64_MAX ||
ref_best_rd == INT64_MAX)
return false;
- if (tmp_rd > top_comp_avg_est_rd[TOP_COMP_AVG_EST_RD_COUNT - 1]) return true;
+ if (tmp_rd > top_comp_avg_est_rd[num_top_cand - 1]) return true;
return false;
}
@@ -1691,13 +1706,13 @@ int av1_compound_type_rd(const AV1_COMP *const cpi, MACROBLOCK *x,
update_mask_best_mv(mbmi, best_mv, &best_tmp_rate_mv, tmp_rate_mv);
}
if (cur_type == COMPOUND_AVERAGE) {
- const bool skip_comp_eval_using_top_comp_avg_est_rd =
- cpi->sf.inter_sf.skip_comp_eval_using_top_comp_avg_est_rd;
+ const int skip_cmp_using_top_cmp_avg_est_rd_lvl =
+ cpi->sf.inter_sf.skip_cmp_using_top_cmp_avg_est_rd_lvl;
push_comp_avg_est_rd(x->top_comp_avg_est_rd, best_rd_cur,
- skip_comp_eval_using_top_comp_avg_est_rd);
+ skip_cmp_using_top_cmp_avg_est_rd_lvl);
if (prune_comp_eval_using_comp_avg_est_rd(
x->top_comp_avg_est_rd, best_rd_cur, ref_best_rd,
- skip_comp_eval_using_top_comp_avg_est_rd)) {
+ skip_cmp_using_top_cmp_avg_est_rd_lvl)) {
*rd = INT64_MAX;
restore_dst_buf(xd, *orig_dst, 1);
return 0;
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index b8990873c2..be45463b7a 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -514,8 +514,8 @@ static inline void inter_modes_info_sort(const InterModesInfo *inter_modes_info,
// Initialize estimated RD Cost records of compound average.
static inline void init_comp_avg_est_rd(
- struct macroblock *x, bool skip_comp_eval_using_top_comp_avg_est_rd) {
- if (!skip_comp_eval_using_top_comp_avg_est_rd) return;
+ struct macroblock *x, int skip_cmp_using_top_cmp_avg_est_rd_lvl) {
+ if (!skip_cmp_using_top_cmp_avg_est_rd_lvl) return;
for (int j = 0; j < TOP_COMP_AVG_EST_RD_COUNT; j++) {
x->top_comp_avg_est_rd[j] = INT64_MAX;
@@ -6285,8 +6285,7 @@ void av1_rd_pick_inter_mode(struct AV1_COMP *cpi, struct TileDataEnc *tile_data,
mode_start = SINGLE_REF_MODE_START;
mode_end = SINGLE_REF_MODE_END;
}
- init_comp_avg_est_rd(x,
- sf->inter_sf.skip_comp_eval_using_top_comp_avg_est_rd);
+ init_comp_avg_est_rd(x, sf->inter_sf.skip_cmp_using_top_cmp_avg_est_rd_lvl);
for (THR_MODES midx = mode_start; midx < mode_end; ++midx) {
// Get the actual prediction mode we are trying in this iteration
const THR_MODES mode_enum = av1_default_mode_order[midx];
diff --git a/av1/encoder/speed_features.c b/av1/encoder/speed_features.c
index 1ccc4d029c..09eba83b7c 100644
--- a/av1/encoder/speed_features.c
+++ b/av1/encoder/speed_features.c
@@ -770,6 +770,12 @@ static void set_good_speed_feature_framesize_dependent(
sf->part_sf.ml_4_partition_search_level_index = 1;
sf->inter_sf.skip_newmv_in_drl = 1;
+ if (is_480p_or_lesser) {
+ sf->inter_sf.skip_cmp_using_top_cmp_avg_est_rd_lvl = 1;
+ } else {
+ sf->inter_sf.skip_cmp_using_top_cmp_avg_est_rd_lvl = 2;
+ }
+
if (is_720p_or_larger) {
sf->part_sf.use_square_partition_only_threshold = BLOCK_128X128;
} else if (is_480p_or_larger) {
@@ -842,6 +848,8 @@ static void set_good_speed_feature_framesize_dependent(
sf->inter_sf.limit_inter_mode_cands = is_lf_frame ? 2 : 0;
}
+ sf->inter_sf.skip_cmp_using_top_cmp_avg_est_rd_lvl = 3;
+
if (is_480p_or_larger) {
sf->tx_sf.tx_type_search.prune_tx_type_using_stats = 1;
if (use_hbd) sf->tx_sf.prune_tx_size_level = 2;
@@ -1234,7 +1242,6 @@ static void set_good_speed_features_framesize_independent(
sf->inter_sf.inter_mode_txfm_breakout = boosted ? 0 : 1;
sf->inter_sf.alt_ref_search_fp = 1;
sf->inter_sf.prune_inter_modes_based_on_tpl = 1;
- sf->inter_sf.skip_comp_eval_using_top_comp_avg_est_rd = true;
sf->inter_sf.prune_single_ref = boosted ? 1 : 2;
sf->interp_sf.adaptive_interp_filter_search = 1;
@@ -2379,7 +2386,7 @@ static inline void init_inter_sf(INTER_MODE_SPEED_FEATURES *inter_sf) {
inter_sf->skip_arf_compound = 0;
inter_sf->bias_warp_mode_rd_scale_pct = 0;
inter_sf->bias_obmc_mode_rd_scale_pct = 0.0f;
- inter_sf->skip_comp_eval_using_top_comp_avg_est_rd = false;
+ inter_sf->skip_cmp_using_top_cmp_avg_est_rd_lvl = 0;
set_txfm_rd_gate_level(inter_sf->txfm_rd_gate_level, 0);
}
diff --git a/av1/encoder/speed_features.h b/av1/encoder/speed_features.h
index 8e89031b5f..db031a3d82 100644
--- a/av1/encoder/speed_features.h
+++ b/av1/encoder/speed_features.h
@@ -1242,7 +1242,9 @@ typedef struct INTER_MODE_SPEED_FEATURES {
// Avoid further evaluation of compound modes using top estimate RD Costs of
// compound average.
- bool skip_comp_eval_using_top_comp_avg_est_rd;
+ // Values are 0 (not used),1 - 3 with progressively increasing
+ // aggressiveness, i.e., decreasing number of top candidates.
+ int skip_cmp_using_top_cmp_avg_est_rd_lvl;
} INTER_MODE_SPEED_FEATURES;
typedef struct INTERP_FILTER_SPEED_FEATURES {