Commit ee698f212e for aom

commit ee698f212eb493e6605ff08a00b60b1dd581155c
Author: Bohan Li <bohanli@google.com>
Date:   Tue Jun 2 13:48:54 2026 -0700

    Add force max q option

    Change-Id: I32d79f3ee0ed112af3aee2a9fe2a7686e502ca42

diff --git a/av1/arg_defs.c b/av1/arg_defs.c
index 2eb3b99291..a3eefc9e8c 100644
--- a/av1/arg_defs.c
+++ b/av1/arg_defs.c
@@ -727,5 +727,7 @@ const av1_codec_arg_definitions_t g_av1_codec_arg_defs = {
               "Check that input samples are within the valid range "
               "for the chosen bit depth with high bit depth encoding (0: "
               "disabled, 1: enabled (default))"),
+  .force_max_q =
+      ARG_DEF(NULL, "force-max-q", 1, "Force max Q used in vbr mode."),
 #endif  // CONFIG_AV1_ENCODER
 };
diff --git a/av1/arg_defs.h b/av1/arg_defs.h
index a9d68bc0bb..77f157672b 100644
--- a/av1/arg_defs.h
+++ b/av1/arg_defs.h
@@ -240,6 +240,7 @@ typedef struct av1_codec_arg_definitions {
   arg_def_t enable_low_complexity_decode;
   arg_def_t screen_detection_mode;
   arg_def_t validate_hbd_input;
+  arg_def_t force_max_q;
 #endif  // CONFIG_AV1_ENCODER
 } av1_codec_arg_definitions_t;

diff --git a/av1/av1_cx_iface.c b/av1/av1_cx_iface.c
index 6b4b74f5a1..9e921bd240 100644
--- a/av1/av1_cx_iface.c
+++ b/av1/av1_cx_iface.c
@@ -247,6 +247,7 @@ struct av1_extracfg {
   int sb_qp_sweep;
   aom_screen_detection_mode screen_detection_mode;
   unsigned int validate_hbd_input;
+  unsigned int force_max_q;
 };

 #if !CONFIG_REALTIME_ONLY
@@ -404,6 +405,7 @@ static const struct av1_extracfg default_extra_cfg = {
   0,               // sb_qp_sweep
   AOM_SCREEN_DETECTION_STANDARD,
   1,  // validate_hbd_input
+  0,  // force_max_q
 };
 #else
 // Some settings are changed for realtime only build.
@@ -561,6 +563,7 @@ static const struct av1_extracfg default_extra_cfg = {
   0,               // sb_qp_sweep
   AOM_SCREEN_DETECTION_STANDARD,
   1,  // validate_hbd_input
+  0,  // force_max_q
 };
 #endif

@@ -1270,6 +1273,7 @@ static void set_encoder_config(AV1EncoderConfig *oxcf,
   rc_cfg->vbrbias = cfg->rc_2pass_vbr_bias_pct;
   rc_cfg->vbrmin_section = cfg->rc_2pass_vbr_minsection_pct;
   rc_cfg->vbrmax_section = cfg->rc_2pass_vbr_maxsection_pct;
+  rc_cfg->force_max_q = extra_cfg->force_max_q;

   // Set Toolset related configuration.
   tool_cfg->bit_depth = cfg->g_bit_depth;
@@ -4871,6 +4875,9 @@ static aom_codec_err_t encoder_set_option(aom_codec_alg_priv_t *ctx,
   } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.validate_hbd_input,
                               argv, err_string)) {
     extra_cfg.validate_hbd_input = arg_parse_int_helper(&arg, err_string);
+  } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.force_max_q, argv,
+                              err_string)) {
+    extra_cfg.force_max_q = arg_parse_uint_helper(&arg, err_string);
   } else {
     match = 0;
     snprintf(err_string, ARG_ERR_MSG_MAX_LEN, "Cannot find aom option %s",
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index 82159e83e6..ab858ea9ba 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -620,6 +620,10 @@ typedef struct {
    * CBR mode.
    */
   int max_consec_drop_ms;
+  /*!
+   * Force to allow the usage of maximum q in vbr mode.
+   */
+  int force_max_q;
 } RateControlCfg;

 /*!\cond */
diff --git a/av1/encoder/encoder_utils.c b/av1/encoder/encoder_utils.c
index 5593486940..47d6921aac 100644
--- a/av1/encoder/encoder_utils.c
+++ b/av1/encoder/encoder_utils.c
@@ -751,7 +751,9 @@ void av1_set_size_dependent_vars(AV1_COMP *cpi, int *q, int *bottom_index,
       cpi->sf.hl_sf.static_segmentation)
     configure_static_seg_features(cpi);

-  if (cpi->oxcf.rc_cfg.over_shoot_pct == 0) *top_index = MAXQ;
+  if (cpi->oxcf.rc_cfg.force_max_q || cpi->oxcf.rc_cfg.over_shoot_pct == 0) {
+    *top_index = MAXQ;
+  }
   if (cpi->oxcf.rc_cfg.under_shoot_pct == 0) *bottom_index = MINQ;
 }