Cap target bitrate to raw rate internally
authorJerome Jiang <jianj@google.com>
Wed, 8 Jul 2020 00:44:13 +0000 (17:44 -0700)
committerJerome Jiang <jianj@google.com>
Fri, 10 Jul 2020 03:25:45 +0000 (20:25 -0700)
BUG=webm:1685

Change-Id: Ida72fe854fadb19c3745724e74b67d88087eb83c

test/realtime_test.cc
vp8/encoder/bitstream.c
vp8/encoder/onyx_if.c
vp9/encoder/vp9_pickmode.c
vp9/encoder/vp9_ratectrl.c
vp9/vp9_cx_iface.c

index 25a933b..63a5347 100644 (file)
@@ -63,15 +63,10 @@ TEST_P(RealtimeTest, RealtimeFirstPassProducesFrames) {
   EXPECT_EQ(kFramesToEncode, frame_packets_);
 }
 
-// TODO(https://crbug.com/webm/1685): the following passes -fsanitize=undefined
-// with bitrate set to 140000000 for vp8 and 128000 for vp9. There are
-// additional failures with lower bitrates using -fsanitize=integer.
-TEST_P(RealtimeTest, DISABLED_IntegerOverflow) {
+TEST_P(RealtimeTest, IntegerOverflow) {
   ::libvpx_test::RandomVideoSource video;
   video.SetSize(800, 480);
   video.set_limit(20);
-  // TODO(https://crbug.com/webm/1685): this should be silently capped
-  // internally to the raw yuv rate or below.
   cfg_.rc_target_bitrate = 140000000;
   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
 }
index 3daa4e2..80cbb88 100644 (file)
@@ -222,7 +222,7 @@ void vp8_pack_tokens(vp8_writer *w, const TOKENEXTRA *p, int xcount) {
 
             validate_buffer(w->buffer + w->pos, 1, w->buffer_end, w->error);
 
-            w->buffer[w->pos++] = (lowvalue >> (24 - offset));
+            w->buffer[w->pos++] = (lowvalue >> (24 - offset)) & 0xff;
             lowvalue <<= offset;
             shift = count;
             lowvalue &= 0xffffff;
index dccc6eb..aeed719 100644 (file)
@@ -1430,6 +1430,7 @@ void vp8_change_config(VP8_COMP *cpi, VP8_CONFIG *oxcf) {
   VP8_COMMON *cm = &cpi->common;
   int last_w, last_h;
   unsigned int prev_number_of_layers;
+  unsigned int raw_target_rate;
 
   if (!cpi) return;
 
@@ -1570,6 +1571,10 @@ void vp8_change_config(VP8_COMP *cpi, VP8_CONFIG *oxcf) {
     cpi->oxcf.maximum_buffer_size_in_ms = 240000;
   }
 
+  raw_target_rate = (unsigned int)((int64_t)cpi->oxcf.Width * cpi->oxcf.Height *
+                                   8 * 3 * cpi->framerate / 1000);
+  if (cpi->oxcf.target_bandwidth > raw_target_rate)
+    cpi->oxcf.target_bandwidth = raw_target_rate;
   /* Convert target bandwidth from Kbit/s to Bit/s */
   cpi->oxcf.target_bandwidth *= 1000;
 
@@ -3615,7 +3620,7 @@ static void encode_frame_to_data_rate(VP8_COMP *cpi, size_t *size,
         if (cpi->this_key_frame_forced) {
           if (cpi->active_best_quality > cpi->avg_frame_qindex * 7 / 8) {
             cpi->active_best_quality = cpi->avg_frame_qindex * 7 / 8;
-          } else if (cpi->active_best_quality<cpi->avg_frame_qindex>> 2) {
+          } else if (cpi->active_best_quality < (cpi->avg_frame_qindex >> 2)) {
             cpi->active_best_quality = cpi->avg_frame_qindex >> 2;
           }
         }
index 23c943c..695fd48 100644 (file)
@@ -1127,7 +1127,7 @@ static INLINE void update_thresh_freq_fact_row_mt(
 }
 
 static INLINE void update_thresh_freq_fact(
-    VP9_COMP *cpi, TileDataEnc *tile_data, int source_variance,
+    VP9_COMP *cpi, TileDataEnc *tile_data, unsigned int source_variance,
     BLOCK_SIZE bsize, MV_REFERENCE_FRAME ref_frame, THR_MODES best_mode_idx,
     PREDICTION_MODE mode) {
   THR_MODES thr_mode_idx = mode_idx[ref_frame][mode_offset(mode)];
index c8b3e0b..2afa361 100644 (file)
@@ -1695,8 +1695,10 @@ void vp9_rc_compute_frame_size_bounds(const VP9_COMP *cpi, int frame_target,
   } else {
     // For very small rate targets where the fractional adjustment
     // may be tiny make sure there is at least a minimum range.
-    const int tol_low = (cpi->sf.recode_tolerance_low * frame_target) / 100;
-    const int tol_high = (cpi->sf.recode_tolerance_high * frame_target) / 100;
+    const int tol_low =
+        (int)(((int64_t)cpi->sf.recode_tolerance_low * frame_target) / 100);
+    const int tol_high =
+        (int)(((int64_t)cpi->sf.recode_tolerance_high * frame_target) / 100);
     *frame_under_shoot_limit = VPXMAX(frame_target - tol_low - 100, 0);
     *frame_over_shoot_limit =
         VPXMIN(frame_target + tol_high + 100, cpi->rc.max_frame_bandwidth);
index 15aa7e6..9074e1b 100644 (file)
@@ -470,10 +470,11 @@ static vpx_rational64_t get_g_timebase_in_ts(vpx_rational_t g_timebase) {
 }
 
 static vpx_codec_err_t set_encoder_config(
-    VP9EncoderConfig *oxcf, const vpx_codec_enc_cfg_t *cfg,
+    VP9EncoderConfig *oxcf, vpx_codec_enc_cfg_t *cfg,
     const struct vp9_extracfg *extra_cfg) {
   const int is_vbr = cfg->rc_end_usage == VPX_VBR;
   int sl, tl;
+  unsigned int raw_target_rate;
   oxcf->profile = cfg->g_profile;
   oxcf->max_threads = (int)cfg->g_threads;
   oxcf->width = cfg->g_w;
@@ -500,8 +501,14 @@ static vpx_codec_err_t set_encoder_config(
       cfg->g_pass == VPX_RC_FIRST_PASS ? 0 : cfg->g_lag_in_frames;
   oxcf->rc_mode = cfg->rc_end_usage;
 
+  raw_target_rate =
+      (unsigned int)((int64_t)oxcf->width * oxcf->height * oxcf->bit_depth * 3 *
+                     oxcf->init_framerate / 1000);
+  // Cap target bitrate to raw rate
+  cfg->rc_target_bitrate = VPXMIN(raw_target_rate, cfg->rc_target_bitrate);
+
   // Convert target bandwidth from Kbit/s to Bit/s
-  oxcf->target_bandwidth = 1000 * cfg->rc_target_bitrate;
+  oxcf->target_bandwidth = 1000 * (int64_t)cfg->rc_target_bitrate;
   oxcf->rc_max_intra_bitrate_pct = extra_cfg->rc_max_intra_bitrate_pct;
   oxcf->rc_max_inter_bitrate_pct = extra_cfg->rc_max_inter_bitrate_pct;
   oxcf->gf_cbr_boost_pct = extra_cfg->gf_cbr_boost_pct;