Commit da01c0dc authored by Debargha Mukherjee's avatar Debargha Mukherjee

Port first pass stats handling from Vp9 into Av1

Some parameter tuning included.

lowres (q, 30 frames, speed 1):
-1.243% av PSNR, -2.337% ov PSNR, +0.577% SSIM

lowres (vbr, 30 frames, speed 1):
-0.327% av PSNR, -1.007% ov PSNR, +0.182% SSIM

A few videos become a lot worse in SSIM, which needs to be
investigated. But PSNR-wise the patch seems pretty good.

Change-Id: I17c8d812c96ee49ddae7d3959a459aa3ffcea208
parent f8daa92d
This diff is collapsed.
......@@ -72,11 +72,15 @@ typedef struct {
double intra_error;
double coded_error;
double sr_coded_error;
double frame_noise_energy;
double pcnt_inter;
double pcnt_motion;
double pcnt_second_ref;
double pcnt_neutral;
double pcnt_intra_low; // Coded intra but low variance
double pcnt_intra_high; // Coded intra high variance
double intra_skip_pct;
double intra_smooth_pct; // % of blocks that are smooth
double inactive_zone_rows; // Image mask rows top and bottom.
double inactive_zone_cols; // Image mask columns at left and right edges.
double MVr;
......@@ -139,10 +143,10 @@ typedef struct {
FIRSTPASS_STATS total_left_stats;
int first_pass_done;
int64_t bits_left;
double modified_error_min;
double modified_error_max;
double modified_error_left;
double normalized_score_left;
double mean_mod_score;
double mb_av_energy;
double mb_smooth_pct;
#if CONFIG_FP_MB_STATS
uint8_t *frame_mb_stats_buf;
......@@ -156,21 +160,25 @@ typedef struct {
int64_t kf_group_bits;
// Error score of frames still to be coded in kf group
int64_t kf_group_error_left;
double kf_group_error_left;
// The fraction for a kf groups total bits allocated to the inter frames
double kfgroup_inter_fraction;
double bpm_factor;
int rolling_arf_group_target_bits;
int rolling_arf_group_actual_bits;
int sr_update_lag;
int kf_zeromotion_pct;
int last_kfgroup_zeromotion_pct;
int gf_zeromotion_pct;
int active_worst_quality;
int baseline_active_worst_quality;
int extend_minq;
int extend_maxq;
int extend_minq_fast;
int arnr_strength_adjustment;
GF_GROUP gf_group;
} TWO_PASS;
......
......@@ -121,7 +121,7 @@ static void init_minq_luts(int *kf_low_m, int *kf_high_m, int *arfgf_low,
kf_high_m[i] = get_minq_index(maxq, 0.0000021, -0.00125, 0.55, bit_depth);
arfgf_low[i] = get_minq_index(maxq, 0.0000015, -0.0009, 0.30, bit_depth);
arfgf_high[i] = get_minq_index(maxq, 0.0000021, -0.00125, 0.55, bit_depth);
inter[i] = get_minq_index(maxq, 0.00000271, -0.00113, 0.90, bit_depth);
inter[i] = get_minq_index(maxq, 0.00000271, -0.00113, 0.70, bit_depth);
rtc[i] = get_minq_index(maxq, 0.00000271, -0.00113, 0.70, bit_depth);
}
}
......@@ -178,17 +178,19 @@ int av1_estimate_bits_at_q(FRAME_TYPE frame_type, int q, int mbs,
int av1_rc_clamp_pframe_target_size(const AV1_COMP *const cpi, int target) {
const RATE_CONTROL *rc = &cpi->rc;
const AV1EncoderConfig *oxcf = &cpi->oxcf;
const int min_frame_target =
AOMMAX(rc->min_frame_bandwidth, rc->avg_frame_bandwidth >> 5);
// Clip the frame target to the minimum setup value.
if (cpi->rc.is_src_frame_alt_ref) {
// If there is an active ARF at this location use the minimum
// bits on this frame even if it is a constructed arf.
// The active maximum quantizer insures that an appropriate
// number of bits will be spent if needed for constructed ARFs.
target = min_frame_target;
} else if (target < min_frame_target) {
target = min_frame_target;
if (cpi->oxcf.pass != 2) {
const int min_frame_target =
AOMMAX(rc->min_frame_bandwidth, rc->avg_frame_bandwidth >> 5);
if (target < min_frame_target) target = min_frame_target;
if (cpi->refresh_golden_frame && rc->is_src_frame_alt_ref) {
// If there is an active ARF at this location use the minimum
// bits on this frame even if it is a constructed arf.
// The active maximum quantizer insures that an appropriate
// number of bits will be spent if needed for
// constructed ARFs.
target = min_frame_target;
}
}
// Clip the frame target to the maximum allowed value.
......@@ -450,6 +452,11 @@ void av1_rc_update_rate_correction_factors(AV1_COMP *cpi, int width,
else
cpi->rc.rc_1_frame = 0;
if (cpi->rc.rc_1_frame == -1 && cpi->rc.rc_2_frame == 1 &&
correction_factor > 1000) {
cpi->rc.rc_2_frame = 0;
}
if (correction_factor > 102) {
// We are not already at the worst allowable quality
correction_factor =
......@@ -1028,8 +1035,7 @@ static int rc_pick_q_and_bounds_two_pass(const AV1_COMP *cpi, int width,
// Extension to max or min Q if undershoot or overshoot is outside
// the permitted range.
if ((cpi->oxcf.rc_mode != AOM_Q) &&
(cpi->twopass.gf_zeromotion_pct < VLOW_MOTION_THRESHOLD)) {
if (cpi->oxcf.rc_mode != AOM_Q) {
if (frame_is_intra_only(cm) ||
(!rc->is_src_frame_alt_ref &&
(cpi->refresh_golden_frame || cpi->refresh_alt2_ref_frame ||
......
......@@ -538,7 +538,16 @@ static void adjust_arnr_filter(AV1_COMP *cpi, int distance, int group_boost,
av1_lookahead_depth(cpi->lookahead) - distance - 1;
int frames_fwd = (cpi->oxcf.arnr_max_frames - 1) >> 1;
int frames_bwd;
int q, frames, strength;
int q, frames, base_strength, strength;
// Context dependent two pass adjustment to strength.
if (oxcf->pass == 2) {
base_strength = oxcf->arnr_strength + cpi->twopass.arnr_strength_adjustment;
// Clip to allowed range.
base_strength = AOMMIN(6, AOMMAX(0, base_strength));
} else {
base_strength = oxcf->arnr_strength;
}
// Define the forward and backwards filter limits for this arnr group.
if (frames_fwd > frames_after_arf) frames_fwd = frames_after_arf;
......@@ -560,10 +569,11 @@ static void adjust_arnr_filter(AV1_COMP *cpi, int distance, int group_boost,
else
q = ((int)av1_convert_qindex_to_q(cpi->rc.avg_frame_qindex[KEY_FRAME],
cpi->common.bit_depth));
if (q > 16) {
strength = oxcf->arnr_strength;
strength = base_strength;
} else {
strength = oxcf->arnr_strength - ((16 - q) / 2);
strength = base_strength - ((16 - q) / 2);
if (strength < 0) strength = 0;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment