Add 3 new rate control variables and frame debug stats.
This patch adds 3 rate control variables for future use and also
some code to output frame level debug stats. The latter is under
a compile time #if and is disabled by default.
Change-Id: I78c804d39e128502920538e9436439181c8e3e2a
diff --git a/av1/encoder/firstpass.h b/av1/encoder/firstpass.h
index dc401d2..4a3a2f9 100644
--- a/av1/encoder/firstpass.h
+++ b/av1/encoder/firstpass.h
@@ -162,6 +162,13 @@
// The fraction for a kf groups total bits allocated to the inter frames
double kfgroup_inter_fraction;
+ // Over time correction for bits per macro block estimation
+ double bpm_factor;
+
+ // Record of target and actual bits spent in current ARF group
+ int rolling_arf_group_target_bits;
+ int rolling_arf_group_actual_bits;
+
int sr_update_lag;
int kf_zeromotion_pct;
diff --git a/av1/encoder/pass2_strategy.c b/av1/encoder/pass2_strategy.c
index 47a1f23..bd3a29a 100644
--- a/av1/encoder/pass2_strategy.c
+++ b/av1/encoder/pass2_strategy.c
@@ -164,12 +164,24 @@
// Similar to find_qindex_by_rate() function in ratectrl.c, but includes
// calculation of a correction_factor.
static int find_qindex_by_rate_with_correction(
- int desired_bits_per_mb, aom_bit_depth_t bit_depth, FRAME_TYPE frame_type,
- double error_per_mb, double ediv_size_correction,
+ AV1_COMP *cpi, int desired_bits_per_mb, aom_bit_depth_t bit_depth,
+ FRAME_TYPE frame_type, double error_per_mb, double ediv_size_correction,
double group_weight_factor, int best_qindex, int worst_qindex) {
assert(best_qindex <= worst_qindex);
int low = best_qindex;
int high = worst_qindex;
+
+ TWO_PASS *twopass = &cpi->twopass;
+ double last_group_rate_err;
+
+ // Based on recent history adjust expectations of bits per macroblock.
+ last_group_rate_err =
+ (double)twopass->rolling_arf_group_actual_bits /
+ DOUBLE_DIVIDE_CHECK((double)twopass->rolling_arf_group_target_bits);
+ last_group_rate_err = AOMMAX(0.25, AOMMIN(4.0, last_group_rate_err));
+ twopass->bpm_factor *= (3.0 + last_group_rate_err) / 4.0;
+ twopass->bpm_factor = AOMMAX(0.25, AOMMIN(4.0, twopass->bpm_factor));
+
while (low < high) {
const int mid = (low + high) >> 1;
const double mid_factor =
@@ -195,8 +207,7 @@
return low;
}
-static int get_twopass_worst_quality(const AV1_COMP *cpi,
- const double section_err,
+static int get_twopass_worst_quality(AV1_COMP *cpi, const double section_err,
double inactive_zone,
int section_target_bandwidth,
double group_weight_factor) {
@@ -231,8 +242,8 @@
// Try and pick a max Q that will be high enough to encode the
// content at the given rate.
int q = find_qindex_by_rate_with_correction(
- target_norm_bits_per_mb, cpi->common.seq_params.bit_depth, INTER_FRAME,
- av_err_per_mb, ediv_size_correction, group_weight_factor,
+ cpi, target_norm_bits_per_mb, cpi->common.seq_params.bit_depth,
+ INTER_FRAME, av_err_per_mb, ediv_size_correction, group_weight_factor,
rc->best_quality, rc->worst_quality);
// Restriction on active max q for constrained quality mode.
@@ -1253,6 +1264,10 @@
twopass->section_intra_rating = calculate_section_intra_ratio(
start_pos, twopass->stats_in_end, rc->baseline_gf_interval);
}
+
+ // Reset rolling actual and target bits counters for ARF groups.
+ twopass->rolling_arf_group_target_bits = 1;
+ twopass->rolling_arf_group_actual_bits = 1;
}
// Minimum % intra coding observed in first pass (1.0 = 100%)
@@ -1893,6 +1908,13 @@
// Static sequence monitor variables.
twopass->kf_zeromotion_pct = 100;
twopass->last_kfgroup_zeromotion_pct = 100;
+
+ // Initialize bits per macro_block estimate correction factor.
+ twopass->bpm_factor = 1.0;
+ // Initialize actual and target bits counters for ARF groups so that
+ // at the start we have a neutral bpm adjustment.
+ twopass->rolling_arf_group_target_bits = 1;
+ twopass->rolling_arf_group_actual_bits = 1;
}
#define MINQ_ADJ_LIMIT 48
@@ -1911,6 +1933,10 @@
rc->vbr_bits_off_target += rc->base_frame_target - rc->projected_frame_size;
twopass->bits_left = AOMMAX(twopass->bits_left - bits_used, 0);
+ // Target vs actual bits for this arf group.
+ twopass->rolling_arf_group_target_bits += rc->this_frame_target;
+ twopass->rolling_arf_group_actual_bits += rc->projected_frame_size;
+
// Calculate the pct rc error.
if (rc->total_actual_bits) {
rc->rate_error_estimate =
@@ -1920,6 +1946,27 @@
rc->rate_error_estimate = 0;
}
+#if 0
+ {
+ AV1_COMMON *cm = &cpi->common;
+ FILE *fpfile;
+ fpfile = fopen("details.stt", "a");
+ fprintf(fpfile, "%10d %10d %10d %10"PRId64" %10"PRId64" %10d %10d %10d %10.4lf %10.4lf %10.4lf %10.4lf\n",
+ cm->current_frame.frame_number,
+ rc->base_frame_target, rc->projected_frame_size,
+ rc->total_actual_bits, rc->vbr_bits_off_target,
+ rc->rate_error_estimate,
+ twopass->rolling_arf_group_target_bits,
+ twopass->rolling_arf_group_actual_bits,
+ (double)twopass->rolling_arf_group_actual_bits /
+ (double)twopass->rolling_arf_group_target_bits,
+ twopass->bpm_factor,
+ av1_convert_qindex_to_q(cm->base_qindex, cm->seq_params.bit_depth),
+ av1_convert_qindex_to_q(rc->active_worst_quality, cm->seq_params.bit_depth));
+ fclose(fpfile);
+ }
+#endif
+
if (cpi->common.current_frame.frame_type != KEY_FRAME) {
twopass->kf_group_bits -= bits_used;
twopass->last_kfgroup_zeromotion_pct = twopass->kf_zeromotion_pct;