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.")