ref: a263098e3ba6053c8325cce83f3362ab2bb55073
parent: 19f3b9c2ca64eb69c828def40b017f3eac9606cd
author: angiebird <angiebird@google.com>
date: Mon Oct 21 15:13:51 EDT 2019
Add get_frames_to_next_key() Change-Id: I0d1709562bf96648fbaf2a0dce2dc23b9d2b81f1
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -3037,8 +3037,68 @@
#define MAX_KF_TOT_BOOST 5400
#endif
+static int get_frames_to_next_key(const VP9EncoderConfig *oxcf,
+ const FRAME_INFO *frame_info,
+ const FIRST_PASS_INFO *first_pass_info,
+ int kf_show_idx, int min_gf_interval) {
+ double recent_loop_decay[FRAMES_TO_CHECK_DECAY];
+ int j;
+ int frames_to_key;
+ int max_frames_to_key = first_pass_info->num_frames - kf_show_idx;
+ max_frames_to_key = VPXMIN(max_frames_to_key, oxcf->key_freq);
+
+ // 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;
+ // Find the next keyframe.
+ if (!oxcf->auto_key) {
+ frames_to_key = max_frames_to_key;
+ } else {
+ frames_to_key = 1;
+ while (frames_to_key < max_frames_to_key) {
+ // Provided that we are not at the end of the file...
+ if (kf_show_idx + frames_to_key + 1 < first_pass_info->num_frames) {
+ double loop_decay_rate;
+ double decay_accumulator;
+ const FIRSTPASS_STATS *next_frame = fps_get_frame_stats(
+ first_pass_info, kf_show_idx + frames_to_key + 1);
+
+ // Check for a scene cut.
+ if (test_candidate_kf(first_pass_info, kf_show_idx + frames_to_key))
+ break;
+
+ // How fast is the prediction quality decaying?
+ loop_decay_rate = get_prediction_decay_rate(frame_info, next_frame);
+
+ // We want to know something about the recent past... rather than
+ // as used elsewhere where we are concerned with decay in prediction
+ // quality since the last GF or KF.
+ recent_loop_decay[(frames_to_key - 1) % FRAMES_TO_CHECK_DECAY] =
+ loop_decay_rate;
+ decay_accumulator = 1.0;
+ for (j = 0; j < FRAMES_TO_CHECK_DECAY; ++j)
+ decay_accumulator *= recent_loop_decay[j];
+
+ // Special check for transition or high motion followed by a
+ // static scene.
+ if ((frames_to_key - 1) > min_gf_interval && loop_decay_rate >= 0.999 &&
+ decay_accumulator < 0.9) {
+ int still_interval = oxcf->key_freq - (frames_to_key - 1);
+ // TODO(angiebird): Figure out why we use "+1" here
+ int show_idx = kf_show_idx + frames_to_key;
+ if (check_transition_to_still(first_pass_info, show_idx,
+ still_interval)) {
+ break;
+ }
+ }
+ }
+ ++frames_to_key;
+ }
+ }
+ return frames_to_key;
+}
+
static void find_next_key_frame(VP9_COMP *cpi, int kf_show_idx) {
- int i, j;
+ int i;
RATE_CONTROL *const rc = &cpi->rc;
TWO_PASS *const twopass = &cpi->twopass;
GF_GROUP *const gf_group = &twopass->gf_group;
@@ -3051,7 +3111,6 @@
FIRSTPASS_STATS next_frame;
int kf_bits = 0;
int64_t max_kf_bits;
- double decay_accumulator = 1.0;
double zero_motion_accumulator = 1.0;
double zero_motion_sum = 0.0;
double zero_motion_avg;
@@ -3063,7 +3122,6 @@
double kf_mod_err = 0.0;
double kf_raw_err = 0.0;
double kf_group_err = 0.0;
- double recent_loop_decay[FRAMES_TO_CHECK_DECAY];
double sr_accumulator = 0.0;
double abs_mv_in_out_accumulator = 0.0;
const double av_err = get_distribution_av_err(cpi, twopass);
@@ -3095,60 +3153,8 @@
kf_mod_err = calc_norm_frame_score(oxcf, frame_info, keyframe_stats,
mean_mod_score, 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;
-
- {
- int frames_to_key;
- int max_frames_to_key = first_pass_info->num_frames - kf_show_idx;
- max_frames_to_key = VPXMIN(max_frames_to_key, oxcf->key_freq);
- // Find the next keyframe.
- if (!oxcf->auto_key) {
- frames_to_key = max_frames_to_key;
- } else {
- frames_to_key = 1;
- while (frames_to_key < max_frames_to_key) {
- // Provided that we are not at the end of the file...
- if (kf_show_idx + frames_to_key + 1 < first_pass_info->num_frames) {
- double loop_decay_rate;
- const FIRSTPASS_STATS *next_frame = fps_get_frame_stats(
- first_pass_info, kf_show_idx + frames_to_key + 1);
-
- // Check for a scene cut.
- if (test_candidate_kf(first_pass_info, kf_show_idx + frames_to_key))
- break;
-
- // How fast is the prediction quality decaying?
- loop_decay_rate =
- get_prediction_decay_rate(&cpi->frame_info, next_frame);
-
- // We want to know something about the recent past... rather than
- // as used elsewhere where we are concerned with decay in prediction
- // quality since the last GF or KF.
- recent_loop_decay[(frames_to_key - 1) % FRAMES_TO_CHECK_DECAY] =
- loop_decay_rate;
- decay_accumulator = 1.0;
- for (j = 0; j < FRAMES_TO_CHECK_DECAY; ++j)
- decay_accumulator *= recent_loop_decay[j];
-
- // Special check for transition or high motion followed by a
- // static scene.
- if ((frames_to_key - 1) > rc->min_gf_interval &&
- loop_decay_rate >= 0.999 && decay_accumulator < 0.9) {
- int still_interval = oxcf->key_freq - (frames_to_key - 1);
- // TODO(angiebird): Figure out why we use "+1" here
- int show_idx = kf_show_idx + frames_to_key;
- if (check_transition_to_still(first_pass_info, show_idx,
- still_interval)) {
- break;
- }
- }
- }
- ++frames_to_key;
- }
- }
- rc->frames_to_key = frames_to_key;
- }
+ rc->frames_to_key = get_frames_to_next_key(oxcf, frame_info, first_pass_info,
+ kf_show_idx, rc->min_gf_interval);
// If there is a max kf interval set by the user we must obey it.
// We already breakout of the loop above at 2x max.