Commit 97da8b8c authored by Paul Wilkins's avatar Paul Wilkins
Browse files

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
parent 499fe05d
......@@ -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,
......
......@@ -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;
......
......@@ -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
......
......@@ -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)
......
......@@ -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_
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment