Refactor: get_active_best_quality Refactor the code to get active_best_quality in a function. Reorder if/else branches to help improve reading. Shorter a long function. Reduces some code redundency. Change-Id: I4357896d66f09b86ea850c30283c9871b36ca6f3
diff --git a/av1/encoder/ratectrl.c b/av1/encoder/ratectrl.c index 7f96b24..15b51b9 100644 --- a/av1/encoder/ratectrl.c +++ b/av1/encoder/ratectrl.c
@@ -1263,6 +1263,93 @@ *q_out = q; } +// Returns |active_best_quality| for an inter frame. +// The |active_best_quality| depends on different rate control modes: +// VBR, Q, CQ, CBR. +// The returning active_best_quality could further be adjusted in +// postprocess_q_and_bounds(). +// TODO(chengchen): consider consolidate the logic here, so that +// |active_best_quality| and |active_worst_quality| are constant after this +// function call. +static int get_active_best_quality(const AV1_COMP *const cpi, + const int active_worst_quality, + const int cq_level, const int gf_index, + int *arf_q) { + const AV1_COMMON *const cm = &cpi->common; + const int bit_depth = cm->seq_params.bit_depth; + const RATE_CONTROL *const rc = &cpi->rc; + const AV1EncoderConfig *const oxcf = &cpi->oxcf; + const GF_GROUP *gf_group = &cpi->gf_group; + const int rc_mode = oxcf->rc_mode; + int *inter_minq; + ASSIGN_MINQ_TABLE(bit_depth, inter_minq); + int active_best_quality = 0; + const int is_intrl_arf_boost = + gf_group->update_type[gf_index] == INTNL_ARF_UPDATE; + const int is_leaf_frame = !(cpi->refresh_golden_frame || + cpi->refresh_alt_ref_frame || is_intrl_arf_boost); + const int is_overlay_frame = rc->is_src_frame_alt_ref; + + if (is_leaf_frame || is_overlay_frame) { + if (rc_mode == AOM_Q) return cq_level; + + active_best_quality = inter_minq[active_worst_quality]; + // For the constrained quality mode we don't want + // q to fall below the cq level. + if ((rc_mode == AOM_CQ) && (active_best_quality < cq_level)) { + active_best_quality = cq_level; + } + return active_best_quality; + } + + if (rc_mode == AOM_Q && !cpi->refresh_alt_ref_frame && !is_intrl_arf_boost) { + return cq_level; + } + + // Determine active_best_quality for frames that are not leaf or overlay. + int q = active_worst_quality; + // Use the lower of active_worst_quality and recent + // average Q as basis for GF/ARF best Q limit unless last frame was + // a key frame. + if (rc->frames_since_key > 1 && + rc->avg_frame_qindex[INTER_FRAME] < active_worst_quality) { + q = rc->avg_frame_qindex[INTER_FRAME]; + } + if (rc_mode == AOM_CQ && q < cq_level) q = cq_level; + active_best_quality = get_gf_active_quality(rc, q, bit_depth); + // Constrained quality use slightly lower active best. + if (rc_mode == AOM_CQ) active_best_quality = active_best_quality * 15 / 16; + const int min_boost = get_gf_high_motion_quality(q, bit_depth); + const int boost = min_boost - active_best_quality; + active_best_quality = min_boost - (int)(boost * rc->arf_boost_factor); + if (rc_mode == AOM_VBR || rc_mode == AOM_CBR) { + if (is_intrl_arf_boost) { + int this_height = gf_group_pyramid_level(gf_group, gf_index); + while (this_height > 1) { + active_best_quality = + (active_best_quality + active_worst_quality + 1) / 2; + --this_height; + } + } + return active_best_quality; + } + + // AOM_Q and AOM_CQ mode. + if (gf_group->update_type[gf_index] == ARF_UPDATE) { + *arf_q = active_best_quality; + } else if (is_intrl_arf_boost) { + assert(rc->arf_q >= 0); // Ensure it is set to a valid value. + active_best_quality = rc->arf_q; + int this_height = gf_group_pyramid_level(gf_group, gf_index); + while (this_height > 1) { + active_best_quality = + (active_best_quality + active_worst_quality + 1) / 2; + --this_height; + } + } + return active_best_quality; +} + static int rc_pick_q_and_bounds_two_pass(const AV1_COMP *cpi, int width, int height, int gf_index, int *bottom_index, int *top_index, @@ -1276,9 +1363,6 @@ int active_best_quality = 0; int active_worst_quality = rc->active_worst_quality; int q; - int *inter_minq; - const int bit_depth = cm->seq_params.bit_depth; - ASSIGN_MINQ_TABLE(bit_depth, inter_minq); const int is_intrl_arf_boost = gf_group->update_type[gf_index] == INTNL_ARF_UPDATE; @@ -1289,93 +1373,9 @@ get_intra_q_and_bounds_two_pass(cpi, width, height, &active_best_quality, &active_worst_quality, arf_q, cq_level, is_fwd_kf); - } else if (!rc->is_src_frame_alt_ref && - (cpi->refresh_golden_frame || is_intrl_arf_boost || - cpi->refresh_alt_ref_frame)) { - // Use the lower of active_worst_quality and recent - // average Q as basis for GF/ARF best Q limit unless last frame was - // a key frame. - if (rc->frames_since_key > 1 && - rc->avg_frame_qindex[INTER_FRAME] < active_worst_quality) { - q = rc->avg_frame_qindex[INTER_FRAME]; - } else { - q = active_worst_quality; - } - // For constrained quality dont allow Q less than the cq level - if (oxcf->rc_mode == AOM_CQ) { - if (q < cq_level) q = cq_level; - - active_best_quality = get_gf_active_quality(rc, q, bit_depth); - - // Constrained quality use slightly lower active best. - active_best_quality = active_best_quality * 15 / 16; - - if (gf_group->update_type[gf_index] == ARF_UPDATE) { - const int min_boost = get_gf_high_motion_quality(q, bit_depth); - const int boost = min_boost - active_best_quality; - - active_best_quality = min_boost - (int)(boost * rc->arf_boost_factor); - *arf_q = active_best_quality; - } else if (is_intrl_arf_boost) { - assert(rc->arf_q >= 0); // Ensure it is set to a valid value. - active_best_quality = rc->arf_q; - int this_height = gf_group_pyramid_level(gf_group, gf_index); - while (this_height > 1) { - active_best_quality = - (active_best_quality + active_worst_quality + 1) / 2; - --this_height; - } - } - } else if (oxcf->rc_mode == AOM_Q) { - if (!cpi->refresh_alt_ref_frame && !is_intrl_arf_boost) { - active_best_quality = cq_level; - } else { - if (gf_group->update_type[gf_index] == ARF_UPDATE) { - active_best_quality = get_gf_active_quality(rc, q, bit_depth); - const int min_boost = get_gf_high_motion_quality(q, bit_depth); - const int boost = min_boost - active_best_quality; - - active_best_quality = min_boost - (int)(boost * rc->arf_boost_factor); - *arf_q = active_best_quality; - } else { - assert(rc->arf_q >= 0); // Ensure it is set to a valid value. - assert(is_intrl_arf_boost); - active_best_quality = rc->arf_q; - int this_height = gf_group_pyramid_level(gf_group, gf_index); - while (this_height > 1) { - active_best_quality = - (active_best_quality + active_worst_quality + 1) / 2; - --this_height; - } - } - } - } else { - active_best_quality = get_gf_active_quality(rc, q, bit_depth); - const int min_boost = get_gf_high_motion_quality(q, bit_depth); - const int boost = min_boost - active_best_quality; - - active_best_quality = min_boost - (int)(boost * rc->arf_boost_factor); - if (is_intrl_arf_boost) { - int this_height = gf_group_pyramid_level(gf_group, gf_index); - while (this_height > 1) { - active_best_quality = - (active_best_quality + active_worst_quality + 1) / 2; - --this_height; - } - } - } } else { - if (oxcf->rc_mode == AOM_Q) { - active_best_quality = cq_level; - } else { - active_best_quality = inter_minq[active_worst_quality]; - - // For the constrained quality mode we don't want - // q to fall below the cq level. - if ((oxcf->rc_mode == AOM_CQ) && (active_best_quality < cq_level)) { - active_best_quality = cq_level; - } - } + active_best_quality = get_active_best_quality(cpi, active_worst_quality, + cq_level, gf_index, arf_q); } postprocess_q_and_bounds(cpi, width, height, &active_worst_quality,