Commit d58711f4fc for aom
commit d58711f4fcdea41793bc64761e452d6ee8c42b6b
Author: Diksha Singh <diksha.singh@ittiam.com>
Date: Mon Mar 23 16:34:44 2026 +0530
Extend sf 'prune_single_ref' to speed 2
The speed feature 'prune_single_ref' is extended to speed 2
conservatively by disallowing the pruning of 5 best reference frames
for ARFs.
Encoder performance results averaged over all resolutions are as follows:
Instruction Count BD-Rate Loss(%)
cpu Reduction(%) avg.psnr ovr.psnr ssim vmaf vmaf_neg
2 1.36 0.0122 0.0173 0.0061 0.0074 0.0200
STATS_CHAGNED for speed=2
Change-Id: I7880c3df7fd2430ef14c00f741c9bbd57997f10f
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index 5846e031cd..7f824a94bf 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -1725,12 +1725,9 @@ static int compare_score_data_asc(const void *a, const void *b) {
static inline void setup_keep_single_ref_frame_mask(AV1_COMP *cpi) {
const int prune_single_ref = cpi->sf.inter_sf.prune_single_ref;
const AV1_COMMON *const cm = &cpi->common;
+ cpi->keep_single_ref_frame_mask = 0;
+ if (frame_is_intra_only(cm)) return;
- if (prune_single_ref != 1 || frame_is_intra_only(cm)) {
- cpi->keep_single_ref_frame_mask =
- (prune_single_ref == 0) ? ((1 << REF_FRAMES) - 1) : 0;
- return;
- }
RefScoreData ref_score_data[INTER_REFS_PER_FRAME];
for (int i = 0; i < INTER_REFS_PER_FRAME; ++i) {
ref_score_data[i].score = INT_MAX;
@@ -1755,8 +1752,15 @@ static inline void setup_keep_single_ref_frame_mask(AV1_COMP *cpi) {
qsort(ref_score_data, INTER_REFS_PER_FRAME, sizeof(ref_score_data[0]),
compare_score_data_asc);
- cpi->keep_single_ref_frame_mask = 0;
- const int num_frames_to_keep = 3;
+ // Decide the number of reference frames for which pruning via the speed
+ // feature prune_single_ref is disallowed.
+ // prune_single_ref = 0 => None of the 7 reference frames are pruned.
+ // prune_single_ref = 1 => The best 5 reference frames are not pruned.
+ // prune_single_ref = 2 => The best 3 reference frames are not pruned.
+ // prune_single_ref = 3, 4 => All the 7 references are allowed to be pruned.
+ static const int num_frames_to_keep_lookup[5] = { INTER_REFS_PER_FRAME, 5, 3,
+ 0, 0 };
+ const int num_frames_to_keep = num_frames_to_keep_lookup[prune_single_ref];
for (int i = 0; i < num_frames_to_keep; ++i) {
const int idx = ref_score_data[i].index;
cpi->keep_single_ref_frame_mask |= 1 << idx;
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index d202419241..dd9d72df41 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -4221,8 +4221,8 @@ static inline void init_mode_skip_mask(mode_skip_mask_t *mask,
// Prune reference frames which are not the closest to the current
// frame and with large pred_mv_sad.
if (inter_sf->prune_single_ref) {
- assert(inter_sf->prune_single_ref > 0 && inter_sf->prune_single_ref < 4);
- const double prune_threshes[3] = { 1.20, 1.20, 1.05 };
+ assert(inter_sf->prune_single_ref > 0 && inter_sf->prune_single_ref < 5);
+ const double prune_thresh = (inter_sf->prune_single_ref <= 3) ? 1.20 : 1.05;
for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
const RefFrameDistanceInfo *const ref_frame_dist_info =
@@ -4239,9 +4239,7 @@ static inline void init_mode_skip_mask(mode_skip_mask_t *mask,
? 0
: 1;
if (x->best_pred_mv_sad[dir] < INT_MAX &&
- x->pred_mv_sad[ref_frame] >
- prune_threshes[inter_sf->prune_single_ref - 1] *
- x->best_pred_mv_sad[dir])
+ x->pred_mv_sad[ref_frame] > prune_thresh * x->best_pred_mv_sad[dir])
mask->pred_modes[ref_frame] |= INTER_SINGLE_ALL;
}
}
diff --git a/av1/encoder/speed_features.c b/av1/encoder/speed_features.c
index 15a2dfb304..b7bbb36065 100644
--- a/av1/encoder/speed_features.c
+++ b/av1/encoder/speed_features.c
@@ -1235,6 +1235,7 @@ static void set_good_speed_features_framesize_independent(
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;
@@ -1291,7 +1292,7 @@ static void set_good_speed_features_framesize_independent(
set_txfm_rd_gate_level(sf->inter_sf.txfm_rd_gate_level,
boosted ? 0 : (is_boosted_arf2_bwd_type ? 1 : 2));
sf->inter_sf.inter_mode_txfm_breakout = boosted ? 0 : 2;
- sf->inter_sf.prune_single_ref = 1;
+ sf->inter_sf.prune_single_ref = 2;
sf->interp_sf.adaptive_interp_filter_search = 2;
@@ -1408,7 +1409,7 @@ static void set_good_speed_features_framesize_independent(
sf->mv_sf.warp_search_method = WARP_SEARCH_DIAMOND;
sf->inter_sf.prune_inter_modes_if_skippable = 1;
- sf->inter_sf.prune_single_ref = is_boosted_arf2_bwd_type ? 0 : 2;
+ sf->inter_sf.prune_single_ref = is_boosted_arf2_bwd_type ? 0 : 3;
sf->inter_sf.txfm_rd_gate_level[TX_SEARCH_DEFAULT] = boosted ? 0 : 4;
sf->inter_sf.txfm_rd_gate_level[TX_SEARCH_COMP_TYPE_MODE] = boosted ? 0 : 5;
sf->inter_sf.enable_fast_compound_mode_search = 2;
@@ -1446,7 +1447,7 @@ static void set_good_speed_features_framesize_independent(
sf->inter_sf.prune_inter_modes_based_on_tpl = boosted ? 1 : 4;
sf->inter_sf.selective_ref_frame = 6;
- sf->inter_sf.prune_single_ref = is_boosted_arf2_bwd_type ? 0 : 3;
+ sf->inter_sf.prune_single_ref = is_boosted_arf2_bwd_type ? 0 : 4;
sf->inter_sf.prune_ext_comp_using_neighbors = 3;
sf->intra_sf.chroma_intra_pruning_with_hog = 4;
diff --git a/av1/encoder/speed_features.h b/av1/encoder/speed_features.h
index b9576e103f..8e89031b5f 100644
--- a/av1/encoder/speed_features.h
+++ b/av1/encoder/speed_features.h
@@ -1023,7 +1023,7 @@ typedef struct INTER_MODE_SPEED_FEATURES {
int alt_ref_search_fp;
// Prune reference frames for single prediction modes based on temporal
- // distance and pred MV SAD. Feasible values are 0, 1, 2, 3. The feature is
+ // distance and pred MV SAD. Feasible values are 0-4. The feature is
// disabled for 0. An increasing value indicates more aggressive pruning
// threshold.
int prune_single_ref;