vp9_tokenize.c 28.7 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 31 32 33 34 35 36 37 38 39 40 41 42
vp9_coeff_accum context_counters_4x4[BLOCK_TYPES_4X4];
vp9_coeff_accum hybrid_context_counters_4x4[BLOCK_TYPES_4X4];
vp9_coeff_accum context_counters_8x8[BLOCK_TYPES_8X8];
vp9_coeff_accum hybrid_context_counters_8x8[BLOCK_TYPES_8X8];
vp9_coeff_accum context_counters_16x16[BLOCK_TYPES_16X16];
vp9_coeff_accum hybrid_context_counters_16x16[BLOCK_TYPES_16X16];
vp9_coeff_accum context_counters_32x32[BLOCK_TYPES_32X32];

extern vp9_coeff_stats tree_update_hist_4x4[BLOCK_TYPES_4X4];
extern vp9_coeff_stats hybrid_tree_update_hist_4x4[BLOCK_TYPES_4X4];
extern vp9_coeff_stats tree_update_hist_8x8[BLOCK_TYPES_8X8];
extern vp9_coeff_stats hybrid_tree_update_hist_8x8[BLOCK_TYPES_8X8];
extern vp9_coeff_stats tree_update_hist_16x16[BLOCK_TYPES_16X16];
extern vp9_coeff_stats hybrid_tree_update_hist_16x16[BLOCK_TYPES_16X16];
extern vp9_coeff_stats tree_update_hist_32x32[BLOCK_TYPES_32X32];
43 44
#endif  /* ENTROPY_STATS */

John Koleszar's avatar
John Koleszar committed
45
static TOKENVALUE dct_value_tokens[DCT_MAX_VALUE * 2];
46
const TOKENVALUE *vp9_dct_value_tokens_ptr;
John Koleszar's avatar
John Koleszar committed
47
static int dct_value_cost[DCT_MAX_VALUE * 2];
48
const int *vp9_dct_value_cost_ptr;
49

John Koleszar's avatar
John Koleszar committed
50
static void fill_value_tokens() {
John Koleszar's avatar
John Koleszar committed
51

John Koleszar's avatar
John Koleszar committed
52
  TOKENVALUE *const t = dct_value_tokens + DCT_MAX_VALUE;
53
  vp9_extra_bit_struct *const e = vp9_extra_bits;
John Koleszar's avatar
John Koleszar committed
54

John Koleszar's avatar
John Koleszar committed
55 56
  int i = -DCT_MAX_VALUE;
  int sign = 1;
John Koleszar's avatar
John Koleszar committed
57

John Koleszar's avatar
John Koleszar committed
58 59 60
  do {
    if (!i)
      sign = 0;
John Koleszar's avatar
John Koleszar committed
61

John Koleszar's avatar
John Koleszar committed
62 63 64
    {
      const int a = sign ? -i : i;
      int eb = sign;
John Koleszar's avatar
John Koleszar committed
65

John Koleszar's avatar
John Koleszar committed
66 67
      if (a > 4) {
        int j = 4;
John Koleszar's avatar
John Koleszar committed
68

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

John Koleszar's avatar
John Koleszar committed
71 72 73 74
        t[i].Token = --j;
        eb |= (a - e[j].base_val) << 1;
      } else
        t[i].Token = a;
John Koleszar's avatar
John Koleszar committed
75

John Koleszar's avatar
John Koleszar committed
76 77
      t[i].Extra = eb;
    }
John Koleszar's avatar
John Koleszar committed
78

John Koleszar's avatar
John Koleszar committed
79 80 81
    // initialize the cost for extra bits for all possible coefficient value.
    {
      int cost = 0;
82
      vp9_extra_bit_struct *p = vp9_extra_bits + t[i].Token;
John Koleszar's avatar
John Koleszar committed
83

John Koleszar's avatar
John Koleszar committed
84 85 86
      if (p->base_val) {
        const int extra = t[i].Extra;
        const int Length = p->Len;
John Koleszar's avatar
John Koleszar committed
87

John Koleszar's avatar
John Koleszar committed
88
        if (Length)
89
          cost += treed_cost(p->tree, p->prob, extra >> 1, Length);
John Koleszar's avatar
John Koleszar committed
90

91
        cost += vp9_cost_bit(vp9_prob_half, extra & 1); /* sign */
John Koleszar's avatar
John Koleszar committed
92 93
        dct_value_cost[i + DCT_MAX_VALUE] = cost;
      }
John Koleszar's avatar
John Koleszar committed
94 95 96

    }

John Koleszar's avatar
John Koleszar committed
97 98
  } while (++i < DCT_MAX_VALUE);

99 100
  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
101
}
102

103
static void tokenize_b(VP9_COMP *cpi,
104
                       MACROBLOCKD *xd,
Yaowu Xu's avatar
Yaowu Xu committed
105
                       const int ib,
106 107 108 109
                       TOKENEXTRA **tp,
                       PLANE_TYPE type,
                       TX_SIZE tx_size,
                       int dry_run) {
Daniel Kang's avatar
Daniel Kang committed
110
  int pt; /* near block/prev token context index */
111
  int c = (type == PLANE_TYPE_Y_NO_DC) ? 1 : 0;
112
  int recent_energy = 0;
Yaowu Xu's avatar
Yaowu Xu committed
113
  const BLOCKD * const b = xd->block + ib;
114
  const int eob = b->eob;     /* one beyond last nonzero coeff */
Daniel Kang's avatar
Daniel Kang committed
115
  TOKENEXTRA *t = *tp;        /* store tokens starting here */
116
  int16_t *qcoeff_ptr = b->qcoeff;
117
  int seg_eob;
Yaowu Xu's avatar
Yaowu Xu committed
118
  const int segment_id = xd->mode_info_context->mbmi.segment_id;
119
  const int *scan;
120 121
  vp9_coeff_count *counts;
  vp9_coeff_probs *probs;
122 123
  const TX_TYPE tx_type = (type == PLANE_TYPE_Y_WITH_DC) ?
                          get_tx_type(xd, b) : DCT_DCT;
Daniel Kang's avatar
Daniel Kang committed
124

Yaowu Xu's avatar
Yaowu Xu committed
125 126 127 128 129 130
  ENTROPY_CONTEXT *const a = (ENTROPY_CONTEXT *)xd->above_context +
      vp9_block2above[tx_size][ib];
  ENTROPY_CONTEXT *const l = (ENTROPY_CONTEXT *)xd->left_context +
      vp9_block2left[tx_size][ib];
  ENTROPY_CONTEXT a_ec = *a, l_ec = *l;

131 132 133 134 135 136
  ENTROPY_CONTEXT *const a1 = (ENTROPY_CONTEXT *)(&xd->above_context[1]) +
      vp9_block2above[tx_size][ib];
  ENTROPY_CONTEXT *const l1 = (ENTROPY_CONTEXT *)(&xd->left_context[1]) +
      vp9_block2left[tx_size][ib];


137 138 139 140
  switch (tx_size) {
    default:
    case TX_4X4:
      seg_eob = 16;
141
      scan = vp9_default_zig_zag1d_4x4;
142
      if (tx_type != DCT_DCT) {
143 144
        counts = cpi->hybrid_coef_counts_4x4;
        probs = cpi->common.fc.hybrid_coef_probs_4x4;
145
        if (tx_type == ADST_DCT) {
146
          scan = vp9_row_scan_4x4;
147
        } else if (tx_type == DCT_ADST) {
148
          scan = vp9_col_scan_4x4;
149 150
        }
      } else {
151 152
        counts = cpi->coef_counts_4x4;
        probs = cpi->common.fc.coef_probs_4x4;
153 154 155 156 157
      }
      break;
    case TX_8X8:
      if (type == PLANE_TYPE_Y2) {
        seg_eob = 4;
158
        scan = vp9_default_zig_zag1d_4x4;
159
      } else {
Yaowu Xu's avatar
Yaowu Xu committed
160 161 162 163
#if CONFIG_CNVCONTEXT
        a_ec = (a[0] + a[1]) != 0;
        l_ec = (l[0] + l[1]) != 0;
#endif
164
        seg_eob = 64;
165
        scan = vp9_default_zig_zag1d_8x8;
166 167 168 169 170 171 172 173 174 175
      }
      if (tx_type != DCT_DCT) {
        counts = cpi->hybrid_coef_counts_8x8;
        probs = cpi->common.fc.hybrid_coef_probs_8x8;
      } else {
        counts = cpi->coef_counts_8x8;
        probs = cpi->common.fc.coef_probs_8x8;
      }
      break;
    case TX_16X16:
Yaowu Xu's avatar
Yaowu Xu committed
176
#if CONFIG_CNVCONTEXT
Yaowu Xu's avatar
Yaowu Xu committed
177 178 179
      if (type != PLANE_TYPE_UV) {
        a_ec = (a[0] + a[1] + a[2] + a[3]) != 0;
        l_ec = (l[0] + l[1] + l[2] + l[3]) != 0;
180 181 182
      } else {
        a_ec = (a[0] + a[1] + a1[0] + a1[1]) != 0;
        l_ec = (l[0] + l[1] + l1[0] + l1[1]) != 0;
Yaowu Xu's avatar
Yaowu Xu committed
183
      }
Yaowu Xu's avatar
Yaowu Xu committed
184
#endif
185
      seg_eob = 256;
186
      scan = vp9_default_zig_zag1d_16x16;
187 188 189 190 191 192 193
      if (tx_type != DCT_DCT) {
        counts = cpi->hybrid_coef_counts_16x16;
        probs = cpi->common.fc.hybrid_coef_probs_16x16;
      } else {
        counts = cpi->coef_counts_16x16;
        probs = cpi->common.fc.coef_probs_16x16;
      }
194
      if (type == PLANE_TYPE_UV) {
195
        int uv_idx = (ib - 16) >> 2;
196 197 198 199
        qcoeff_ptr = xd->sb_coeff_data.qcoeff + 1024 + 256 * uv_idx;
      }
      break;
    case TX_32X32:
200 201 202 203 204 205 206 207
#if CONFIG_CNVCONTEXT
      a_ec = a[0] + a[1] + a[2] + a[3] +
             a1[0] + a1[1] + a1[2] + a1[3];
      l_ec = l[0] + l[1] + l[2] + l[3] +
             l1[0] + l1[1] + l1[2] + l1[3];
      a_ec = a_ec != 0;
      l_ec = l_ec != 0;
#endif
208 209 210 211 212
      seg_eob = 1024;
      scan = vp9_default_zig_zag1d_32x32;
      counts = cpi->coef_counts_32x32;
      probs = cpi->common.fc.coef_probs_32x32;
      qcoeff_ptr = xd->sb_coeff_data.qcoeff;
213
      break;
John Koleszar's avatar
John Koleszar committed
214 215
  }

Yaowu Xu's avatar
Yaowu Xu committed
216 217
  VP9_COMBINEENTROPYCONTEXTS(pt, a_ec, l_ec);

Paul Wilkins's avatar
Paul Wilkins committed
218 219
  if (vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP))
    seg_eob = 0;
John Koleszar's avatar
John Koleszar committed
220

221
  do {
222
    const int band = get_coef_band(c);
223 224 225
    int token;

    if (c < eob) {
226
      const int rc = scan[c];
227
      const int v = qcoeff_ptr[rc];
228 229
      assert(-DCT_MAX_VALUE <= v  &&  v < DCT_MAX_VALUE);

230 231
      t->Extra = vp9_dct_value_tokens_ptr[v].Extra;
      token    = vp9_dct_value_tokens_ptr[v].Token;
232 233 234
    } else {
      token = DCT_EOB_TOKEN;
    }
John Koleszar's avatar
John Koleszar committed
235 236

    t->Token = token;
237
    t->context_tree = probs[type][band][pt];
238 239
    t->skip_eob_node = (pt == 0) && ((band > 0 && type != PLANE_TYPE_Y_NO_DC) ||
                                     (band > 1 && type == PLANE_TYPE_Y_NO_DC));
240
    assert(vp9_coef_encodings[t->Token].Len - t->skip_eob_node > 0);
241
    if (!dry_run) {
242
      ++counts[type][band][pt][token];
243
    }
244 245

    pt = vp9_get_coef_context(&recent_energy, token);
246
    ++t;
247 248 249
  } while (c < eob && ++c < seg_eob);

  *tp = t;
Yaowu Xu's avatar
Yaowu Xu committed
250 251 252 253 254 255 256 257
  a_ec = l_ec = (c > !type); /* 0 <-> all coeff data is zero */
  a[0] = a_ec;
  l[0] = l_ec;

  if (tx_size == TX_8X8 && type != PLANE_TYPE_Y2) {
    a[1] = a_ec;
    l[1] = l_ec;
  } else if (tx_size == TX_16X16) {
Yaowu Xu's avatar
Yaowu Xu committed
258 259 260 261
    if (type != PLANE_TYPE_UV) {
      a[1] = a[2] = a[3] = a_ec;
      l[1] = l[2] = l[3] = l_ec;
    } else {
262 263
      a1[0] = a1[1] = a[1] = a_ec;
      l1[0] = l1[1] = l[1] = l_ec;
Yaowu Xu's avatar
Yaowu Xu committed
264
    }
265 266 267 268 269
  } else if (tx_size == TX_32X32) {
    a[1] = a[2] = a[3] = a_ec;
    l[1] = l[2] = l[3] = l_ec;
    a1[0] = a1[1] = a1[2] = a1[3] = a_ec;
    l1[0] = l1[1] = l1[2] = l1[3] = l_ec;
Yaowu Xu's avatar
Yaowu Xu committed
270
  }
John Koleszar's avatar
John Koleszar committed
271 272
}

273
int vp9_mby_is_skippable_4x4(MACROBLOCKD *xd, int has_2nd_order) {
John Koleszar's avatar
John Koleszar committed
274 275
  int skip = 1;
  int i = 0;
276

277
  if (has_2nd_order) {
John Koleszar's avatar
John Koleszar committed
278
    for (i = 0; i < 16; i++)
Paul Wilkins's avatar
Paul Wilkins committed
279 280
      skip &= (xd->block[i].eob < 2);
    skip &= (!xd->block[24].eob);
John Koleszar's avatar
John Koleszar committed
281 282
  } else {
    for (i = 0; i < 16; i++)
Paul Wilkins's avatar
Paul Wilkins committed
283
      skip &= (!xd->block[i].eob);
John Koleszar's avatar
John Koleszar committed
284 285
  }
  return skip;
286
}
287

288
int vp9_mbuv_is_skippable_4x4(MACROBLOCKD *xd) {
John Koleszar's avatar
John Koleszar committed
289 290
  int skip = 1;
  int i;
291

John Koleszar's avatar
John Koleszar committed
292
  for (i = 16; i < 24; i++)
Paul Wilkins's avatar
Paul Wilkins committed
293
    skip &= (!xd->block[i].eob);
John Koleszar's avatar
John Koleszar committed
294
  return skip;
295 296
}

297 298
static int mb_is_skippable_4x4(MACROBLOCKD *xd, int has_2nd_order) {
  return (vp9_mby_is_skippable_4x4(xd, has_2nd_order) &
299
          vp9_mbuv_is_skippable_4x4(xd));
300
}
Yaowu Xu's avatar
Yaowu Xu committed
301

302
int vp9_mby_is_skippable_8x8(MACROBLOCKD *xd, int has_2nd_order) {
John Koleszar's avatar
John Koleszar committed
303 304
  int skip = 1;
  int i = 0;
305

306
  if (has_2nd_order) {
Deb Mukherjee's avatar
Deb Mukherjee committed
307 308 309 310 311 312 313
    for (i = 0; i < 16; i += 4)
      skip &= (xd->block[i].eob < 2);
    skip &= (!xd->block[24].eob);
  } else {
    for (i = 0; i < 16; i += 4)
      skip &= (!xd->block[i].eob);
  }
John Koleszar's avatar
John Koleszar committed
314
  return skip;
315
}
316

317
int vp9_mbuv_is_skippable_8x8(MACROBLOCKD *xd) {
Paul Wilkins's avatar
Paul Wilkins committed
318
  return (!xd->block[16].eob) & (!xd->block[20].eob);
319
}
320

321 322
static int mb_is_skippable_8x8(MACROBLOCKD *xd, int has_2nd_order) {
  return (vp9_mby_is_skippable_8x8(xd, has_2nd_order) &
323
          vp9_mbuv_is_skippable_8x8(xd));
Deb Mukherjee's avatar
Deb Mukherjee committed
324 325
}

326 327
static int mb_is_skippable_8x8_4x4uv(MACROBLOCKD *xd, int has_2nd_order) {
  return (vp9_mby_is_skippable_8x8(xd, has_2nd_order) &
328
          vp9_mbuv_is_skippable_4x4(xd));
329
}
Yaowu Xu's avatar
Yaowu Xu committed
330

331
int vp9_mby_is_skippable_16x16(MACROBLOCKD *xd) {
Daniel Kang's avatar
Daniel Kang committed
332
  int skip = 1;
Paul Wilkins's avatar
Paul Wilkins committed
333
  skip &= !xd->block[0].eob;
Daniel Kang's avatar
Daniel Kang committed
334 335 336
  return skip;
}

337 338
static int mb_is_skippable_16x16(MACROBLOCKD *xd) {
  return (vp9_mby_is_skippable_16x16(xd) & vp9_mbuv_is_skippable_8x8(xd));
Daniel Kang's avatar
Daniel Kang committed
339
}
340

341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368
int vp9_sby_is_skippable_32x32(MACROBLOCKD *xd) {
  int skip = 1;
  skip &= !xd->block[0].eob;
  return skip;
}

int vp9_sbuv_is_skippable_16x16(MACROBLOCKD *xd) {
  return (!xd->block[16].eob) & (!xd->block[20].eob);
}

static int sb_is_skippable_32x32(MACROBLOCKD *xd) {
  return vp9_sby_is_skippable_32x32(xd) &&
         vp9_sbuv_is_skippable_16x16(xd);
}

void vp9_tokenize_sb(VP9_COMP *cpi,
                     MACROBLOCKD *xd,
                     TOKENEXTRA **t,
                     int dry_run) {
  VP9_COMMON * const cm = &cpi->common;
  MB_MODE_INFO * const mbmi = &xd->mode_info_context->mbmi;
  TOKENEXTRA *t_backup = *t;
  ENTROPY_CONTEXT *A[2] = { (ENTROPY_CONTEXT *) (xd->above_context + 0),
                            (ENTROPY_CONTEXT *) (xd->above_context + 1), };
  ENTROPY_CONTEXT *L[2] = { (ENTROPY_CONTEXT *) (xd->left_context + 0),
                            (ENTROPY_CONTEXT *) (xd->left_context + 1), };
  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
369
  const int skip_inc = !vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP);
370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389
  int b;

  mbmi->mb_skip_coeff = sb_is_skippable_32x32(xd);

  if (mbmi->mb_skip_coeff) {
    if (!dry_run)
      cpi->skip_true_count[mb_skip_context] += skip_inc;
    if (!cm->mb_no_coeff_skip) {
      vp9_stuff_sb(cpi, xd, t, dry_run);
    } else {
      vp9_fix_contexts_sb(xd);
    }
    if (dry_run)
      *t = t_backup;
    return;
  }

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

390 391
  tokenize_b(cpi, xd, 0, t, PLANE_TYPE_Y_WITH_DC,
             TX_32X32, dry_run);
392 393

  for (b = 16; b < 24; b += 4) {
394
    tokenize_b(cpi, xd, b, t, PLANE_TYPE_UV,
395 396
               TX_16X16, dry_run);
  }
397
  A[0][8] = L[0][8] = A[1][8] = L[1][8] = 0;
398 399 400 401
  if (dry_run)
    *t = t_backup;
}

402
void vp9_tokenize_mb(VP9_COMP *cpi,
Paul Wilkins's avatar
Paul Wilkins committed
403
                     MACROBLOCKD *xd,
404 405
                     TOKENEXTRA **t,
                     int dry_run) {
406
  PLANE_TYPE plane_type;
407
  int has_2nd_order;
John Koleszar's avatar
John Koleszar committed
408
  int b;
409
  int tx_size = xd->mode_info_context->mbmi.txfm_size;
Paul Wilkins's avatar
Paul Wilkins committed
410
  int mb_skip_context = vp9_get_pred_context(&cpi->common, xd, PRED_MBSKIP);
411
  TOKENEXTRA *t_backup = *t;
Paul Wilkins's avatar
Paul Wilkins committed
412

John Koleszar's avatar
John Koleszar committed
413 414 415 416
  // If the MB is going to be skipped because of a segment level flag
  // exclude this from the skip count stats used to calculate the
  // transmitted skip probability;
  int skip_inc;
Paul Wilkins's avatar
Paul Wilkins committed
417
  int segment_id = xd->mode_info_context->mbmi.segment_id;
418

Paul Wilkins's avatar
Paul Wilkins committed
419
  if (!vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)) {
John Koleszar's avatar
John Koleszar committed
420 421 422
    skip_inc = 1;
  } else
    skip_inc = 0;
423

424
  has_2nd_order = get_2nd_order_usage(xd);
John Koleszar's avatar
John Koleszar committed
425

426
  switch (tx_size) {
Daniel Kang's avatar
Daniel Kang committed
427
    case TX_16X16:
428

Daniel Kang's avatar
Daniel Kang committed
429
      xd->mode_info_context->mbmi.mb_skip_coeff = mb_is_skippable_16x16(xd);
Daniel Kang's avatar
Daniel Kang committed
430 431
      break;
    case TX_8X8:
432 433
      if (xd->mode_info_context->mbmi.mode == I8X8_PRED ||
          xd->mode_info_context->mbmi.mode == SPLITMV)
434 435
        xd->mode_info_context->mbmi.mb_skip_coeff =
            mb_is_skippable_8x8_4x4uv(xd, 0);
Deb Mukherjee's avatar
Deb Mukherjee committed
436
      else
437 438
        xd->mode_info_context->mbmi.mb_skip_coeff =
            mb_is_skippable_8x8(xd, has_2nd_order);
Daniel Kang's avatar
Daniel Kang committed
439
      break;
Deb Mukherjee's avatar
Deb Mukherjee committed
440

Daniel Kang's avatar
Daniel Kang committed
441
    default:
442 443
      xd->mode_info_context->mbmi.mb_skip_coeff =
          mb_is_skippable_4x4(xd, has_2nd_order);
Daniel Kang's avatar
Daniel Kang committed
444 445
      break;
  }
446

Paul Wilkins's avatar
Paul Wilkins committed
447
  if (xd->mode_info_context->mbmi.mb_skip_coeff) {
448 449
    if (!dry_run)
      cpi->skip_true_count[mb_skip_context] += skip_inc;
John Koleszar's avatar
John Koleszar committed
450
    if (!cpi->common.mb_no_coeff_skip) {
451
      vp9_stuff_mb(cpi, xd, t, dry_run);
John Koleszar's avatar
John Koleszar committed
452
    } else {
Yaowu Xu's avatar
Yaowu Xu committed
453
      vp9_reset_mb_tokens_context(xd);
John Koleszar's avatar
John Koleszar committed
454
    }
Yaowu Xu's avatar
Yaowu Xu committed
455

456 457
    if (dry_run)
      *t = t_backup;
John Koleszar's avatar
John Koleszar committed
458 459 460
    return;
  }

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

464
  if (has_2nd_order) {
Yaowu Xu's avatar
Yaowu Xu committed
465
    tokenize_b(cpi, xd, 24, t, PLANE_TYPE_Y2, tx_size, dry_run);
466
    plane_type = PLANE_TYPE_Y_NO_DC;
Yaowu Xu's avatar
Yaowu Xu committed
467
  } else {
Yaowu Xu's avatar
Yaowu Xu committed
468 469
    xd->above_context->y2 = 0;
    xd->left_context->y2 = 0;
470
    plane_type = PLANE_TYPE_Y_WITH_DC;
Yaowu Xu's avatar
Yaowu Xu committed
471
  }
John Koleszar's avatar
John Koleszar committed
472

473
  if (tx_size == TX_16X16) {
Yaowu Xu's avatar
Yaowu Xu committed
474
    tokenize_b(cpi, xd, 0, t, PLANE_TYPE_Y_WITH_DC, TX_16X16, dry_run);
Daniel Kang's avatar
Daniel Kang committed
475
    for (b = 16; b < 24; b += 4) {
Yaowu Xu's avatar
Yaowu Xu committed
476
      tokenize_b(cpi, xd, b, t, PLANE_TYPE_UV, TX_8X8, dry_run);
Daniel Kang's avatar
Daniel Kang committed
477
    }
478
  } else if (tx_size == TX_8X8) {
John Koleszar's avatar
John Koleszar committed
479
    for (b = 0; b < 16; b += 4) {
Yaowu Xu's avatar
Yaowu Xu committed
480
      tokenize_b(cpi, xd, b, t, plane_type, TX_8X8, dry_run);
John Koleszar's avatar
John Koleszar committed
481
    }
482 483
    if (xd->mode_info_context->mbmi.mode == I8X8_PRED ||
        xd->mode_info_context->mbmi.mode == SPLITMV) {
484
      for (b = 16; b < 24; b++) {
Yaowu Xu's avatar
Yaowu Xu committed
485
        tokenize_b(cpi, xd, b, t, PLANE_TYPE_UV, TX_4X4, dry_run);
486
      }
487
    } else {
Deb Mukherjee's avatar
Deb Mukherjee committed
488
      for (b = 16; b < 24; b += 4) {
Yaowu Xu's avatar
Yaowu Xu committed
489
        tokenize_b(cpi, xd, b, t, PLANE_TYPE_UV, TX_8X8, dry_run);
Deb Mukherjee's avatar
Deb Mukherjee committed
490
      }
491
    }
Jingning Han's avatar
Jingning Han committed
492
  } else {
Yaowu Xu's avatar
Yaowu Xu committed
493 494 495 496
    for (b = 0; b < 24; b++) {
      if (b >= 16)
        plane_type = PLANE_TYPE_UV;
      tokenize_b(cpi, xd, b, t, plane_type, TX_4X4, dry_run);
497
    }
Jingning Han's avatar
Jingning Han committed
498
  }
499 500
  if (dry_run)
    *t = t_backup;
John Koleszar's avatar
John Koleszar committed
501
}
502

John Koleszar's avatar
John Koleszar committed
503
#ifdef ENTROPY_STATS
John Koleszar's avatar
John Koleszar committed
504 505 506
void init_context_counters(void) {
  FILE *f = fopen("context.bin", "rb");
  if (!f) {
507 508 509
    vpx_memset(context_counters_4x4, 0, sizeof(context_counters_4x4));
    vpx_memset(hybrid_context_counters_4x4, 0,
               sizeof(hybrid_context_counters_4x4));
John Koleszar's avatar
John Koleszar committed
510
    vpx_memset(context_counters_8x8, 0, sizeof(context_counters_8x8));
511 512
    vpx_memset(hybrid_context_counters_8x8, 0,
               sizeof(hybrid_context_counters_8x8));
Daniel Kang's avatar
Daniel Kang committed
513
    vpx_memset(context_counters_16x16, 0, sizeof(context_counters_16x16));
514 515 516
    vpx_memset(hybrid_context_counters_16x16, 0,
               sizeof(hybrid_context_counters_16x16));
    vpx_memset(context_counters_32x32, 0, sizeof(context_counters_32x32));
John Koleszar's avatar
John Koleszar committed
517
  } else {
518 519 520
    fread(context_counters_4x4, sizeof(context_counters_4x4), 1, f);
    fread(hybrid_context_counters_4x4,
          sizeof(hybrid_context_counters_4x4), 1, f);
John Koleszar's avatar
John Koleszar committed
521
    fread(context_counters_8x8, sizeof(context_counters_8x8), 1, f);
522 523
    fread(hybrid_context_counters_8x8,
          sizeof(hybrid_context_counters_8x8), 1, f);
Daniel Kang's avatar
Daniel Kang committed
524
    fread(context_counters_16x16, sizeof(context_counters_16x16), 1, f);
525 526 527
    fread(hybrid_context_counters_16x16,
          sizeof(hybrid_context_counters_16x16), 1, f);
    fread(context_counters_32x32, sizeof(context_counters_32x32), 1, f);
John Koleszar's avatar
John Koleszar committed
528 529 530 531 532
    fclose(f);
  }

  f = fopen("treeupdate.bin", "rb");
  if (!f) {
533 534 535
    vpx_memset(tree_update_hist_4x4, 0, sizeof(tree_update_hist_4x4));
    vpx_memset(hybrid_tree_update_hist_4x4, 0,
               sizeof(hybrid_tree_update_hist_4x4));
John Koleszar's avatar
John Koleszar committed
536
    vpx_memset(tree_update_hist_8x8, 0, sizeof(tree_update_hist_8x8));
537 538
    vpx_memset(hybrid_tree_update_hist_8x8, 0,
               sizeof(hybrid_tree_update_hist_8x8));
Daniel Kang's avatar
Daniel Kang committed
539
    vpx_memset(tree_update_hist_16x16, 0, sizeof(tree_update_hist_16x16));
540 541 542
    vpx_memset(hybrid_tree_update_hist_16x16, 0,
               sizeof(hybrid_tree_update_hist_16x16));
    vpx_memset(tree_update_hist_32x32, 0, sizeof(tree_update_hist_32x32));
John Koleszar's avatar
John Koleszar committed
543
  } else {
544 545 546
    fread(tree_update_hist_4x4, sizeof(tree_update_hist_4x4), 1, f);
    fread(hybrid_tree_update_hist_4x4,
          sizeof(hybrid_tree_update_hist_4x4), 1, f);
John Koleszar's avatar
John Koleszar committed
547
    fread(tree_update_hist_8x8, sizeof(tree_update_hist_8x8), 1, f);
548 549
    fread(hybrid_tree_update_hist_8x8,
          sizeof(hybrid_tree_update_hist_8x8), 1, f);
Daniel Kang's avatar
Daniel Kang committed
550
    fread(tree_update_hist_16x16, sizeof(tree_update_hist_16x16), 1, f);
551 552 553
    fread(hybrid_tree_update_hist_16x16,
          sizeof(hybrid_tree_update_hist_16x16), 1, f);
    fread(tree_update_hist_32x32, sizeof(tree_update_hist_32x32), 1, f);
John Koleszar's avatar
John Koleszar committed
554 555
    fclose(f);
  }
John Koleszar's avatar
John Koleszar committed
556 557
}

558 559
static void print_counter(FILE *f, vp9_coeff_accum *context_counters,
                          int block_types, const char *header) {
John Koleszar's avatar
John Koleszar committed
560
  int type, band, pt, t;
John Koleszar's avatar
John Koleszar committed
561

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

564
#define Comma(X) (X ? "," : "")
John Koleszar's avatar
John Koleszar committed
565 566 567 568 569 570 571 572 573 574 575 576
  type = 0;
  do {
    fprintf(f, "%s\n  { /* block Type %d */", Comma(type), type);
    band = 0;
    do {
      fprintf(f, "%s\n    { /* Coeff Band %d */", Comma(band), band);
      pt = 0;
      do {
        fprintf(f, "%s\n      {", Comma(pt));

        t = 0;
        do {
John Koleszar's avatar
John Koleszar committed
577
          const int64_t x = context_counters[type][band][pt][t];
John Koleszar's avatar
John Koleszar committed
578
          const int y = (int) x;
579

John Koleszar's avatar
John Koleszar committed
580
          assert(x == (int64_t) y);  /* no overflow handling yet */
John Koleszar's avatar
John Koleszar committed
581 582 583 584 585 586 587
          fprintf(f, "%s %d", Comma(t), y);
        } while (++t < MAX_ENTROPY_TOKENS);
        fprintf(f, "}");
      } while (++pt < PREV_COEF_CONTEXTS);
      fprintf(f, "\n    }");
    } while (++band < COEF_BANDS);
    fprintf(f, "\n  }");
588
  } while (++type < block_types);
Daniel Kang's avatar
Daniel Kang committed
589
  fprintf(f, "\n};\n");
590
}
591

592 593 594
static void print_probs(FILE *f, vp9_coeff_accum *context_counters,
                        int block_types, const char *header) {
  int type, band, pt, t;
Daniel Kang's avatar
Daniel Kang committed
595

596
  fprintf(f, "static const vp9_coeff_probs %s = {", header);
597

John Koleszar's avatar
John Koleszar committed
598
  type = 0;
599
#define Newline(x, spaces) (x ? " " : "\n" spaces)
John Koleszar's avatar
John Koleszar committed
600
  do {
601 602
    fprintf(f, "%s%s{ /* block Type %d */",
            Comma(type), Newline(type, "  "), type);
John Koleszar's avatar
John Koleszar committed
603 604
    band = 0;
    do {
605 606
      fprintf(f, "%s%s{ /* Coeff Band %d */",
              Comma(band), Newline(band, "    "), band);
John Koleszar's avatar
John Koleszar committed
607 608
      pt = 0;
      do {
609
        unsigned int branch_ct[ENTROPY_NODES][2];
John Koleszar's avatar
John Koleszar committed
610
        unsigned int coef_counts[MAX_ENTROPY_TOKENS];
611
        vp9_prob coef_probs[ENTROPY_NODES];
612

John Koleszar's avatar
John Koleszar committed
613
        for (t = 0; t < MAX_ENTROPY_TOKENS; ++t)
614 615 616
          coef_counts[t] = context_counters[type][band][pt][t];
        vp9_tree_probs_from_distribution(MAX_ENTROPY_TOKENS,
                                         vp9_coef_encodings, vp9_coef_tree,
617
                                         coef_probs, branch_ct, coef_counts);
John Koleszar's avatar
John Koleszar committed
618
        fprintf(f, "%s\n      {", Comma(pt));
619

John Koleszar's avatar
John Koleszar committed
620 621
        t = 0;
        do {
622
          fprintf(f, "%s %3d", Comma(t), coef_probs[t]);
John Koleszar's avatar
John Koleszar committed
623
        } while (++t < ENTROPY_NODES);
624

625
        fprintf(f, " }");
John Koleszar's avatar
John Koleszar committed
626 627 628 629
      } while (++pt < PREV_COEF_CONTEXTS);
      fprintf(f, "\n    }");
    } while (++band < COEF_BANDS);
    fprintf(f, "\n  }");
630
  } while (++type < block_types);
John Koleszar's avatar
John Koleszar committed
631
  fprintf(f, "\n};\n");
632
}
633

634 635
void print_context_counters() {
  FILE *f = fopen("vp9_context.c", "w");
636

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

640 641 642 643 644 645 646 647 648 649 650 651 652 653 654
  /* print counts */
  print_counter(f, context_counters_4x4, BLOCK_TYPES_4X4,
                "vp9_default_coef_counts_4x4[BLOCK_TYPES_4X4]");
  print_counter(f, hybrid_context_counters_4x4, BLOCK_TYPES_4X4,
                "vp9_default_hybrid_coef_counts_4x4[BLOCK_TYPES_4X4]");
  print_counter(f, context_counters_8x8, BLOCK_TYPES_8X8,
                "vp9_default_coef_counts_8x8[BLOCK_TYPES_8X8]");
  print_counter(f, hybrid_context_counters_8x8, BLOCK_TYPES_8X8,
                "vp9_default_hybrid_coef_counts_8x8[BLOCK_TYPES_8X8]");
  print_counter(f, context_counters_16x16, BLOCK_TYPES_16X16,
                "vp9_default_coef_counts_16x16[BLOCK_TYPES_16X16]");
  print_counter(f, hybrid_context_counters_16x16, BLOCK_TYPES_16X16,
                "vp9_default_hybrid_coef_counts_16x16[BLOCK_TYPES_16X16]");
  print_counter(f, context_counters_32x32, BLOCK_TYPES_32X32,
                "vp9_default_coef_counts_32x32[BLOCK_TYPES_32X32]");
Daniel Kang's avatar
Daniel Kang committed
655

656 657
  /* print coefficient probabilities */
  print_probs(f, context_counters_4x4, BLOCK_TYPES_4X4,
658
              "default_coef_probs_4x4[BLOCK_TYPES_4X4]");
659
  print_probs(f, hybrid_context_counters_4x4, BLOCK_TYPES_4X4,
660
              "default_hybrid_coef_probs_4x4[BLOCK_TYPES_4X4]");
661
  print_probs(f, context_counters_8x8, BLOCK_TYPES_8X8,
662
              "default_coef_probs_8x8[BLOCK_TYPES_8X8]");
663
  print_probs(f, hybrid_context_counters_8x8, BLOCK_TYPES_8X8,
664
              "default_hybrid_coef_probs_8x8[BLOCK_TYPES_8X8]");
665
  print_probs(f, context_counters_16x16, BLOCK_TYPES_16X16,
666
              "default_coef_probs_16x16[BLOCK_TYPES_16X16]");
667
  print_probs(f, hybrid_context_counters_16x16, BLOCK_TYPES_16X16,
668
              "default_hybrid_coef_probs_16x16[BLOCK_TYPES_16X16]");
669
  print_probs(f, context_counters_32x32, BLOCK_TYPES_32X32,
670
              "default_coef_probs_32x32[BLOCK_TYPES_32X32]");
Daniel Kang's avatar
Daniel Kang committed
671

John Koleszar's avatar
John Koleszar committed
672 673 674
  fclose(f);

  f = fopen("context.bin", "wb");
675 676 677
  fwrite(context_counters_4x4, sizeof(context_counters_4x4), 1, f);
  fwrite(hybrid_context_counters_4x4,
         sizeof(hybrid_context_counters_4x4), 1, f);
John Koleszar's avatar
John Koleszar committed
678
  fwrite(context_counters_8x8, sizeof(context_counters_8x8), 1, f);
679 680
  fwrite(hybrid_context_counters_8x8,
         sizeof(hybrid_context_counters_8x8), 1, f);
Daniel Kang's avatar
Daniel Kang committed
681
  fwrite(context_counters_16x16, sizeof(context_counters_16x16), 1, f);
682 683 684
  fwrite(hybrid_context_counters_16x16,
         sizeof(hybrid_context_counters_16x16), 1, f);
  fwrite(context_counters_32x32, sizeof(context_counters_32x32), 1, f);
John Koleszar's avatar
John Koleszar committed
685
  fclose(f);
John Koleszar's avatar
John Koleszar committed
686 687 688
}
#endif

689
void vp9_tokenize_initialize() {
John Koleszar's avatar
John Koleszar committed
690
  fill_value_tokens();
John Koleszar's avatar
John Koleszar committed
691 692
}

693 694 695 696 697 698 699
static INLINE void stuff_b(VP9_COMP *cpi,
                           MACROBLOCKD *xd,
                           const int ib,
                           TOKENEXTRA **tp,
                           PLANE_TYPE type,
                           TX_SIZE tx_size,
                           int dry_run) {
Yaowu Xu's avatar
Yaowu Xu committed
700
  const BLOCKD * const b = xd->block + ib;
701 702
  vp9_coeff_count *counts;
  vp9_coeff_probs *probs;
703 704 705 706
  int pt, band;
  TOKENEXTRA *t = *tp;
  const TX_TYPE tx_type = (type == PLANE_TYPE_Y_WITH_DC) ?
                          get_tx_type(xd, b) : DCT_DCT;
Yaowu Xu's avatar
Yaowu Xu committed
707 708 709 710 711
  ENTROPY_CONTEXT *const a = (ENTROPY_CONTEXT *)xd->above_context +
      vp9_block2above[tx_size][ib];
  ENTROPY_CONTEXT *const l = (ENTROPY_CONTEXT *)xd->left_context +
      vp9_block2left[tx_size][ib];
  ENTROPY_CONTEXT a_ec = *a, l_ec = *l;
712 713 714 715
  ENTROPY_CONTEXT *const a1 = (ENTROPY_CONTEXT *)(&xd->above_context[1]) +
      vp9_block2above[tx_size][ib];
  ENTROPY_CONTEXT *const l1 = (ENTROPY_CONTEXT *)(&xd->left_context[1]) +
      vp9_block2left[tx_size][ib];
John Koleszar's avatar
John Koleszar committed
716

717 718 719 720
  switch (tx_size) {
    default:
    case TX_4X4:
      if (tx_type != DCT_DCT) {
721 722
        counts = cpi->hybrid_coef_counts_4x4;
        probs = cpi->common.fc.hybrid_coef_probs_4x4;
723
      } else {
724 725
        counts = cpi->coef_counts_4x4;
        probs = cpi->common.fc.coef_probs_4x4;
726 727 728
      }
      break;
    case TX_8X8:
Yaowu Xu's avatar
Yaowu Xu committed
729 730 731 732 733 734
#if CONFIG_CNVCONTEXT
      if (type != PLANE_TYPE_Y2) {
        a_ec = (a[0] + a[1]) != 0;
        l_ec = (l[0] + l[1]) != 0;
      }
#endif
735 736 737 738 739 740 741 742 743
      if (tx_type != DCT_DCT) {
        counts = cpi->hybrid_coef_counts_8x8;
        probs = cpi->common.fc.hybrid_coef_probs_8x8;
      } else {
        counts = cpi->coef_counts_8x8;
        probs = cpi->common.fc.coef_probs_8x8;
      }
      break;
    case TX_16X16:
Yaowu Xu's avatar
Yaowu Xu committed
744
#if CONFIG_CNVCONTEXT
Yaowu Xu's avatar
Yaowu Xu committed
745 746 747
      if (type != PLANE_TYPE_UV) {
        a_ec = (a[0] + a[1] + a[2] + a[3]) != 0;
        l_ec = (l[0] + l[1] + l[2] + l[3]) != 0;
748 749 750
      } else {
        a_ec = (a[0] + a[1] + a1[0] + a1[1]) != 0;
        l_ec = (l[0] + l[1] + l1[0] + l1[1]) != 0;
Yaowu Xu's avatar
Yaowu Xu committed
751
      }
Yaowu Xu's avatar
Yaowu Xu committed
752
#endif
753 754 755 756 757 758 759 760
      if (tx_type != DCT_DCT) {
        counts = cpi->hybrid_coef_counts_16x16;
        probs = cpi->common.fc.hybrid_coef_probs_16x16;
      } else {
        counts = cpi->coef_counts_16x16;
        probs = cpi->common.fc.coef_probs_16x16;
      }
      break;
761
    case TX_32X32:
762 763 764 765 766 767 768 769
#if CONFIG_CNVCONTEXT
      a_ec = a[0] + a[1] + a[2] + a[3] +
             a1[0] + a1[1] + a1[2] + a1[3];
      l_ec = l[0] + l[1] + l[2] + l[3] +
             l1[0] + l1[1] + l1[2] + l1[3];
      a_ec = a_ec != 0;
      l_ec = l_ec != 0;
#endif
770 771 772
      counts = cpi->coef_counts_32x32;
      probs = cpi->common.fc.coef_probs_32x32;
      break;
773
  }
Yaowu Xu's avatar
Yaowu Xu committed
774 775 776

  VP9_COMBINEENTROPYCONTEXTS(pt, a_ec, l_ec);

777
  band = get_coef_band((type == PLANE_TYPE_Y_NO_DC) ? 1 : 0);
John Koleszar's avatar
John Koleszar committed
778
  t->Token = DCT_EOB_TOKEN;
779
  t->context_tree = probs[type][band][pt];
John Koleszar's avatar
John Koleszar committed
780 781 782
  t->skip_eob_node = 0;
  ++t;
  *tp = t;
783
  *a = *l = 0;
Yaowu Xu's avatar
Yaowu Xu committed