Commit bd95a14ccb for aom

commit bd95a14ccbdfb80d8ecb9a6458456b0cb7033dfd
Author: Yunqing Wang <yunqingwang@google.com>
Date:   Thu Apr 2 14:43:44 2026 -0700

    Bias towards sharp filter for non-boosted frames

    Saw 1.5 - 2.2% vmaf gain. This is enabled for speed <=3
    except LC mode due to the decoder time impact.

    Bug: 503081456

    STATS_CHANGED

    Change-Id: I7e2db661d5d4a25b00f74f6cacdb7131dd9eb3a6

diff --git a/av1/encoder/interp_search.c b/av1/encoder/interp_search.c
index 0135d239f9..994c78b767 100644
--- a/av1/encoder/interp_search.c
+++ b/av1/encoder/interp_search.c
@@ -169,12 +169,19 @@ static inline int64_t interpolation_filter_rd(
   this_rd_stats = *rd_stats_luma;
   const int_interpfilters last_best = mbmi->interp_filters;
   mbmi->interp_filters = filter_sets[filter_idx];
+
+  const int is_sharp =
+      (mbmi->interp_filters.as_filters.x_filter == MULTITAP_SHARP ||
+       mbmi->interp_filters.as_filters.y_filter == MULTITAP_SHARP);
+  const int mul =
+      (is_sharp && cpi->sf.interp_sf.use_more_sharp_interp) ? 90 : 100;
+
   const int tmp_rs =
       get_switchable_rate(x, mbmi->interp_filters, switchable_ctx,
                           cm->seq_params->enable_dual_filter);

   int64_t min_rd = RDCOST(x->rdmult, tmp_rs, 0);
-  if (min_rd > *rd) {
+  if (min_rd * mul / 100 > *rd) {
     mbmi->interp_filters = last_best;
     return 0;
   }
@@ -222,7 +229,7 @@ static inline int64_t interpolation_filter_rd(
       for (int plane = 1; plane < num_planes; ++plane) {
         int64_t tmp_rd =
             RDCOST(x->rdmult, tmp_rs + this_rd_stats.rate, this_rd_stats.dist);
-        if (tmp_rd >= *rd) {
+        if (tmp_rd * mul / 100 >= *rd) {
           mbmi->interp_filters = last_best;
           return 0;
         }
@@ -240,7 +247,7 @@ static inline int64_t interpolation_filter_rd(
   int64_t tmp_rd =
       RDCOST(x->rdmult, tmp_rs + this_rd_stats.rate, this_rd_stats.dist);

-  if (tmp_rd < *rd) {
+  if (tmp_rd * mul / 100 < *rd) {
     *rd = tmp_rd;
     *switchable_rate = tmp_rs;
     if (skip_pred != interp_search_flags->default_interp_skip_flags) {
diff --git a/av1/encoder/speed_features.c b/av1/encoder/speed_features.c
index 3f00173288..ac031e2575 100644
--- a/av1/encoder/speed_features.c
+++ b/av1/encoder/speed_features.c
@@ -647,6 +647,9 @@ static void set_good_speed_features_lc_dec_framesize_dependent(
   const int boosted = frame_is_boosted(cpi);
   const int is_key_frame = frame_is_intra_only(cm);

+  // Need to study the decoder time impact.
+  sf->interp_sf.use_more_sharp_interp = 0;
+
   // Speed features for vertical videos
   if (is_vertical_video && is_between_608p_and_1080p) {
     const int leaf_and_overlay_frames =
@@ -691,6 +694,9 @@ static void set_good_speed_features_lc_dec_framesize_independent(
     const AV1_COMP *const cpi, SPEED_FEATURES *const sf, int speed) {
   if (speed < 1 || speed > 3) return;

+  // Need to study the decoder time impact.
+  sf->interp_sf.use_more_sharp_interp = 0;
+
   const FRAME_UPDATE_TYPE update_type =
       get_frame_update_type(&cpi->ppi->gf_group, cpi->gf_frame_index);

@@ -1131,6 +1137,7 @@ static void set_good_speed_features_framesize_independent(

   sf->interp_sf.use_fast_interpolation_filter_search = 1;
   sf->interp_sf.disable_dual_filter = 1;
+  sf->interp_sf.use_more_sharp_interp = boosted ? 0 : 1;

   sf->intra_sf.intra_pruning_with_hog = 1;

@@ -1378,6 +1385,7 @@ static void set_good_speed_features_framesize_independent(
     sf->interp_sf.cb_pred_filter_search = 1;
     sf->interp_sf.skip_sharp_interp_filter_search = 1;
     sf->interp_sf.use_interp_filter = 2;
+    sf->interp_sf.use_more_sharp_interp = 0;

     sf->intra_sf.intra_uv_mode_mask[TX_16X16] = UV_INTRA_DC_H_V_CFL;
     sf->intra_sf.intra_uv_mode_mask[TX_32X32] = UV_INTRA_DC_H_V_CFL;
@@ -2407,6 +2415,7 @@ static inline void init_interp_sf(INTERP_FILTER_SPEED_FEATURES *interp_sf) {
   interp_sf->use_fast_interpolation_filter_search = 0;
   interp_sf->use_interp_filter = 0;
   interp_sf->skip_interp_filter_search = 0;
+  interp_sf->use_more_sharp_interp = 0;
 }

 static inline void init_intra_sf(INTRA_MODE_SPEED_FEATURES *intra_sf) {
@@ -2843,6 +2852,9 @@ static void set_good_speed_features_lc_dec_qindex_dependent(
                                          AOMMIN(cm->width, cm->height) <= 1080;
   const bool is_vertical_video = cm->width < cm->height;

+  // Need to study the decoder time impact.
+  sf->interp_sf.use_more_sharp_interp = 0;
+
   // Speed features for vertical videos
   if (is_vertical_video && is_between_608p_and_1080p) {
     sf->lpf_sf.min_lr_unit_size = RESTORATION_UNITSIZE_MAX >> 1;
diff --git a/av1/encoder/speed_features.h b/av1/encoder/speed_features.h
index 1af82a89e8..05db0a921a 100644
--- a/av1/encoder/speed_features.h
+++ b/av1/encoder/speed_features.h
@@ -1276,6 +1276,9 @@ typedef struct INTERP_FILTER_SPEED_FEATURES {
   // Forces interpolation filter to EIGHTTAP_REGULAR and skips interpolation
   // filter search.
   int skip_interp_filter_search;
+
+  // Bias towards sharp filter
+  int use_more_sharp_interp;
 } INTERP_FILTER_SPEED_FEATURES;

 typedef struct INTRA_MODE_SPEED_FEATURES {