vp9_tokenize.c 18.9 KB
Newer Older
John Koleszar's avatar
John Koleszar committed
1
/*
2
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
John Koleszar's avatar
John Koleszar committed
3
 *
4
 *  Use of this source code is governed by a BSD-style license
5 6
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
7
 *  in the file PATENTS.  All contributing project authors may
8
 *  be found in the AUTHORS file in the root of the source tree.
John Koleszar's avatar
John Koleszar committed
9 10 11 12 13 14 15
 */


#include <math.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
16 17
#include "vp9/encoder/vp9_onyx_int.h"
#include "vp9/encoder/vp9_tokenize.h"
John Koleszar's avatar
John Koleszar committed
18 19
#include "vpx_mem/vpx_mem.h"

20 21 22
#include "vp9/common/vp9_pred_common.h"
#include "vp9/common/vp9_seg_common.h"
#include "vp9/common/vp9_entropy.h"
23

John Koleszar's avatar
John Koleszar committed
24
/* Global event counters used for accumulating statistics across several
25
   compressions, then generating vp9_context.c = initial stats. */
John Koleszar's avatar
John Koleszar committed
26 27

#ifdef ENTROPY_STATS
28 29 30
vp9_coeff_accum context_counters_4x4[BLOCK_TYPES];
vp9_coeff_accum context_counters_8x8[BLOCK_TYPES];
vp9_coeff_accum context_counters_16x16[BLOCK_TYPES];
31
vp9_coeff_accum context_counters_32x32[BLOCK_TYPES];
32

33 34 35
extern vp9_coeff_stats tree_update_hist_4x4[BLOCK_TYPES];
extern vp9_coeff_stats tree_update_hist_8x8[BLOCK_TYPES];
extern vp9_coeff_stats tree_update_hist_16x16[BLOCK_TYPES];
36
extern vp9_coeff_stats tree_update_hist_32x32[BLOCK_TYPES];
37 38
#endif  /* ENTROPY_STATS */

John Koleszar's avatar
John Koleszar committed
39
static TOKENVALUE dct_value_tokens[DCT_MAX_VALUE * 2];
40
const TOKENVALUE *vp9_dct_value_tokens_ptr;
John Koleszar's avatar
John Koleszar committed
41
static int dct_value_cost[DCT_MAX_VALUE * 2];
42
const int *vp9_dct_value_cost_ptr;
43

John Koleszar's avatar
John Koleszar committed
44
static void fill_value_tokens() {
John Koleszar's avatar
John Koleszar committed
45

John Koleszar's avatar
John Koleszar committed
46
  TOKENVALUE *const t = dct_value_tokens + DCT_MAX_VALUE;
47
  vp9_extra_bit *const e = vp9_extra_bits;
John Koleszar's avatar
John Koleszar committed
48

John Koleszar's avatar
John Koleszar committed
49 50
  int i = -DCT_MAX_VALUE;
  int sign = 1;
John Koleszar's avatar
John Koleszar committed
51

John Koleszar's avatar
John Koleszar committed
52 53 54
  do {
    if (!i)
      sign = 0;
John Koleszar's avatar
John Koleszar committed
55

John Koleszar's avatar
John Koleszar committed
56 57 58
    {
      const int a = sign ? -i : i;
      int eb = sign;
John Koleszar's avatar
John Koleszar committed
59

John Koleszar's avatar
John Koleszar committed
60 61
      if (a > 4) {
        int j = 4;
John Koleszar's avatar
John Koleszar committed
62

John Koleszar's avatar
John Koleszar committed
63
        while (++j < 11  &&  e[j].base_val <= a) {}
John Koleszar's avatar
John Koleszar committed
64

65
        t[i].token = --j;
John Koleszar's avatar
John Koleszar committed
66 67
        eb |= (a - e[j].base_val) << 1;
      } else
68
        t[i].token = a;
John Koleszar's avatar
John Koleszar committed
69

70
      t[i].extra = eb;
John Koleszar's avatar
John Koleszar committed
71
    }
John Koleszar's avatar
John Koleszar committed
72

John Koleszar's avatar
John Koleszar committed
73 74 75
    // initialize the cost for extra bits for all possible coefficient value.
    {
      int cost = 0;
76
      vp9_extra_bit *p = vp9_extra_bits + t[i].token;
John Koleszar's avatar
John Koleszar committed
77

John Koleszar's avatar
John Koleszar committed
78
      if (p->base_val) {
79
        const int extra = t[i].extra;
80
        const int length = p->len;
John Koleszar's avatar
John Koleszar committed
81

82 83
        if (length)
          cost += treed_cost(p->tree, p->prob, extra >> 1, length);
John Koleszar's avatar
John Koleszar committed
84

85
        cost += vp9_cost_bit(vp9_prob_half, extra & 1); /* sign */
John Koleszar's avatar
John Koleszar committed
86 87
        dct_value_cost[i + DCT_MAX_VALUE] = cost;
      }
John Koleszar's avatar
John Koleszar committed
88 89 90

    }

John Koleszar's avatar
John Koleszar committed
91 92
  } while (++i < DCT_MAX_VALUE);

93 94
  vp9_dct_value_tokens_ptr = dct_value_tokens + DCT_MAX_VALUE;
  vp9_dct_value_cost_ptr   = dct_value_cost + DCT_MAX_VALUE;
John Koleszar's avatar
John Koleszar committed
95
}
96

97 98
extern const int *vp9_get_coef_neighbors_handle(const int *scan, int *pad);

99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
struct tokenize_b_args {
  VP9_COMP *cpi;
  MACROBLOCKD *xd;
  TOKENEXTRA **tp;
  TX_SIZE tx_size;
  int dry_run;
};
static void tokenize_b(int plane, int block, BLOCK_SIZE_TYPE bsize,
                       int ss_txfrm_size, void *arg) {
  struct tokenize_b_args* const args = arg;
  VP9_COMP *cpi = args->cpi;
  MACROBLOCKD *xd = args->xd;
  TOKENEXTRA **tp = args->tp;
  PLANE_TYPE type = plane ? PLANE_TYPE_UV : PLANE_TYPE_Y_WITH_DC;
  TX_SIZE tx_size = ss_txfrm_size / 2;
  int dry_run = args->dry_run;

116
  MB_MODE_INFO *mbmi = &xd->mode_info_context->mbmi;
Daniel Kang's avatar
Daniel Kang committed
117
  int pt; /* near block/prev token context index */
118
  int c = 0, rc = 0;
Daniel Kang's avatar
Daniel Kang committed
119
  TOKENEXTRA *t = *tp;        /* store tokens starting here */
120 121
  const int eob = xd->plane[plane].eobs[block];
  const int16_t *qcoeff_ptr = BLOCK_OFFSET(xd->plane[plane].qcoeff, block, 16);
122 123
  const BLOCK_SIZE_TYPE sb_type = mbmi->sb_type;
  const int bwl = b_width_log2(sb_type);
124 125
  const int off = block >> (2 * tx_size);
  const int mod = bwl - tx_size - xd->plane[plane].subsampling_x;
126 127
  const int aoff = (off & ((1 << mod) - 1)) << tx_size;
  const int loff = (off >> mod) << tx_size;
128 129
  ENTROPY_CONTEXT *A = xd->plane[plane].above_context + aoff;
  ENTROPY_CONTEXT *L = xd->plane[plane].left_context + loff;
130
  int seg_eob, default_eob, pad;
131
  const int segment_id = mbmi->segment_id;
132
  const int *scan, *nb;
133
  vp9_coeff_count *counts;
134
  vp9_coeff_probs *coef_probs;
135
  const int ref = mbmi->ref_frame != INTRA_FRAME;
136
  ENTROPY_CONTEXT above_ec, left_ec;
137
  uint8_t token_cache[1024];
138 139 140 141 142 143 144 145 146 147 148 149 150 151
  TX_TYPE tx_type = DCT_DCT;
#if CONFIG_CODE_ZEROGROUP
  int last_nz_pos[3] = {-1, -1, -1};  // Encoder only
  int is_eoo_list[3] = {0, 0, 0};
  int is_last_zero[3] = {0, 0, 0};
  int is_eoo_negative[3] = {0, 0, 0};
  int o;
  vp9_zpc_probs *zpc_probs;
  vp9_zpc_count *zpc_count;
  uint8_t token_cache_full[1024];
#endif
#if CONFIG_CODE_ZEROGROUP
  vpx_memset(token_cache, UNKNOWN_TOKEN, sizeof(token_cache));
#endif
152

153
  assert((!type && !plane) || (type && plane));
154

155 156
  switch (tx_size) {
    default:
157
    case TX_4X4: {
158
      tx_type = (type == PLANE_TYPE_Y_WITH_DC) ?
John Koleszar's avatar
John Koleszar committed
159
          get_tx_type_4x4(xd, block) : DCT_DCT;
160 161
      above_ec = A[0] != 0;
      left_ec = L[0] != 0;
162
      seg_eob = 16;
163
      scan = get_scan_4x4(tx_type);
164
      counts = cpi->coef_counts_4x4;
165 166 167 168 169
      coef_probs = cpi->common.fc.coef_probs_4x4;
#if CONFIG_CODE_ZEROGROUP
      zpc_count = &cpi->common.fc.zpc_counts_4x4;
      zpc_probs = &cpi->common.fc.zpc_probs_4x4;
#endif
170
      break;
171
    }
172
    case TX_8X8: {
173
      const int sz = 1 + b_width_log2(sb_type);
John Koleszar's avatar
John Koleszar committed
174
      const int x = block & ((1 << sz) - 1), y = block - x;
175 176
      tx_type = (type == PLANE_TYPE_Y_WITH_DC) ?
          get_tx_type_8x8(xd, y + (x >> 1)) : DCT_DCT;
177 178
      above_ec = (A[0] + A[1]) != 0;
      left_ec = (L[0] + L[1]) != 0;
179
      seg_eob = 64;
180
      scan = get_scan_8x8(tx_type);
181
      counts = cpi->coef_counts_8x8;
182 183 184 185 186
      coef_probs = cpi->common.fc.coef_probs_8x8;
#if CONFIG_CODE_ZEROGROUP
      zpc_count = &cpi->common.fc.zpc_counts_8x8;
      zpc_probs = &cpi->common.fc.zpc_probs_8x8;
#endif
187
      break;
188 189
    }
    case TX_16X16: {
190
      const int sz = 2 + b_width_log2(sb_type);
John Koleszar's avatar
John Koleszar committed
191
      const int x = block & ((1 << sz) - 1), y = block - x;
192 193
      tx_type = (type == PLANE_TYPE_Y_WITH_DC) ?
          get_tx_type_16x16(xd, y + (x >> 2)) : DCT_DCT;
194 195
      above_ec = (A[0] + A[1] + A[2] + A[3]) != 0;
      left_ec = (L[0] + L[1] + L[2] + L[3]) != 0;
196
      seg_eob = 256;
197
      scan = get_scan_16x16(tx_type);
198
      counts = cpi->coef_counts_16x16;
199 200 201 202 203
      coef_probs = cpi->common.fc.coef_probs_16x16;
#if CONFIG_CODE_ZEROGROUP
      zpc_count = &cpi->common.fc.zpc_counts_16x16;
      zpc_probs = &cpi->common.fc.zpc_probs_16x16;
#endif
204
      break;
205
    }
206
    case TX_32X32:
207 208
      above_ec = (A[0] + A[1] + A[2] + A[3] + A[4] + A[5] + A[6] + A[7]) != 0;
      left_ec = (L[0] + L[1] + L[2] + L[3] + L[4] + L[5] + L[6] + L[7]) != 0;
209 210 211
      seg_eob = 1024;
      scan = vp9_default_zig_zag1d_32x32;
      counts = cpi->coef_counts_32x32;
212 213 214 215 216
      coef_probs = cpi->common.fc.coef_probs_32x32;
#if CONFIG_CODE_ZEROGROUP
      zpc_count = &cpi->common.fc.zpc_counts_32x32;
      zpc_probs = &cpi->common.fc.zpc_probs_32x32;
#endif
217
      break;
John Koleszar's avatar
John Koleszar committed
218 219
  }

220
  pt = combine_entropy_contexts(above_ec, left_ec);
221 222
  nb = vp9_get_coef_neighbors_handle(scan, &pad);
  default_eob = seg_eob;
Yaowu Xu's avatar
Yaowu Xu committed
223

Paul Wilkins's avatar
Paul Wilkins committed
224 225
  if (vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP))
    seg_eob = 0;
John Koleszar's avatar
John Koleszar committed
226

227 228 229 230 231 232 233 234 235 236 237 238
#if CONFIG_CODE_ZEROGROUP
  vpx_memset(token_cache_full, ZERO_TOKEN, sizeof(token_cache_full));
  for (c = 0; c < eob; ++c) {
    rc = scan[c];
    token_cache_full[rc] = vp9_dct_value_tokens_ptr[qcoeff_ptr[rc]].token;
    o = vp9_get_orientation(rc, tx_size);
    if (qcoeff_ptr[rc] != 0) {
      last_nz_pos[o] = c;
    }
  }
#endif
  c = 0;
239
  do {
240
    const int band = get_coef_band(scan, tx_size, c);
241
    int token;
242
    int v = 0;
243 244 245
    rc = scan[c];
    if (c)
      pt = vp9_get_coef_context(scan, nb, pad, token_cache, c, default_eob);
246
    if (c < eob) {
247
      v = qcoeff_ptr[rc];
248 249
      assert(-DCT_MAX_VALUE <= v  &&  v < DCT_MAX_VALUE);

250 251
      t->extra = vp9_dct_value_tokens_ptr[v].extra;
      token    = vp9_dct_value_tokens_ptr[v].token;
252
    } else {
253
      token = DCT_EOB_TOKEN;
254
    }
John Koleszar's avatar
John Koleszar committed
255

256
    t->token = token;
257 258
    t->context_tree = coef_probs[type][ref][band][pt];
      t->skip_eob_node = (c > 0) && (token_cache[scan[c - 1]] == 0);
259
    assert(vp9_coef_encodings[t->token].len - t->skip_eob_node > 0);
260 261 262 263 264 265 266 267 268 269 270 271 272 273
#if CONFIG_CODE_ZEROGROUP
    o = vp9_get_orientation(rc, tx_size);
    t->skip_coef_val = (token_cache[rc] == ZERO_TOKEN || is_eoo_list[o]);
    if (t->skip_coef_val) {
      assert(v == 0);
    }
    // No need to transmit any token
    if (t->skip_eob_node && t->skip_coef_val) {
      assert(token == ZERO_TOKEN);
      is_last_zero[o] = 1;
      token_cache[scan[c]] = ZERO_TOKEN;
      continue;
    }
#endif
274
    if (!dry_run) {
275
      ++counts[type][ref][band][pt][token];
276 277
      if (!t->skip_eob_node)
        ++cpi->common.fc.eob_branch_counts[tx_size][type][ref][band][pt];
278
    }
279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347
    token_cache[scan[c]] = token;
#if CONFIG_CODE_ZEROGROUP
    if (token == ZERO_TOKEN && !t->skip_coef_val) {
      int eoo = 0, use_eoo;
#if USE_ZPC_EOORIENT == 1
      use_eoo = vp9_use_eoo(c, seg_eob, scan, tx_size,
                            is_last_zero, is_eoo_list);
#else
      use_eoo = 0;
#endif
      if (use_eoo) {
        eoo = vp9_is_eoo(c, eob, scan, tx_size, qcoeff_ptr, last_nz_pos);
        if (eoo && is_eoo_negative[o]) eoo = 0;
        if (eoo) {
          int c_;
          int savings = 0;
          int zsaved = 0;
          savings =
              vp9_cost_bit((*zpc_probs)[ref]
                           [coef_to_zpc_band(band)]
                           [coef_to_zpc_ptok(pt)][0], 1) -
              vp9_cost_bit((*zpc_probs)[ref]
                           [coef_to_zpc_band(band)]
                           [coef_to_zpc_ptok(pt)][0], 0);
          for (c_ = c + 1; c_ < eob; ++c_) {
            if (o == vp9_get_orientation(scan[c_], tx_size)) {
              int pt_ = vp9_get_coef_context(scan, nb, pad, token_cache_full,
                                             c_, default_eob);
              int band_ = get_coef_band(scan, tx_size, c_);
              assert(token_cache_full[scan[c_]] == ZERO_TOKEN);
              if (!c_ || token_cache_full[scan[c_ - 1]])
                savings +=
                    vp9_cost_bit(coef_probs[type][ref][band_][pt_][0], 1);
              savings += vp9_cost_bit(coef_probs[type][ref][band_][pt_][1], 0);
              zsaved++;
            }
          }
          /*
          if (!dry_run)
            if (savings > 0)
              printf("savings %d zsaved %d (%d, %d)\n",
                     savings, zsaved, tx_size, band);
                     */
          if (savings < 0) {
            eoo = 0;
            is_eoo_negative[o] = 1;
          }
        }
      }
      if (use_eoo) {
        t++;
        t->skip_eob_node = t->skip_coef_val = 0;
        // transmit the eoo symbol
        t->token = !eoo ? ZPC_ISOLATED : ZPC_EOORIENT;
        t->context_tree = &((*zpc_probs)[ref]
                            [coef_to_zpc_band(band)]
                            [coef_to_zpc_ptok(pt)][0]);
        if (!dry_run)
          (*zpc_count)[ref]
              [coef_to_zpc_band(band)]
              [coef_to_zpc_ptok(pt)][0][!eoo]++;
        if (eoo) {
          assert(is_eoo_list[o] == 0);
          is_eoo_list[o] = 1;
        }
      }
    }
    is_last_zero[o] = (token == ZERO_TOKEN);
#endif
348
    ++t;
349
  } while (c < eob && ++c < seg_eob);
350 351

  *tp = t;
352 353
  for (pt = 0; pt < (1 << tx_size); pt++) {
    A[pt] = L[pt] = c > 0;
Yaowu Xu's avatar
Yaowu Xu committed
354
  }
John Koleszar's avatar
John Koleszar committed
355 356
}

357 358 359 360 361
struct is_skippable_args {
  MACROBLOCKD *xd;
  int *skippable;
};
static void is_skippable(int plane, int block,
362
                         BLOCK_SIZE_TYPE bsize, int ss_txfrm_size, void *argv) {
363 364
  struct is_skippable_args *args = argv;
  args->skippable[0] &= (!args->xd->plane[plane].eobs[block]);
Deb Mukherjee's avatar
Deb Mukherjee committed
365 366
}

367 368 369
int vp9_sb_is_skippable(MACROBLOCKD *xd, BLOCK_SIZE_TYPE bsize) {
  int result = 1;
  struct is_skippable_args args = {xd, &result};
370
  foreach_transformed_block(xd, bsize, is_skippable, &args);
371
  return result;
372 373
}

374 375 376
int vp9_sby_is_skippable(MACROBLOCKD *xd, BLOCK_SIZE_TYPE bsize) {
  int result = 1;
  struct is_skippable_args args = {xd, &result};
377 378
  foreach_transformed_block_in_plane(xd, bsize, 0,
                                     is_skippable, &args);
379
  return result;
380 381
}

382 383 384
int vp9_sbuv_is_skippable(MACROBLOCKD *xd, BLOCK_SIZE_TYPE bsize) {
  int result = 1;
  struct is_skippable_args args = {xd, &result};
385
  foreach_transformed_block_uv(xd, bsize, is_skippable, &args);
386
  return result;
387 388
}

389 390 391
void vp9_tokenize_sb(VP9_COMP *cpi,
                     MACROBLOCKD *xd,
                     TOKENEXTRA **t,
392
                     int dry_run, BLOCK_SIZE_TYPE bsize) {
393 394 395 396 397
  VP9_COMMON * const cm = &cpi->common;
  MB_MODE_INFO * const mbmi = &xd->mode_info_context->mbmi;
  TOKENEXTRA *t_backup = *t;
  const int mb_skip_context = vp9_get_pred_context(cm, xd, PRED_MBSKIP);
  const int segment_id = mbmi->segment_id;
Paul Wilkins's avatar
Paul Wilkins committed
398
  const int skip_inc = !vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP);
399
  const TX_SIZE txfm_size = mbmi->txfm_size;
400 401 402
  struct tokenize_b_args arg = {
    cpi, xd, t, txfm_size, dry_run
  };
403

404
  mbmi->mb_skip_coeff = vp9_sb_is_skippable(xd, bsize);
405 406 407 408

  if (mbmi->mb_skip_coeff) {
    if (!dry_run)
      cpi->skip_true_count[mb_skip_context] += skip_inc;
409
    vp9_reset_sb_tokens_context(xd, bsize);
410 411 412 413 414 415 416 417
    if (dry_run)
      *t = t_backup;
    return;
  }

  if (!dry_run)
    cpi->skip_false_count[mb_skip_context] += skip_inc;

418
  foreach_transformed_block(xd, bsize, tokenize_b, &arg);
419

420 421 422 423
  if (dry_run)
    *t = t_backup;
}

John Koleszar's avatar
John Koleszar committed
424
#ifdef ENTROPY_STATS
John Koleszar's avatar
John Koleszar committed
425 426 427
void init_context_counters(void) {
  FILE *f = fopen("context.bin", "rb");
  if (!f) {
428
    vpx_memset(context_counters_4x4, 0, sizeof(context_counters_4x4));
John Koleszar's avatar
John Koleszar committed
429
    vpx_memset(context_counters_8x8, 0, sizeof(context_counters_8x8));
Daniel Kang's avatar
Daniel Kang committed
430
    vpx_memset(context_counters_16x16, 0, sizeof(context_counters_16x16));
431
    vpx_memset(context_counters_32x32, 0, sizeof(context_counters_32x32));
John Koleszar's avatar
John Koleszar committed
432
  } else {
433
    fread(context_counters_4x4, sizeof(context_counters_4x4), 1, f);
John Koleszar's avatar
John Koleszar committed
434
    fread(context_counters_8x8, sizeof(context_counters_8x8), 1, f);
Daniel Kang's avatar
Daniel Kang committed
435
    fread(context_counters_16x16, sizeof(context_counters_16x16), 1, f);
436
    fread(context_counters_32x32, sizeof(context_counters_32x32), 1, f);
John Koleszar's avatar
John Koleszar committed
437 438 439 440 441
    fclose(f);
  }

  f = fopen("treeupdate.bin", "rb");
  if (!f) {
442
    vpx_memset(tree_update_hist_4x4, 0, sizeof(tree_update_hist_4x4));
John Koleszar's avatar
John Koleszar committed
443
    vpx_memset(tree_update_hist_8x8, 0, sizeof(tree_update_hist_8x8));
Daniel Kang's avatar
Daniel Kang committed
444
    vpx_memset(tree_update_hist_16x16, 0, sizeof(tree_update_hist_16x16));
445
    vpx_memset(tree_update_hist_32x32, 0, sizeof(tree_update_hist_32x32));
John Koleszar's avatar
John Koleszar committed
446
  } else {
447
    fread(tree_update_hist_4x4, sizeof(tree_update_hist_4x4), 1, f);
John Koleszar's avatar
John Koleszar committed
448
    fread(tree_update_hist_8x8, sizeof(tree_update_hist_8x8), 1, f);
Daniel Kang's avatar
Daniel Kang committed
449
    fread(tree_update_hist_16x16, sizeof(tree_update_hist_16x16), 1, f);
450
    fread(tree_update_hist_32x32, sizeof(tree_update_hist_32x32), 1, f);
John Koleszar's avatar
John Koleszar committed
451 452
    fclose(f);
  }
John Koleszar's avatar
John Koleszar committed
453 454
}

455 456
static void print_counter(FILE *f, vp9_coeff_accum *context_counters,
                          int block_types, const char *header) {
457
  int type, ref, band, pt, t;
John Koleszar's avatar
John Koleszar committed
458

459
  fprintf(f, "static const vp9_coeff_count %s = {\n", header);
John Koleszar's avatar
John Koleszar committed
460

461
#define Comma(X) (X ? "," : "")
John Koleszar's avatar
John Koleszar committed
462 463
  type = 0;
  do {
464
    ref = 0;
John Koleszar's avatar
John Koleszar committed
465 466
    fprintf(f, "%s\n  { /* block Type %d */", Comma(type), type);
    do {
467 468
      fprintf(f, "%s\n    { /* %s */", Comma(type), ref ? "Inter" : "Intra");
      band = 0;
John Koleszar's avatar
John Koleszar committed
469
      do {
470 471
        fprintf(f, "%s\n      { /* Coeff Band %d */", Comma(band), band);
        pt = 0;
John Koleszar's avatar
John Koleszar committed
472
        do {
473 474 475 476 477 478 479 480 481
          fprintf(f, "%s\n        {", Comma(pt));

          t = 0;
          do {
            const int64_t x = context_counters[type][ref][band][pt][t];
            const int y = (int) x;

            assert(x == (int64_t) y);  /* no overflow handling yet */
            fprintf(f, "%s %d", Comma(t), y);
482
          } while (++t < 1 + MAX_ENTROPY_TOKENS);
483 484 485 486
          fprintf(f, "}");
        } while (++pt < PREV_COEF_CONTEXTS);
        fprintf(f, "\n      }");
      } while (++band < COEF_BANDS);
John Koleszar's avatar
John Koleszar committed
487
      fprintf(f, "\n    }");
488
    } while (++ref < REF_TYPES);
John Koleszar's avatar
John Koleszar committed
489
    fprintf(f, "\n  }");
490
  } while (++type < block_types);
Daniel Kang's avatar
Daniel Kang committed
491
  fprintf(f, "\n};\n");
492
}
493

494 495
static void print_probs(FILE *f, vp9_coeff_accum *context_counters,
                        int block_types, const char *header) {
496
  int type, ref, band, pt, t;
Daniel Kang's avatar
Daniel Kang committed
497

498
  fprintf(f, "static const vp9_coeff_probs %s = {", header);
499

John Koleszar's avatar
John Koleszar committed
500
  type = 0;
501
#define Newline(x, spaces) (x ? " " : "\n" spaces)
John Koleszar's avatar
John Koleszar committed
502
  do {
503 504
    fprintf(f, "%s%s{ /* block Type %d */",
            Comma(type), Newline(type, "  "), type);
505
    ref = 0;
John Koleszar's avatar
John Koleszar committed
506
    do {
507 508 509
      fprintf(f, "%s%s{ /* %s */",
              Comma(band), Newline(band, "    "), ref ? "Inter" : "Intra");
      band = 0;
John Koleszar's avatar
John Koleszar committed
510
      do {
511 512 513
        fprintf(f, "%s%s{ /* Coeff Band %d */",
                Comma(band), Newline(band, "      "), band);
        pt = 0;
John Koleszar's avatar
John Koleszar committed
514
        do {
515
          unsigned int branch_ct[ENTROPY_NODES][2];
516
          unsigned int coef_counts[MAX_ENTROPY_TOKENS + 1];
517 518
          vp9_prob coef_probs[ENTROPY_NODES];

519 520 521
          if (pt >= 3 && band == 0)
            break;
          for (t = 0; t < MAX_ENTROPY_TOKENS + 1; ++t)
522
            coef_counts[t] = context_counters[type][ref][band][pt][t];
523 524
          vp9_tree_probs_from_distribution(vp9_coef_tree, coef_probs,
                                           branch_ct, coef_counts, 0);
525 526
          branch_ct[0][1] = coef_counts[MAX_ENTROPY_TOKENS] - branch_ct[0][0];
          coef_probs[0] = get_binary_prob(branch_ct[0][0], branch_ct[0][1]);
527 528 529 530 531 532 533 534 535 536 537
          fprintf(f, "%s\n      {", Comma(pt));

          t = 0;
          do {
            fprintf(f, "%s %3d", Comma(t), coef_probs[t]);
          } while (++t < ENTROPY_NODES);

          fprintf(f, " }");
        } while (++pt < PREV_COEF_CONTEXTS);
        fprintf(f, "\n      }");
      } while (++band < COEF_BANDS);
John Koleszar's avatar
John Koleszar committed
538
      fprintf(f, "\n    }");
539
    } while (++ref < REF_TYPES);
John Koleszar's avatar
John Koleszar committed
540
    fprintf(f, "\n  }");
541
  } while (++type < block_types);
John Koleszar's avatar
John Koleszar committed
542
  fprintf(f, "\n};\n");
543
}
544

545 546
void print_context_counters() {
  FILE *f = fopen("vp9_context.c", "w");
547

548 549
  fprintf(f, "#include \"vp9_entropy.h\"\n");
  fprintf(f, "\n/* *** GENERATED FILE: DO NOT EDIT *** */\n\n");
John Koleszar's avatar
John Koleszar committed
550

551
  /* print counts */
552
  print_counter(f, context_counters_4x4, BLOCK_TYPES,
553
                "vp9_default_coef_counts_4x4[BLOCK_TYPES]");
554
  print_counter(f, context_counters_8x8, BLOCK_TYPES,
555
                "vp9_default_coef_counts_8x8[BLOCK_TYPES]");
556
  print_counter(f, context_counters_16x16, BLOCK_TYPES,
557 558 559
                "vp9_default_coef_counts_16x16[BLOCK_TYPES]");
  print_counter(f, context_counters_32x32, BLOCK_TYPES,
                "vp9_default_coef_counts_32x32[BLOCK_TYPES]");
Daniel Kang's avatar
Daniel Kang committed
560

561
  /* print coefficient probabilities */
562
  print_probs(f, context_counters_4x4, BLOCK_TYPES,
563
              "default_coef_probs_4x4[BLOCK_TYPES]");
564
  print_probs(f, context_counters_8x8, BLOCK_TYPES,
565
              "default_coef_probs_8x8[BLOCK_TYPES]");
566
  print_probs(f, context_counters_16x16, BLOCK_TYPES,
567 568 569
              "default_coef_probs_16x16[BLOCK_TYPES]");
  print_probs(f, context_counters_32x32, BLOCK_TYPES,
              "default_coef_probs_32x32[BLOCK_TYPES]");
Daniel Kang's avatar
Daniel Kang committed
570

John Koleszar's avatar
John Koleszar committed
571 572 573
  fclose(f);

  f = fopen("context.bin", "wb");
574
  fwrite(context_counters_4x4, sizeof(context_counters_4x4), 1, f);
John Koleszar's avatar
John Koleszar committed
575
  fwrite(context_counters_8x8, sizeof(context_counters_8x8), 1, f);
Daniel Kang's avatar
Daniel Kang committed
576
  fwrite(context_counters_16x16, sizeof(context_counters_16x16), 1, f);
577
  fwrite(context_counters_32x32, sizeof(context_counters_32x32), 1, f);
John Koleszar's avatar
John Koleszar committed
578
  fclose(f);
John Koleszar's avatar
John Koleszar committed
579 580 581
}
#endif

582
void vp9_tokenize_initialize() {
John Koleszar's avatar
John Koleszar committed
583
  fill_value_tokens();
John Koleszar's avatar
John Koleszar committed
584
}