]> granicus.if.org Git - libvpx/commitdiff
Modified Handling of min and max vbr rates.
authorPaul Wilkins <paulwilkins@google.com>
Thu, 2 Jan 2014 15:45:06 +0000 (15:45 +0000)
committerPaul Wilkins <paulwilkins@google.com>
Fri, 3 Jan 2014 14:56:08 +0000 (14:56 +0000)
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

vp9/encoder/vp9_firstpass.c
vp9/encoder/vp9_onyx_int.h

index 16cf2847311deab2086d289bf0d1780e878a32c9..065dc19b714c5ec48a58f53239175d0579140f4b 100644 (file)
@@ -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);
-  }
 }
index f5b6562da6f6ba76925b7dcb7563b85570322720..d32711c32e0c9123caa5dac76b8264c607034b8b 100644 (file)
@@ -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;