diff options
author | John Koleszar <jkoleszar@google.com> | 2011-06-21 16:42:33 -0400 |
---|---|---|
committer | John Koleszar <jkoleszar@google.com> | 2011-06-23 10:22:44 -0400 |
commit | c96f8e238d37f8063b306053fe9e663e05f3832f (patch) | |
tree | 2ff6247d10ab5179feceb6b0d5f077bb01a4ccb1 /vpxenc.c | |
parent | 3fde9964ce31948ebf2a11f1a0eae77d876600ee (diff) | |
download | libvpx-c96f8e238d37f8063b306053fe9e663e05f3832f.tar.gz |
vpxenc: add rate histogram display
Add the --rate-hist=n option, which displays a histogram with n
buckets for the rate over the --buf-sz window.
Change-Id: I2807b5a1525c7972e9ba40839b37e92b23ceffaf
Diffstat (limited to 'vpxenc.c')
-rw-r--r-- | vpxenc.c | 153 |
1 files changed, 149 insertions, 4 deletions
@@ -912,12 +912,14 @@ static const arg_def_t use_ivf = ARG_DEF(NULL, "ivf", 0, "Output IVF (default is WebM)"); static const arg_def_t q_hist_n = ARG_DEF(NULL, "q-hist", 1, "Show quantizer histogram (n-buckets)"); +static const arg_def_t rate_hist_n = ARG_DEF(NULL, "rate-hist", 1, + "Show rate histogram (n-buckets)"); static const arg_def_t *main_args[] = { &debugmode, &outputfile, &codecarg, &passes, &pass_arg, &fpf_name, &limit, &deadline, &best_dl, &good_dl, &rt_dl, - &verbosearg, &psnrarg, &use_ivf, &q_hist_n, + &verbosearg, &psnrarg, &use_ivf, &q_hist_n, &rate_hist_n, NULL }; @@ -1201,8 +1203,42 @@ static void show_histogram(const struct hist_bucket *bucket, int total, int scale) { + const char *pat1, *pat2; int i; + switch((int)(log(bucket[buckets-1].high)/log(10))+1) + { + case 1: + case 2: + pat1 = "%4d %2s: "; + pat2 = "%4d-%2d: "; + break; + case 3: + pat1 = "%5d %3s: "; + pat2 = "%5d-%3d: "; + break; + case 4: + pat1 = "%6d %4s: "; + pat2 = "%6d-%4d: "; + break; + case 5: + pat1 = "%7d %5s: "; + pat2 = "%7d-%5d: "; + break; + case 6: + pat1 = "%8d %6s: "; + pat2 = "%8d-%6d: "; + break; + case 7: + pat1 = "%9d %7s: "; + pat2 = "%9d-%7d: "; + break; + default: + pat1 = "%12d %10s: "; + pat2 = "%12d-%10d: "; + break; + } + for(i=0; i<buckets; i++) { int len; @@ -1216,9 +1252,9 @@ static void show_histogram(const struct hist_bucket *bucket, assert(len <= HIST_BAR_MAX); if(bucket[i].low == bucket[i].high) - fprintf(stderr, "%4d : ", bucket[i].low); + fprintf(stderr, pat1, bucket[i].low, ""); else - fprintf(stderr, "%4d-%2d: ", bucket[i].low, bucket[i].high); + fprintf(stderr, pat2, bucket[i].low, bucket[i].high); for(j=0; j<HIST_BAR_MAX; j++) fprintf(stderr, j<len?"=":" "); @@ -1247,12 +1283,110 @@ static void show_q_histogram(const int counts[64], int max_buckets) } } - fprintf(stderr, "Quantizer Selection:\n"); + fprintf(stderr, "\nQuantizer Selection:\n"); scale = merge_hist_buckets(bucket, &buckets, max_buckets); show_histogram(bucket, buckets, total, scale); } +#define RATE_BINS (100) +struct rate_hist +{ + int64_t *pts; + int *sz; + int samples; + int frames; + struct hist_bucket bucket[RATE_BINS]; + int total; +}; + + +static void init_rate_histogram(struct rate_hist *hist, + const vpx_codec_enc_cfg_t *cfg) +{ + int i; + + hist->samples = cfg->rc_buf_sz * 60 / 1000; // max 60 fps + hist->pts = calloc(hist->samples, sizeof(*hist->pts)); + hist->sz = calloc(hist->samples, sizeof(*hist->sz)); + for(i=0; i<RATE_BINS; i++) + { + hist->bucket[i].low = INT_MAX; + hist->bucket[i].high = 0; + hist->bucket[i].count = 0; + } +} + + +static void destroy_rate_histogram(struct rate_hist *hist) +{ + free(hist->pts); + free(hist->sz); +} + + +static void update_rate_histogram(struct rate_hist *hist, + const vpx_codec_enc_cfg_t *cfg, + const vpx_codec_cx_pkt_t *pkt) +{ + int i, idx; + int64_t now, then, sum_sz = 0, avg_bitrate; + + now = pkt->data.frame.pts * 1000 + * (uint64_t)cfg->g_timebase.num / (uint64_t)cfg->g_timebase.den; + + idx = hist->frames++ % hist->samples; + hist->pts[idx] = now; + hist->sz[idx] = pkt->data.frame.sz; + + if(now < cfg->rc_buf_initial_sz) + return; + + /* Sum the size over the past rc_buf_sz ms */ + for(i = hist->frames; i > 0; i--) + { + int i_idx = (i-1) % hist->samples; + + then = hist->pts[i_idx]; + if(now - then > cfg->rc_buf_sz) + break; + sum_sz += hist->sz[i_idx]; + } + + avg_bitrate = sum_sz * 8 * 1000 / (now - then); + idx = avg_bitrate * (RATE_BINS/2) / (cfg->rc_target_bitrate * 1000); + if(idx < 0) + idx = 0; + if(idx > RATE_BINS-1) + idx = RATE_BINS-1; + if(hist->bucket[idx].low > avg_bitrate) + hist->bucket[idx].low = avg_bitrate; + if(hist->bucket[idx].high < avg_bitrate) + hist->bucket[idx].high = avg_bitrate; + hist->bucket[idx].count++; + hist->total++; +} + + +static void show_rate_histogram(struct rate_hist *hist, + const vpx_codec_enc_cfg_t *cfg, + int max_buckets) +{ + int i, scale; + int buckets = 0; + + for(i = 0; i < RATE_BINS; i++) + { + if(hist->bucket[i].low == INT_MAX) + continue; + hist->bucket[buckets++] = hist->bucket[i]; + } + + fprintf(stderr, "\nRate (over %dms window):\n", cfg->rc_buf_sz); + scale = merge_hist_buckets(hist->bucket, &buckets, max_buckets); + show_histogram(hist->bucket, buckets, hist->total, scale); +} + #define ARG_CTRL_CNT_MAX 10 int main(int argc, const char **argv_) @@ -1293,6 +1427,8 @@ int main(int argc, const char **argv_) stereo_format_t stereo_fmt = STEREO_FORMAT_MONO; int counts[64]={0}; int show_q_hist_buckets=0; + int show_rate_hist_buckets=0; + struct rate_hist rate_hist={0}; exec_name = argv_[0]; ebml.last_pts_ms = -1; @@ -1378,6 +1514,8 @@ int main(int argc, const char **argv_) ebml.debug = 1; else if (arg_match(&arg, &q_hist_n, argi)) show_q_hist_buckets = arg_parse_uint(&arg); + else if (arg_match(&arg, &rate_hist_n, argi)) + show_rate_hist_buckets = arg_parse_uint(&arg); else argj++; } @@ -1561,6 +1699,8 @@ 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; @@ -1821,6 +1961,7 @@ int main(int argc, const char **argv_) fprintf(stderr, " %6luF", (unsigned long)pkt->data.frame.sz); + update_rate_histogram(&rate_hist, &cfg, pkt); if(write_webm) { /* Update the hash */ @@ -1921,6 +2062,10 @@ int main(int argc, const char **argv_) if (show_q_hist_buckets) show_q_histogram(counts, show_q_hist_buckets); + if (show_rate_hist_buckets) + show_rate_histogram(&rate_hist, &cfg, show_rate_hist_buckets); + destroy_rate_histogram(&rate_hist); + vpx_img_free(&raw); free(argv); return EXIT_SUCCESS; |