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;