Group encoder algorithm config in AV1EncoderConfig
This CL groups the configuration parameters related to encoder
algorithm in AV1EncoderConfig into a new struct AlgoCfg, cleans
up function interfaces, and adds relevant documentation.
BUG=aomedia:2701
Change-Id: I7408066a2e2d34ccf1e27d6cacd464a30335b50e
diff --git a/av1/av1_cx_iface.c b/av1/av1_cx_iface.c
index 4ba57c4..132920f 100644
--- a/av1/av1_cx_iface.c
+++ b/av1/av1_cx_iface.c
@@ -732,6 +732,8 @@
InputCfg *const input_cfg = &oxcf->input_cfg;
+ AlgoCfg *const algo_cfg = &oxcf->algo_cfg;
+
const int is_vbr = cfg->rc_end_usage == AOM_VBR;
oxcf->profile = cfg->g_profile;
oxcf->max_threads = (int)cfg->g_threads;
@@ -826,9 +828,7 @@
oxcf->enable_restoration =
(cfg->g_usage == AOM_USAGE_REALTIME) ? 0 : extra_cfg->enable_restoration;
oxcf->force_video_mode = extra_cfg->force_video_mode;
- oxcf->enable_overlay = extra_cfg->enable_overlay;
oxcf->enable_palette = extra_cfg->enable_palette;
- oxcf->disable_trellis_quant = extra_cfg->disable_trellis_quant;
oxcf->allow_ref_frame_mvs = extra_cfg->enable_ref_frame_mvs;
// Set Quantization related configuration.
@@ -879,6 +879,17 @@
oxcf->drop_frames_water_mark = cfg->rc_dropframe_thresh;
+ // Set encoder algorithm related configuration.
+ algo_cfg->enable_overlay = extra_cfg->enable_overlay;
+ algo_cfg->disable_trellis_quant = extra_cfg->disable_trellis_quant;
+ algo_cfg->sharpness = extra_cfg->sharpness;
+ algo_cfg->arnr_max_frames = extra_cfg->arnr_max_frames;
+ algo_cfg->arnr_strength = extra_cfg->arnr_strength;
+ algo_cfg->cdf_update_mode = (uint8_t)extra_cfg->cdf_update_mode;
+ // TODO(any): Fix and Enable TPL for resize-mode > 0
+ algo_cfg->enable_tpl_model =
+ resize_cfg->resize_mode ? 0 : extra_cfg->enable_tpl_model;
+
// Set two-pass configuration.
two_pass_cfg->vbrbias = cfg->rc_2pass_vbr_bias_pct;
two_pass_cfg->vbrmin_section = cfg->rc_2pass_vbr_minsection_pct;
@@ -898,7 +909,6 @@
kf_cfg->enable_intrabc = extra_cfg->enable_intrabc;
oxcf->speed = extra_cfg->cpu_used;
- oxcf->sharpness = extra_cfg->sharpness;
// Set Color related configuration.
color_cfg->color_primaries = extra_cfg->color_primaries;
@@ -907,8 +917,6 @@
color_cfg->color_range = extra_cfg->color_range;
oxcf->chroma_sample_position = extra_cfg->chroma_sample_position;
- oxcf->arnr_max_frames = extra_cfg->arnr_max_frames;
- oxcf->arnr_strength = extra_cfg->arnr_strength;
// Set Group of frames configuration.
gf_cfg->lag_in_frames = clamp(cfg->g_lag_in_frames, 0, MAX_LAG_BUFFERS);
@@ -922,7 +930,6 @@
oxcf->tuning = extra_cfg->tuning;
oxcf->vmaf_model_path = extra_cfg->vmaf_model_path;
oxcf->content = extra_cfg->content;
- oxcf->cdf_update_mode = (uint8_t)extra_cfg->cdf_update_mode;
oxcf->superblock_size = extra_cfg->superblock_size;
if (cfg->large_scale_tile) {
oxcf->film_grain_test_vector = 0;
@@ -1071,10 +1078,6 @@
dec_model_cfg->timing_info_present = 0;
}
- // TODO(any): Fix and Enable TPL for resize-mode > 0
- oxcf->enable_tpl_model =
- resize_cfg->resize_mode ? 0 : extra_cfg->enable_tpl_model;
-
oxcf->deltalf_mode =
(q_cfg->deltaq_mode != NO_DELTA_Q) && extra_cfg->deltalf_mode;
diff --git a/av1/encoder/encode_strategy.c b/av1/encoder/encode_strategy.c
index 63b55bf..c9acf72 100644
--- a/av1/encoder/encode_strategy.c
+++ b/av1/encoder/encode_strategy.c
@@ -387,7 +387,7 @@
cpi->no_show_kf = 1;
} else {
#if !CONFIG_REALTIME_ONLY
- if (oxcf->arnr_max_frames > 0) {
+ if (oxcf->algo_cfg.arnr_max_frames > 0) {
// Produce the filtered ARF frame.
cm->current_frame.frame_type = INTER_FRAME;
FRAME_UPDATE_TYPE frame_update_type =
@@ -886,8 +886,9 @@
frame_params->frame_type == KEY_FRAME &&
oxcf->kf_cfg.enable_keyframe_filtering &&
!is_stat_generation_stage(cpi) && !frame_params->show_existing_frame &&
- cpi->rc.frames_to_key > cpi->oxcf.arnr_max_frames &&
- !is_lossless_requested(&oxcf->rc_cfg) && oxcf->arnr_max_frames > 0;
+ cpi->rc.frames_to_key > cpi->oxcf.algo_cfg.arnr_max_frames &&
+ !is_lossless_requested(&oxcf->rc_cfg) &&
+ oxcf->algo_cfg.arnr_max_frames > 0;
if (apply_filtering) {
const double y_noise_level = av1_estimate_noise_from_single_plane(
frame_input->source, 0, cm->seq_params.bit_depth);
@@ -933,7 +934,7 @@
if (!cpi->sf.tpl_sf.disable_filtered_key_tpl) {
if (frame_params->frame_type == KEY_FRAME &&
- !is_stat_generation_stage(cpi) && oxcf->enable_tpl_model &&
+ !is_stat_generation_stage(cpi) && oxcf->algo_cfg.enable_tpl_model &&
oxcf->gf_cfg.lag_in_frames > 0 && frame_params->show_frame) {
av1_tpl_setup_stats(cpi, 0, frame_params, frame_input);
}
@@ -1080,7 +1081,8 @@
frame_params.show_existing_frame = 1;
} else {
frame_params.show_existing_frame =
- ((oxcf->enable_overlay == 0 || cpi->sf.hl_sf.disable_overlay_frames ||
+ ((oxcf->algo_cfg.enable_overlay == 0 ||
+ cpi->sf.hl_sf.disable_overlay_frames ||
cpi->show_existing_alt_ref) &&
gf_group->update_type[gf_group->index] == OVERLAY_UPDATE) ||
gf_group->update_type[gf_group->index] == INTNL_OVERLAY_UPDATE;
@@ -1273,7 +1275,7 @@
cm->quant_params.using_qmatrix = oxcf->q_cfg.using_qm;
#if !CONFIG_REALTIME_ONLY
if (gf_cfg->lag_in_frames > 0 && !is_stat_generation_stage(cpi)) {
- if (cpi->gf_group.index == 1 && oxcf->enable_tpl_model) {
+ if (cpi->gf_group.index == 1 && oxcf->algo_cfg.enable_tpl_model) {
av1_configure_buffer_updates(cpi, &frame_params.refresh_frame,
frame_update_type, 0);
av1_set_frame_size(cpi, cm->width, cm->height);
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index 694d6be..8421a04 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -4375,7 +4375,7 @@
int mi_col, SuperBlockEnc *sb_enc) {
sb_enc->tpl_data_count = 0;
- if (!cpi->oxcf.enable_tpl_model) return;
+ if (!cpi->oxcf.algo_cfg.enable_tpl_model) return;
if (cpi->superres_mode != AOM_SUPERRES_NONE) return;
if (cpi->common.current_frame.frame_type == KEY_FRAME) return;
const FRAME_UPDATE_TYPE update_type = get_frame_update_type(&cpi->gf_group);
@@ -4545,7 +4545,7 @@
av1_compute_q_from_energy_level_deltaq_mode(cpi, block_var_level);
}
} else if (cpi->oxcf.q_cfg.deltaq_mode == DELTA_Q_OBJECTIVE &&
- cpi->oxcf.enable_tpl_model) {
+ cpi->oxcf.algo_cfg.enable_tpl_model) {
// Setup deltaq based on tpl stats
current_qindex = get_q_for_deltaq_objective(cpi, sb_size, mi_row, mi_col);
}
@@ -4553,7 +4553,8 @@
const int delta_q_res = delta_q_info->delta_q_res;
// Right now aq only works with tpl model. So if tpl is disabled, we set the
// current_qindex to base_qindex.
- if (cpi->oxcf.enable_tpl_model && cpi->oxcf.q_cfg.deltaq_mode != NO_DELTA_Q) {
+ if (cpi->oxcf.algo_cfg.enable_tpl_model &&
+ cpi->oxcf.q_cfg.deltaq_mode != NO_DELTA_Q) {
current_qindex =
clamp(current_qindex, delta_q_res, 256 - delta_q_info->delta_q_res);
} else {
@@ -4793,7 +4794,7 @@
assert(IMPLIES(cpi->gf_group.size > 0,
cpi->gf_group.index < cpi->gf_group.size));
const int gf_group_index = cpi->gf_group.index;
- if (cpi->oxcf.enable_tpl_model && cpi->oxcf.q_cfg.aq_mode == NO_AQ &&
+ if (cpi->oxcf.algo_cfg.enable_tpl_model && cpi->oxcf.q_cfg.aq_mode == NO_AQ &&
cpi->oxcf.q_cfg.deltaq_mode == NO_DELTA_Q && gf_group_index > 0 &&
cpi->gf_group.update_type[gf_group_index] == ARF_UPDATE) {
const int dr =
@@ -5131,7 +5132,7 @@
setup_delta_q(cpi, td, x, tile_info, mi_row, mi_col, num_planes);
av1_tpl_rdmult_setup_sb(cpi, x, sb_size, mi_row, mi_col);
}
- if (cpi->oxcf.enable_tpl_model) {
+ if (cpi->oxcf.algo_cfg.enable_tpl_model) {
adjust_rdmult_tpl_model(cpi, x, mi_row, mi_col);
}
}
diff --git a/av1/encoder/encodemb.c b/av1/encoder/encodemb.c
index 9cda30e..1326f7f 100644
--- a/av1/encoder/encodemb.c
+++ b/av1/encoder/encodemb.c
@@ -98,7 +98,8 @@
}
return av1_optimize_txb_new(cpi, x, plane, block, tx_size, tx_type, txb_ctx,
- rate_cost, cpi->oxcf.sharpness, fast_mode);
+ rate_cost, cpi->oxcf.algo_cfg.sharpness,
+ fast_mode);
}
// Hyper-parameters for dropout optimization, based on following logics.
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index cc6dd30..dd79d6b 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -2871,7 +2871,7 @@
}
}
- switch (oxcf->cdf_update_mode) {
+ switch (oxcf->algo_cfg.cdf_update_mode) {
case 0: // No CDF update for any frames(4~6% compression loss).
features->disable_cdf_update = 1;
break;
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index 1915e47..cc36a13 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -610,6 +610,31 @@
bool using_qm;
} QuantizationCfg;
+typedef struct {
+ // Indicates the loop filter sharpness.
+ int sharpness;
+ // Indicates the trellis optimization mode of quantized coefficients.
+ // 0: disabled
+ // 1: enabled
+ // 2: enabled for rd search
+ // 3: true for estimate yrd search
+ int disable_trellis_quant;
+ // Indicates the maximum number of frames to create arf.
+ int arnr_max_frames;
+ // Indicates the temporal filter strength for arf.
+ int arnr_strength;
+ // Indicates the CDF update mode
+ // 0: no update
+ // 1: update on every frame(default)
+ // 2: selectively update
+ uint8_t cdf_update_mode;
+ // Indicates if RDO based on frame temporal dependency should be enabled.
+ bool enable_tpl_model;
+ // Indicates if coding of overlay frames for filtered ALTREF frames is
+ // enabled.
+ bool enable_overlay;
+} AlgoCfg;
+
/*!\endcond */
/*!
* \brief Main encoder configuration data structure.
@@ -626,7 +651,9 @@
// Configuration related to frame-dimensions.
FrameDimensionCfg frm_dim_cfg;
- int sharpness; // sharpening output: recommendation 0:
+ // Configuration related to encoder algorithm.
+ AlgoCfg algo_cfg;
+
int speed;
MODE mode;
@@ -663,7 +690,6 @@
int enable_cdef;
int enable_restoration;
int force_video_mode;
- int disable_trellis_quant;
unsigned int vbr_corpus_complexity_lap; // 0 indicates corpus complexity vbr
// mode is disabled
@@ -694,9 +720,6 @@
*/
unsigned int frame_parallel_decoding_mode;
- int arnr_max_frames;
- int arnr_strength;
-
// Configuration related to Group of frames.
GFConfig gf_cfg;
@@ -705,8 +728,6 @@
int row_mt;
- int enable_tpl_model;
-
int max_threads;
aom_tune_metric tuning;
@@ -729,7 +750,6 @@
// Configuration related to unit tests.
UnitTestCfg unit_test_cfg;
- uint8_t cdf_update_mode;
aom_superblock_size_t superblock_size;
uint8_t monochrome;
unsigned int full_still_picture_hdr;
@@ -739,7 +759,6 @@
unsigned int allow_ref_frame_mvs;
int enable_interintra_comp;
int enable_global_motion;
- int enable_overlay;
int enable_palette;
unsigned int save_as_annexb;
diff --git a/av1/encoder/encoder_utils.c b/av1/encoder/encoder_utils.c
index b55acb6..98e6505 100644
--- a/av1/encoder/encoder_utils.c
+++ b/av1/encoder/encoder_utils.c
@@ -557,7 +557,7 @@
#if !CONFIG_REALTIME_ONLY
GF_GROUP *gf_group = &cpi->gf_group;
- if (cpi->oxcf.enable_tpl_model && is_frame_tpl_eligible(gf_group)) {
+ if (cpi->oxcf.algo_cfg.enable_tpl_model && is_frame_tpl_eligible(gf_group)) {
process_tpl_stats_frame(cpi);
av1_tpl_rdmult_setup(cpi);
}
diff --git a/av1/encoder/ethread.c b/av1/encoder/ethread.c
index 35cf820..19826f8 100644
--- a/av1/encoder/ethread.c
+++ b/av1/encoder/ethread.c
@@ -263,7 +263,7 @@
row_mt_sync_mem_dealloc(&this_tile->row_mt_sync);
- if (cpi->oxcf.cdf_update_mode) aom_free(this_tile->row_ctx);
+ if (cpi->oxcf.algo_cfg.cdf_update_mode) aom_free(this_tile->row_ctx);
}
}
enc_row_mt->allocated_sb_rows = 0;
@@ -994,7 +994,8 @@
enc_row_mt->allocated_sb_rows != max_sb_rows ||
enc_row_mt->allocated_sb_cols != (max_sb_cols - 1)) {
av1_row_mt_mem_dealloc(cpi);
- row_mt_mem_alloc(cpi, max_sb_rows, max_sb_cols, cpi->oxcf.cdf_update_mode);
+ row_mt_mem_alloc(cpi, max_sb_rows, max_sb_cols,
+ cpi->oxcf.algo_cfg.cdf_update_mode);
}
memset(thread_id_to_tile_id, -1,
diff --git a/av1/encoder/pass2_strategy.c b/av1/encoder/pass2_strategy.c
index 96d082f..d492df1 100644
--- a/av1/encoder/pass2_strategy.c
+++ b/av1/encoder/pass2_strategy.c
@@ -2714,14 +2714,14 @@
int max_gop_length =
(oxcf->gf_cfg.lag_in_frames >= 32 &&
is_stat_consumption_stage_twopass(cpi))
- ? AOMMIN(MAX_GF_INTERVAL,
- oxcf->gf_cfg.lag_in_frames - oxcf->arnr_max_frames / 2)
+ ? AOMMIN(MAX_GF_INTERVAL, oxcf->gf_cfg.lag_in_frames -
+ oxcf->algo_cfg.arnr_max_frames / 2)
: MAX_GF_LENGTH_LAP;
if (rc->intervals_till_gf_calculate_due == 0) {
calculate_gf_length(cpi, max_gop_length, MAX_NUM_GF_INTERVALS);
}
- if (max_gop_length > 16 && oxcf->enable_tpl_model &&
+ if (max_gop_length > 16 && oxcf->algo_cfg.enable_tpl_model &&
!cpi->sf.tpl_sf.disable_gop_length_decision) {
if (rc->gf_intervals[rc->cur_gf_index] - 1 > 16) {
// The calculate_gf_length function is previously used with
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index a6f2e64..197873c 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -3719,7 +3719,8 @@
// unless ARNR filtering is enabled in which case we want
// an unfiltered alternative. We allow near/nearest as well
// because they may result in zero-zero MVs but be cheaper.
- if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) {
+ if (cpi->rc.is_src_frame_alt_ref &&
+ (cpi->oxcf.algo_cfg.arnr_max_frames == 0)) {
disable_inter_references_except_altref(mask->ref_combo);
mask->pred_modes[ALTREF_FRAME] = ~INTER_NEAREST_NEAR_ZERO;
diff --git a/av1/encoder/speed_features.c b/av1/encoder/speed_features.c
index c5b7959c..fdae2ac 100644
--- a/av1/encoder/speed_features.c
+++ b/av1/encoder/speed_features.c
@@ -1120,22 +1120,23 @@
}
static AOM_INLINE void init_rd_sf(RD_CALC_SPEED_FEATURES *rd_sf,
- const AV1_COMP *cpi) {
- if (cpi->oxcf.disable_trellis_quant == 3) {
- rd_sf->optimize_coefficients = !is_lossless_requested(&cpi->oxcf.rc_cfg)
+ const AV1EncoderConfig *oxcf) {
+ const int disable_trellis_quant = oxcf->algo_cfg.disable_trellis_quant;
+ if (disable_trellis_quant == 3) {
+ rd_sf->optimize_coefficients = !is_lossless_requested(&oxcf->rc_cfg)
? NO_ESTIMATE_YRD_TRELLIS_OPT
: NO_TRELLIS_OPT;
- } else if (cpi->oxcf.disable_trellis_quant == 2) {
- rd_sf->optimize_coefficients = !is_lossless_requested(&cpi->oxcf.rc_cfg)
+ } else if (disable_trellis_quant == 2) {
+ rd_sf->optimize_coefficients = !is_lossless_requested(&oxcf->rc_cfg)
? FINAL_PASS_TRELLIS_OPT
: NO_TRELLIS_OPT;
- } else if (cpi->oxcf.disable_trellis_quant == 0) {
- if (is_lossless_requested(&cpi->oxcf.rc_cfg)) {
+ } else if (disable_trellis_quant == 0) {
+ if (is_lossless_requested(&oxcf->rc_cfg)) {
rd_sf->optimize_coefficients = NO_TRELLIS_OPT;
} else {
rd_sf->optimize_coefficients = FULL_TRELLIS_OPT;
}
- } else if (cpi->oxcf.disable_trellis_quant == 1) {
+ } else if (disable_trellis_quant == 1) {
rd_sf->optimize_coefficients = NO_TRELLIS_OPT;
} else {
assert(0 && "Invalid disable_trellis_quant value");
@@ -1220,7 +1221,7 @@
init_interp_sf(&sf->interp_sf);
init_intra_sf(&sf->intra_sf);
init_tx_sf(&sf->tx_sf);
- init_rd_sf(&sf->rd_sf, cpi);
+ init_rd_sf(&sf->rd_sf, oxcf);
init_winner_mode_sf(&sf->winner_mode_sf);
init_lpf_sf(&sf->lpf_sf);
init_rt_sf(&sf->rt_sf);
diff --git a/av1/encoder/speed_features.h b/av1/encoder/speed_features.h
index 41d1339..216ba55 100644
--- a/av1/encoder/speed_features.h
+++ b/av1/encoder/speed_features.h
@@ -291,7 +291,7 @@
MV_PREC_LOGIC high_precision_mv_usage;
// Whether to disable overlay frames for filtered Altref frames,
- // overiding oxcf->enable_overlay flag set as 1.
+ // overiding oxcf->algo_cfg.enable_overlay flag set as 1.
int disable_overlay_frames;
// Enable/disable adaptively deciding whether or not to encode ALTREF overlay
diff --git a/av1/encoder/temporal_filter.c b/av1/encoder/temporal_filter.c
index bb52175..94ac9ec 100644
--- a/av1/encoder/temporal_filter.c
+++ b/av1/encoder/temporal_filter.c
@@ -710,7 +710,7 @@
// Quantization factor used in temporal filtering.
const int q_factor = get_q(cpi);
// Factor to control the filering strength.
- const int filter_strength = cpi->oxcf.arnr_strength;
+ const int filter_strength = cpi->oxcf.algo_cfg.arnr_strength;
// Save input state.
MACROBLOCK *const mb = &cpi->td.mb;
@@ -874,7 +874,7 @@
double *noise_levels) {
// Number of frames used for filtering. Set `arnr_max_frames` as 1 to disable
// temporal filtering.
- int num_frames = AOMMAX(cpi->oxcf.arnr_max_frames, 1);
+ int num_frames = AOMMAX(cpi->oxcf.algo_cfg.arnr_max_frames, 1);
int num_before = 0; // Number of filtering frames before the to-filter frame.
int num_after = 0; // Number of filtering frames after the to-filer frame.
const int lookahead_depth =
@@ -1054,9 +1054,10 @@
// Set showable frame.
if (filter_frame_lookahead_idx >= 0) {
- cpi->common.showable_frame =
- num_frames_for_filtering == 1 || is_second_arf ||
- (cpi->oxcf.enable_overlay == 0 || cpi->sf.hl_sf.disable_overlay_frames);
+ cpi->common.showable_frame = num_frames_for_filtering == 1 ||
+ is_second_arf ||
+ (cpi->oxcf.algo_cfg.enable_overlay == 0 ||
+ cpi->sf.hl_sf.disable_overlay_frames);
}
// Do filtering.