aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Wilkins <paulwilkins@google.com>2014-01-02 15:45:06 +0000
committerPaul Wilkins <paulwilkins@google.com>2014-01-03 14:56:08 +0000
commit65ede3da45fe9aa10e9eee0433466bf36f30520c (patch)
tree54e5b5353af70710403c2064994dcca860d9fb75
parent3bcece9578a9d5a536cdb3d11cb897f25fdaeea4 (diff)
downloadlibvpx-65ede3da45fe9aa10e9eee0433466bf36f30520c.tar
libvpx-65ede3da45fe9aa10e9eee0433466bf36f30520c.tar.gz
libvpx-65ede3da45fe9aa10e9eee0433466bf36f30520c.tar.bz2
libvpx-65ede3da45fe9aa10e9eee0433466bf36f30520c.zip
Modified Handling of min and max vbr rates.
In two pass encodes bits are allocated to each frame according to a modified error score for the frame as a fraction of the modified error score for the clip or section. Previously a minimum rate per frame was reserved and subtracted from the bits allocatable by the two pass code. The vbr max section rate was enforced by clipping the actual number of bits allocated. In this patch the min and max vbr rates are enforced instead by clipping the modified error scores for each frame rather than the number of bits allocated. Small gains for all test sets (psnr and SSIM) ranging from ~ +0.05 for YT psnr up to ~ +0.25 for Std-hd SSIM. Change-Id: Iae27d70bdd3944e3f0cceaf225bad2e8802833de
-rw-r--r--vp9/encoder/vp9_firstpass.c39
-rw-r--r--vp9/encoder/vp9_onyx_int.h2
2 files changed, 20 insertions, 21 deletions
diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c
index 16cf28473..065dc19b7 100644
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -271,8 +271,17 @@ static double calculate_modified_err(VP9_COMP *cpi,
const FIRSTPASS_STATS *const stats = &cpi->twopass.total_stats;
const double av_err = stats->ssim_weighted_pred_err / stats->count;
const double this_err = this_frame->ssim_weighted_pred_err;
- return av_err * pow(this_err / DOUBLE_DIVIDE_CHECK(av_err),
- this_err > av_err ? POW1 : POW2);
+ double modified_error;
+
+ modified_error = av_err * pow(this_err / DOUBLE_DIVIDE_CHECK(av_err),
+ this_err > av_err ? POW1 : POW2);
+
+ if (modified_error < cpi->twopass.modified_error_min)
+ modified_error = cpi->twopass.modified_error_min;
+ else if (modified_error > cpi->twopass.modified_error_max)
+ modified_error = cpi->twopass.modified_error_max;
+
+ return modified_error;
}
static const double weight_table[256] = {
@@ -1077,13 +1086,6 @@ void vp9_init_second_pass(VP9_COMP *cpi) {
FIRSTPASS_STATS this_frame;
FIRSTPASS_STATS *start_pos;
- double lower_bounds_min_rate = FRAME_OVERHEAD_BITS * cpi->oxcf.framerate;
- double two_pass_min_rate = (double)(cpi->oxcf.target_bandwidth *
- cpi->oxcf.two_pass_vbrmin_section / 100);
-
- if (two_pass_min_rate < lower_bounds_min_rate)
- two_pass_min_rate = lower_bounds_min_rate;
-
zero_stats(&cpi->twopass.total_stats);
zero_stats(&cpi->twopass.total_left_stats);
@@ -1104,8 +1106,6 @@ void vp9_init_second_pass(VP9_COMP *cpi) {
cpi->output_framerate = cpi->oxcf.framerate;
cpi->twopass.bits_left = (int64_t)(cpi->twopass.total_stats.duration *
cpi->oxcf.target_bandwidth / 10000000.0);
- cpi->twopass.bits_left -= (int64_t)(cpi->twopass.total_stats.duration *
- two_pass_min_rate / 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
@@ -1142,9 +1142,16 @@ void vp9_init_second_pass(VP9_COMP *cpi) {
// Scan the first pass file and calculate a modified total error based upon
// the bias/power function used to allocate bits.
{
+ double av_error = cpi->twopass.total_stats.ssim_weighted_pred_err /
+ DOUBLE_DIVIDE_CHECK(cpi->twopass.total_stats.count);
+
start_pos = cpi->twopass.stats_in; // Note starting "file" position
cpi->twopass.modified_error_total = 0.0;
+ cpi->twopass.modified_error_min =
+ (av_error * cpi->oxcf.two_pass_vbrmin_section) / 100;
+ cpi->twopass.modified_error_max =
+ (av_error * cpi->oxcf.two_pass_vbrmax_section) / 100;
while (input_stats(cpi, &this_frame) != EOF) {
cpi->twopass.modified_error_total +=
@@ -2635,14 +2642,4 @@ void vp9_twopass_postencode_update(VP9_COMP *cpi, uint64_t bytes_used) {
#else
cpi->twopass.bits_left -= 8 * bytes_used;
#endif
- if (!cpi->refresh_alt_ref_frame) {
- double lower_bounds_min_rate = FRAME_OVERHEAD_BITS * cpi->oxcf.framerate;
- double two_pass_min_rate = (double)(cpi->oxcf.target_bandwidth *
- cpi->oxcf.two_pass_vbrmin_section
- / 100);
- if (two_pass_min_rate < lower_bounds_min_rate)
- two_pass_min_rate = lower_bounds_min_rate;
- cpi->twopass.bits_left += (int64_t)(two_pass_min_rate /
- cpi->oxcf.framerate);
- }
}
diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h
index f5b6562da..d32711c32 100644
--- a/vp9/encoder/vp9_onyx_int.h
+++ b/vp9/encoder/vp9_onyx_int.h
@@ -525,6 +525,8 @@ typedef struct VP9_COMP {
int64_t bits_left;
int64_t clip_bits_total;
double avg_iiratio;
+ double modified_error_min;
+ double modified_error_max;
double modified_error_total;
double modified_error_left;
double kf_intra_err_min;