ref: 454877d8748fdbaa3d4e9bcd4994355d50dd6c6d
parent: 2be0ee5f05b3dc0782626b8b10894d5d920bcb96
parent: ab7974d36df5c548c8f3549545d12f42e2b274ce
author: Angie Chiang <angiebird@google.com>
date: Fri Oct 18 15:19:06 EDT 2019
Merge changes I2acc7d6b,I560dccfc,I3fb23f5c,Ifa24a501 * changes: Rename num_show_frames by num_coding_frames Use compute_arf_boost() in define_gf_group() Localize av_err mean_mod_score in define_gf_group Move code of deciding gop size into brackets
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -2496,21 +2496,10 @@
double gf_group_inter = 0.0;
double gf_group_motion = 0.0;
- double mv_ratio_accumulator = 0.0;
double zero_motion_accumulator = 1.0;
- double loop_decay_rate = 1.00;
- double this_frame_mv_in_out = 0.0;
- double mv_in_out_accumulator = 0.0;
- double abs_mv_in_out_accumulator = 0.0;
- double mv_ratio_accumulator_thresh;
- double abs_mv_in_out_thresh;
- double sr_accumulator = 0.0;
- const double av_err = get_distribution_av_err(cpi, twopass);
- const double mean_mod_score = twopass->mean_mod_score;
unsigned int allow_alt_ref = is_altref_enabled(cpi);
- int flash_detected;
int active_max_gf_interval;
int active_min_gf_interval;
int64_t gf_group_bits;
@@ -2532,11 +2521,6 @@
vpx_clear_system_state();
- // Motion breakout threshold for loop below depends on image size.
- mv_ratio_accumulator_thresh =
- (cpi->initial_height + cpi->initial_width) / 4.0;
- abs_mv_in_out_thresh = ARF_ABS_ZOOM_THRESH;
-
// Set a maximum and minimum interval for the GF group.
// If the image appears almost completely static we can extend beyond this.
{
@@ -2590,88 +2574,102 @@
}
i = 0;
- while (i < rc->static_scene_max_gf_interval && i < rc->frames_to_key) {
- const FIRSTPASS_STATS *next_next_frame;
- const FIRSTPASS_STATS *next_frame;
- ++i;
+ {
+ double loop_decay_rate = 1.00;
+ double mv_ratio_accumulator = 0.0;
+ double this_frame_mv_in_out = 0.0;
+ double mv_in_out_accumulator = 0.0;
+ double abs_mv_in_out_accumulator = 0.0;
+ double sr_accumulator = 0.0;
+ // Motion breakout threshold for loop below depends on image size.
+ double mv_ratio_accumulator_thresh =
+ (cpi->initial_height + cpi->initial_width) / 4.0;
- next_frame = fps_get_frame_stats(first_pass_info, gf_start_show_idx + i);
- if (next_frame == NULL) {
- break;
- }
+ while (i < rc->static_scene_max_gf_interval && i < rc->frames_to_key) {
+ const FIRSTPASS_STATS *next_next_frame;
+ const FIRSTPASS_STATS *next_frame;
+ int flash_detected;
+ ++i;
- // Test for the case where there is a brief flash but the prediction
- // quality back to an earlier frame is then restored.
- next_next_frame =
- fps_get_frame_stats(first_pass_info, gf_start_show_idx + i + 1);
- flash_detected = detect_flash_from_frame_stats(next_next_frame);
+ next_frame = fps_get_frame_stats(first_pass_info, gf_start_show_idx + i);
+ if (next_frame == NULL) {
+ break;
+ }
- // Update the motion related elements to the boost calculation.
- accumulate_frame_motion_stats(
- next_frame, &this_frame_mv_in_out, &mv_in_out_accumulator,
- &abs_mv_in_out_accumulator, &mv_ratio_accumulator);
+ // Test for the case where there is a brief flash but the prediction
+ // quality back to an earlier frame is then restored.
+ next_next_frame =
+ fps_get_frame_stats(first_pass_info, gf_start_show_idx + i + 1);
+ flash_detected = detect_flash_from_frame_stats(next_next_frame);
- // Monitor for static sections.
- if ((rc->frames_since_key + i - 1) > 1) {
- zero_motion_accumulator =
- VPXMIN(zero_motion_accumulator,
- get_zero_motion_factor(frame_info, next_frame));
- }
+ // Update the motion related elements to the boost calculation.
+ accumulate_frame_motion_stats(
+ next_frame, &this_frame_mv_in_out, &mv_in_out_accumulator,
+ &abs_mv_in_out_accumulator, &mv_ratio_accumulator);
- // Accumulate the effect of prediction quality decay.
- if (!flash_detected) {
- double last_loop_decay_rate = loop_decay_rate;
- loop_decay_rate = get_prediction_decay_rate(frame_info, next_frame);
+ // Monitor for static sections.
+ if ((rc->frames_since_key + i - 1) > 1) {
+ zero_motion_accumulator =
+ VPXMIN(zero_motion_accumulator,
+ get_zero_motion_factor(frame_info, next_frame));
+ }
- // Break clause to detect very still sections after motion. For example,
- // a static image after a fade or other transition.
- if (i > rc->min_gf_interval && loop_decay_rate >= 0.999 &&
- last_loop_decay_rate < 0.9) {
- int still_interval = 5;
- if (check_transition_to_still(first_pass_info, gf_start_show_idx + i,
- still_interval)) {
- allow_alt_ref = 0;
- break;
+ // Accumulate the effect of prediction quality decay.
+ if (!flash_detected) {
+ double last_loop_decay_rate = loop_decay_rate;
+ loop_decay_rate = get_prediction_decay_rate(frame_info, next_frame);
+
+ // Break clause to detect very still sections after motion. For example,
+ // a static image after a fade or other transition.
+ if (i > rc->min_gf_interval && loop_decay_rate >= 0.999 &&
+ last_loop_decay_rate < 0.9) {
+ int still_interval = 5;
+ if (check_transition_to_still(first_pass_info, gf_start_show_idx + i,
+ still_interval)) {
+ allow_alt_ref = 0;
+ break;
+ }
}
+
+ // Update the accumulator for second ref error difference.
+ // This is intended to give an indication of how much the coded error is
+ // increasing over time.
+ if (i == 1) {
+ sr_accumulator += next_frame->coded_error;
+ } else {
+ sr_accumulator +=
+ (next_frame->sr_coded_error - next_frame->coded_error);
+ }
}
- // Update the accumulator for second ref error difference.
- // This is intended to give an indication of how much the coded error is
- // increasing over time.
- if (i == 1) {
- sr_accumulator += next_frame->coded_error;
- } else {
- sr_accumulator +=
- (next_frame->sr_coded_error - next_frame->coded_error);
+ // Break out conditions.
+ // Break at maximum of active_max_gf_interval unless almost totally
+ // static.
+ //
+ // Note that the addition of a test of rc->source_alt_ref_active is
+ // deliberate. The effect of this is that after a normal altref group even
+ // if the material is static there will be one normal length GF group
+ // before allowing longer GF groups. The reason for this is that in cases
+ // such as slide shows where slides are separated by a complex transition
+ // such as a fade, the arf group spanning the transition may not be coded
+ // at a very high quality and hence this frame (with its overlay) is a
+ // poor golden frame to use for an extended group.
+ if ((i >= active_max_gf_interval) &&
+ ((zero_motion_accumulator < 0.995) || (rc->source_alt_ref_active))) {
+ break;
}
+ if (
+ // Don't break out with a very short interval.
+ (i >= active_min_gf_interval) &&
+ // If possible dont break very close to a kf
+ ((rc->frames_to_key - i) >= rc->min_gf_interval) && (i & 0x01) &&
+ (!flash_detected) &&
+ ((mv_ratio_accumulator > mv_ratio_accumulator_thresh) ||
+ (abs_mv_in_out_accumulator > ARF_ABS_ZOOM_THRESH) ||
+ (sr_accumulator > gop_intra_factor * next_frame->intra_error))) {
+ break;
+ }
}
-
- // Break out conditions.
- // Break at maximum of active_max_gf_interval unless almost totally static.
- //
- // Note that the addition of a test of rc->source_alt_ref_active is
- // deliberate. The effect of this is that after a normal altref group even
- // if the material is static there will be one normal length GF group
- // before allowing longer GF groups. The reason for this is that in cases
- // such as slide shows where slides are separated by a complex transition
- // such as a fade, the arf group spanning the transition may not be coded
- // at a very high quality and hence this frame (with its overlay) is a
- // poor golden frame to use for an extended group.
- if ((i >= active_max_gf_interval) &&
- ((zero_motion_accumulator < 0.995) || (rc->source_alt_ref_active))) {
- break;
- }
- if (
- // Don't break out with a very short interval.
- (i >= active_min_gf_interval) &&
- // If possible dont break very close to a kf
- ((rc->frames_to_key - i) >= rc->min_gf_interval) && (i & 0x01) &&
- (!flash_detected) &&
- ((mv_ratio_accumulator > mv_ratio_accumulator_thresh) ||
- (abs_mv_in_out_accumulator > abs_mv_in_out_thresh) ||
- (sr_accumulator > gop_intra_factor * next_frame->intra_error))) {
- break;
- }
}
// Was the group length constrained by the requirement for a new KF?
@@ -2696,8 +2694,16 @@
b_frames, avg_inter_frame_qindex);
rc->source_alt_ref_pending = 1;
} else {
- reset_fpf_position(twopass, start_pos);
- rc->gfu_boost = VPXMIN(MAX_GF_BOOST, calc_arf_boost(cpi, (i - 1), 0));
+ const int f_frames = i - 1;
+ const int b_frames = 0;
+ const int avg_inter_frame_qindex = rc->avg_frame_qindex[INTER_FRAME];
+ // TODO(angiebird): figure out why arf's location is assigned this way
+ const int gld_show_idx =
+ VPXMIN(gf_start_show_idx + 1, fps_get_num_frames(first_pass_info));
+ const int arf_boost =
+ compute_arf_boost(frame_info, first_pass_info, gld_show_idx, f_frames,
+ b_frames, avg_inter_frame_qindex);
+ rc->gfu_boost = VPXMIN(MAX_GF_BOOST, arf_boost);
rc->source_alt_ref_pending = 0;
}
@@ -2742,18 +2748,17 @@
rc->baseline_gf_interval = i - rc->source_alt_ref_pending;
- // Reset the file position.
- reset_fpf_position(twopass, start_pos);
-
if (rc->source_alt_ref_pending)
is_alt_ref_flash = detect_flash(twopass, rc->baseline_gf_interval);
{
+ const double av_err = get_distribution_av_err(cpi, twopass);
+ const double mean_mod_score = twopass->mean_mod_score;
// If the first frame is a key frame or the overlay from a previous arf then
// the error score / cost of this frame has already been accounted for.
int start_idx = arf_active_or_kf ? 1 : 0;
- int num_show_frames = i;
- for (j = start_idx; j < num_show_frames; ++j) {
+ int num_coding_frames = i;
+ for (j = start_idx; j < num_coding_frames; ++j) {
int show_idx = gf_start_show_idx + j;
const FIRSTPASS_STATS *frame_stats =
fps_get_frame_stats(first_pass_info, show_idx);