Facilitation for VBR using LAP - Modify KF and GF group bits. In case of single pass VBR using LAP, calculate kf_group_bits and gf_group_bits based on average frame bandwidth. Change-Id: Ia1c59b2a8dd888444ee7c927e586c453d65b597f
diff --git a/av1/encoder/pass2_strategy.c b/av1/encoder/pass2_strategy.c index 6adc1fb..0c73e99 100644 --- a/av1/encoder/pass2_strategy.c +++ b/av1/encoder/pass2_strategy.c
@@ -704,6 +704,11 @@ const int max_bits = frame_max_bits(rc, &cpi->oxcf); int64_t total_group_bits; + if (cpi->lap_enabled) { + total_group_bits = rc->avg_frame_bandwidth * rc->baseline_gf_interval; + return total_group_bits; + } + // Calculate the bits to be allocated to the group as a whole. if ((twopass->kf_group_bits > 0) && (twopass->kf_group_error_left > 0)) { total_group_bits = (int64_t)(twopass->kf_group_bits * @@ -2157,6 +2162,19 @@ return frames_to_key; } +static int64_t get_kf_group_bits(AV1_COMP *cpi, double kf_group_err) { + RATE_CONTROL *const rc = &cpi->rc; + TWO_PASS *const twopass = &cpi->twopass; + int64_t kf_group_bits; + if (cpi->lap_enabled) + kf_group_bits = (int64_t)(rc->frames_to_key * rc->avg_frame_bandwidth); + else + kf_group_bits = (int64_t)(twopass->bits_left * + (kf_group_err / twopass->modified_error_left)); + + return kf_group_bits; +} + static void find_next_key_frame(AV1_COMP *cpi, FIRSTPASS_STATS *this_frame) { RATE_CONTROL *const rc = &cpi->rc; TWO_PASS *const twopass = &cpi->twopass; @@ -2263,7 +2281,8 @@ } // Calculate the number of bits that should be assigned to the kf group. - if (twopass->bits_left > 0 && twopass->modified_error_left > 0.0) { + if ((twopass->bits_left > 0 && twopass->modified_error_left > 0.0) || + (cpi->lap_enabled && cpi->oxcf.rc_mode != AOM_Q)) { // Maximum number of bits for a single normal frame (not key frame). const int max_bits = frame_max_bits(rc, &cpi->oxcf); @@ -2272,9 +2291,7 @@ // Default allocation based on bits left and relative // complexity of the section. - twopass->kf_group_bits = (int64_t)( - twopass->bits_left * (kf_group_err / twopass->modified_error_left)); - + twopass->kf_group_bits = get_kf_group_bits(cpi, kf_group_err); // Clip based on maximum per frame rate defined by the user. max_grp_bits = (int64_t)max_bits * (int64_t)rc->frames_to_key; if (twopass->kf_group_bits > max_grp_bits) @@ -2402,6 +2419,21 @@ #endif #define DEFAULT_GRP_WEIGHT 1.0 +static int get_section_target_bandwidth(AV1_COMP *cpi) { + AV1_COMMON *const cm = &cpi->common; + CurrentFrame *const current_frame = &cm->current_frame; + RATE_CONTROL *const rc = &cpi->rc; + TWO_PASS *const twopass = &cpi->twopass; + int section_target_bandwidth; + const int frames_left = (int)(twopass->stats_buf_ctx->total_stats->count - + current_frame->frame_number); + if (cpi->lap_enabled) + section_target_bandwidth = (int)rc->avg_frame_bandwidth; + else + section_target_bandwidth = (int)(twopass->bits_left / frames_left); + return section_target_bandwidth; +} + static void process_first_pass_stats(AV1_COMP *cpi, FIRSTPASS_STATS *this_frame) { AV1_COMMON *const cm = &cpi->common; @@ -2420,12 +2452,8 @@ *cpi->twopass.stats_buf_ctx->total_left_stats = *cpi->twopass.stats_buf_ctx->total_stats; } - const int frames_left = (int)(twopass->stats_buf_ctx->total_stats->count - - current_frame->frame_number); - // Special case code for first frame. - const int section_target_bandwidth = - (int)(twopass->bits_left / frames_left); + const int section_target_bandwidth = get_section_target_bandwidth(cpi); const double section_length = twopass->stats_buf_ctx->total_left_stats->count; const double section_error =
diff --git a/av1/encoder/speed_features.c b/av1/encoder/speed_features.c index 4a69840..e6d25f3 100644 --- a/av1/encoder/speed_features.c +++ b/av1/encoder/speed_features.c
@@ -1213,7 +1213,8 @@ sf->rd_sf.optimize_coefficients = NO_TRELLIS_OPT; // No recode or trellis for 1 pass. - if (oxcf->pass == 0) sf->hl_sf.recode_loop = DISALLOW_RECODE; + if (oxcf->pass == 0 && has_no_stats_stage(cpi)) + sf->hl_sf.recode_loop = DISALLOW_RECODE; MotionVectorSearchParams *const mv_search_params = &cpi->mv_search_params; if (sf->mv_sf.subpel_search_method == SUBPEL_TREE) {