Rate ctrl changes to track target bitrates closer
authorDeb Mukherjee <debargha@google.com>
Wed, 2 Apr 2014 00:31:59 +0000 (17:31 -0700)
committerDeb Mukherjee <debargha@google.com>
Wed, 2 Apr 2014 18:16:20 +0000 (11:16 -0700)
Turns off the DISABLE_RC_LONG_TERM_MEM macro and makes other changes
in the way the bits are updated, to make 2-pass rate control track
target bitrates closer.

Change-Id: I5f3be4b11c2908e6a9a9a1dd4fcf4e65531c44d8

vp9/encoder/vp9_bitstream.c
vp9/encoder/vp9_encodeframe.c
vp9/encoder/vp9_firstpass.c
vp9/encoder/vp9_firstpass.h
vp9/encoder/vp9_onyx_if.c
vp9/encoder/vp9_ratectrl.c
vp9/encoder/vp9_ratectrl.h
vp9/vp9_cx_iface.c

index 544a27d..7c811e2 100644 (file)
@@ -1186,7 +1186,7 @@ static size_t write_compressed_header(VP9_COMP *cpi, uint8_t *data) {
 
 void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, size_t *size) {
   uint8_t *data = dest;
-  size_t first_part_size;
+  size_t first_part_size, uncompressed_hdr_size;
   struct vp9_write_bit_buffer wb = {data, 0};
   struct vp9_write_bit_buffer saved_wb;
 
@@ -1194,7 +1194,8 @@ void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, size_t *size) {
   saved_wb = wb;
   vp9_wb_write_literal(&wb, 0, 16);  // don't know in advance first part. size
 
-  data += vp9_rb_bytes_written(&wb);
+  uncompressed_hdr_size = vp9_rb_bytes_written(&wb);
+  data += uncompressed_hdr_size;
 
   vp9_compute_update_table();
 
index cdca93a..42e1ac8 100644 (file)
@@ -2336,6 +2336,7 @@ static void encode_rd_sb_row(VP9_COMP *cpi, const TileInfo *const tile,
     if ((cpi->sf.partition_search_type == SEARCH_PARTITION &&
          cpi->sf.use_lastframe_partitioning) ||
         cpi->sf.partition_search_type == FIXED_PARTITION ||
+        cpi->sf.partition_search_type == VAR_BASED_PARTITION ||
         cpi->sf.partition_search_type == VAR_BASED_FIXED_PARTITION) {
       const int idx_str = cm->mi_stride * mi_row + mi_col;
       MODE_INFO **mi_8x8 = cm->mi_grid_visible + idx_str;
index cf0f805..7ec5255 100644 (file)
@@ -54,8 +54,6 @@
 
 #define MIN_KF_BOOST        300
 
-#define DISABLE_RC_LONG_TERM_MEM 0
-
 #if CONFIG_MULTIPLE_ARF
 // Set MIN_GF_INTERVAL to 1 for the full decomposition.
 #define MIN_GF_INTERVAL             2
@@ -1736,10 +1734,6 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
   {
     // Adjust KF group bits and error remaining.
     twopass->kf_group_error_left -= (int64_t)gf_group_err;
-    twopass->kf_group_bits -= twopass->gf_group_bits;
-
-    if (twopass->kf_group_bits < 0)
-      twopass->kf_group_bits = 0;
 
     // If this is an arf update we want to remove the score for the overlay
     // frame at the end which will usually be very cheap to code.
@@ -1756,11 +1750,6 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
       twopass->gf_group_error_left = (int64_t)gf_group_err;
     }
 
-    twopass->gf_group_bits -= twopass->gf_bits;
-
-    if (twopass->gf_group_bits < 0)
-      twopass->gf_group_bits = 0;
-
     // This condition could fail if there are two kfs very close together
     // despite MIN_GF_INTERVAL and would cause a divide by 0 in the
     // calculation of alt_extra_bits.
@@ -1769,8 +1758,9 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
 
       if (boost >= 150) {
         const int pct_extra = MIN(20, (boost - 100) / 50);
-        const int alt_extra_bits = (int)((twopass->gf_group_bits * pct_extra) /
-                                       100);
+        const int alt_extra_bits = (int)((
+            MAX(twopass->gf_group_bits - twopass->gf_bits, 0) *
+            pct_extra) / 100);
         twopass->gf_group_bits -= alt_extra_bits;
       }
     }
@@ -1823,10 +1813,6 @@ static void assign_std_frame_bits(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
 
   // Adjust error and bits remaining.
   cpi->twopass.gf_group_error_left -= (int64_t)modified_err;
-  cpi->twopass.gf_group_bits -= target_frame_size;
-
-  if (cpi->twopass.gf_group_bits < 0)
-    cpi->twopass.gf_group_bits = 0;
 
   // Per frame bit target for this frame.
   vp9_rc_set_frame_target(cpi, target_frame_size);
@@ -2343,23 +2329,20 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
   subtract_stats(&twopass->total_left_stats, &this_frame);
 }
 
-void vp9_twopass_postencode_update(VP9_COMP *cpi, uint64_t bytes_used) {
-#ifdef DISABLE_RC_LONG_TERM_MEM
-  cpi->twopass.bits_left -=  cpi->rc.this_frame_target;
-#else
-  cpi->twopass.bits_left -= 8 * bytes_used;
+void vp9_twopass_postencode_update(VP9_COMP *cpi) {
+  const uint64_t bits_used = cpi->rc.projected_frame_size;
+  cpi->twopass.bits_left -= bits_used;
+  cpi->twopass.bits_left = MAX(cpi->twopass.bits_left, 0);
   // Update bits left to the kf and gf groups to account for overshoot or
   // undershoot on these frames.
-  if (cm->frame_type == KEY_FRAME) {
-    cpi->twopass.kf_group_bits += cpi->rc.this_frame_target -
-        cpi->rc.projected_frame_size;
-
-    cpi->twopass.kf_group_bits = MAX(cpi->twopass.kf_group_bits, 0);
-  } else if (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame) {
-    cpi->twopass.gf_group_bits += cpi->rc.this_frame_target -
-        cpi->rc.projected_frame_size;
-
+  if (cpi->common.frame_type == KEY_FRAME) {
+    // For key frames kf_group_bits already had the target bits subtracted out.
+    // So now update to the correct value based on the actual bits used.
+    cpi->twopass.kf_group_bits += cpi->rc.this_frame_target - bits_used;
+  } else {
+    cpi->twopass.kf_group_bits -= bits_used;
+    cpi->twopass.gf_group_bits -= bits_used;
     cpi->twopass.gf_group_bits = MAX(cpi->twopass.gf_group_bits, 0);
   }
-#endif
+  cpi->twopass.kf_group_bits = MAX(cpi->twopass.kf_group_bits, 0);
 }
index 9268c38..7a16c8f 100644 (file)
@@ -95,8 +95,7 @@ int vp9_twopass_worst_quality(struct VP9_COMP *cpi, FIRSTPASS_STATS *fpstats,
                               int section_target_bandwitdh);
 
 // Post encode update of the rate control parameters for 2-pass
-void vp9_twopass_postencode_update(struct VP9_COMP *cpi,
-                                   uint64_t bytes_used);
+void vp9_twopass_postencode_update(struct VP9_COMP *cpi);
 #ifdef __cplusplus
 }  // extern "C"
 #endif
index 1f83f6b..f8427cf 100644 (file)
@@ -696,10 +696,9 @@ void vp9_new_framerate(VP9_COMP *cpi, double framerate) {
   oxcf->framerate = framerate < 0.1 ? 30 : framerate;
   cpi->output_framerate = cpi->oxcf.framerate;
   rc->av_per_frame_bandwidth = (int)(oxcf->target_bandwidth /
-                                         cpi->output_framerate);
+                                     cpi->output_framerate);
   rc->min_frame_bandwidth = (int)(rc->av_per_frame_bandwidth *
-                                      oxcf->two_pass_vbrmin_section / 100);
-
+                                  oxcf->two_pass_vbrmin_section / 100);
 
   rc->min_frame_bandwidth = MAX(rc->min_frame_bandwidth, FRAME_OVERHEAD_BITS);
 
@@ -2883,7 +2882,7 @@ static void Pass2Encode(VP9_COMP *cpi, size_t *size,
   vp9_rc_get_second_pass_params(cpi);
   encode_frame_to_data_rate(cpi, size, dest, frame_flags);
 
-  vp9_twopass_postencode_update(cpi, *size);
+  vp9_twopass_postencode_update(cpi);
 }
 
 static void check_initial_width(VP9_COMP *cpi, int subsampling_x,
index 9ee5818..0169014 100644 (file)
@@ -1150,10 +1150,9 @@ void vp9_rc_postencode_update(VP9_COMP *cpi, uint64_t bytes_used) {
 
   // Actual bits spent
   rc->total_actual_bits += rc->projected_frame_size;
+  rc->total_target_bits += (cm->show_frame ? rc->av_per_frame_bandwidth : 0);
 
-  // Debug stats
-  rc->total_target_vs_actual += (rc->this_frame_target -
-                                 rc->projected_frame_size);
+  rc->total_target_vs_actual = rc->total_actual_bits - rc->total_target_bits;
 
   if (cpi->oxcf.play_alternate && cpi->refresh_alt_ref_frame &&
       (cm->frame_type != KEY_FRAME))
index 87421af..f2d128c 100644 (file)
@@ -58,7 +58,7 @@ typedef struct {
   int ni_av_qi;
   int ni_tot_qi;
   int ni_frames;
-  int avg_frame_qindex[3];  // 0 - KEY, 1 - INTER, 2 - ARF/GF
+  int avg_frame_qindex[3];        // 0 - KEY, 1 - INTER, 2 - ARF/GF
   double tot_q;
   double avg_q;
 
@@ -75,7 +75,8 @@ typedef struct {
   int long_rolling_actual_bits;
 
   int64_t total_actual_bits;
-  int total_target_vs_actual;        // debug stats
+  int64_t total_target_bits;
+  int64_t total_target_vs_actual;
 
   int worst_quality;
   int best_quality;
index c39ccba..a9fd8c1 100644 (file)
@@ -730,8 +730,8 @@ static vpx_codec_err_t vp9e_encode(vpx_codec_alg_priv_t  *ctx,
     // Convert API flags to internal codec lib flags
     lib_flags = (flags & VPX_EFLAG_FORCE_KF) ? FRAMEFLAGS_KEY : 0;
 
-    // vp8 use 10,000,000 ticks/second as time stamp
-    dst_time_stamp = pts * 10000000 * ctx->cfg.g_timebase.num
+    /* vp9 use 10,000,000 ticks/second as time stamp */
+    dst_time_stamp = (pts * 10000000 * ctx->cfg.g_timebase.num)
                      / ctx->cfg.g_timebase.den;
     dst_end_time_stamp = (pts + duration) * 10000000 * ctx->cfg.g_timebase.num /
                          ctx->cfg.g_timebase.den;