]> granicus.if.org Git - libvpx/commitdiff
Add max burst bitrate control.
authorPaul Wilkins <paulwilkins@google.com>
Fri, 10 Jan 2014 17:26:44 +0000 (17:26 +0000)
committerPaul Wilkins <paulwilkins@google.com>
Tue, 14 Jan 2014 09:52:49 +0000 (09:52 +0000)
Applies an upper limit on burst bitrate for any
frame. This is to insure that typical encodes for YT
do not produce frames that are so large that they
risk stalling HW implementations. Such frames
could also cause playback problems in SW.

For now the limit is set at 250 bits per MB for 1080P
and larger (with the 1080P limit used for smaller frames).

Setting maxQ, constant quality mode or targeting a
very high bandwidth will have precedence over this limit.

Change-Id: Ie6f776c38b06ac7cec043d034085f4b79ee46a38

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

index 7c4ca637849e4326b69339a999ac98a3544b9518..adc1b793531fe428f48dc25633b387cd39c9b2f3 100644 (file)
@@ -353,13 +353,14 @@ static double simple_weight(YV12_BUFFER_CONFIG *source) {
 // This function returns the maximum target rate per frame.
 static int frame_max_bits(VP9_COMP *cpi) {
   int64_t max_bits =
-     ((int64_t)cpi->rc.av_per_frame_bandwidth *
-      (int64_t)cpi->oxcf.two_pass_vbrmax_section) / 100;
+    ((int64_t)cpi->rc.av_per_frame_bandwidth *
+     (int64_t)cpi->oxcf.two_pass_vbrmax_section) / 100;
 
   if (max_bits < 0)
-    return 0;
-  if (max_bits >= INT_MAX)
-    return INT_MAX;
+    max_bits = 0;
+  else if (max_bits > cpi->rc.max_frame_bandwidth)
+    max_bits = cpi->rc.max_frame_bandwidth;
+
   return (int)max_bits;
 }
 
index 8e60bc96d2c1ed76461110ae61092e8e4b9c13a7..2bcfcd4f07a52448639c31aeab77ce29d21bfff9 100644 (file)
@@ -59,6 +59,11 @@ void vp9_coef_tree_initialize();
 #define DISABLE_COMPOUND_SPLIT    0x18
 #define LAST_AND_INTRA_SPLIT_ONLY 0x1E
 
+// Max rate target for 1080P and below encodes under normal circumstances
+// (1920 * 1080 / (16 * 16)) * MAX_MB_RATE bits per MB
+#define MAX_MB_RATE 250
+#define MAXRATE_1080P 2025000
+
 #if CONFIG_INTERNAL_STATS
 extern double vp9_calc_ssim(YV12_BUFFER_CONFIG *source,
                             YV12_BUFFER_CONFIG *dest, int lumamask,
@@ -1093,6 +1098,9 @@ int vp9_reverse_trans(int x) {
 };
 
 void vp9_new_framerate(VP9_COMP *cpi, double framerate) {
+  VP9_COMMON *const cm = &cpi->common;
+  int64_t vbr_max_bits;
+
   if (framerate < 0.1)
     framerate = 30;
 
@@ -1109,6 +1117,19 @@ void vp9_new_framerate(VP9_COMP *cpi, double framerate) {
   cpi->rc.min_frame_bandwidth = MAX(cpi->rc.min_frame_bandwidth,
                                     FRAME_OVERHEAD_BITS);
 
+  // A maximum bitrate for a frame is defined.
+  // The baseline for this aligns with HW implementations that
+  // can support decode of 1080P content up to a bitrate of MAX_MB_RATE bits
+  // per 16x16 MB (averaged over a frame). However this limit is extended if
+  // a very high rate is given on the command line or the the rate cannnot
+  // be acheived because of a user specificed max q (e.g. when the user
+  // specifies lossless encode.
+  //
+  vbr_max_bits = ((int64_t)cpi->rc.av_per_frame_bandwidth *
+                  (int64_t)cpi->oxcf.two_pass_vbrmax_section) / 100;
+  cpi->rc.max_frame_bandwidth =
+    MAX(MAX((cm->MBs * MAX_MB_RATE), MAXRATE_1080P), vbr_max_bits);
+
   // Set Maximum gf/arf interval
   cpi->rc.max_gf_interval = 16;
 
@@ -2449,10 +2470,14 @@ static int recode_loop_test(VP9_COMP *cpi,
   int force_recode = 0;
   VP9_COMMON *cm = &cpi->common;
 
-  // Is frame recode allowed at all
-  // Yes if either recode mode 1 is selected or mode two is selected
-  // and the frame is a key frame. golden frame or alt_ref_frame
-  if ((cpi->sf.recode_loop == 1) ||
+  // Special case trap if maximum allowed frame size exceeded.
+  if (cpi->rc.projected_frame_size > cpi->rc.max_frame_bandwidth) {
+    force_recode = 1;
+
+  // Is frame recode allowed.
+  // Yes if either recode mode 1 is selected or mode 2 is selected
+  // and the frame is a key frame, golden frame or alt_ref_frame
+  } else if ((cpi->sf.recode_loop == 1) ||
       ((cpi->sf.recode_loop == 2) &&
        ((cm->frame_type == KEY_FRAME) ||
         cpi->refresh_golden_frame ||
@@ -2630,7 +2655,8 @@ static void output_frame_level_debug_stats(VP9_COMP *cpi) {
         "%6d %6d %5d %5d %5d %10d %10.3f"
         "%10.3f %8d %10d %10d %10d\n",
         cpi->common.current_video_frame, cpi->rc.this_frame_target,
-        cpi->rc.projected_frame_size, 0,
+        cpi->rc.projected_frame_size,
+        cpi->rc.projected_frame_size / cpi->common.MBs,
         (cpi->rc.projected_frame_size - cpi->rc.this_frame_target),
         (int)cpi->rc.total_target_vs_actual,
         (int)(cpi->oxcf.starting_buffer_level - cpi->rc.bits_off_target),
@@ -2740,8 +2766,9 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
     if (cpi->oxcf.end_usage == USAGE_CONSTANT_QUALITY) {
       loop = 0;
     } else {
-      // Special case handling for forced key frames
-      if ((cm->frame_type == KEY_FRAME) && cpi->rc.this_key_frame_forced) {
+      if ((cm->frame_type == KEY_FRAME) &&
+           cpi->rc.this_key_frame_forced &&
+           (cpi->rc.projected_frame_size < cpi->rc.max_frame_bandwidth)) {
         int last_q = *q;
         int kf_err = vp9_calc_ss_err(cpi->Source, get_frame_new_buffer(cm));
 
@@ -2780,7 +2807,7 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
         loop = *q != last_q;
       } else if (recode_loop_test(
           cpi, frame_over_shoot_limit, frame_under_shoot_limit,
-          *q, top_index, bottom_index)) {
+          *q, MAX(q_high, top_index), bottom_index)) {
         // Is the projected frame size out of range and are we allowed
         // to attempt to recode.
         int last_q = *q;
@@ -2791,6 +2818,10 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
 
         // Frame is too large
         if (cpi->rc.projected_frame_size > cpi->rc.this_frame_target) {
+          // Special case if the projected size is > the max allowed.
+          if (cpi->rc.projected_frame_size >= cpi->rc.max_frame_bandwidth)
+            q_high = cpi->rc.worst_quality;
+
           // Raise Qlow as to at least the current value
           q_low = *q < q_high ? *q + 1 : q_high;
 
@@ -2804,12 +2835,12 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
             vp9_rc_update_rate_correction_factors(cpi, 0);
 
             *q = vp9_rc_regulate_q(cpi, cpi->rc.this_frame_target,
-                                   bottom_index, top_index);
+                                   bottom_index, MAX(q_high, top_index));
 
             while (*q < q_low && retries < 10) {
               vp9_rc_update_rate_correction_factors(cpi, 0);
               *q = vp9_rc_regulate_q(cpi, cpi->rc.this_frame_target,
-                                     bottom_index, top_index);
+                                     bottom_index, MAX(q_high, top_index));
               retries++;
             }
           }
@@ -2855,7 +2886,9 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
       }
     }
 
-    if (cpi->rc.is_src_frame_alt_ref)
+    // Special case for overlay frame.
+    if (cpi->rc.is_src_frame_alt_ref &&
+        (cpi->rc.projected_frame_size < cpi->rc.max_frame_bandwidth))
       loop = 0;
 
     if (loop) {
index a5be0f424734548ff66f1d0855deb5384004bbb0..be079d8596ca9af4eb6d8e71c835a545ae585fd4 100644 (file)
@@ -442,9 +442,10 @@ typedef struct {
   unsigned int source_alt_ref_active;
   unsigned int is_src_frame_alt_ref;
 
-  int per_frame_bandwidth;  // Current section per frame bandwidth target
-  int av_per_frame_bandwidth;  // Average frame size target for clip
-  int min_frame_bandwidth;  // Minimum allocation used for any frame
+  int per_frame_bandwidth;        // Current section per frame bandwidth target
+  int av_per_frame_bandwidth;     // Average frame size target for clip
+  int min_frame_bandwidth;        // Minimum allocation used for any frame
+  int max_frame_bandwidth;        // Maximum burst rate allowed for a frame.
 
   int ni_av_qi;
   int ni_tot_qi;
index 939a7f9983e3864deaa5020ee36958626ea3d0dc..ae1aaa32ea0aaf43d84ea5c0f91e4312440eb727 100644 (file)
@@ -746,8 +746,13 @@ int vp9_rc_pick_q_and_adjust_q_bounds(const VP9_COMP *cpi,
   } else {
     q = vp9_rc_regulate_q(cpi, cpi->rc.this_frame_target,
                           active_best_quality, active_worst_quality);
-    if (q > *top_index)
-      q = *top_index;
+    if (q > *top_index) {
+      // Special case when we are targeting the max allowed rate
+      if (cpi->rc.this_frame_target >= cpi->rc.max_frame_bandwidth)
+        *top_index = q;
+      else
+        q = *top_index;
+    }
   }
 #if CONFIG_MULTIPLE_ARF
   // Force the quantizer determined by the coding order pattern.
@@ -810,6 +815,11 @@ void vp9_rc_compute_frame_size_bounds(const VP9_COMP *cpi,
     *frame_under_shoot_limit -= 200;
     if (*frame_under_shoot_limit < 0)
       *frame_under_shoot_limit = 0;
+
+    // Clip to maximum allowed rate for a frame.
+    if (*frame_over_shoot_limit > cpi->rc.max_frame_bandwidth) {
+      *frame_over_shoot_limit = cpi->rc.max_frame_bandwidth;
+    }
   }
 }
 
@@ -822,6 +832,10 @@ int vp9_rc_pick_frame_size_target(VP9_COMP *cpi) {
   else
     calc_pframe_target_size(cpi);
 
+  // Clip the frame target to the maximum allowed value.
+  if (cpi->rc.this_frame_target > cpi->rc.max_frame_bandwidth)
+    cpi->rc.this_frame_target = cpi->rc.max_frame_bandwidth;
+
   // Target rate per SB64 (including partial SB64s.
   cpi->rc.sb64_target_rate = ((int64_t)cpi->rc.this_frame_target * 64 * 64) /
                              (cpi->common.width * cpi->common.height);