shithub: libvpx

Download patch

ref: 587f0cd39d9b949185f148a683db410d4e3f04b0
parent: 3c715863da0afdc42fb44c9f6d04e983d25a8de7
parent: ffa06b37083d028b50f27e67ae6ed0c6ee9953bb
author: Yaowu Xu <yaowu@google.com>
date: Tue Nov 18 11:56:06 EST 2014

Merge "Prevent severe rate control errors in CBR mode"

--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -430,7 +430,8 @@
       adjustment_limit = 0.75;
       break;
     case 1:
-      adjustment_limit = 0.125 + 0.5 * MIN(1, fabs(log10(0.01 * correction_factor)));
+      adjustment_limit = 0.25 +
+          0.5 * MIN(1, fabs(log10(0.01 * correction_factor)));
       break;
     case 2:
     default:
@@ -438,12 +439,21 @@
       break;
   }
 
+  cpi->rc.q_2_frame = cpi->rc.q_1_frame;
+  cpi->rc.q_1_frame = cm->base_qindex;
+  cpi->rc.rc_2_frame = cpi->rc.rc_1_frame;
+  if (correction_factor > 110)
+    cpi->rc.rc_1_frame = -1;
+  else if (correction_factor < 90)
+    cpi->rc.rc_1_frame = 1;
+  else
+    cpi->rc.rc_1_frame = 0;
+
   if (correction_factor > 102) {
     // We are not already at the worst allowable quality
     correction_factor = (int)(100 + ((correction_factor - 100) *
                                   adjustment_limit));
     rate_correction_factor = (rate_correction_factor * correction_factor) / 100;
-
     // Keep rate_correction_factor within limits
     if (rate_correction_factor > MAX_BPB_FACTOR)
       rate_correction_factor = MAX_BPB_FACTOR;
@@ -494,6 +504,14 @@
     }
   } while (++i <= active_worst_quality);
 
+  // In CBR mode, this makes sure q is between oscillating Qs to prevent
+  // resonance.
+  if (cpi->oxcf.rc_mode == VPX_CBR &&
+      (cpi->rc.rc_1_frame * cpi->rc.rc_2_frame == -1) &&
+      cpi->rc.q_1_frame != cpi->rc.q_2_frame) {
+    q = clamp(q, MIN(cpi->rc.q_1_frame, cpi->rc.q_2_frame),
+              MAX(cpi->rc.q_1_frame, cpi->rc.q_2_frame));
+  }
   return q;
 }
 
--- a/vp9/encoder/vp9_ratectrl.h
+++ b/vp9/encoder/vp9_ratectrl.h
@@ -99,7 +99,14 @@
   int64_t starting_buffer_level;
   int64_t optimal_buffer_level;
   int64_t maximum_buffer_size;
-  // int active_best_quality;
+  // rate control history for last frame(1) and the frame before(2).
+  // -1: undershot
+  //  1: overshoot
+  //  0: not initialized.
+  int rc_1_frame;
+  int rc_2_frame;
+  int q_1_frame;
+  int q_2_frame;
 } RATE_CONTROL;
 
 struct VP9_COMP;