vpxenc: prevent wraparound in the --rate-hist ringbuffer
authorJohn Koleszar <jkoleszar@google.com>
Wed, 29 Jun 2011 13:53:12 +0000 (09:53 -0400)
committerJohn Koleszar <jkoleszar@google.com>
Wed, 29 Jun 2011 14:30:19 +0000 (10:30 -0400)
For clips that are near 60fps and have a lot of alt refs, it's possible
that the ring buffer holding the previous frames sizes/pts could wrap
around, leading to a division by zero.

In addition to checking for this condition in the ring buffer loop,
the buffer size is made dependent on the actual frame rate in use,
rather than defaulting to 60, which should improve accuracy at frame
rates >= ~60.

Change-Id: If5a04d6e847316dc5f7504f25c01164cf9332be8

vpxenc.c

index 26afcd6..82f9071 100644 (file)
--- a/vpxenc.c
+++ b/vpxenc.c
@@ -1302,11 +1302,16 @@ struct rate_hist
 
 
 static void init_rate_histogram(struct rate_hist          *hist,
-                                const vpx_codec_enc_cfg_t *cfg)
+                                const vpx_codec_enc_cfg_t *cfg,
+                                const vpx_rational_t      *fps)
 {
     int i;
 
-    hist->samples = cfg->rc_buf_sz * 60 / 1000; // max 60 fps
+    /* Determine the number of samples in the buffer. Use the file's framerate
+     * to determine the number of frames in rc_buf_sz milliseconds, with an
+     * adjustment (5/4) to account for alt-refs
+     */
+    hist->samples = cfg->rc_buf_sz * 5 / 4 * fps->num / fps->den / 1000;
     hist->pts = calloc(hist->samples, sizeof(*hist->pts));
     hist->sz = calloc(hist->samples, sizeof(*hist->sz));
     for(i=0; i<RATE_BINS; i++)
@@ -1343,7 +1348,7 @@ static void update_rate_histogram(struct rate_hist          *hist,
         return;
 
     /* Sum the size over the past rc_buf_sz ms */
-    for(i = hist->frames; i > 0; i--)
+    for(i = hist->frames; i > 0 && hist->frames - i < hist->samples; i--)
     {
         int i_idx = (i-1) % hist->samples;
 
@@ -1699,8 +1704,6 @@ int main(int argc, const char **argv_)
 
     memset(&stats, 0, sizeof(stats));
 
-    init_rate_histogram(&rate_hist, &cfg);
-
     for (pass = one_pass_only ? one_pass_only - 1 : 0; pass < arg_passes; pass++)
     {
         int frames_in = 0, frames_out = 0;
@@ -1827,6 +1830,8 @@ int main(int argc, const char **argv_)
             else
                 vpx_img_alloc(&raw, arg_use_i420 ? VPX_IMG_FMT_I420 : VPX_IMG_FMT_YV12,
                               cfg.g_w, cfg.g_h, 1);
+
+            init_rate_histogram(&rate_hist, &cfg, &arg_framerate);
         }
 
         outfile = strcmp(out_fn, "-") ? fopen(out_fn, "wb")