Commit 446d160a74 for aom
commit 446d160a742feed92ebe4401a0070f5f843aeda2
Author: Ranjit Kumar Tulabandu <ranjit.tulabandu@ittiam.com>
Date: Fri Mar 20 12:16:53 2026 +0530
Skip the evaluation of compound modes
In the CL, top N estimated RD Costs of compound average are tracked
and further evaluation of a compound mode is skipped if the
relevant estimated RD Cost is worser than top Nth estimated RD Cost.
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
2 2.691 0.0451 0.0479 0.0390 0.0833 0.0630
3 1.221 0.0246 0.0129 0.0018 0.0153 0.0147
4 0.710 0.0048 0.0098 0.0039 0.0314 0.0225
5 0.654 0.0117 0.0180 -0.0036 0.0085 -0.0061
6 0.336 0.0358 0.0186 0.0239 0.0513 0.0424
STATS_CHANGED
Change-Id: Ibd2abc62845d6ec05ae0e8acf9ca37c580b3b6ac
diff --git a/av1/encoder/block.h b/av1/encoder/block.h
index 6734f34e7c..f36f8cc6a6 100644
--- a/av1/encoder/block.h
+++ b/av1/encoder/block.h
@@ -873,6 +873,9 @@ typedef struct SetOffsetsLoc {
/*!\endcond */
+//! Maximum number of estimated RD Cost records for compound average.
+#define TOP_COMP_AVG_EST_RD_COUNT 2
+
/*! \brief Encoder's parameters related to the current coding block.
*
* This struct contains most of the information the encoder needs to encode the
@@ -1419,6 +1422,9 @@ typedef struct macroblock {
*/
struct SB_FIRST_PASS_STATS *sb_fp_stats;
+ /*!\brief Array of best estimated RD Costs of compound average. */
+ int64_t top_comp_avg_est_rd[TOP_COMP_AVG_EST_RD_COUNT];
+
#if CONFIG_PARTITION_SEARCH_ORDER
/*!\brief Pointer to RD_STATS structure to be used in
* av1_rd_partition_search().
diff --git a/av1/encoder/compound_type.c b/av1/encoder/compound_type.c
index f8364f1cf9..da895f3238 100644
--- a/av1/encoder/compound_type.c
+++ b/av1/encoder/compound_type.c
@@ -730,6 +730,41 @@ static int handle_wedge_inter_intra_mode(
return 0;
}
+// 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;
+
+ // Insert the RD Cost in sorted order
+ for (int i = 0; i < TOP_COMP_AVG_EST_RD_COUNT; i++) {
+ if (tmp_rd < top_comp_avg_est_rd[i]) {
+ for (int j = TOP_COMP_AVG_EST_RD_COUNT - 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;
+ break;
+ }
+ }
+}
+
+// Avoid further evaluation of compound modes based on top estimated RD Costs of
+// 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;
+
+ // 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 ||
+ ref_best_rd == INT64_MAX)
+ return false;
+
+ if (tmp_rd > top_comp_avg_est_rd[TOP_COMP_AVG_EST_RD_COUNT - 1]) return true;
+
+ return false;
+}
+
int av1_handle_inter_intra_mode(const AV1_COMP *const cpi, MACROBLOCK *const x,
BLOCK_SIZE bsize, MB_MODE_INFO *mbmi,
HandleInterModeArgs *args, int64_t ref_best_rd,
@@ -1655,6 +1690,19 @@ int av1_compound_type_rd(const AV1_COMP *const cpi, MACROBLOCK *x,
if (have_newmv_in_inter_mode(this_mode))
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;
+ push_comp_avg_est_rd(x->top_comp_avg_est_rd, best_rd_cur,
+ skip_comp_eval_using_top_comp_avg_est_rd);
+ 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)) {
+ *rd = INT64_MAX;
+ restore_dst_buf(xd, *orig_dst, 1);
+ return 0;
+ }
+ }
// reset to original mvs for next iteration
mbmi->mv[0].as_int = cur_mv[0].as_int;
mbmi->mv[1].as_int = cur_mv[1].as_int;
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index 74a25dfa73..d202419241 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -512,6 +512,16 @@ static inline void inter_modes_info_sort(const InterModesInfo *inter_modes_info,
compare_rd_idx_pair);
}
+// 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;
+
+ for (int j = 0; j < TOP_COMP_AVG_EST_RD_COUNT; j++) {
+ x->top_comp_avg_est_rd[j] = INT64_MAX;
+ }
+}
+
// Similar to get_horver_correlation, but also takes into account first
// row/column, when computing horizontal/vertical correlation.
void av1_get_horver_correlation_full_c(const int16_t *diff, int stride,
@@ -6274,7 +6284,8 @@ 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);
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 7939f7c217..15a2dfb304 100644
--- a/av1/encoder/speed_features.c
+++ b/av1/encoder/speed_features.c
@@ -1234,6 +1234,7 @@ 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->interp_sf.adaptive_interp_filter_search = 1;
@@ -2378,6 +2379,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;
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 3d81c3b4f2..b9576e103f 100644
--- a/av1/encoder/speed_features.h
+++ b/av1/encoder/speed_features.h
@@ -1239,6 +1239,10 @@ typedef struct INTER_MODE_SPEED_FEATURES {
// that encoder decisions are biased against local obmc, favoring low
// complexity modes.
float bias_obmc_mode_rd_scale_pct;
+
+ // Avoid further evaluation of compound modes using top estimate RD Costs of
+ // compound average.
+ bool skip_comp_eval_using_top_comp_avg_est_rd;
} INTER_MODE_SPEED_FEATURES;
typedef struct INTERP_FILTER_SPEED_FEATURES {