summaryrefslogtreecommitdiff
path: root/vp9
diff options
context:
space:
mode:
authorPaul Wilkins <paulwilkins@google.com>2013-02-25 12:36:38 +0000
committerPaul Wilkins <paulwilkins@google.com>2013-02-25 17:07:45 +0000
commit97da8b8c3395ba3de5e13b8d77a8432b9a462b78 (patch)
tree8d9a9a798a8bc2fd5cb24f56131f556c9c5510b1 /vp9
parent499fe05dc030b31d15c2ad9717e6bcee839f7d12 (diff)
downloadlibvpx-97da8b8c3395ba3de5e13b8d77a8432b9a462b78.tar
libvpx-97da8b8c3395ba3de5e13b8d77a8432b9a462b78.tar.gz
libvpx-97da8b8c3395ba3de5e13b8d77a8432b9a462b78.tar.bz2
libvpx-97da8b8c3395ba3de5e13b8d77a8432b9a462b78.zip
Minor rate control refactoring and experiments.
Some minor refactoring code relating to estimates of bits per MB at a given Q and estimating the allowed Q range. Most of the changes here were included in a previous commit. This commit seeks to separate out the refactoring from more the material changes. Two #define control flags have been added for experimentation. ONE_SHOT_Q_ESTIMATE force the two pass encoder to use its initial Q range estimate for the whole clip even if this results in a miss on the target data rate. In effect this tightens the Q range seen at the expense of rate control accuracy. DISABLE_RC_LONG_TERM_MEM is a related flag that disables the long term memory in the rate control. Local adjustments are still made to try and better hit the rate target on a per frame basis but the impact of rate control misses is not propagated to the remainder of the clip. This means that for example an overshoot early on will not cause frames later in the clip to be starved of bits. Again the result of this relaxation amy be less rate control accuracy especially on short clips. The flags are disabled by default for now. Change-Id: I7482f980146d8ea033b5d50cc689f772e4bd119e
Diffstat (limited to 'vp9')
-rw-r--r--vp9/encoder/vp9_firstpass.c79
-rw-r--r--vp9/encoder/vp9_onyx_if.c23
-rw-r--r--vp9/encoder/vp9_onyx_int.h4
-rw-r--r--vp9/encoder/vp9_ratectrl.c31
-rw-r--r--vp9/encoder/vp9_ratectrl.h3
5 files changed, 55 insertions, 85 deletions
diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c
index 0a407dfdb..a4924874d 100644
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -844,16 +844,13 @@ static double calc_correction_factor(double err_per_mb,
power_term = (vp9_convert_qindex_to_q(Q) * 0.01) + pt_low;
power_term = (power_term > pt_high) ? pt_high : power_term;
- // Adjustments to error term
- // TBD
-
// Calculate correction factor
correction_factor = pow(error_term, power_term);
// Clip range
correction_factor =
(correction_factor < 0.05)
- ? 0.05 : (correction_factor > 2.0) ? 2.0 : correction_factor;
+ ? 0.05 : (correction_factor > 5.0) ? 5.0 : correction_factor;
return correction_factor;
}
@@ -887,8 +884,7 @@ static void adjust_maxq_qrange(VP9_COMP *cpi) {
static int estimate_max_q(VP9_COMP *cpi,
FIRSTPASS_STATS *fpstats,
- int section_target_bandwitdh,
- int overhead_bits) {
+ int section_target_bandwitdh) {
int Q;
int num_mbs = cpi->common.MBs;
int target_norm_bits_per_mb;
@@ -899,7 +895,6 @@ static int estimate_max_q(VP9_COMP *cpi,
double err_per_mb = section_err / num_mbs;
double err_correction_factor;
double speed_correction = 1.0;
- double overhead_bits_per_mb;
if (section_target_bandwitdh <= 0)
return cpi->twopass.maxq_max_limit; // Highest value allowed
@@ -951,13 +946,6 @@ static int estimate_max_q(VP9_COMP *cpi,
speed_correction = 1.25;
}
- // Estimate of overhead bits per mb
- // Correction to overhead bits for min allowed Q.
- // PGW TODO.. This code is broken for the extended Q range
- // for now overhead set to 0.
- overhead_bits_per_mb = overhead_bits / num_mbs;
- overhead_bits_per_mb *= pow(0.98, (double)cpi->twopass.maxq_min_limit);
-
// Try and pick a max Q that will be high enough to encode the
// content at the given rate.
for (Q = cpi->twopass.maxq_min_limit; Q < cpi->twopass.maxq_max_limit; Q++) {
@@ -968,23 +956,9 @@ static int estimate_max_q(VP9_COMP *cpi,
sr_correction * speed_correction *
cpi->twopass.est_max_qcorrection_factor;
- if (err_correction_factor < 0.05)
- err_correction_factor = 0.05;
- else if (err_correction_factor > 5.0)
- err_correction_factor = 5.0;
bits_per_mb_at_this_q =
- vp9_bits_per_mb(INTER_FRAME, Q) + (int)overhead_bits_per_mb;
-
- bits_per_mb_at_this_q = (int)(.5 + err_correction_factor *
- (double)bits_per_mb_at_this_q);
-
- // Mode and motion overhead
- // As Q rises in real encode loop rd code will force overhead down
- // We make a crude adjustment for this here as *.98 per Q step.
- // PGW TODO.. This code is broken for the extended Q range
- // for now overhead set to 0.
- // overhead_bits_per_mb = (int)((double)overhead_bits_per_mb * 0.98);
+ vp9_bits_per_mb(INTER_FRAME, Q, err_correction_factor);
if (bits_per_mb_at_this_q <= target_norm_bits_per_mb)
break;
@@ -1002,7 +976,7 @@ static int estimate_max_q(VP9_COMP *cpi,
// PGW TODO.. This code is broken for the extended Q range
if ((cpi->ni_frames >
((int)cpi->twopass.total_stats->count >> 8)) &&
- (cpi->ni_frames > 150)) {
+ (cpi->ni_frames > 25)) {
adjust_maxq_qrange(cpi);
}
@@ -1013,8 +987,7 @@ static int estimate_max_q(VP9_COMP *cpi,
// complexity and data rate.
static int estimate_cq(VP9_COMP *cpi,
FIRSTPASS_STATS *fpstats,
- int section_target_bandwitdh,
- int overhead_bits) {
+ int section_target_bandwitdh) {
int Q;
int num_mbs = cpi->common.MBs;
int target_norm_bits_per_mb;
@@ -1027,15 +1000,11 @@ static int estimate_cq(VP9_COMP *cpi,
double speed_correction = 1.0;
double clip_iiratio;
double clip_iifactor;
- double overhead_bits_per_mb;
-
target_norm_bits_per_mb = (section_target_bandwitdh < (1 << 20))
? (512 * section_target_bandwitdh) / num_mbs
: 512 * (section_target_bandwitdh / num_mbs);
- // Estimate of overhead bits per mb
- overhead_bits_per_mb = overhead_bits / num_mbs;
// Corrections for higher compression speed settings
// (reduced compression expected)
@@ -1074,23 +1043,8 @@ static int estimate_cq(VP9_COMP *cpi,
calc_correction_factor(err_per_mb, 100.0, 0.4, 0.90, Q) *
sr_correction * speed_correction * clip_iifactor;
- if (err_correction_factor < 0.05)
- err_correction_factor = 0.05;
- else if (err_correction_factor > 5.0)
- err_correction_factor = 5.0;
-
bits_per_mb_at_this_q =
- vp9_bits_per_mb(INTER_FRAME, Q) + (int)overhead_bits_per_mb;
-
- bits_per_mb_at_this_q = (int)(.5 + err_correction_factor *
- (double)bits_per_mb_at_this_q);
-
- // Mode and motion overhead
- // As Q rises in real encode loop rd code will force overhead down
- // We make a crude adjustment for this here as *.98 per Q step.
- // PGW TODO.. This code is broken for the extended Q range
- // for now overhead set to 0.
- overhead_bits_per_mb = (int)((double)overhead_bits_per_mb * 0.98);
+ vp9_bits_per_mb(INTER_FRAME, Q, err_correction_factor);
if (bits_per_mb_at_this_q <= target_norm_bits_per_mb)
break;
@@ -1953,8 +1907,6 @@ void vp9_second_pass(VP9_COMP *cpi) {
double this_frame_intra_error;
double this_frame_coded_error;
- int overhead_bits;
-
if (!cpi->twopass.stats_in) {
return;
}
@@ -2018,11 +1970,6 @@ void vp9_second_pass(VP9_COMP *cpi) {
if (cpi->target_bandwidth < 0)
cpi->target_bandwidth = 0;
-
- // Account for mv, mode and other overheads.
- overhead_bits = (int)estimate_modemvcost(
- cpi, cpi->twopass.total_left_stats);
-
// Special case code for first frame.
if (cpi->common.current_video_frame == 0) {
cpi->twopass.est_max_qcorrection_factor = 1.0;
@@ -2034,8 +1981,7 @@ void vp9_second_pass(VP9_COMP *cpi) {
est_cq =
estimate_cq(cpi,
cpi->twopass.total_left_stats,
- (int)(cpi->twopass.bits_left / frames_left),
- overhead_bits);
+ (int)(cpi->twopass.bits_left / frames_left));
cpi->cq_target_quality = cpi->oxcf.cq_level;
if (est_cq > cpi->cq_target_quality)
@@ -2049,21 +1995,23 @@ void vp9_second_pass(VP9_COMP *cpi) {
tmp_q = estimate_max_q(
cpi,
cpi->twopass.total_left_stats,
- (int)(cpi->twopass.bits_left / frames_left),
- overhead_bits);
+ (int)(cpi->twopass.bits_left / frames_left));
cpi->active_worst_quality = tmp_q;
cpi->ni_av_qi = tmp_q;
cpi->avg_q = vp9_convert_qindex_to_q(tmp_q);
+#ifndef ONE_SHOT_Q_ESTIMATE
// 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);
+#endif
}
+#ifndef ONE_SHOT_Q_ESTIMATE
// The last few frames of a clip almost always have to few or too many
// bits and for the sake of over exact rate control we dont want to make
// radical adjustments to the allowed quantizer range just to use up a
@@ -2078,13 +2026,13 @@ void vp9_second_pass(VP9_COMP *cpi) {
tmp_q = estimate_max_q(
cpi,
cpi->twopass.total_left_stats,
- (int)(cpi->twopass.bits_left / frames_left),
- overhead_bits);
+ (int)(cpi->twopass.bits_left / frames_left));
// Make a damped adjustment to active max Q
cpi->active_worst_quality =
adjust_active_maxq(cpi->active_worst_quality, tmp_q);
}
+#endif
cpi->twopass.frames_to_key--;
@@ -2092,7 +2040,6 @@ void vp9_second_pass(VP9_COMP *cpi) {
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,
diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c
index 40a1263a8..feb1e36c0 100644
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -3321,11 +3321,19 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
if (cpi->bits_off_target > cpi->oxcf.maximum_buffer_size)
cpi->bits_off_target = cpi->oxcf.maximum_buffer_size;
- // Rolling monitors of whether we are over or underspending used to help regulate min and Max Q in two pass.
- cpi->rolling_target_bits = ((cpi->rolling_target_bits * 3) + cpi->this_frame_target + 2) / 4;
- cpi->rolling_actual_bits = ((cpi->rolling_actual_bits * 3) + cpi->projected_frame_size + 2) / 4;
- cpi->long_rolling_target_bits = ((cpi->long_rolling_target_bits * 31) + cpi->this_frame_target + 16) / 32;
- cpi->long_rolling_actual_bits = ((cpi->long_rolling_actual_bits * 31) + cpi->projected_frame_size + 16) / 32;
+ // Rolling monitors of whether we are over or underspending used to help
+ // regulate min and Max Q in two pass.
+ if (cm->frame_type != KEY_FRAME) {
+ cpi->rolling_target_bits =
+ ((cpi->rolling_target_bits * 3) + cpi->this_frame_target + 2) / 4;
+ cpi->rolling_actual_bits =
+ ((cpi->rolling_actual_bits * 3) + cpi->projected_frame_size + 2) / 4;
+ cpi->long_rolling_target_bits =
+ ((cpi->long_rolling_target_bits * 31) + cpi->this_frame_target + 16) / 32;
+ cpi->long_rolling_actual_bits =
+ ((cpi->long_rolling_actual_bits * 31) +
+ cpi->projected_frame_size + 16) / 32;
+ }
// Actual bits spent
cpi->total_actual_bits += cpi->projected_frame_size;
@@ -3551,7 +3559,12 @@ static void Pass2Encode(VP9_COMP *cpi, unsigned long *size,
vp9_second_pass(cpi);
encode_frame_to_data_rate(cpi, size, dest, frame_flags);
+
+#ifdef DISABLE_RC_LONG_TERM_MEM
+ cpi->twopass.bits_left -= cpi->this_frame_target;
+#else
cpi->twopass.bits_left -= 8 * *size;
+#endif
if (!cpi->refresh_alt_ref_frame) {
double lower_bounds_min_rate = FRAME_OVERHEAD_BITS * cpi->oxcf.frame_rate;
diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h
index 6b9bf8711..9b509ea0b 100644
--- a/vp9/encoder/vp9_onyx_int.h
+++ b/vp9/encoder/vp9_onyx_int.h
@@ -29,6 +29,10 @@
#include "vp9/common/vp9_findnearmv.h"
#include "vp9/encoder/vp9_lookahead.h"
+// Experimental rate control switches
+// #define ONE_SHOT_Q_ESTIMATE 1
+// #define DISABLE_RC_LONG_TERM_MEM 1
+
// #define SPEEDSTATS 1
#define MIN_GF_INTERVAL 4
#define DEFAULT_GF_INTERVAL 7
diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c
index 53d931c9b..a2a79574d 100644
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -114,13 +114,19 @@ static int kfboost_qadjust(int qindex) {
return retval;
}
-int vp9_bits_per_mb(FRAME_TYPE frame_type, int qindex) {
- if (frame_type == KEY_FRAME)
- return (int)(4500000 / vp9_convert_qindex_to_q(qindex));
- else
- return (int)(2850000 / vp9_convert_qindex_to_q(qindex));
-}
+int vp9_bits_per_mb(FRAME_TYPE frame_type, int qindex,
+ double correction_factor) {
+ int enumerator;
+ double q = vp9_convert_qindex_to_q(qindex);
+
+ if (frame_type == KEY_FRAME) {
+ enumerator = 4500000;
+ } else {
+ enumerator = 2850000;
+ }
+ return (int)(0.5 + (enumerator * correction_factor / q));
+}
void vp9_save_coding_context(VP9_COMP *cpi) {
CODING_CONTEXT *const cc = &cpi->coding_context;
@@ -259,7 +265,7 @@ void vp9_setup_inter_frame(VP9_COMP *cpi) {
static int estimate_bits_at_q(int frame_kind, int Q, int MBs,
double correction_factor) {
- int Bpm = (int)(.5 + correction_factor * vp9_bits_per_mb(frame_kind, Q));
+ int Bpm = (int)(vp9_bits_per_mb(frame_kind, Q, correction_factor));
/* Attempt to retain reasonable accuracy without overflow. The cutoff is
* chosen such that the maximum product of Bpm and MBs fits 31 bits. The
@@ -397,12 +403,12 @@ void vp9_update_rate_correction_factors(VP9_COMP *cpi, int damp_var) {
rate_correction_factor = cpi->rate_correction_factor;
}
- // Work out how big we would have expected the frame to be at this Q given the current correction factor.
+ // Work out how big we would have expected the frame to be at this Q given
+ // the current correction factor.
// Stay in double to avoid int overflow when values are large
projected_size_based_on_q =
- (int)(((.5 + rate_correction_factor *
- vp9_bits_per_mb(cpi->common.frame_type, Q)) *
- cpi->common.MBs) / (1 << BPER_MB_NORMBITS));
+ estimate_bits_at_q(cpi->common.frame_type, Q,
+ cpi->common.MBs, rate_correction_factor);
// Work out a size correction factor.
// if ( cpi->this_frame_target > 0 )
@@ -485,8 +491,7 @@ int vp9_regulate_q(VP9_COMP *cpi, int target_bits_per_frame) {
do {
bits_per_mb_at_this_q =
- (int)(.5 + correction_factor *
- vp9_bits_per_mb(cpi->common.frame_type, i));
+ (int)(vp9_bits_per_mb(cpi->common.frame_type, i, correction_factor));
if (bits_per_mb_at_this_q <= target_bits_per_mb) {
if ((target_bits_per_mb - bits_per_mb_at_this_q) <= last_error)
diff --git a/vp9/encoder/vp9_ratectrl.h b/vp9/encoder/vp9_ratectrl.h
index c5817d787..473317605 100644
--- a/vp9/encoder/vp9_ratectrl.h
+++ b/vp9/encoder/vp9_ratectrl.h
@@ -32,7 +32,8 @@ int vp9_pick_frame_size(VP9_COMP *cpi);
double vp9_convert_qindex_to_q(int qindex);
int vp9_gfboost_qadjust(int qindex);
-int vp9_bits_per_mb(FRAME_TYPE frame_type, int qindex);
+extern int vp9_bits_per_mb(FRAME_TYPE frame_type, int qindex,
+ double correction_factor);
void vp9_setup_inter_frame(VP9_COMP *cpi);
#endif // VP9_ENCODER_VP9_RATECTRL_H_