From 9f57bc4d6c7a577538042a49ede8ee98dc8cc300 Mon Sep 17 00:00:00 2001 From: Paul Wilkins Date: Mon, 26 Apr 2021 15:06:54 +0100 Subject: [PATCH] Add limits to Vizier input parameters. Imposed provisional upper and lower limits to each parameter that can be adjusted in the Vizier ML experiment. Also in some cases applied secondary limits on on the range of the final "used" values. Defaults and limits may well require further tuning after subsequent rounds of experimentation. Re-factor get_sr_decay_rate(). Change-Id: I28e804ce3d3710f30cd51a203348e4ab23ef06c0 --- vp9/encoder/vp9_firstpass.c | 41 +++++++++++-------- vp9/vp9_cx_iface.c | 79 ++++++++++++++++++++++++++++++++++++- 2 files changed, 103 insertions(+), 17 deletions(-) diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c index a4717ad03..ce7590fe4 100644 --- a/vp9/encoder/vp9_firstpass.c +++ b/vp9/encoder/vp9_firstpass.c @@ -1832,33 +1832,35 @@ void vp9_init_second_pass(VP9_COMP *cpi) { } /* This function considers how the quality of prediction may be deteriorating - * with distance. It comapres the coded error for the last frame and the + * with distance. It compares the coded error for the last frame and the * second reference frame (usually two frames old) and also applies a factor * based on the extent of INTRA coding. * * The decay factor is then used to reduce the contribution of frames further - * from the alt-ref or golden frame, to the bitframe boost calculation for that + * from the alt-ref or golden frame, to the bitrate boost calculation for that * alt-ref or golden frame. */ static double get_sr_decay_rate(const TWO_PASS *const twopass, const FIRSTPASS_STATS *frame) { double sr_diff = (frame->sr_coded_error - frame->coded_error); double sr_decay = 1.0; - double modified_pct_inter; - double modified_pcnt_intra; - - modified_pct_inter = frame->pcnt_inter; - if ((frame->coded_error > LOW_CODED_ERR_PER_MB) && - ((frame->intra_error / DOUBLE_DIVIDE_CHECK(frame->coded_error)) < - (double)NCOUNT_FRAME_II_THRESH)) { - modified_pct_inter = - frame->pcnt_inter + frame->pcnt_intra_low - frame->pcnt_neutral; - } - modified_pcnt_intra = 100 * (1.0 - modified_pct_inter); + // Do nothing if the second ref to last frame error difference is + // very small or even negative. if ((sr_diff > LOW_SR_DIFF_TRHESH)) { - double sr_diff_part = + const double sr_diff_part = twopass->sr_diff_factor * ((sr_diff * 0.25) / frame->intra_error); + double modified_pct_inter = frame->pcnt_inter; + double modified_pcnt_intra; + + if ((frame->coded_error > LOW_CODED_ERR_PER_MB) && + ((frame->intra_error / DOUBLE_DIVIDE_CHECK(frame->coded_error)) < + (double)NCOUNT_FRAME_II_THRESH)) { + modified_pct_inter = + frame->pcnt_inter + frame->pcnt_intra_low - frame->pcnt_neutral; + } + modified_pcnt_intra = 100 * (1.0 - modified_pct_inter); + sr_decay = 1.0 - sr_diff_part - (INTRA_PART * modified_pcnt_intra); } return VPXMAX(sr_decay, twopass->sr_default_decay_limit); @@ -1979,7 +1981,7 @@ static double calc_frame_boost(const FRAME_INFO *frame_info, const double boost_q_correction = VPXMIN((0.5 + (lq * 0.015)), 1.5); const double active_area = calculate_active_area(frame_info, this_frame); - // Underlying boost factor is based on inter error ratio. + // Frame booost is based on inter error. frame_boost = (twopass->err_per_mb * active_area) / DOUBLE_DIVIDE_CHECK(this_frame->coded_error); @@ -2007,7 +2009,7 @@ static double calc_kf_frame_boost(VP9_COMP *cpi, calculate_active_area(&cpi->frame_info, this_frame); double max_boost; - // Underlying boost factor is based on inter error ratio. + // Frame booost is based on inter error. frame_boost = (twopass->kf_err_per_mb * active_area) / DOUBLE_DIVIDE_CHECK(this_frame->coded_error + *sr_accumulator); @@ -3499,14 +3501,21 @@ static void init_vizier_params(TWO_PASS *const twopass, int screen_area) { twopass->active_wq_factor *= AV_WQ_FACTOR; twopass->err_per_mb *= BASELINE_ERR_PER_MB; twopass->sr_default_decay_limit *= DEFAULT_DECAY_LIMIT; + if (twopass->sr_default_decay_limit > 1.0) // > 1.0 here makes no sense + twopass->sr_default_decay_limit = 1.0; twopass->sr_diff_factor *= 1.0; twopass->gf_frame_max_boost *= GF_MAX_FRAME_BOOST; twopass->gf_max_total_boost *= MAX_GF_BOOST; + // NOTE: In use max boost has precedence over min boost. So even if min is + // somehow set higher than max the final boost value will be clamped to the + // appropriate maximum. twopass->kf_frame_min_boost *= KF_MIN_FRAME_BOOST; twopass->kf_frame_max_boost_first *= KF_MAX_FRAME_BOOST; twopass->kf_frame_max_boost_subs *= KF_MAX_FRAME_BOOST; twopass->kf_max_total_boost *= MAX_KF_TOT_BOOST; twopass->zm_factor *= DEFAULT_ZM_FACTOR; + if (twopass->zm_factor > 1.0) // > 1.0 here makes no sense + twopass->zm_factor = 1.0; // Correction for the fact that the kf_err_per_mb_factor default is // already different for different video formats and ensures that a passed diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c index c700620ef..438f9b5ed 100644 --- a/vp9/vp9_cx_iface.c +++ b/vp9/vp9_cx_iface.c @@ -664,41 +664,118 @@ static vpx_codec_err_t set_twopass_params_from_config( cpi->twopass.use_vizier_rc_params = cfg->use_vizier_rc_params; // The values set here are factors that will be applied to default values - // to get the final value used in the two pass code. 1.0 will hence + // to get the final value used in the two pass code. Hence 1.0 will // match the default behaviour when not using passed in values. + // We also apply limits here to prevent the user from applying settings + // that make no sense. cpi->twopass.active_wq_factor = (double)cfg->active_wq_factor.num / (double)cfg->active_wq_factor.den; + if (cpi->twopass.active_wq_factor < 0.25) + cpi->twopass.active_wq_factor = 0.25; + else if (cpi->twopass.active_wq_factor > 16.0) + cpi->twopass.active_wq_factor = 16.0; + cpi->twopass.err_per_mb = (double)cfg->err_per_mb_factor.num / (double)cfg->err_per_mb_factor.den; + if (cpi->twopass.err_per_mb < 0.25) + cpi->twopass.err_per_mb = 0.25; + else if (cpi->twopass.err_per_mb > 4.0) + cpi->twopass.err_per_mb = 4.0; + cpi->twopass.sr_default_decay_limit = (double)cfg->sr_default_decay_limit.num / (double)cfg->sr_default_decay_limit.den; + if (cpi->twopass.sr_default_decay_limit < 0.25) + cpi->twopass.sr_default_decay_limit = 0.25; + // If the default changes this will need to change. + else if (cpi->twopass.sr_default_decay_limit > 1.33) + cpi->twopass.sr_default_decay_limit = 1.33; + cpi->twopass.sr_diff_factor = (double)cfg->sr_diff_factor.num / (double)cfg->sr_diff_factor.den; + if (cpi->twopass.sr_diff_factor < 0.25) + cpi->twopass.sr_diff_factor = 0.25; + else if (cpi->twopass.sr_diff_factor > 4.0) + cpi->twopass.sr_diff_factor = 4.0; + cpi->twopass.kf_err_per_mb = (double)cfg->kf_err_per_mb_factor.num / (double)cfg->kf_err_per_mb_factor.den; + if (cpi->twopass.kf_err_per_mb < 0.25) + cpi->twopass.kf_err_per_mb = 0.25; + else if (cpi->twopass.kf_err_per_mb > 4.0) + cpi->twopass.kf_err_per_mb = 4.0; + cpi->twopass.kf_frame_min_boost = (double)cfg->kf_frame_min_boost_factor.num / (double)cfg->kf_frame_min_boost_factor.den; + if (cpi->twopass.kf_frame_min_boost < 0.25) + cpi->twopass.kf_frame_min_boost = 0.25; + else if (cpi->twopass.kf_frame_min_boost > 4.0) + cpi->twopass.kf_frame_min_boost = 4.0; + cpi->twopass.kf_frame_max_boost_first = (double)cfg->kf_frame_max_boost_first_factor.num / (double)cfg->kf_frame_max_boost_first_factor.den; + if (cpi->twopass.kf_frame_max_boost_first < 0.25) + cpi->twopass.kf_frame_max_boost_first = 0.25; + else if (cpi->twopass.kf_frame_max_boost_first > 4.0) + cpi->twopass.kf_frame_max_boost_first = 4.0; + cpi->twopass.kf_frame_max_boost_subs = (double)cfg->kf_frame_max_boost_subs_factor.num / (double)cfg->kf_frame_max_boost_subs_factor.den; + if (cpi->twopass.kf_frame_max_boost_subs < 0.25) + cpi->twopass.kf_frame_max_boost_subs = 0.25; + else if (cpi->twopass.kf_frame_max_boost_subs > 4.0) + cpi->twopass.kf_frame_max_boost_subs = 4.0; + cpi->twopass.kf_max_total_boost = (double)cfg->kf_max_total_boost_factor.num / (double)cfg->kf_max_total_boost_factor.den; + if (cpi->twopass.kf_max_total_boost < 0.25) + cpi->twopass.kf_max_total_boost = 0.25; + else if (cpi->twopass.kf_max_total_boost > 4.0) + cpi->twopass.kf_max_total_boost = 4.0; + cpi->twopass.gf_max_total_boost = (double)cfg->gf_max_total_boost_factor.num / (double)cfg->gf_max_total_boost_factor.den; + if (cpi->twopass.gf_max_total_boost < 0.25) + cpi->twopass.gf_max_total_boost = 0.25; + else if (cpi->twopass.gf_max_total_boost > 4.0) + cpi->twopass.gf_max_total_boost = 4.0; + cpi->twopass.gf_frame_max_boost = (double)cfg->gf_frame_max_boost_factor.num / (double)cfg->gf_frame_max_boost_factor.den; + if (cpi->twopass.gf_frame_max_boost < 0.25) + cpi->twopass.gf_frame_max_boost = 0.25; + else if (cpi->twopass.gf_frame_max_boost > 4.0) + cpi->twopass.gf_frame_max_boost = 4.0; + cpi->twopass.zm_factor = (double)cfg->zm_factor.num / (double)cfg->zm_factor.den; + if (cpi->twopass.zm_factor < 0.25) + cpi->twopass.zm_factor = 0.25; + else if (cpi->twopass.zm_factor > 2.0) + cpi->twopass.zm_factor = 2.0; + cpi->rd_ctrl.rd_mult_inter_qp_fac = (double)cfg->rd_mult_inter_qp_fac.num / (double)cfg->rd_mult_inter_qp_fac.den; + if (cpi->rd_ctrl.rd_mult_inter_qp_fac < 0.25) + cpi->rd_ctrl.rd_mult_inter_qp_fac = 0.25; + else if (cpi->rd_ctrl.rd_mult_inter_qp_fac > 4.0) + cpi->rd_ctrl.rd_mult_inter_qp_fac = 4.0; + cpi->rd_ctrl.rd_mult_arf_qp_fac = (double)cfg->rd_mult_arf_qp_fac.num / (double)cfg->rd_mult_arf_qp_fac.den; + if (cpi->rd_ctrl.rd_mult_arf_qp_fac < 0.25) + cpi->rd_ctrl.rd_mult_arf_qp_fac = 0.25; + else if (cpi->rd_ctrl.rd_mult_arf_qp_fac > 4.0) + cpi->rd_ctrl.rd_mult_arf_qp_fac = 4.0; + cpi->rd_ctrl.rd_mult_key_qp_fac = (double)cfg->rd_mult_key_qp_fac.num / (double)cfg->rd_mult_key_qp_fac.den; + if (cpi->rd_ctrl.rd_mult_key_qp_fac < 0.25) + cpi->rd_ctrl.rd_mult_key_qp_fac = 0.25; + else if (cpi->rd_ctrl.rd_mult_key_qp_fac > 4.0) + cpi->rd_ctrl.rd_mult_key_qp_fac = 4.0; return VPX_CODEC_OK; } -- 2.40.0