From a1af335f448923e2f9edadb7c02c549f06306256 Mon Sep 17 00:00:00 2001 From: paulwilkins Date: Fri, 19 May 2017 15:08:15 +0100 Subject: [PATCH] Further refactoring of mod error calculation. Further refactoring to support alternative error distributions. Change-Id: I0f7fa3fd6f3baa4b0a1e53c6aa3be63966e97b82 --- vp9/encoder/vp9_firstpass.c | 55 ++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c index b6e327548..4344c2afc 100644 --- a/vp9/encoder/vp9_firstpass.c +++ b/vp9/encoder/vp9_firstpass.c @@ -235,16 +235,21 @@ static double calculate_active_area(const VP9_COMP *cpi, return fclamp(active_pct, MIN_ACTIVE_AREA, MAX_ACTIVE_AREA); } +// Get the average weighted error for the clip (or corpus) +static double get_distribution_av_err(TWO_PASS *const twopass) { + const double av_weight = + twopass->total_stats.weight / twopass->total_stats.count; + return (twopass->total_stats.coded_error * av_weight) / + twopass->total_stats.count; +} + // Calculate a modified Error used in distributing bits between easier and // harder frames. #define ACT_AREA_CORRECTION 0.5 static double calculate_mod_frame_score(const VP9_COMP *cpi, - const TWO_PASS *twopass, const VP9EncoderConfig *oxcf, - const FIRSTPASS_STATS *this_frame) { - const FIRSTPASS_STATS *const stats = &twopass->total_stats; - const double av_weight = stats->weight / stats->count; - const double av_err = (stats->coded_error * av_weight) / stats->count; + const FIRSTPASS_STATS *this_frame, + const double av_err) { double modified_score = av_err * pow(this_frame->coded_error * this_frame->weight / DOUBLE_DIVIDE_CHECK(av_err), @@ -263,10 +268,8 @@ static double calculate_mod_frame_score(const VP9_COMP *cpi, static double calculate_norm_frame_score(const VP9_COMP *cpi, const TWO_PASS *twopass, const VP9EncoderConfig *oxcf, - const FIRSTPASS_STATS *this_frame) { - const FIRSTPASS_STATS *const stats = &twopass->total_stats; - const double av_weight = stats->weight / stats->count; - const double av_err = (stats->coded_error * av_weight) / stats->count; + const FIRSTPASS_STATS *this_frame, + const double av_err) { double modified_score = av_err * pow(this_frame->coded_error * this_frame->weight / DOUBLE_DIVIDE_CHECK(av_err), @@ -1713,12 +1716,13 @@ void vp9_init_second_pass(VP9_COMP *cpi) { // to provide a linear basis for bit allocation. I.e a frame A with a score // that is double that of frame B will be allocated 2x as many bits. { - const FIRSTPASS_STATS *s = twopass->stats_in; double modified_score_total = 0.0; + const FIRSTPASS_STATS *s = twopass->stats_in; + const double av_err = get_distribution_av_err(twopass); // The first scan is unclamped and gives a raw average. while (s < twopass->stats_in_end) { - modified_score_total += calculate_mod_frame_score(cpi, twopass, oxcf, s); + modified_score_total += calculate_mod_frame_score(cpi, oxcf, s, av_err); ++s; } @@ -1730,10 +1734,11 @@ void vp9_init_second_pass(VP9_COMP *cpi) { // Second scan using clamps based on the previous cycle average. // This may modify the total and average somewhat but we dont bother with // further itterations. - s = twopass->stats_in; modified_score_total = 0.0; + s = twopass->stats_in; while (s < twopass->stats_in_end) { - modified_score_total += calculate_norm_frame_score(cpi, twopass, oxcf, s); + modified_score_total += + calculate_norm_frame_score(cpi, twopass, oxcf, s, av_err); ++s; } twopass->normalized_score_left = modified_score_total; @@ -2350,6 +2355,7 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { double mv_in_out_thresh; double abs_mv_in_out_thresh; double sr_accumulator = 0.0; + const double av_err = get_distribution_av_err(twopass); unsigned int allow_alt_ref = is_altref_enabled(cpi); int f_boost = 0; @@ -2372,7 +2378,8 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { vp9_zero(next_frame); // Load stats for the current frame. - mod_frame_err = calculate_norm_frame_score(cpi, twopass, oxcf, this_frame); + mod_frame_err = + calculate_norm_frame_score(cpi, twopass, oxcf, this_frame, av_err); // Note the error of the frame at the start of the group. This will be // the GF frame error if we code a normal gf. @@ -2438,7 +2445,8 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { ++i; // Accumulate error score of frames in this gf group. - mod_frame_err = calculate_norm_frame_score(cpi, twopass, oxcf, this_frame); + mod_frame_err = + calculate_norm_frame_score(cpi, twopass, oxcf, this_frame, av_err); gf_group_err += mod_frame_err; gf_group_raw_error += this_frame->coded_error; gf_group_noise += this_frame->frame_noise_energy; @@ -2548,7 +2556,7 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { for (j = 0; j < new_gf_interval - rc->baseline_gf_interval; ++j) { if (EOF == input_stats(twopass, this_frame)) break; gf_group_err += - calculate_norm_frame_score(cpi, twopass, oxcf, this_frame); + calculate_norm_frame_score(cpi, twopass, oxcf, this_frame, av_err); gf_group_raw_error += this_frame->coded_error; gf_group_noise += this_frame->frame_noise_energy; gf_group_skip_pct += this_frame->intra_skip_pct; @@ -2769,7 +2777,7 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { double kf_group_err = 0.0; double recent_loop_decay[FRAMES_TO_CHECK_DECAY]; double sr_accumulator = 0.0; - + const double av_err = get_distribution_av_err(twopass); vp9_zero(next_frame); cpi->common.frame_type = KEY_FRAME; @@ -2793,7 +2801,8 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { twopass->kf_group_bits = 0; // Total bits available to kf group twopass->kf_group_error_left = 0.0; // Group modified error score. - kf_mod_err = calculate_norm_frame_score(cpi, twopass, oxcf, this_frame); + kf_mod_err = + calculate_norm_frame_score(cpi, twopass, oxcf, this_frame, av_err); // Initialize the decay rates for the recent frames to check for (j = 0; j < FRAMES_TO_CHECK_DECAY; ++j) recent_loop_decay[j] = 1.0; @@ -2803,7 +2812,8 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { while (twopass->stats_in < twopass->stats_in_end && rc->frames_to_key < cpi->oxcf.key_freq) { // Accumulate kf group error. - kf_group_err += calculate_norm_frame_score(cpi, twopass, oxcf, this_frame); + kf_group_err += + calculate_norm_frame_score(cpi, twopass, oxcf, this_frame, av_err); // Load the next frame's stats. last_frame = *this_frame; @@ -2864,7 +2874,7 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { // Rescan to get the correct error data for the forced kf group. for (i = 0; i < rc->frames_to_key; ++i) { kf_group_err += - calculate_norm_frame_score(cpi, twopass, oxcf, &tmp_frame); + calculate_norm_frame_score(cpi, twopass, oxcf, &tmp_frame, av_err); input_stats(twopass, &tmp_frame); } rc->next_key_frame_forced = 1; @@ -2882,7 +2892,7 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { for (j = 0; j < new_frame_to_key - rc->frames_to_key; ++j) { if (EOF == input_stats(twopass, this_frame)) break; kf_group_err += - calculate_norm_frame_score(cpi, twopass, oxcf, this_frame); + calculate_norm_frame_score(cpi, twopass, oxcf, this_frame, av_err); } rc->frames_to_key = new_frame_to_key; } @@ -2890,7 +2900,8 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { // Special case for the last key frame of the file. if (twopass->stats_in >= twopass->stats_in_end) { // Accumulate kf group error. - kf_group_err += calculate_norm_frame_score(cpi, twopass, oxcf, this_frame); + kf_group_err += + calculate_norm_frame_score(cpi, twopass, oxcf, this_frame, av_err); } // Calculate the number of bits that should be assigned to the kf group. -- 2.40.0