Add RD_COMMAND for rdmult experiment
Add CONFIG_RD_COMMAND as the experimental flag.
When it's on, the encoder will read rd_command from
rd_command.txt and use it to assign rdmult / q_index
accordingly.
Note that this flag is for experimental purpose at the
moment.
Change-Id: I95a006798041fb14f0c2e42f484cd8b926e4570b
diff --git a/av1/encoder/encode_strategy.c b/av1/encoder/encode_strategy.c
index 01f2959..a505eff 100644
--- a/av1/encoder/encode_strategy.c
+++ b/av1/encoder/encode_strategy.c
@@ -1077,6 +1077,13 @@
}
}
+#if CONFIG_RD_COMMAND
+ if (frame_params->frame_type == KEY_FRAME) {
+ char filepath[] = "rd_command.txt";
+ av1_read_rd_command(filepath, &cpi->rd_command);
+ }
+#endif // CONFIG_RD_COMMAND
+
if (allow_tpl == 0) {
// Avoid the use of unintended TPL stats from previous GOP's results.
if (cpi->gf_frame_index == 0 && !is_stat_generation_stage(cpi))
diff --git a/av1/encoder/encodeframe_utils.c b/av1/encoder/encodeframe_utils.c
index d3fa502..6ce65a1 100644
--- a/av1/encoder/encodeframe_utils.c
+++ b/av1/encoder/encodeframe_utils.c
@@ -130,11 +130,13 @@
int rdmult = (int)((double)orig_rdmult * geom_mean_of_scale + 0.5);
rdmult = AOMMAX(rdmult, 0);
av1_set_error_per_bit(&x->errorperbit, rdmult);
+#if !CONFIG_RD_COMMAND
if (bsize == cm->seq_params->sb_size) {
const int rdmult_sb = set_deltaq_rdmult(cpi, x);
assert(rdmult_sb == rdmult);
(void)rdmult_sb;
}
+#endif // !CONFIG_RD_COMMAND
return rdmult;
}
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index 41122ef..a062286 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -2495,9 +2495,11 @@
printf("\n Encoding a frame:");
#endif
+#if !CONFIG_RD_COMMAND
// Determine whether to use screen content tools using two fast encoding.
if (!cpi->sf.hl_sf.disable_extra_sc_testing)
av1_determine_sc_tools_with_encoding(cpi, q);
+#endif // !CONFIG_RD_COMMAND
#if CONFIG_TUNE_VMAF
if (oxcf->tune_cfg.tuning == AOM_TUNE_VMAF_NEG_MAX_GAIN) {
@@ -2570,6 +2572,14 @@
}
#endif
+#if CONFIG_RD_COMMAND
+ RD_COMMAND *rd_command = &cpi->rd_command;
+ RD_OPTION option = rd_command->option_ls[rd_command->frame_index];
+ if (option == RD_OPTION_SET_Q || option == RD_OPTION_SET_Q_RDMULT) {
+ q = rd_command->q_index_ls[rd_command->frame_index];
+ }
+#endif // CONFIG_RD_COMMAND
+
av1_set_quantizer(cm, q_cfg->qm_minlevel, q_cfg->qm_maxlevel, q,
q_cfg->enable_chroma_deltaq);
av1_set_speed_features_qindex_dependent(cpi, oxcf->speed);
@@ -2654,7 +2664,7 @@
aom_clear_system_state();
-#if CONFIG_BITRATE_ACCURACY
+#if CONFIG_BITRATE_ACCURACY || CONFIG_RD_COMMAND
const int do_dummy_pack = 1;
#else // CONFIG_BITRATE_ACCURACY
// Dummy pack of the bitstream using up to date stats to get an
@@ -2676,6 +2686,16 @@
// bits used for this frame
rc->projected_frame_size = (int)(*size) << 3;
+#if CONFIG_RD_COMMAND
+ PSNR_STATS psnr;
+ aom_calc_psnr(cpi->source, &cpi->common.cur_frame->buf, &psnr);
+ printf("q %d rdmult %d rate %d dist %lu\n", q, cpi->rd.RDMULT,
+ rc->projected_frame_size, psnr.sse[0]);
+ ++rd_command->frame_index;
+ if (rd_command->frame_index == rd_command->frame_count) {
+ exit(0);
+ }
+#endif // CONFIG_RD_COMMAND
#if CONFIG_BITRATE_ACCURACY
cpi->ppi->tpl_data.actual_gop_bitrate += rc->projected_frame_size;
@@ -2705,9 +2725,9 @@
}
#endif
-#if CONFIG_BITRATE_ACCURACY
+#if CONFIG_BITRATE_ACCURACY || CONFIG_RD_COMMAND
loop = 0; // turn off recode loop when CONFIG_BITRATE_ACCURACY is on
-#endif // CONFIG_BITRATE_ACCURACY
+#endif // CONFIG_BITRATE_ACCURACY || CONFIG_RD_COMMAND
if (loop) {
++loop_count;
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index fe6e76f..a9dca94 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -2920,6 +2920,13 @@
*/
bool do_frame_data_update;
#endif
+#if CONFIG_RD_COMMAND
+ /*!
+ * A structure for assigning external q_index / rdmult for experiments
+ */
+ RD_COMMAND rd_command;
+#endif // CONFIG_RD_COMMAND
+
} AV1_COMP;
/*!
diff --git a/av1/encoder/rd.c b/av1/encoder/rd.c
index e361264..7d62f35 100644
--- a/av1/encoder/rd.c
+++ b/av1/encoder/rd.c
@@ -643,6 +643,15 @@
rd->RDMULT = av1_compute_rd_mult(
cpi, cm->quant_params.base_qindex + cm->quant_params.y_dc_delta_q);
+#if CONFIG_RD_COMMAND
+ if (cpi->oxcf.pass == 2) {
+ const RD_COMMAND *rd_command = &cpi->rd_command;
+ if (rd_command->option_ls[rd_command->frame_index] ==
+ RD_OPTION_SET_Q_RDMULT) {
+ rd->RDMULT = rd_command->rdmult_ls[rd_command->frame_index];
+ }
+ }
+#endif // CONFIG_RD_COMMAND
av1_set_error_per_bit(&x->errorperbit, rd->RDMULT);
diff --git a/av1/encoder/tpl_model.c b/av1/encoder/tpl_model.c
index e07ab3e..5a84dad 100644
--- a/av1/encoder/tpl_model.c
+++ b/av1/encoder/tpl_model.c
@@ -1912,3 +1912,23 @@
}
return est_rate;
}
+
+#if CONFIG_RD_COMMAND
+void av1_read_rd_command(const char *filepath, RD_COMMAND *rd_command) {
+ FILE *fptr = fopen(filepath, "r");
+ fscanf(fptr, "%d", &rd_command->frame_count);
+ rd_command->frame_index = 0;
+ for (int i = 0; i < rd_command->frame_count; ++i) {
+ int option;
+ fscanf(fptr, "%d", &option);
+ rd_command->option_ls[i] = (RD_OPTION)option;
+ if (option == RD_OPTION_SET_Q) {
+ fscanf(fptr, "%d", &rd_command->q_index_ls[i]);
+ } else if (option == RD_OPTION_SET_Q_RDMULT) {
+ fscanf(fptr, "%d", &rd_command->q_index_ls[i]);
+ fscanf(fptr, "%d", &rd_command->rdmult_ls[i]);
+ }
+ }
+ fclose(fptr);
+}
+#endif // CONFIG_RD_COMMAND
diff --git a/av1/encoder/tpl_model.h b/av1/encoder/tpl_model.h
index c764d92..408a4b2 100644
--- a/av1/encoder/tpl_model.h
+++ b/av1/encoder/tpl_model.h
@@ -221,6 +221,24 @@
#endif
} TplParams;
+#if CONFIG_RD_COMMAND
+typedef enum {
+ RD_OPTION_NONE,
+ RD_OPTION_SET_Q,
+ RD_OPTION_SET_Q_RDMULT
+} RD_OPTION;
+
+typedef struct RD_COMMAND {
+ RD_OPTION option_ls[MAX_LENGTH_TPL_FRAME_STATS];
+ int q_index_ls[MAX_LENGTH_TPL_FRAME_STATS];
+ int rdmult_ls[MAX_LENGTH_TPL_FRAME_STATS];
+ int frame_count;
+ int frame_index;
+} RD_COMMAND;
+
+void av1_read_rd_command(const char *filepath, RD_COMMAND *rd_command);
+#endif // CONFIG_RD_COMMAND
+
/*!\brief Allocate buffers used by tpl model
*
* \param[in] Top-level encode/decode structure
diff --git a/build/cmake/aom_config_defaults.cmake b/build/cmake/aom_config_defaults.cmake
index 8bf12c5..d75d446 100644
--- a/build/cmake/aom_config_defaults.cmake
+++ b/build/cmake/aom_config_defaults.cmake
@@ -130,6 +130,8 @@
set_aom_config_var(CONFIG_BITSTREAM_DEBUG 0
"AV1 experiment flag for bitstream debugging.")
set_aom_config_var(CONFIG_RD_DEBUG 0 "AV1 experiment flag.")
+set_aom_config_var(CONFIG_RD_COMMAND 0
+ "An experiment flag for using external rdmult and q_index.")
set_aom_config_var(CONFIG_SHARP_SETTINGS 0 "AV1 experiment flag.")
set_aom_config_var(CONFIG_DISABLE_FULL_PIXEL_SPLIT_8X8 1
"Disable full_pixel_motion_search_based_split on BLOCK_8X8.")