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) {