1233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* 2233d2500723e5594f3e7c70896ffeeef32b9c950ywan * Copyright (c) 2014 The WebM project authors. All Rights Reserved. 3233d2500723e5594f3e7c70896ffeeef32b9c950ywan * 4233d2500723e5594f3e7c70896ffeeef32b9c950ywan * Use of this source code is governed by a BSD-style license 5233d2500723e5594f3e7c70896ffeeef32b9c950ywan * that can be found in the LICENSE file in the root of the source 6233d2500723e5594f3e7c70896ffeeef32b9c950ywan * tree. An additional intellectual property rights grant can be found 7233d2500723e5594f3e7c70896ffeeef32b9c950ywan * in the file PATENTS. All contributing project authors may 8233d2500723e5594f3e7c70896ffeeef32b9c950ywan * be found in the AUTHORS file in the root of the source tree. 9233d2500723e5594f3e7c70896ffeeef32b9c950ywan */ 10233d2500723e5594f3e7c70896ffeeef32b9c950ywan 11233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <assert.h> 12233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <stdlib.h> 13233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <limits.h> 14233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <stdio.h> 15233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <math.h> 16233d2500723e5594f3e7c70896ffeeef32b9c950ywan 17233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "./rate_hist.h" 18233d2500723e5594f3e7c70896ffeeef32b9c950ywan 19233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define RATE_BINS 100 20233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define HIST_BAR_MAX 40 21233d2500723e5594f3e7c70896ffeeef32b9c950ywan 22233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct hist_bucket { 23233d2500723e5594f3e7c70896ffeeef32b9c950ywan int low; 24233d2500723e5594f3e7c70896ffeeef32b9c950ywan int high; 25233d2500723e5594f3e7c70896ffeeef32b9c950ywan int count; 26233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 27233d2500723e5594f3e7c70896ffeeef32b9c950ywan 28233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct rate_hist { 29233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t *pts; 30233d2500723e5594f3e7c70896ffeeef32b9c950ywan int *sz; 31233d2500723e5594f3e7c70896ffeeef32b9c950ywan int samples; 32233d2500723e5594f3e7c70896ffeeef32b9c950ywan int frames; 33233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct hist_bucket bucket[RATE_BINS]; 34233d2500723e5594f3e7c70896ffeeef32b9c950ywan int total; 35233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 36233d2500723e5594f3e7c70896ffeeef32b9c950ywan 37233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct rate_hist *init_rate_histogram(const vpx_codec_enc_cfg_t *cfg, 38233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vpx_rational_t *fps) { 39233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i; 40233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct rate_hist *hist = malloc(sizeof(*hist)); 41233d2500723e5594f3e7c70896ffeeef32b9c950ywan 42233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Determine the number of samples in the buffer. Use the file's framerate 43233d2500723e5594f3e7c70896ffeeef32b9c950ywan // to determine the number of frames in rc_buf_sz milliseconds, with an 44233d2500723e5594f3e7c70896ffeeef32b9c950ywan // adjustment (5/4) to account for alt-refs 45233d2500723e5594f3e7c70896ffeeef32b9c950ywan hist->samples = cfg->rc_buf_sz * 5 / 4 * fps->num / fps->den / 1000; 46233d2500723e5594f3e7c70896ffeeef32b9c950ywan 47233d2500723e5594f3e7c70896ffeeef32b9c950ywan // prevent division by zero 48233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (hist->samples == 0) 49233d2500723e5594f3e7c70896ffeeef32b9c950ywan hist->samples = 1; 50233d2500723e5594f3e7c70896ffeeef32b9c950ywan 51233d2500723e5594f3e7c70896ffeeef32b9c950ywan hist->frames = 0; 52233d2500723e5594f3e7c70896ffeeef32b9c950ywan hist->total = 0; 53233d2500723e5594f3e7c70896ffeeef32b9c950ywan 54233d2500723e5594f3e7c70896ffeeef32b9c950ywan hist->pts = calloc(hist->samples, sizeof(*hist->pts)); 55233d2500723e5594f3e7c70896ffeeef32b9c950ywan hist->sz = calloc(hist->samples, sizeof(*hist->sz)); 56233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < RATE_BINS; i++) { 57233d2500723e5594f3e7c70896ffeeef32b9c950ywan hist->bucket[i].low = INT_MAX; 58233d2500723e5594f3e7c70896ffeeef32b9c950ywan hist->bucket[i].high = 0; 59233d2500723e5594f3e7c70896ffeeef32b9c950ywan hist->bucket[i].count = 0; 60233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 61233d2500723e5594f3e7c70896ffeeef32b9c950ywan 62233d2500723e5594f3e7c70896ffeeef32b9c950ywan return hist; 63233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 64233d2500723e5594f3e7c70896ffeeef32b9c950ywan 65233d2500723e5594f3e7c70896ffeeef32b9c950ywanvoid destroy_rate_histogram(struct rate_hist *hist) { 66233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (hist) { 67233d2500723e5594f3e7c70896ffeeef32b9c950ywan free(hist->pts); 68233d2500723e5594f3e7c70896ffeeef32b9c950ywan free(hist->sz); 69233d2500723e5594f3e7c70896ffeeef32b9c950ywan free(hist); 70233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 71233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 72233d2500723e5594f3e7c70896ffeeef32b9c950ywan 73233d2500723e5594f3e7c70896ffeeef32b9c950ywanvoid update_rate_histogram(struct rate_hist *hist, 74233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vpx_codec_enc_cfg_t *cfg, 75233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vpx_codec_cx_pkt_t *pkt) { 76233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i; 77233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t then = 0; 78233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t avg_bitrate = 0; 79233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t sum_sz = 0; 80233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int64_t now = pkt->data.frame.pts * 1000 * 81233d2500723e5594f3e7c70896ffeeef32b9c950ywan (uint64_t)cfg->g_timebase.num / 82233d2500723e5594f3e7c70896ffeeef32b9c950ywan (uint64_t)cfg->g_timebase.den; 83233d2500723e5594f3e7c70896ffeeef32b9c950ywan 84233d2500723e5594f3e7c70896ffeeef32b9c950ywan int idx = hist->frames++ % hist->samples; 85233d2500723e5594f3e7c70896ffeeef32b9c950ywan hist->pts[idx] = now; 86233d2500723e5594f3e7c70896ffeeef32b9c950ywan hist->sz[idx] = (int)pkt->data.frame.sz; 87233d2500723e5594f3e7c70896ffeeef32b9c950ywan 88233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (now < cfg->rc_buf_initial_sz) 89233d2500723e5594f3e7c70896ffeeef32b9c950ywan return; 90233d2500723e5594f3e7c70896ffeeef32b9c950ywan 91233d2500723e5594f3e7c70896ffeeef32b9c950ywan then = now; 92233d2500723e5594f3e7c70896ffeeef32b9c950ywan 93233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* Sum the size over the past rc_buf_sz ms */ 94233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = hist->frames; i > 0 && hist->frames - i < hist->samples; i--) { 95233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int i_idx = (i - 1) % hist->samples; 96233d2500723e5594f3e7c70896ffeeef32b9c950ywan 97233d2500723e5594f3e7c70896ffeeef32b9c950ywan then = hist->pts[i_idx]; 98233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (now - then > cfg->rc_buf_sz) 99233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 100233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_sz += hist->sz[i_idx]; 101233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 102233d2500723e5594f3e7c70896ffeeef32b9c950ywan 103233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (now == then) 104233d2500723e5594f3e7c70896ffeeef32b9c950ywan return; 105233d2500723e5594f3e7c70896ffeeef32b9c950ywan 106233d2500723e5594f3e7c70896ffeeef32b9c950ywan avg_bitrate = sum_sz * 8 * 1000 / (now - then); 107233d2500723e5594f3e7c70896ffeeef32b9c950ywan idx = (int)(avg_bitrate * (RATE_BINS / 2) / (cfg->rc_target_bitrate * 1000)); 108233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (idx < 0) 109233d2500723e5594f3e7c70896ffeeef32b9c950ywan idx = 0; 110233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (idx > RATE_BINS - 1) 111233d2500723e5594f3e7c70896ffeeef32b9c950ywan idx = RATE_BINS - 1; 112233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (hist->bucket[idx].low > avg_bitrate) 113233d2500723e5594f3e7c70896ffeeef32b9c950ywan hist->bucket[idx].low = (int)avg_bitrate; 114233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (hist->bucket[idx].high < avg_bitrate) 115233d2500723e5594f3e7c70896ffeeef32b9c950ywan hist->bucket[idx].high = (int)avg_bitrate; 116233d2500723e5594f3e7c70896ffeeef32b9c950ywan hist->bucket[idx].count++; 117233d2500723e5594f3e7c70896ffeeef32b9c950ywan hist->total++; 118233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 119233d2500723e5594f3e7c70896ffeeef32b9c950ywan 120233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int merge_hist_buckets(struct hist_bucket *bucket, 121233d2500723e5594f3e7c70896ffeeef32b9c950ywan int max_buckets, int *num_buckets) { 122233d2500723e5594f3e7c70896ffeeef32b9c950ywan int small_bucket = 0, merge_bucket = INT_MAX, big_bucket = 0; 123233d2500723e5594f3e7c70896ffeeef32b9c950ywan int buckets = *num_buckets; 124233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i; 125233d2500723e5594f3e7c70896ffeeef32b9c950ywan 126233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* Find the extrema for this list of buckets */ 127233d2500723e5594f3e7c70896ffeeef32b9c950ywan big_bucket = small_bucket = 0; 128233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < buckets; i++) { 129233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (bucket[i].count < bucket[small_bucket].count) 130233d2500723e5594f3e7c70896ffeeef32b9c950ywan small_bucket = i; 131233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (bucket[i].count > bucket[big_bucket].count) 132233d2500723e5594f3e7c70896ffeeef32b9c950ywan big_bucket = i; 133233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 134233d2500723e5594f3e7c70896ffeeef32b9c950ywan 135233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* If we have too many buckets, merge the smallest with an adjacent 136233d2500723e5594f3e7c70896ffeeef32b9c950ywan * bucket. 137233d2500723e5594f3e7c70896ffeeef32b9c950ywan */ 138233d2500723e5594f3e7c70896ffeeef32b9c950ywan while (buckets > max_buckets) { 139233d2500723e5594f3e7c70896ffeeef32b9c950ywan int last_bucket = buckets - 1; 140233d2500723e5594f3e7c70896ffeeef32b9c950ywan 141233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* merge the small bucket with an adjacent one. */ 142233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (small_bucket == 0) 143233d2500723e5594f3e7c70896ffeeef32b9c950ywan merge_bucket = 1; 144233d2500723e5594f3e7c70896ffeeef32b9c950ywan else if (small_bucket == last_bucket) 145233d2500723e5594f3e7c70896ffeeef32b9c950ywan merge_bucket = last_bucket - 1; 146233d2500723e5594f3e7c70896ffeeef32b9c950ywan else if (bucket[small_bucket - 1].count < bucket[small_bucket + 1].count) 147233d2500723e5594f3e7c70896ffeeef32b9c950ywan merge_bucket = small_bucket - 1; 148233d2500723e5594f3e7c70896ffeeef32b9c950ywan else 149233d2500723e5594f3e7c70896ffeeef32b9c950ywan merge_bucket = small_bucket + 1; 150233d2500723e5594f3e7c70896ffeeef32b9c950ywan 151233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(abs(merge_bucket - small_bucket) <= 1); 152233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(small_bucket < buckets); 153233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(big_bucket < buckets); 154233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(merge_bucket < buckets); 155233d2500723e5594f3e7c70896ffeeef32b9c950ywan 156233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (merge_bucket < small_bucket) { 157233d2500723e5594f3e7c70896ffeeef32b9c950ywan bucket[merge_bucket].high = bucket[small_bucket].high; 158233d2500723e5594f3e7c70896ffeeef32b9c950ywan bucket[merge_bucket].count += bucket[small_bucket].count; 159233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 160233d2500723e5594f3e7c70896ffeeef32b9c950ywan bucket[small_bucket].high = bucket[merge_bucket].high; 161233d2500723e5594f3e7c70896ffeeef32b9c950ywan bucket[small_bucket].count += bucket[merge_bucket].count; 162233d2500723e5594f3e7c70896ffeeef32b9c950ywan merge_bucket = small_bucket; 163233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 164233d2500723e5594f3e7c70896ffeeef32b9c950ywan 165233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(bucket[merge_bucket].low != bucket[merge_bucket].high); 166233d2500723e5594f3e7c70896ffeeef32b9c950ywan 167233d2500723e5594f3e7c70896ffeeef32b9c950ywan buckets--; 168233d2500723e5594f3e7c70896ffeeef32b9c950ywan 169233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* Remove the merge_bucket from the list, and find the new small 170233d2500723e5594f3e7c70896ffeeef32b9c950ywan * and big buckets while we're at it 171233d2500723e5594f3e7c70896ffeeef32b9c950ywan */ 172233d2500723e5594f3e7c70896ffeeef32b9c950ywan big_bucket = small_bucket = 0; 173233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < buckets; i++) { 174233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (i > merge_bucket) 175233d2500723e5594f3e7c70896ffeeef32b9c950ywan bucket[i] = bucket[i + 1]; 176233d2500723e5594f3e7c70896ffeeef32b9c950ywan 177233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (bucket[i].count < bucket[small_bucket].count) 178233d2500723e5594f3e7c70896ffeeef32b9c950ywan small_bucket = i; 179233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (bucket[i].count > bucket[big_bucket].count) 180233d2500723e5594f3e7c70896ffeeef32b9c950ywan big_bucket = i; 181233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 182233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 183233d2500723e5594f3e7c70896ffeeef32b9c950ywan 184233d2500723e5594f3e7c70896ffeeef32b9c950ywan *num_buckets = buckets; 185233d2500723e5594f3e7c70896ffeeef32b9c950ywan return bucket[big_bucket].count; 186233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 187233d2500723e5594f3e7c70896ffeeef32b9c950ywan 188233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void show_histogram(const struct hist_bucket *bucket, 189233d2500723e5594f3e7c70896ffeeef32b9c950ywan int buckets, int total, int scale) { 190233d2500723e5594f3e7c70896ffeeef32b9c950ywan const char *pat1, *pat2; 191233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i; 192233d2500723e5594f3e7c70896ffeeef32b9c950ywan 193233d2500723e5594f3e7c70896ffeeef32b9c950ywan switch ((int)(log(bucket[buckets - 1].high) / log(10)) + 1) { 194233d2500723e5594f3e7c70896ffeeef32b9c950ywan case 1: 195233d2500723e5594f3e7c70896ffeeef32b9c950ywan case 2: 196233d2500723e5594f3e7c70896ffeeef32b9c950ywan pat1 = "%4d %2s: "; 197233d2500723e5594f3e7c70896ffeeef32b9c950ywan pat2 = "%4d-%2d: "; 198233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 199233d2500723e5594f3e7c70896ffeeef32b9c950ywan case 3: 200233d2500723e5594f3e7c70896ffeeef32b9c950ywan pat1 = "%5d %3s: "; 201233d2500723e5594f3e7c70896ffeeef32b9c950ywan pat2 = "%5d-%3d: "; 202233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 203233d2500723e5594f3e7c70896ffeeef32b9c950ywan case 4: 204233d2500723e5594f3e7c70896ffeeef32b9c950ywan pat1 = "%6d %4s: "; 205233d2500723e5594f3e7c70896ffeeef32b9c950ywan pat2 = "%6d-%4d: "; 206233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 207233d2500723e5594f3e7c70896ffeeef32b9c950ywan case 5: 208233d2500723e5594f3e7c70896ffeeef32b9c950ywan pat1 = "%7d %5s: "; 209233d2500723e5594f3e7c70896ffeeef32b9c950ywan pat2 = "%7d-%5d: "; 210233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 211233d2500723e5594f3e7c70896ffeeef32b9c950ywan case 6: 212233d2500723e5594f3e7c70896ffeeef32b9c950ywan pat1 = "%8d %6s: "; 213233d2500723e5594f3e7c70896ffeeef32b9c950ywan pat2 = "%8d-%6d: "; 214233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 215233d2500723e5594f3e7c70896ffeeef32b9c950ywan case 7: 216233d2500723e5594f3e7c70896ffeeef32b9c950ywan pat1 = "%9d %7s: "; 217233d2500723e5594f3e7c70896ffeeef32b9c950ywan pat2 = "%9d-%7d: "; 218233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 219233d2500723e5594f3e7c70896ffeeef32b9c950ywan default: 220233d2500723e5594f3e7c70896ffeeef32b9c950ywan pat1 = "%12d %10s: "; 221233d2500723e5594f3e7c70896ffeeef32b9c950ywan pat2 = "%12d-%10d: "; 222233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 223233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 224233d2500723e5594f3e7c70896ffeeef32b9c950ywan 225233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < buckets; i++) { 226233d2500723e5594f3e7c70896ffeeef32b9c950ywan int len; 227233d2500723e5594f3e7c70896ffeeef32b9c950ywan int j; 228233d2500723e5594f3e7c70896ffeeef32b9c950ywan float pct; 229233d2500723e5594f3e7c70896ffeeef32b9c950ywan 230233d2500723e5594f3e7c70896ffeeef32b9c950ywan pct = (float)(100.0 * bucket[i].count / total); 231233d2500723e5594f3e7c70896ffeeef32b9c950ywan len = HIST_BAR_MAX * bucket[i].count / scale; 232233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (len < 1) 233233d2500723e5594f3e7c70896ffeeef32b9c950ywan len = 1; 234233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(len <= HIST_BAR_MAX); 235233d2500723e5594f3e7c70896ffeeef32b9c950ywan 236233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (bucket[i].low == bucket[i].high) 237233d2500723e5594f3e7c70896ffeeef32b9c950ywan fprintf(stderr, pat1, bucket[i].low, ""); 238233d2500723e5594f3e7c70896ffeeef32b9c950ywan else 239233d2500723e5594f3e7c70896ffeeef32b9c950ywan fprintf(stderr, pat2, bucket[i].low, bucket[i].high); 240233d2500723e5594f3e7c70896ffeeef32b9c950ywan 241233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (j = 0; j < HIST_BAR_MAX; j++) 242233d2500723e5594f3e7c70896ffeeef32b9c950ywan fprintf(stderr, j < len ? "=" : " "); 243233d2500723e5594f3e7c70896ffeeef32b9c950ywan fprintf(stderr, "\t%5d (%6.2f%%)\n", bucket[i].count, pct); 244233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 245233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 246233d2500723e5594f3e7c70896ffeeef32b9c950ywan 247233d2500723e5594f3e7c70896ffeeef32b9c950ywanvoid show_q_histogram(const int counts[64], int max_buckets) { 248233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct hist_bucket bucket[64]; 249233d2500723e5594f3e7c70896ffeeef32b9c950ywan int buckets = 0; 250233d2500723e5594f3e7c70896ffeeef32b9c950ywan int total = 0; 251233d2500723e5594f3e7c70896ffeeef32b9c950ywan int scale; 252233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i; 253233d2500723e5594f3e7c70896ffeeef32b9c950ywan 254233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < 64; i++) { 255233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (counts[i]) { 256233d2500723e5594f3e7c70896ffeeef32b9c950ywan bucket[buckets].low = bucket[buckets].high = i; 257233d2500723e5594f3e7c70896ffeeef32b9c950ywan bucket[buckets].count = counts[i]; 258233d2500723e5594f3e7c70896ffeeef32b9c950ywan buckets++; 259233d2500723e5594f3e7c70896ffeeef32b9c950ywan total += counts[i]; 260233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 261233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 262233d2500723e5594f3e7c70896ffeeef32b9c950ywan 263233d2500723e5594f3e7c70896ffeeef32b9c950ywan fprintf(stderr, "\nQuantizer Selection:\n"); 264233d2500723e5594f3e7c70896ffeeef32b9c950ywan scale = merge_hist_buckets(bucket, max_buckets, &buckets); 265233d2500723e5594f3e7c70896ffeeef32b9c950ywan show_histogram(bucket, buckets, total, scale); 266233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 267233d2500723e5594f3e7c70896ffeeef32b9c950ywan 268233d2500723e5594f3e7c70896ffeeef32b9c950ywanvoid show_rate_histogram(struct rate_hist *hist, 269233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vpx_codec_enc_cfg_t *cfg, int max_buckets) { 270233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i, scale; 271233d2500723e5594f3e7c70896ffeeef32b9c950ywan int buckets = 0; 272233d2500723e5594f3e7c70896ffeeef32b9c950ywan 273233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < RATE_BINS; i++) { 274233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (hist->bucket[i].low == INT_MAX) 275233d2500723e5594f3e7c70896ffeeef32b9c950ywan continue; 276233d2500723e5594f3e7c70896ffeeef32b9c950ywan hist->bucket[buckets++] = hist->bucket[i]; 277233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 278233d2500723e5594f3e7c70896ffeeef32b9c950ywan 279233d2500723e5594f3e7c70896ffeeef32b9c950ywan fprintf(stderr, "\nRate (over %dms window):\n", cfg->rc_buf_sz); 280233d2500723e5594f3e7c70896ffeeef32b9c950ywan scale = merge_hist_buckets(hist->bucket, max_buckets, &buckets); 281233d2500723e5594f3e7c70896ffeeef32b9c950ywan show_histogram(hist->bucket, buckets, hist->total, scale); 282233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 283