summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vp9/encoder/vp9_firstpass.c121
1 files changed, 87 insertions, 34 deletions
diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c
index b76687d7f..788952d34 100644
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -1679,6 +1679,7 @@ static void accumulate_frame_motion_stats(const FIRSTPASS_STATS *stats,
#define BASELINE_ERR_PER_MB 1000.0
static double calc_frame_boost(VP9_COMP *cpi, const FIRSTPASS_STATS *this_frame,
+ double *sr_accumulator,
double this_frame_mv_in_out, double max_boost) {
double frame_boost;
const double lq = vp9_convert_qindex_to_q(
@@ -1692,7 +1693,13 @@ static double calc_frame_boost(VP9_COMP *cpi, const FIRSTPASS_STATS *this_frame,
// Underlying boost factor is based on inter error ratio.
frame_boost = (BASELINE_ERR_PER_MB * num_mbs) /
- DOUBLE_DIVIDE_CHECK(this_frame->coded_error);
+ DOUBLE_DIVIDE_CHECK(this_frame->coded_error + *sr_accumulator);
+
+ // 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.
+ *sr_accumulator += (this_frame->sr_coded_error - this_frame->coded_error) / 1;
+ *sr_accumulator = VPXMAX(0.0, *sr_accumulator);
// Small adjustment for cases where there is a zoom out
if (this_frame_mv_in_out > 0.0)
@@ -1704,6 +1711,42 @@ static double calc_frame_boost(VP9_COMP *cpi, const FIRSTPASS_STATS *this_frame,
return VPXMIN(frame_boost, max_boost * boost_q_correction);
}
+#define KF_BOOST_FACTOR 12.5
+static double calc_kf_frame_boost(VP9_COMP *cpi,
+ const FIRSTPASS_STATS *this_frame,
+ double *sr_accumulator,
+ double this_frame_mv_in_out,
+ double max_boost) {
+ double frame_boost;
+ const double lq = vp9_convert_qindex_to_q(
+ cpi->rc.avg_frame_qindex[INTER_FRAME], cpi->common.bit_depth);
+ const double boost_q_correction = VPXMIN((0.50 + (lq * 0.015)), 2.00);
+ int num_mbs = (cpi->oxcf.resize_mode != RESIZE_NONE) ? cpi->initial_mbs
+ : cpi->common.MBs;
+
+ // Correct for any inactive region in the image
+ num_mbs = (int)VPXMAX(1, num_mbs * calculate_active_area(cpi, this_frame));
+
+ // Underlying boost factor is based on inter error ratio.
+ frame_boost = (BASELINE_ERR_PER_MB * num_mbs) /
+ DOUBLE_DIVIDE_CHECK(this_frame->coded_error + *sr_accumulator);
+
+ // 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.
+ *sr_accumulator += (this_frame->sr_coded_error - this_frame->coded_error) / 1;
+ *sr_accumulator = VPXMAX(0.0, *sr_accumulator);
+
+ // Small adjustment for cases where there is a zoom out
+ if (this_frame_mv_in_out > 0.0)
+ frame_boost += frame_boost * (this_frame_mv_in_out * 2.0);
+
+ // Q correction and scalling
+ frame_boost = frame_boost * KF_BOOST_FACTOR * boost_q_correction;
+
+ return VPXMIN(frame_boost, max_boost * boost_q_correction);
+}
+
static int calc_arf_boost(VP9_COMP *cpi, int offset, int f_frames, int b_frames,
int *f_boost, int *b_boost) {
TWO_PASS *const twopass = &cpi->twopass;
@@ -1714,6 +1757,7 @@ static int calc_arf_boost(VP9_COMP *cpi, int offset, int f_frames, int b_frames,
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;
int arf_boost;
int flash_detected = 0;
@@ -1740,9 +1784,10 @@ static int calc_arf_boost(VP9_COMP *cpi, int offset, int f_frames, int b_frames,
: decay_accumulator;
}
- boost_score +=
- decay_accumulator *
- calc_frame_boost(cpi, this_frame, this_frame_mv_in_out, GF_MAX_BOOST);
+ sr_accumulator = 0.0;
+ boost_score += decay_accumulator *
+ calc_frame_boost(cpi, this_frame, &sr_accumulator,
+ this_frame_mv_in_out, GF_MAX_BOOST);
}
*f_boost = (int)boost_score;
@@ -1754,6 +1799,7 @@ static int calc_arf_boost(VP9_COMP *cpi, int offset, int f_frames, int b_frames,
this_frame_mv_in_out = 0.0;
mv_in_out_accumulator = 0.0;
abs_mv_in_out_accumulator = 0.0;
+ sr_accumulator = 0.0;
// Search backward towards last gf position.
for (i = -1; i >= -b_frames; --i) {
@@ -1778,9 +1824,10 @@ static int calc_arf_boost(VP9_COMP *cpi, int offset, int f_frames, int b_frames,
: decay_accumulator;
}
- boost_score +=
- decay_accumulator *
- calc_frame_boost(cpi, this_frame, this_frame_mv_in_out, GF_MAX_BOOST);
+ sr_accumulator = 0.0;
+ boost_score += decay_accumulator *
+ calc_frame_boost(cpi, this_frame, &sr_accumulator,
+ this_frame_mv_in_out, GF_MAX_BOOST);
}
*b_boost = (int)boost_score;
@@ -2080,7 +2127,6 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
double mv_ratio_accumulator = 0.0;
double decay_accumulator = 1.0;
double zero_motion_accumulator = 1.0;
-
double loop_decay_rate = 1.00;
double last_loop_decay_rate = 1.00;
@@ -2090,6 +2136,7 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
double mv_ratio_accumulator_thresh;
double mv_in_out_thresh;
double abs_mv_in_out_thresh;
+ double sr_accumulator = 0.0;
unsigned int allow_alt_ref = is_altref_enabled(cpi);
int f_boost = 0;
@@ -2216,9 +2263,10 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
}
// Calculate a boost number for this frame.
- boost_score +=
- decay_accumulator *
- calc_frame_boost(cpi, &next_frame, this_frame_mv_in_out, GF_MAX_BOOST);
+ sr_accumulator = 0.0;
+ boost_score += decay_accumulator *
+ calc_frame_boost(cpi, &next_frame, &sr_accumulator,
+ this_frame_mv_in_out, GF_MAX_BOOST);
// Break out conditions.
if (
@@ -2468,9 +2516,10 @@ static int test_candidate_kf(TWO_PASS *twopass,
}
#define FRAMES_TO_CHECK_DECAY 8
-#define KF_MAX_FRAME_BOOST 128.0
+#define KF_MAX_FRAME_BOOST 96.0
#define MIN_KF_TOT_BOOST 300
-#define MAX_KF_TOT_BOOST 4800
+#define MAX_KF_TOT_BOOST 5400
+#define KF_BOOST_SCAN_MAX_FRAMES 32
static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
int i, j;
@@ -2483,13 +2532,13 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
FIRSTPASS_STATS next_frame;
FIRSTPASS_STATS last_frame;
int kf_bits = 0;
- int loop_decay_counter = 0;
double decay_accumulator = 1.0;
double zero_motion_accumulator = 1.0;
double boost_score = 0.0;
double kf_mod_err = 0.0;
double kf_group_err = 0.0;
double recent_loop_decay[FRAMES_TO_CHECK_DECAY];
+ double sr_accumulator = 0.0;
vp9_zero(next_frame);
@@ -2639,30 +2688,34 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
// Scan through the kf group collating various stats used to determine
// how many bits to spend on it.
- decay_accumulator = 1.0;
boost_score = 0.0;
+
for (i = 0; i < (rc->frames_to_key - 1); ++i) {
if (EOF == input_stats(twopass, &next_frame)) break;
- // Monitor for static sections.
- zero_motion_accumulator = VPXMIN(zero_motion_accumulator,
- get_zero_motion_factor(cpi, &next_frame));
-
- // Not all frames in the group are necessarily used in calculating boost.
- if ((i <= rc->max_gf_interval) ||
- ((i <= (rc->max_gf_interval * 4)) && (decay_accumulator > 0.5))) {
- const double frame_boost =
- calc_frame_boost(cpi, &next_frame, 0, KF_MAX_FRAME_BOOST);
-
- // How fast is prediction quality decaying.
- if (!detect_flash(twopass, 0)) {
- const double loop_decay_rate =
- get_prediction_decay_rate(cpi, &next_frame);
- decay_accumulator *= loop_decay_rate;
- decay_accumulator = VPXMAX(decay_accumulator, MIN_DECAY_FACTOR);
- ++loop_decay_counter;
- }
- boost_score += (decay_accumulator * frame_boost);
+ if (i <= KF_BOOST_SCAN_MAX_FRAMES) {
+ double frame_boost;
+ double zm_factor;
+
+ // Monitor for static sections.
+ zero_motion_accumulator = VPXMIN(
+ zero_motion_accumulator, get_zero_motion_factor(cpi, &next_frame));
+
+ // Factor 0.75-1.25 based on how much of frame is static.
+ zm_factor = (0.75 + (zero_motion_accumulator / 2.0));
+
+ // The second (lagging) ref error is not valid immediately after
+ // a key frame because either the lag has not built up (in the case of
+ // the first key frame or it points to a refernce before the new key
+ // frame.
+ if (i < 2) sr_accumulator = 0.0;
+ frame_boost = calc_kf_frame_boost(cpi, &next_frame, &sr_accumulator, 0,
+ KF_MAX_FRAME_BOOST * zm_factor);
+
+ boost_score += frame_boost;
+ if (frame_boost < 25.00) break;
+ } else {
+ break;
}
}