Commit 99b20f5fda for aom
commit 99b20f5fdaaae1fc7dbc53f805e20a5827b4b1a3
Author: Jerome Jiang <jianj@google.com>
Date: Wed Jan 21 14:23:31 2026 -0500
ext rc: implement delta q
Bug: 477330660
Change-Id: I9fc30c04cbae6cf79f6689a03a05e3eb4dd04d70
diff --git a/av1/encoder/av1_ext_ratectrl.c b/av1/encoder/av1_ext_ratectrl.c
index 75182b6061..90ef4b2423 100644
--- a/av1/encoder/av1_ext_ratectrl.c
+++ b/av1/encoder/av1_ext_ratectrl.c
@@ -190,6 +190,7 @@ aom_codec_err_t av1_extrc_delete(AOM_EXT_RATECTRL *ext_ratectrl) {
return AOM_CODEC_ERROR;
}
aom_free(ext_ratectrl->rc_firstpass_stats.frame_stats);
+ aom_free(ext_ratectrl->sb_params_list);
}
return av1_extrc_init(ext_ratectrl);
}
diff --git a/av1/encoder/av1_ext_ratectrl.h b/av1/encoder/av1_ext_ratectrl.h
index 6c46a78573..4cab2f0617 100644
--- a/av1/encoder/av1_ext_ratectrl.h
+++ b/av1/encoder/av1_ext_ratectrl.h
@@ -24,6 +24,7 @@ typedef struct AOM_EXT_RATECTRL {
aom_rc_funcs_t funcs;
aom_rc_config_t ratectrl_config;
aom_rc_firstpass_stats_t rc_firstpass_stats;
+ aom_sb_params *sb_params_list;
} AOM_EXT_RATECTRL;
aom_codec_err_t av1_extrc_init(AOM_EXT_RATECTRL *ext_ratectrl);
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index 4bb5c0d617..ece4d95809 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -308,15 +308,23 @@ static inline void setup_delta_q(AV1_COMP *const cpi, ThreadData *td,
const int delta_q_res = delta_q_info->delta_q_res;
int current_qindex = cm->quant_params.base_qindex;
+ const int sb_row = mi_row >> cm->seq_params->mib_size_log2;
+ const int sb_col = mi_col >> cm->seq_params->mib_size_log2;
+ const int sb_cols =
+ CEIL_POWER_OF_TWO(cm->mi_params.mi_cols, cm->seq_params->mib_size_log2);
+ const int sb_index = sb_row * sb_cols + sb_col;
if (cpi->use_ducky_encode && cpi->ducky_encode_info.frame_info.qp_mode ==
DUCKY_ENCODE_FRAME_MODE_QINDEX) {
- const int sb_row = mi_row >> cm->seq_params->mib_size_log2;
- const int sb_col = mi_col >> cm->seq_params->mib_size_log2;
- const int sb_cols =
- CEIL_POWER_OF_TWO(cm->mi_params.mi_cols, cm->seq_params->mib_size_log2);
- const int sb_index = sb_row * sb_cols + sb_col;
current_qindex =
cpi->ducky_encode_info.frame_info.superblock_encode_qindex[sb_index];
+ } else if (cpi->ext_ratectrl.ready &&
+ (cpi->ext_ratectrl.funcs.rc_type & AOM_RC_QP) != 0 &&
+ cpi->ext_ratectrl.funcs.get_encodeframe_decision != NULL &&
+ cpi->ext_ratectrl.sb_params_list != NULL) {
+ const int q_index = cpi->ext_ratectrl.sb_params_list[sb_index].q_index;
+ if (q_index != AOM_DEFAULT_Q) {
+ current_qindex = q_index;
+ }
} else if (cpi->oxcf.q_cfg.deltaq_mode == DELTA_Q_PERCEPTUAL) {
if (DELTA_Q_PERCEPTUAL_MODULATION == 1) {
const int block_wavelet_energy_level =
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index 67b780b68c..5545251487 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -3434,6 +3434,19 @@ static int encode_with_recode_loop(AV1_COMP *cpi, size_t *size, uint8_t *dest,
cpi->ext_ratectrl.funcs.get_encodeframe_decision != NULL) {
aom_codec_err_t codec_status;
aom_rc_encodeframe_decision_t encode_frame_decision;
+ const int sb_rows = CEIL_POWER_OF_TWO(cm->mi_params.mi_rows,
+ cm->seq_params->mib_size_log2);
+ const int sb_cols = CEIL_POWER_OF_TWO(cm->mi_params.mi_cols,
+ cm->seq_params->mib_size_log2);
+ // This assumes frame sizes don't change when used with external RC.
+ // cpi->ext_ratectrl is zero'ed at init.
+ if (cpi->ext_ratectrl.sb_params_list == NULL) {
+ CHECK_MEM_ERROR(
+ cm, cpi->ext_ratectrl.sb_params_list,
+ (aom_sb_params *)aom_calloc(
+ sb_rows * sb_cols, sizeof(*cpi->ext_ratectrl.sb_params_list)));
+ encode_frame_decision.sb_params_list = cpi->ext_ratectrl.sb_params_list;
+ }
codec_status = av1_extrc_get_encodeframe_decision(
&cpi->ext_ratectrl, cpi->gf_frame_index, &encode_frame_decision);
if (codec_status != AOM_CODEC_OK) {