vp9_tokenize.c 19.1 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
116
117
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;
  int ib = old_block_idx_4x4(xd, b_width_log2(bsize) + b_height_log2(bsize),
                             plane, block);

118
  MB_MODE_INFO *mbmi = &xd->mode_info_context->mbmi;
Daniel Kang's avatar
Daniel Kang committed
119
  int pt; /* near block/prev token context index */
120
  int c = 0, rc = 0;
Daniel Kang's avatar
Daniel Kang committed
121
  TOKENEXTRA *t = *tp;        /* store tokens starting here */
122
123
  const int eob = xd->plane[plane].eobs[block];
  const int16_t *qcoeff_ptr = BLOCK_OFFSET(xd->plane[plane].qcoeff, block, 16);
124
125
  const BLOCK_SIZE_TYPE sb_type = mbmi->sb_type;
  const int bwl = b_width_log2(sb_type);
126
127
  const int off = block >> (2 * tx_size);
  const int mod = bwl - tx_size - xd->plane[plane].subsampling_x;
128
129
  const int aoff = (off & ((1 << mod) - 1)) << tx_size;
  const int loff = (off >> mod) << tx_size;
130
131
  ENTROPY_CONTEXT *A = xd->plane[plane].above_context + aoff;
  ENTROPY_CONTEXT *L = xd->plane[plane].left_context + loff;
132
  int seg_eob, default_eob, pad;
133
  const int segment_id = mbmi->segment_id;
134
  const int *scan, *nb;
135
  vp9_coeff_count *counts;
136
  vp9_coeff_probs *coef_probs;
137
  const int ref = mbmi->ref_frame != INTRA_FRAME;
138
  ENTROPY_CONTEXT above_ec, left_ec;
139
  uint8_t token_cache[1024];
140
141
142
143
144
145
146
147
148
149
150
151
152
153
  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
154

155
  assert((!type && !plane) || (type && plane));
156

157
158
  switch (tx_size) {
    default:
159
    case TX_4X4: {
160
161
      tx_type = (type == PLANE_TYPE_Y_WITH_DC) ?
          get_tx_type_4x4(xd, ib) : DCT_DCT;
162
163
      above_ec = A[0] != 0;
      left_ec = L[0] != 0;
164
      seg_eob = 16;
165
      scan = get_scan_4x4(tx_type);
166
      counts = cpi->coef_counts_4x4;
167
168
169
170
171
      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
172
      break;
173
    }
174
    case TX_8X8: {
175
      const int sz = 1 + b_width_log2(sb_type);
176
      const int x = ib & ((1 << sz) - 1), y = ib - x;
177
178
      tx_type = (type == PLANE_TYPE_Y_WITH_DC) ?
          get_tx_type_8x8(xd, y + (x >> 1)) : DCT_DCT;
179
180
      above_ec = (A[0] + A[1]) != 0;
      left_ec = (L[0] + L[1]) != 0;
181
      seg_eob = 64;
182
      scan = get_scan_8x8(tx_type);
183
      counts = cpi->coef_counts_8x8;
184
185
186
187
188
      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
189
      break;
190
191
    }
    case TX_16X16: {
192
      const int sz = 2 + b_width_log2(sb_type);
193
      const int x = ib & ((1 << sz) - 1), y = ib - x;
194
195
      tx_type = (type == PLANE_TYPE_Y_WITH_DC) ?
          get_tx_type_16x16(xd, y + (x >> 2)) : DCT_DCT;
196
197
      above_ec = (A[0] + A[1] + A[2] + A[3]) != 0;
      left_ec = (L[0] + L[1] + L[2] + L[3]) != 0;
198
      seg_eob = 256;
199
      scan = get_scan_16x16(tx_type);
200
      counts = cpi->coef_counts_16x16;
201
202
203
204
205
      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
206
      break;
207
    }
208
    case TX_32X32:
209
210
      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;
211
212
213
      seg_eob = 1024;
      scan = vp9_default_zig_zag1d_32x32;
      counts = cpi->coef_counts_32x32;
214
215
216
217
218
      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
219
      break;
John Koleszar's avatar
John Koleszar committed
220
221
  }

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

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

229
230
231
232
233
234
235
236
237
238
239
240
#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;
241
  do {
242
    const int band = get_coef_band(scan, tx_size, c);
243
    int token;
244
    int v = 0;
245
246
247
    rc = scan[c];
    if (c)
      pt = vp9_get_coef_context(scan, nb, pad, token_cache, c, default_eob);
248
    if (c < eob) {
249
      v = qcoeff_ptr[rc];
250
251
      assert(-DCT_MAX_VALUE <= v  &&  v < DCT_MAX_VALUE);

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

258
    t->token = token;
259
260
    t->context_tree = coef_probs[type][ref][band][pt];
      t->skip_eob_node = (c > 0) && (token_cache[scan[c - 1]] == 0);
261
    assert(vp9_coef_encodings[t->token].len - t->skip_eob_node > 0);
262
263
264
265
266
267
268
269
270
271
272
273
274
275
#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
276
    if (!dry_run) {
277
      ++counts[type][ref][band][pt][token];
278
279
      if (!t->skip_eob_node)
        ++cpi->common.fc.eob_branch_counts[tx_size][type][ref][band][pt];
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
348
349
    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
350
    ++t;
351
  } while (c < eob && ++c < seg_eob);
352
353

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

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

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

376
377
378
int vp9_sby_is_skippable(MACROBLOCKD *xd, BLOCK_SIZE_TYPE bsize) {
  int result = 1;
  struct is_skippable_args args = {xd, &result};
379
380
381
382
383
  foreach_transformed_block_in_plane(xd, bsize, 0,
#if !CONFIG_SB8X8
                                     0,
#endif
                                     is_skippable, &args);
384
  return result;
385
386
}

387
388
389
int vp9_sbuv_is_skippable(MACROBLOCKD *xd, BLOCK_SIZE_TYPE bsize) {
  int result = 1;
  struct is_skippable_args args = {xd, &result};
390
  foreach_transformed_block_uv(xd, bsize, is_skippable, &args);
391
  return result;
392
393
}

394
395
396
void vp9_tokenize_sb(VP9_COMP *cpi,
                     MACROBLOCKD *xd,
                     TOKENEXTRA **t,
397
                     int dry_run, BLOCK_SIZE_TYPE bsize) {
398
399
400
401
402
  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
403
  const int skip_inc = !vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP);
404
  const TX_SIZE txfm_size = mbmi->txfm_size;
405
406
407
  struct tokenize_b_args arg = {
    cpi, xd, t, txfm_size, dry_run
  };
408

409
  mbmi->mb_skip_coeff = vp9_sb_is_skippable(xd, bsize);
410
411
412
413

  if (mbmi->mb_skip_coeff) {
    if (!dry_run)
      cpi->skip_true_count[mb_skip_context] += skip_inc;
414
    vp9_reset_sb_tokens_context(xd, bsize);
415
416
417
418
419
420
421
422
    if (dry_run)
      *t = t_backup;
    return;
  }

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

423
  foreach_transformed_block(xd, bsize, tokenize_b, &arg);
424

425
426
427
428
  if (dry_run)
    *t = t_backup;
}

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

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

460
461
static void print_counter(FILE *f, vp9_coeff_accum *context_counters,
                          int block_types, const char *header) {
462
  int type, ref, band, pt, t;
John Koleszar's avatar
John Koleszar committed
463

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

466
#define Comma(X) (X ? "," : "")
John Koleszar's avatar
John Koleszar committed
467
468
  type = 0;
  do {
469
    ref = 0;
John Koleszar's avatar
John Koleszar committed
470
471
    fprintf(f, "%s\n  { /* block Type %d */", Comma(type), type);
    do {
472
473
      fprintf(f, "%s\n    { /* %s */", Comma(type), ref ? "Inter" : "Intra");
      band = 0;
John Koleszar's avatar
John Koleszar committed
474
      do {
475
476
        fprintf(f, "%s\n      { /* Coeff Band %d */", Comma(band), band);
        pt = 0;
John Koleszar's avatar
John Koleszar committed
477
        do {
478
479
480
481
482
483
484
485
486
          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);
487
          } while (++t < 1 + MAX_ENTROPY_TOKENS);
488
489
490
491
          fprintf(f, "}");
        } while (++pt < PREV_COEF_CONTEXTS);
        fprintf(f, "\n      }");
      } while (++band < COEF_BANDS);
John Koleszar's avatar
John Koleszar committed
492
      fprintf(f, "\n    }");
493
    } while (++ref < REF_TYPES);
John Koleszar's avatar
John Koleszar committed
494
    fprintf(f, "\n  }");
495
  } while (++type < block_types);
Daniel Kang's avatar
Daniel Kang committed
496
  fprintf(f, "\n};\n");
497
}
498

499
500
static void print_probs(FILE *f, vp9_coeff_accum *context_counters,
                        int block_types, const char *header) {
501
  int type, ref, band, pt, t;
Daniel Kang's avatar
Daniel Kang committed
502

503
  fprintf(f, "static const vp9_coeff_probs %s = {", header);
504

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

524
525
526
          if (pt >= 3 && band == 0)
            break;
          for (t = 0; t < MAX_ENTROPY_TOKENS + 1; ++t)
527
            coef_counts[t] = context_counters[type][ref][band][pt][t];
528
529
          vp9_tree_probs_from_distribution(vp9_coef_tree, coef_probs,
                                           branch_ct, coef_counts, 0);
530
531
          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]);
532
533
534
535
536
537
538
539
540
541
542
          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
543
      fprintf(f, "\n    }");
544
    } while (++ref < REF_TYPES);
John Koleszar's avatar
John Koleszar committed
545
    fprintf(f, "\n  }");
546
  } while (++type < block_types);
John Koleszar's avatar
John Koleszar committed
547
  fprintf(f, "\n};\n");
548
}
549

550
551
void print_context_counters() {
  FILE *f = fopen("vp9_context.c", "w");
552

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

556
  /* print counts */
557
  print_counter(f, context_counters_4x4, BLOCK_TYPES,
558
                "vp9_default_coef_counts_4x4[BLOCK_TYPES]");
559
  print_counter(f, context_counters_8x8, BLOCK_TYPES,
560
                "vp9_default_coef_counts_8x8[BLOCK_TYPES]");
561
  print_counter(f, context_counters_16x16, BLOCK_TYPES,
562
563
564
                "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
565

566
  /* print coefficient probabilities */
567
  print_probs(f, context_counters_4x4, BLOCK_TYPES,
568
              "default_coef_probs_4x4[BLOCK_TYPES]");
569
  print_probs(f, context_counters_8x8, BLOCK_TYPES,
570
              "default_coef_probs_8x8[BLOCK_TYPES]");
571
  print_probs(f, context_counters_16x16, BLOCK_TYPES,
572
573
574
              "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
575

John Koleszar's avatar
John Koleszar committed
576
577
578
  fclose(f);

  f = fopen("context.bin", "wb");
579
  fwrite(context_counters_4x4, sizeof(context_counters_4x4), 1, f);
John Koleszar's avatar
John Koleszar committed
580
  fwrite(context_counters_8x8, sizeof(context_counters_8x8), 1, f);
Daniel Kang's avatar
Daniel Kang committed
581
  fwrite(context_counters_16x16, sizeof(context_counters_16x16), 1, f);
582
  fwrite(context_counters_32x32, sizeof(context_counters_32x32), 1, f);
John Koleszar's avatar
John Koleszar committed
583
  fclose(f);
John Koleszar's avatar
John Koleszar committed
584
585
586
}
#endif

587
void vp9_tokenize_initialize() {
John Koleszar's avatar
John Koleszar committed
588
  fill_value_tokens();
John Koleszar's avatar
John Koleszar committed
589
}