summaryrefslogtreecommitdiff
path: root/vp9/encoder/vp9_firstpass.c
diff options
context:
space:
mode:
Diffstat (limited to 'vp9/encoder/vp9_firstpass.c')
-rw-r--r--vp9/encoder/vp9_firstpass.c419
1 files changed, 201 insertions, 218 deletions
diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c
index 572f8c653..812c13148 100644
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -55,8 +55,6 @@ static void swap_yv12(YV12_BUFFER_CONFIG *a, YV12_BUFFER_CONFIG *b) {
*b = temp;
}
-static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame);
-
static int select_cq_level(int qindex) {
int ret_val = QINDEX_RANGE - 1;
int i;
@@ -924,7 +922,7 @@ static int estimate_max_q(VP9_COMP *cpi,
FIRSTPASS_STATS *fpstats,
int section_target_bandwitdh) {
int q;
- int num_mbs = cpi->common.MBs;
+ const int num_mbs = cpi->common.MBs;
int target_norm_bits_per_mb;
RATE_CONTROL *const rc = &cpi->rc;
@@ -950,9 +948,8 @@ static int estimate_max_q(VP9_COMP *cpi,
}
// Restriction on active max q for constrained quality mode.
- if (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY &&
- q < cpi->cq_target_quality)
- q = cpi->cq_target_quality;
+ if (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY)
+ q = MAX(q, cpi->cq_target_quality);
return q;
}
@@ -1015,6 +1012,7 @@ void vp9_init_second_pass(VP9_COMP *cpi) {
FIRSTPASS_STATS this_frame;
FIRSTPASS_STATS *start_pos;
struct twopass_rc *const twopass = &cpi->twopass;
+ const VP9_CONFIG *const oxcf = &cpi->oxcf;
zero_stats(&twopass->total_stats);
zero_stats(&twopass->total_left_stats);
@@ -1033,9 +1031,9 @@ void vp9_init_second_pass(VP9_COMP *cpi) {
vp9_new_framerate(cpi, 10000000.0 * twopass->total_stats.count /
twopass->total_stats.duration);
- cpi->output_framerate = cpi->oxcf.framerate;
+ cpi->output_framerate = oxcf->framerate;
twopass->bits_left = (int64_t)(twopass->total_stats.duration *
- cpi->oxcf.target_bandwidth / 10000000.0);
+ oxcf->target_bandwidth / 10000000.0);
// Calculate a minimum intra value to be used in determining the IIratio
// scores used in the second pass. We have this minimum to make sure
@@ -1051,15 +1049,12 @@ void vp9_init_second_pass(VP9_COMP *cpi) {
// ratio for the sequence.
{
double sum_iiratio = 0.0;
- double IIRatio;
-
start_pos = twopass->stats_in; // Note the starting "file" position.
while (input_stats(twopass, &this_frame) != EOF) {
- IIRatio = this_frame.intra_error
- / DOUBLE_DIVIDE_CHECK(this_frame.coded_error);
- IIRatio = (IIRatio < 1.0) ? 1.0 : (IIRatio > 20.0) ? 20.0 : IIRatio;
- sum_iiratio += IIRatio;
+ const double iiratio = this_frame.intra_error /
+ DOUBLE_DIVIDE_CHECK(this_frame.coded_error);
+ sum_iiratio += fclamp(iiratio, 1.0, 20.0);
}
twopass->avg_iiratio = sum_iiratio /
@@ -1079,9 +1074,9 @@ void vp9_init_second_pass(VP9_COMP *cpi) {
twopass->modified_error_total = 0.0;
twopass->modified_error_min =
- (av_error * cpi->oxcf.two_pass_vbrmin_section) / 100;
+ (av_error * oxcf->two_pass_vbrmin_section) / 100;
twopass->modified_error_max =
- (av_error * cpi->oxcf.two_pass_vbrmax_section) / 100;
+ (av_error * oxcf->two_pass_vbrmax_section) / 100;
while (input_stats(twopass, &this_frame) != EOF) {
twopass->modified_error_total +=
@@ -1185,9 +1180,6 @@ static void accumulate_frame_motion_stats(
double *mv_in_out_accumulator,
double *abs_mv_in_out_accumulator,
double *mv_ratio_accumulator) {
- // double this_frame_mv_in_out;
- double this_frame_mvr_ratio;
- double this_frame_mvc_ratio;
double motion_pct;
// Accumulate motion stats.
@@ -1202,29 +1194,25 @@ static void accumulate_frame_motion_stats(
// Accumulate a measure of how uniform (or conversely how random)
// the motion field is. (A ratio of absmv / mv)
if (motion_pct > 0.05) {
- this_frame_mvr_ratio = fabs(this_frame->mvr_abs) /
+ double this_frame_mvr_ratio = fabs(this_frame->mvr_abs) /
DOUBLE_DIVIDE_CHECK(fabs(this_frame->MVr));
- this_frame_mvc_ratio = fabs(this_frame->mvc_abs) /
+ double this_frame_mvc_ratio = fabs(this_frame->mvc_abs) /
DOUBLE_DIVIDE_CHECK(fabs(this_frame->MVc));
- *mv_ratio_accumulator +=
- (this_frame_mvr_ratio < this_frame->mvr_abs)
+ *mv_ratio_accumulator += (this_frame_mvr_ratio < this_frame->mvr_abs)
? (this_frame_mvr_ratio * motion_pct)
: this_frame->mvr_abs * motion_pct;
- *mv_ratio_accumulator +=
- (this_frame_mvc_ratio < this_frame->mvc_abs)
+ *mv_ratio_accumulator += (this_frame_mvc_ratio < this_frame->mvc_abs)
? (this_frame_mvc_ratio * motion_pct)
: this_frame->mvc_abs * motion_pct;
}
}
// Calculate a baseline boost number for the current frame.
-static double calc_frame_boost(
- VP9_COMP *cpi,
- FIRSTPASS_STATS *this_frame,
- double this_frame_mv_in_out) {
+static double calc_frame_boost(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame,
+ double this_frame_mv_in_out) {
double frame_boost;
// Underlying boost factor is based on inter intra error ratio
@@ -1245,11 +1233,7 @@ static double calc_frame_boost(
else
frame_boost += frame_boost * (this_frame_mv_in_out / 2.0);
- // Clip to maximum
- if (frame_boost > GF_RMAX)
- frame_boost = GF_RMAX;
-
- return frame_boost;
+ return MIN(frame_boost, GF_RMAX);
}
static int calc_arf_boost(VP9_COMP *cpi, int offset,
@@ -1924,186 +1908,6 @@ static int test_for_kf_one_pass(VP9_COMP *cpi) {
return 0;
}
-void vp9_get_svc_params(VP9_COMP *cpi) {
- VP9_COMMON *const cm = &cpi->common;
- if ((cm->current_video_frame == 0) ||
- (cm->frame_flags & FRAMEFLAGS_KEY) ||
- (cpi->oxcf.auto_key && (cpi->rc.frames_since_key %
- cpi->key_frame_frequency == 0))) {
- cm->frame_type = KEY_FRAME;
- } else {
- cm->frame_type = INTER_FRAME;
- }
- cpi->rc.frames_till_gf_update_due = INT_MAX;
- cpi->rc.baseline_gf_interval = INT_MAX;
-}
-
-void vp9_get_one_pass_params(VP9_COMP *cpi) {
- VP9_COMMON *const cm = &cpi->common;
- if (!cpi->refresh_alt_ref_frame &&
- (cm->current_video_frame == 0 ||
- cm->frame_flags & FRAMEFLAGS_KEY ||
- cpi->rc.frames_to_key == 0 ||
- (cpi->oxcf.auto_key && test_for_kf_one_pass(cpi)))) {
- cm->frame_type = KEY_FRAME;
- cpi->rc.this_key_frame_forced = cm->current_video_frame != 0 &&
- cpi->rc.frames_to_key == 0;
- cpi->rc.frames_to_key = cpi->key_frame_frequency;
- cpi->rc.kf_boost = 300;
- } else {
- cm->frame_type = INTER_FRAME;
- }
- if (cpi->rc.frames_till_gf_update_due == 0) {
- cpi->rc.frames_till_gf_update_due = cpi->rc.baseline_gf_interval;
- cpi->refresh_golden_frame = 1;
- }
-}
-
-void vp9_get_one_pass_cbr_params(VP9_COMP *cpi) {
- VP9_COMMON *const cm = &cpi->common;
- if ((cm->current_video_frame == 0 ||
- cm->frame_flags & FRAMEFLAGS_KEY ||
- cpi->rc.frames_to_key == 0 ||
- (cpi->oxcf.auto_key && test_for_kf_one_pass(cpi)))) {
- cm->frame_type = KEY_FRAME;
- cpi->rc.this_key_frame_forced = cm->current_video_frame != 0 &&
- cpi->rc.frames_to_key == 0;
- cpi->rc.frames_to_key = cpi->key_frame_frequency;
- cpi->rc.kf_boost = 300;
- } else {
- cm->frame_type = INTER_FRAME;
- }
- // Don't use gf_update by default in CBR mode.
- cpi->rc.frames_till_gf_update_due = INT_MAX;
- cpi->rc.baseline_gf_interval = INT_MAX;
-}
-
-void vp9_get_first_pass_params(VP9_COMP *cpi) {
- VP9_COMMON *const cm = &cpi->common;
- if (!cpi->refresh_alt_ref_frame &&
- (cm->current_video_frame == 0 ||
- cm->frame_flags & FRAMEFLAGS_KEY)) {
- cm->frame_type = KEY_FRAME;
- } else {
- cm->frame_type = INTER_FRAME;
- }
- // Do not use periodic key frames
- cpi->rc.frames_to_key = INT_MAX;
-}
-
-void vp9_get_second_pass_params(VP9_COMP *cpi) {
- int tmp_q;
- int frames_left = (int)(cpi->twopass.total_stats.count -
- cpi->common.current_video_frame);
-
- FIRSTPASS_STATS this_frame;
- FIRSTPASS_STATS this_frame_copy;
- RATE_CONTROL *rc = &cpi->rc;
-
- double this_frame_intra_error;
- double this_frame_coded_error;
-
- if (cpi->refresh_alt_ref_frame) {
- cpi->common.frame_type = INTER_FRAME;
- return;
- }
- if (!cpi->twopass.stats_in)
- return;
-
- vp9_clear_system_state();
-
- if (cpi->oxcf.end_usage == USAGE_CONSTANT_QUALITY) {
- rc->active_worst_quality = cpi->oxcf.cq_level;
- } else if (cpi->common.current_video_frame == 0) {
- // Special case code for first frame.
- int section_target_bandwidth =
- (int)(cpi->twopass.bits_left / frames_left);
-
- tmp_q = estimate_max_q(cpi, &cpi->twopass.total_left_stats,
- section_target_bandwidth);
-
- rc->active_worst_quality = tmp_q;
- rc->ni_av_qi = tmp_q;
- rc->avg_q = vp9_convert_qindex_to_q(tmp_q);
-
- // Limit the maxq value returned subsequently.
- // This increases the risk of overspend or underspend if the initial
- // estimate for the clip is bad, but helps prevent excessive
- // variation in Q, especially near the end of a clip
- // where for example a small overspend may cause Q to crash
- // adjust_maxq_qrange(cpi);
- }
- vp9_zero(this_frame);
- if (EOF == input_stats(&cpi->twopass, &this_frame))
- return;
-
- this_frame_intra_error = this_frame.intra_error;
- this_frame_coded_error = this_frame.coded_error;
-
- // keyframe and section processing !
- if (rc->frames_to_key == 0 ||
- (cpi->common.frame_flags & FRAMEFLAGS_KEY)) {
- // Define next KF group and assign bits to it
- this_frame_copy = this_frame;
- find_next_key_frame(cpi, &this_frame_copy);
- } else {
- cpi->common.frame_type = INTER_FRAME;
- }
-
- // Is this a GF / ARF (Note that a KF is always also a GF)
- if (rc->frames_till_gf_update_due == 0) {
- // Define next gf group and assign bits to it
- this_frame_copy = this_frame;
-
-#if CONFIG_MULTIPLE_ARF
- if (cpi->multi_arf_enabled) {
- define_fixed_arf_period(cpi);
- } else {
-#endif
- define_gf_group(cpi, &this_frame_copy);
-#if CONFIG_MULTIPLE_ARF
- }
-#endif
-
- if (cpi->twopass.gf_zeromotion_pct > 995) {
- // As long as max_thresh for encode breakout is small enough, it is ok
- // to enable it for no-show frame, i.e. set enable_encode_breakout to 2.
- if (!cpi->common.show_frame)
- cpi->enable_encode_breakout = 0;
- else
- cpi->enable_encode_breakout = 2;
- }
-
- rc->frames_till_gf_update_due = rc->baseline_gf_interval;
- cpi->refresh_golden_frame = 1;
- } else {
- // Otherwise this is an ordinary frame
- // Assign bits from those allocated to the GF group
- this_frame_copy = this_frame;
- assign_std_frame_bits(cpi, &this_frame_copy);
- }
-
- // Keep a globally available copy of this and the next frame's iiratio.
- cpi->twopass.this_iiratio = (int)(this_frame_intra_error /
- DOUBLE_DIVIDE_CHECK(this_frame_coded_error));
- {
- FIRSTPASS_STATS next_frame;
- if (lookup_next_frame_stats(&cpi->twopass, &next_frame) != EOF) {
- cpi->twopass.next_iiratio = (int)(next_frame.intra_error /
- DOUBLE_DIVIDE_CHECK(next_frame.coded_error));
- }
- }
-
- // Set nominal per second bandwidth for this frame
- cpi->target_bandwidth = (int)(rc->per_frame_bandwidth *
- cpi->output_framerate);
- if (cpi->target_bandwidth < 0)
- cpi->target_bandwidth = 0;
-
- // Update the total stats remaining structure
- subtract_stats(&cpi->twopass.total_left_stats, &this_frame);
-}
-
static int test_candidate_kf(VP9_COMP *cpi,
FIRSTPASS_STATS *last_frame,
FIRSTPASS_STATS *this_frame,
@@ -2134,7 +1938,6 @@ static int test_candidate_kf(VP9_COMP *cpi,
double boost_score = 0.0;
double old_boost_score = 0.0;
double decay_accumulator = 1.0;
- double next_iiratio;
local_next_frame = *next_frame;
@@ -2143,8 +1946,8 @@ static int test_candidate_kf(VP9_COMP *cpi,
// Examine how well the key frame predicts subsequent frames
for (i = 0; i < 16; i++) {
- next_iiratio = (IIKFACTOR1 * local_next_frame.intra_error /
- DOUBLE_DIVIDE_CHECK(local_next_frame.coded_error));
+ double next_iiratio = (IIKFACTOR1 * local_next_frame.intra_error /
+ DOUBLE_DIVIDE_CHECK(local_next_frame.coded_error));
if (next_iiratio > RMAX)
next_iiratio = RMAX;
@@ -2402,7 +2205,7 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
// How fast is prediction quality decaying
if (!detect_flash(cpi, 0)) {
loop_decay_rate = get_prediction_decay_rate(cpi, &next_frame);
- decay_accumulator = decay_accumulator * loop_decay_rate;
+ decay_accumulator *= loop_decay_rate;
decay_accumulator = decay_accumulator < MIN_DECAY_FACTOR
? MIN_DECAY_FACTOR : decay_accumulator;
}
@@ -2523,6 +2326,186 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
twopass->modified_error_left -= kf_group_err;
}
+void vp9_get_svc_params(VP9_COMP *cpi) {
+ VP9_COMMON *const cm = &cpi->common;
+ if ((cm->current_video_frame == 0) ||
+ (cm->frame_flags & FRAMEFLAGS_KEY) ||
+ (cpi->oxcf.auto_key && (cpi->rc.frames_since_key %
+ cpi->key_frame_frequency == 0))) {
+ cm->frame_type = KEY_FRAME;
+ } else {
+ cm->frame_type = INTER_FRAME;
+ }
+ cpi->rc.frames_till_gf_update_due = INT_MAX;
+ cpi->rc.baseline_gf_interval = INT_MAX;
+}
+
+void vp9_get_one_pass_params(VP9_COMP *cpi) {
+ VP9_COMMON *const cm = &cpi->common;
+ if (!cpi->refresh_alt_ref_frame &&
+ (cm->current_video_frame == 0 ||
+ cm->frame_flags & FRAMEFLAGS_KEY ||
+ cpi->rc.frames_to_key == 0 ||
+ (cpi->oxcf.auto_key && test_for_kf_one_pass(cpi)))) {
+ cm->frame_type = KEY_FRAME;
+ cpi->rc.this_key_frame_forced = cm->current_video_frame != 0 &&
+ cpi->rc.frames_to_key == 0;
+ cpi->rc.frames_to_key = cpi->key_frame_frequency;
+ cpi->rc.kf_boost = 300;
+ } else {
+ cm->frame_type = INTER_FRAME;
+ }
+ if (cpi->rc.frames_till_gf_update_due == 0) {
+ cpi->rc.frames_till_gf_update_due = cpi->rc.baseline_gf_interval;
+ cpi->refresh_golden_frame = 1;
+ }
+}
+
+void vp9_get_one_pass_cbr_params(VP9_COMP *cpi) {
+ VP9_COMMON *const cm = &cpi->common;
+ if ((cm->current_video_frame == 0 ||
+ cm->frame_flags & FRAMEFLAGS_KEY ||
+ cpi->rc.frames_to_key == 0 ||
+ (cpi->oxcf.auto_key && test_for_kf_one_pass(cpi)))) {
+ cm->frame_type = KEY_FRAME;
+ cpi->rc.this_key_frame_forced = cm->current_video_frame != 0 &&
+ cpi->rc.frames_to_key == 0;
+ cpi->rc.frames_to_key = cpi->key_frame_frequency;
+ cpi->rc.kf_boost = 300;
+ } else {
+ cm->frame_type = INTER_FRAME;
+ }
+ // Don't use gf_update by default in CBR mode.
+ cpi->rc.frames_till_gf_update_due = INT_MAX;
+ cpi->rc.baseline_gf_interval = INT_MAX;
+}
+
+void vp9_get_first_pass_params(VP9_COMP *cpi) {
+ VP9_COMMON *const cm = &cpi->common;
+ if (!cpi->refresh_alt_ref_frame &&
+ (cm->current_video_frame == 0 ||
+ cm->frame_flags & FRAMEFLAGS_KEY)) {
+ cm->frame_type = KEY_FRAME;
+ } else {
+ cm->frame_type = INTER_FRAME;
+ }
+ // Do not use periodic key frames
+ cpi->rc.frames_to_key = INT_MAX;
+}
+
+void vp9_get_second_pass_params(VP9_COMP *cpi) {
+ int tmp_q;
+ int frames_left = (int)(cpi->twopass.total_stats.count -
+ cpi->common.current_video_frame);
+
+ FIRSTPASS_STATS this_frame;
+ FIRSTPASS_STATS this_frame_copy;
+ RATE_CONTROL *rc = &cpi->rc;
+
+ double this_frame_intra_error;
+ double this_frame_coded_error;
+
+ if (cpi->refresh_alt_ref_frame) {
+ cpi->common.frame_type = INTER_FRAME;
+ return;
+ }
+ if (!cpi->twopass.stats_in)
+ return;
+
+ vp9_clear_system_state();
+
+ if (cpi->oxcf.end_usage == USAGE_CONSTANT_QUALITY) {
+ rc->active_worst_quality = cpi->oxcf.cq_level;
+ } else if (cpi->common.current_video_frame == 0) {
+ // Special case code for first frame.
+ int section_target_bandwidth =
+ (int)(cpi->twopass.bits_left / frames_left);
+
+ tmp_q = estimate_max_q(cpi, &cpi->twopass.total_left_stats,
+ section_target_bandwidth);
+
+ rc->active_worst_quality = tmp_q;
+ rc->ni_av_qi = tmp_q;
+ rc->avg_q = vp9_convert_qindex_to_q(tmp_q);
+
+ // Limit the maxq value returned subsequently.
+ // This increases the risk of overspend or underspend if the initial
+ // estimate for the clip is bad, but helps prevent excessive
+ // variation in Q, especially near the end of a clip
+ // where for example a small overspend may cause Q to crash
+ // adjust_maxq_qrange(cpi);
+ }
+ vp9_zero(this_frame);
+ if (EOF == input_stats(&cpi->twopass, &this_frame))
+ return;
+
+ this_frame_intra_error = this_frame.intra_error;
+ this_frame_coded_error = this_frame.coded_error;
+
+ // keyframe and section processing !
+ if (rc->frames_to_key == 0 ||
+ (cpi->common.frame_flags & FRAMEFLAGS_KEY)) {
+ // Define next KF group and assign bits to it
+ this_frame_copy = this_frame;
+ find_next_key_frame(cpi, &this_frame_copy);
+ } else {
+ cpi->common.frame_type = INTER_FRAME;
+ }
+
+ // Is this a GF / ARF (Note that a KF is always also a GF)
+ if (rc->frames_till_gf_update_due == 0) {
+ // Define next gf group and assign bits to it
+ this_frame_copy = this_frame;
+
+#if CONFIG_MULTIPLE_ARF
+ if (cpi->multi_arf_enabled) {
+ define_fixed_arf_period(cpi);
+ } else {
+#endif
+ define_gf_group(cpi, &this_frame_copy);
+#if CONFIG_MULTIPLE_ARF
+ }
+#endif
+
+ if (cpi->twopass.gf_zeromotion_pct > 995) {
+ // As long as max_thresh for encode breakout is small enough, it is ok
+ // to enable it for no-show frame, i.e. set enable_encode_breakout to 2.
+ if (!cpi->common.show_frame)
+ cpi->enable_encode_breakout = 0;
+ else
+ cpi->enable_encode_breakout = 2;
+ }
+
+ rc->frames_till_gf_update_due = rc->baseline_gf_interval;
+ cpi->refresh_golden_frame = 1;
+ } else {
+ // Otherwise this is an ordinary frame
+ // Assign bits from those allocated to the GF group
+ this_frame_copy = this_frame;
+ assign_std_frame_bits(cpi, &this_frame_copy);
+ }
+
+ // Keep a globally available copy of this and the next frame's iiratio.
+ cpi->twopass.this_iiratio = (int)(this_frame_intra_error /
+ DOUBLE_DIVIDE_CHECK(this_frame_coded_error));
+ {
+ FIRSTPASS_STATS next_frame;
+ if (lookup_next_frame_stats(&cpi->twopass, &next_frame) != EOF) {
+ cpi->twopass.next_iiratio = (int)(next_frame.intra_error /
+ DOUBLE_DIVIDE_CHECK(next_frame.coded_error));
+ }
+ }
+
+ // Set nominal per second bandwidth for this frame
+ cpi->target_bandwidth = (int)(rc->per_frame_bandwidth *
+ cpi->output_framerate);
+ if (cpi->target_bandwidth < 0)
+ cpi->target_bandwidth = 0;
+
+ // Update the total stats remaining structure
+ subtract_stats(&cpi->twopass.total_left_stats, &this_frame);
+}
+
void vp9_twopass_postencode_update(VP9_COMP *cpi, uint64_t bytes_used) {
#ifdef DISABLE_RC_LONG_TERM_MEM
cpi->twopass.bits_left -= cpi->rc.this_frame_target;