vp9_tokenize.c 29.2 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 43 44 45 46
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];
#if CONFIG_TX32X32
vp9_coeff_accum context_counters_32x32[BLOCK_TYPES_32X32];
#endif

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];
#if CONFIG_TX32X32
extern vp9_coeff_stats tree_update_hist_32x32[BLOCK_TYPES_32X32];
#endif
47 48
#endif  /* ENTROPY_STATS */

John Koleszar's avatar
John Koleszar committed
49
static TOKENVALUE dct_value_tokens[DCT_MAX_VALUE * 2];
50
const TOKENVALUE *vp9_dct_value_tokens_ptr;
John Koleszar's avatar
John Koleszar committed
51
static int dct_value_cost[DCT_MAX_VALUE * 2];
52
const int *vp9_dct_value_cost_ptr;
53

John Koleszar's avatar
John Koleszar committed
54
static void fill_value_tokens() {
John Koleszar's avatar
John Koleszar committed
55

John Koleszar's avatar
John Koleszar committed
56
  TOKENVALUE *const t = dct_value_tokens + DCT_MAX_VALUE;
57
  vp9_extra_bit_struct *const e = vp9_extra_bits;
John Koleszar's avatar
John Koleszar committed
58

John Koleszar's avatar
John Koleszar committed
59 60
  int i = -DCT_MAX_VALUE;
  int sign = 1;
John Koleszar's avatar
John Koleszar committed
61

John Koleszar's avatar
John Koleszar committed
62 63 64
  do {
    if (!i)
      sign = 0;
John Koleszar's avatar
John Koleszar committed
65

John Koleszar's avatar
John Koleszar committed
66 67 68
    {
      const int a = sign ? -i : i;
      int eb = sign;
John Koleszar's avatar
John Koleszar committed
69

John Koleszar's avatar
John Koleszar committed
70 71
      if (a > 4) {
        int j = 4;
John Koleszar's avatar
John Koleszar committed
72

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

John Koleszar's avatar
John Koleszar committed
75 76 77 78
        t[i].Token = --j;
        eb |= (a - e[j].base_val) << 1;
      } else
        t[i].Token = a;
John Koleszar's avatar
John Koleszar committed
79

John Koleszar's avatar
John Koleszar committed
80 81
      t[i].Extra = eb;
    }
John Koleszar's avatar
John Koleszar committed
82

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

John Koleszar's avatar
John Koleszar committed
88 89 90
      if (p->base_val) {
        const int extra = t[i].Extra;
        const int Length = p->Len;
John Koleszar's avatar
John Koleszar committed
91

John Koleszar's avatar
John Koleszar committed
92
        if (Length)
93
          cost += treed_cost(p->tree, p->prob, extra >> 1, Length);
John Koleszar's avatar
John Koleszar committed
94

95
        cost += vp9_cost_bit(vp9_prob_half, extra & 1); /* sign */
John Koleszar's avatar
John Koleszar committed
96 97
        dct_value_cost[i + DCT_MAX_VALUE] = cost;
      }
John Koleszar's avatar
John Koleszar committed
98 99 100

    }

John Koleszar's avatar
John Koleszar committed
101 102
  } while (++i < DCT_MAX_VALUE);

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

Yaowu Xu's avatar
Yaowu Xu committed
127 128 129 130 131 132
  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;

133 134 135 136
  switch (tx_size) {
    default:
    case TX_4X4:
      seg_eob = 16;
137 138
      bands = vp9_coef_bands;
      scan = vp9_default_zig_zag1d;
139
      if (tx_type != DCT_DCT) {
140 141
        counts = cpi->hybrid_coef_counts_4x4;
        probs = cpi->common.fc.hybrid_coef_probs_4x4;
142
        if (tx_type == ADST_DCT) {
143
          scan = vp9_row_scan;
144
        } else if (tx_type == DCT_ADST) {
145
          scan = vp9_col_scan;
146 147
        }
      } else {
148 149
        counts = cpi->coef_counts_4x4;
        probs = cpi->common.fc.coef_probs_4x4;
150 151 152 153 154
      }
      break;
    case TX_8X8:
      if (type == PLANE_TYPE_Y2) {
        seg_eob = 4;
155 156
        bands = vp9_coef_bands;
        scan = vp9_default_zig_zag1d;
157
      } else {
Yaowu Xu's avatar
Yaowu Xu committed
158 159 160 161
#if CONFIG_CNVCONTEXT
        a_ec = (a[0] + a[1]) != 0;
        l_ec = (l[0] + l[1]) != 0;
#endif
162
        seg_eob = 64;
163 164
        bands = vp9_coef_bands_8x8;
        scan = vp9_default_zig_zag1d_8x8;
165 166 167 168 169 170 171 172 173 174
      }
      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
175
#if CONFIG_CNVCONTEXT
Yaowu Xu's avatar
Yaowu Xu committed
176 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;
      }
Yaowu Xu's avatar
Yaowu Xu committed
180
#endif
181
      seg_eob = 256;
182 183
      bands = vp9_coef_bands_16x16;
      scan = vp9_default_zig_zag1d_16x16;
184 185 186 187 188 189 190
      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;
      }
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
#if CONFIG_SUPERBLOCKS && CONFIG_TX32X32
      if (type == PLANE_TYPE_UV) {
        int uv_idx = (((int) (b - xd->block)) - 16) >> 2;
        qcoeff_ptr = xd->sb_coeff_data.qcoeff + 1024 + 256 * uv_idx;
      }
#endif
      break;
#if CONFIG_TX32X32 && CONFIG_SUPERBLOCKS
    case TX_32X32:
      seg_eob = 1024;
      bands = vp9_coef_bands_32x32;
      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;
206
      break;
207
#endif
John Koleszar's avatar
John Koleszar committed
208 209
  }

Yaowu Xu's avatar
Yaowu Xu committed
210 211
  VP9_COMBINEENTROPYCONTEXTS(pt, a_ec, l_ec);

212 213
  if (vp9_segfeature_active(xd, segment_id, SEG_LVL_EOB))
    seg_eob = vp9_get_segdata(xd, segment_id, SEG_LVL_EOB);
John Koleszar's avatar
John Koleszar committed
214

215
  do {
216
    const int band = bands[c];
217 218 219
    int token;

    if (c < eob) {
220
      const int rc = scan[c];
221
      const int v = qcoeff_ptr[rc];
222 223
      assert(-DCT_MAX_VALUE <= v  &&  v < DCT_MAX_VALUE);

224 225
      t->Extra = vp9_dct_value_tokens_ptr[v].Extra;
      token    = vp9_dct_value_tokens_ptr[v].Token;
226 227 228
    } else {
      token = DCT_EOB_TOKEN;
    }
John Koleszar's avatar
John Koleszar committed
229 230

    t->Token = token;
231 232 233
    t->context_tree = probs[type][band][pt];
    t->skip_eob_node = (pt == 0) && ((band > 0 && type != PLANE_TYPE_Y_NO_DC) ||
                                     (band > 1 && type == PLANE_TYPE_Y_NO_DC));
234
    assert(vp9_coef_encodings[t->Token].Len - t->skip_eob_node > 0);
235
    if (!dry_run) {
236
      ++counts[type][band][pt][token];
237
    }
238
    pt = vp9_prev_token_class[token];
239
    ++t;
240 241 242
  } while (c < eob && ++c < seg_eob);

  *tp = t;
Yaowu Xu's avatar
Yaowu Xu committed
243 244 245 246 247 248 249 250
  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
251 252 253 254 255 256 257 258 259
    if (type != PLANE_TYPE_UV) {
      a[1] = a[2] = a[3] = a_ec;
      l[1] = l[2] = l[3] = l_ec;
#if CONFIG_TX32X32 && CONFIG_SUPERBLOCKS
    } else {
      a[1] = a_ec;
      l[1] = l_ec;
#endif
    }
Yaowu Xu's avatar
Yaowu Xu committed
260
  }
John Koleszar's avatar
John Koleszar committed
261 262
}

263
int vp9_mby_is_skippable_4x4(MACROBLOCKD *xd, int has_2nd_order) {
John Koleszar's avatar
John Koleszar committed
264 265
  int skip = 1;
  int i = 0;
266

267
  if (has_2nd_order) {
John Koleszar's avatar
John Koleszar committed
268
    for (i = 0; i < 16; i++)
Paul Wilkins's avatar
Paul Wilkins committed
269 270
      skip &= (xd->block[i].eob < 2);
    skip &= (!xd->block[24].eob);
John Koleszar's avatar
John Koleszar committed
271 272
  } else {
    for (i = 0; i < 16; i++)
Paul Wilkins's avatar
Paul Wilkins committed
273
      skip &= (!xd->block[i].eob);
John Koleszar's avatar
John Koleszar committed
274 275
  }
  return skip;
276
}
277

278
int vp9_mbuv_is_skippable_4x4(MACROBLOCKD *xd) {
John Koleszar's avatar
John Koleszar committed
279 280
  int skip = 1;
  int i;
281

John Koleszar's avatar
John Koleszar committed
282
  for (i = 16; i < 24; i++)
Paul Wilkins's avatar
Paul Wilkins committed
283
    skip &= (!xd->block[i].eob);
John Koleszar's avatar
John Koleszar committed
284
  return skip;
285 286
}

287 288
static int mb_is_skippable_4x4(MACROBLOCKD *xd, int has_2nd_order) {
  return (vp9_mby_is_skippable_4x4(xd, has_2nd_order) &
289
          vp9_mbuv_is_skippable_4x4(xd));
290
}
Yaowu Xu's avatar
Yaowu Xu committed
291

292
int vp9_mby_is_skippable_8x8(MACROBLOCKD *xd, int has_2nd_order) {
John Koleszar's avatar
John Koleszar committed
293 294
  int skip = 1;
  int i = 0;
295

296
  if (has_2nd_order) {
Deb Mukherjee's avatar
Deb Mukherjee committed
297 298 299 300 301 302 303
    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
304
  return skip;
305
}
306

307
int vp9_mbuv_is_skippable_8x8(MACROBLOCKD *xd) {
Paul Wilkins's avatar
Paul Wilkins committed
308
  return (!xd->block[16].eob) & (!xd->block[20].eob);
309
}
310

311 312
static int mb_is_skippable_8x8(MACROBLOCKD *xd, int has_2nd_order) {
  return (vp9_mby_is_skippable_8x8(xd, has_2nd_order) &
313
          vp9_mbuv_is_skippable_8x8(xd));
Deb Mukherjee's avatar
Deb Mukherjee committed
314 315
}

316 317
static int mb_is_skippable_8x8_4x4uv(MACROBLOCKD *xd, int has_2nd_order) {
  return (vp9_mby_is_skippable_8x8(xd, has_2nd_order) &
318
          vp9_mbuv_is_skippable_4x4(xd));
319
}
Yaowu Xu's avatar
Yaowu Xu committed
320

321
int vp9_mby_is_skippable_16x16(MACROBLOCKD *xd) {
Daniel Kang's avatar
Daniel Kang committed
322
  int skip = 1;
Paul Wilkins's avatar
Paul Wilkins committed
323
  skip &= !xd->block[0].eob;
Daniel Kang's avatar
Daniel Kang committed
324 325 326
  return skip;
}

327 328
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
329
}
330

331 332 333 334 335 336 337 338 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 369 370 371 372 373 374 375 376 377 378 379 380 381
#if CONFIG_TX32X32 && CONFIG_SUPERBLOCKS
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;
  const int skip_inc =  !vp9_segfeature_active(xd, segment_id, SEG_LVL_EOB) ||
                        (vp9_get_segdata(xd, segment_id, SEG_LVL_EOB) != 0);
  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;

382 383
  tokenize_b(cpi, xd, 0, t, PLANE_TYPE_Y_WITH_DC,
             TX_32X32, dry_run);
384 385 386 387
  A[0][1] = A[0][2] = A[0][3] = A[0][0];
  L[0][1] = L[0][2] = L[0][3] = L[0][0];

  for (b = 16; b < 24; b += 4) {
388
    tokenize_b(cpi, xd, b, t, PLANE_TYPE_UV,
389 390 391 392 393 394 395 396 397 398 399 400
               TX_16X16, dry_run);
  }
  vpx_memset(&A[0][8], 0, sizeof(A[0][8]));
  vpx_memset(&L[0][8], 0, sizeof(L[0][8]));
  vpx_memcpy(A[1], A[0], sizeof(ENTROPY_CONTEXT_PLANES));
  vpx_memcpy(L[1], L[0], sizeof(ENTROPY_CONTEXT_PLANES));

  if (dry_run)
    *t = t_backup;
}
#endif

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

John Koleszar's avatar
John Koleszar committed
412 413 414 415
  // 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
416
  int segment_id = xd->mode_info_context->mbmi.segment_id;
417

418 419
  if (!vp9_segfeature_active(xd, segment_id, SEG_LVL_EOB) ||
      (vp9_get_segdata(xd, segment_id, SEG_LVL_EOB) != 0)) {
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:
Daniel Kang's avatar
Daniel Kang committed
428
      xd->mode_info_context->mbmi.mb_skip_coeff = mb_is_skippable_16x16(xd);
Daniel Kang's avatar
Daniel Kang committed
429 430
      break;
    case TX_8X8:
431 432
      if (xd->mode_info_context->mbmi.mode == I8X8_PRED ||
          xd->mode_info_context->mbmi.mode == SPLITMV)
433 434
        xd->mode_info_context->mbmi.mb_skip_coeff =
            mb_is_skippable_8x8_4x4uv(xd, 0);
Deb Mukherjee's avatar
Deb Mukherjee committed
435
      else
436 437
        xd->mode_info_context->mbmi.mb_skip_coeff =
            mb_is_skippable_8x8(xd, has_2nd_order);
Daniel Kang's avatar
Daniel Kang committed
438
      break;
Deb Mukherjee's avatar
Deb Mukherjee committed
439

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

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

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

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

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

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

John Koleszar's avatar
John Koleszar committed
502 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 517 518
    vpx_memset(hybrid_context_counters_16x16, 0,
               sizeof(hybrid_context_counters_16x16));
#if CONFIG_TX32X32
    vpx_memset(context_counters_32x32, 0, sizeof(context_counters_32x32));
#endif
John Koleszar's avatar
John Koleszar committed
519
  } else {
520 521 522
    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
523
    fread(context_counters_8x8, sizeof(context_counters_8x8), 1, f);
524 525
    fread(hybrid_context_counters_8x8,
          sizeof(hybrid_context_counters_8x8), 1, f);
Daniel Kang's avatar
Daniel Kang committed
526
    fread(context_counters_16x16, sizeof(context_counters_16x16), 1, f);
527 528 529 530 531
    fread(hybrid_context_counters_16x16,
          sizeof(hybrid_context_counters_16x16), 1, f);
#if CONFIG_TX32X32
    fread(context_counters_32x32, sizeof(context_counters_32x32), 1, f);
#endif
John Koleszar's avatar
John Koleszar committed
532 533 534 535 536
    fclose(f);
  }

  f = fopen("treeupdate.bin", "rb");
  if (!f) {
537 538 539
    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
540
    vpx_memset(tree_update_hist_8x8, 0, sizeof(tree_update_hist_8x8));
541 542
    vpx_memset(hybrid_tree_update_hist_8x8, 0,
               sizeof(hybrid_tree_update_hist_8x8));
Daniel Kang's avatar
Daniel Kang committed
543
    vpx_memset(tree_update_hist_16x16, 0, sizeof(tree_update_hist_16x16));
544 545 546 547 548
    vpx_memset(hybrid_tree_update_hist_16x16, 0,
               sizeof(hybrid_tree_update_hist_16x16));
#if CONFIG_TX32X32
    vpx_memset(tree_update_hist_32x32, 0, sizeof(tree_update_hist_32x32));
#endif
John Koleszar's avatar
John Koleszar committed
549
  } else {
550 551 552
    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
553
    fread(tree_update_hist_8x8, sizeof(tree_update_hist_8x8), 1, f);
554 555
    fread(hybrid_tree_update_hist_8x8,
          sizeof(hybrid_tree_update_hist_8x8), 1, f);
Daniel Kang's avatar
Daniel Kang committed
556
    fread(tree_update_hist_16x16, sizeof(tree_update_hist_16x16), 1, f);
557 558 559 560 561
    fread(hybrid_tree_update_hist_16x16,
          sizeof(hybrid_tree_update_hist_16x16), 1, f);
#if CONFIG_TX32X32
    fread(tree_update_hist_32x32, sizeof(tree_update_hist_32x32), 1, f);
#endif
John Koleszar's avatar
John Koleszar committed
562 563
    fclose(f);
  }
John Koleszar's avatar
John Koleszar committed
564 565
}

566 567
static void print_counter(FILE *f, vp9_coeff_accum *context_counters,
                          int block_types, const char *header) {
John Koleszar's avatar
John Koleszar committed
568
  int type, band, pt, t;
John Koleszar's avatar
John Koleszar committed
569

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

572
#define Comma(X) (X ? "," : "")
John Koleszar's avatar
John Koleszar committed
573 574 575 576 577 578 579 580 581 582 583 584
  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
585
          const int64_t x = context_counters[type][band][pt][t];
John Koleszar's avatar
John Koleszar committed
586
          const int y = (int) x;
587

John Koleszar's avatar
John Koleszar committed
588
          assert(x == (int64_t) y);  /* no overflow handling yet */
John Koleszar's avatar
John Koleszar committed
589 590 591 592 593 594 595
          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  }");
596
  } while (++type < block_types);
Daniel Kang's avatar
Daniel Kang committed
597
  fprintf(f, "\n};\n");
598
}
599

600 601 602
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
603

604
  fprintf(f, "static const vp9_coeff_probs %s = {", header);
605

John Koleszar's avatar
John Koleszar committed
606
  type = 0;
607
#define Newline(x, spaces) (x ? " " : "\n" spaces)
John Koleszar's avatar
John Koleszar committed
608
  do {
609 610
    fprintf(f, "%s%s{ /* block Type %d */",
            Comma(type), Newline(type, "  "), type);
John Koleszar's avatar
John Koleszar committed
611 612
    band = 0;
    do {
613 614
      fprintf(f, "%s%s{ /* Coeff Band %d */",
              Comma(band), Newline(band, "    "), band);
John Koleszar's avatar
John Koleszar committed
615 616
      pt = 0;
      do {
617
        unsigned int branch_ct[ENTROPY_NODES][2];
John Koleszar's avatar
John Koleszar committed
618
        unsigned int coef_counts[MAX_ENTROPY_TOKENS];
619
        vp9_prob coef_probs[ENTROPY_NODES];
620

John Koleszar's avatar
John Koleszar committed
621
        for (t = 0; t < MAX_ENTROPY_TOKENS; ++t)
622 623 624
          coef_counts[t] = context_counters[type][band][pt][t];
        vp9_tree_probs_from_distribution(MAX_ENTROPY_TOKENS,
                                         vp9_coef_encodings, vp9_coef_tree,
625
                                         coef_probs, branch_ct, coef_counts);
John Koleszar's avatar
John Koleszar committed
626
        fprintf(f, "%s\n      {", Comma(pt));
627

John Koleszar's avatar
John Koleszar committed
628 629
        t = 0;
        do {
630
          fprintf(f, "%s %3d", Comma(t), coef_probs[t]);
John Koleszar's avatar
John Koleszar committed
631
        } while (++t < ENTROPY_NODES);
632

633
        fprintf(f, " }");
John Koleszar's avatar
John Koleszar committed
634 635 636 637
      } while (++pt < PREV_COEF_CONTEXTS);
      fprintf(f, "\n    }");
    } while (++band < COEF_BANDS);
    fprintf(f, "\n  }");
638
  } while (++type < block_types);
John Koleszar's avatar
John Koleszar committed
639
  fprintf(f, "\n};\n");
640
}
641

642 643
void print_context_counters() {
  FILE *f = fopen("vp9_context.c", "w");
644

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

648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664
  /* 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]");
#if CONFIG_TX32X32
  print_counter(f, context_counters_32x32, BLOCK_TYPES_32X32,
                "vp9_default_coef_counts_32x32[BLOCK_TYPES_32X32]");
#endif
Daniel Kang's avatar
Daniel Kang committed
665

666 667
  /* print coefficient probabilities */
  print_probs(f, context_counters_4x4, BLOCK_TYPES_4X4,
668
              "default_coef_probs_4x4[BLOCK_TYPES_4X4]");
669
  print_probs(f, hybrid_context_counters_4x4, BLOCK_TYPES_4X4,
670
              "default_hybrid_coef_probs_4x4[BLOCK_TYPES_4X4]");
671
  print_probs(f, context_counters_8x8, BLOCK_TYPES_8X8,
672
              "default_coef_probs_8x8[BLOCK_TYPES_8X8]");
673
  print_probs(f, hybrid_context_counters_8x8, BLOCK_TYPES_8X8,
674
              "default_hybrid_coef_probs_8x8[BLOCK_TYPES_8X8]");
675
  print_probs(f, context_counters_16x16, BLOCK_TYPES_16X16,
676
              "default_coef_probs_16x16[BLOCK_TYPES_16X16]");
677
  print_probs(f, hybrid_context_counters_16x16, BLOCK_TYPES_16X16,
678
              "default_hybrid_coef_probs_16x16[BLOCK_TYPES_16X16]");
679 680
#if CONFIG_TX32X32
  print_probs(f, context_counters_32x32, BLOCK_TYPES_32X32,
681
              "default_coef_probs_32x32[BLOCK_TYPES_32X32]");
682
#endif
Daniel Kang's avatar
Daniel Kang committed
683

John Koleszar's avatar
John Koleszar committed
684 685 686
  fclose(f);

  f = fopen("context.bin", "wb");
687 688 689
  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
690
  fwrite(context_counters_8x8, sizeof(context_counters_8x8), 1, f);
691 692
  fwrite(hybrid_context_counters_8x8,
         sizeof(hybrid_context_counters_8x8), 1, f);
Daniel Kang's avatar
Daniel Kang committed
693
  fwrite(context_counters_16x16, sizeof(context_counters_16x16), 1, f);
694 695 696 697 698
  fwrite(hybrid_context_counters_16x16,
         sizeof(hybrid_context_counters_16x16), 1, f);
#if CONFIG_TX32X32
  fwrite(context_counters_32x32, sizeof(context_counters_32x32), 1, f);
#endif
John Koleszar's avatar
John Koleszar committed
699
  fclose(f);
John Koleszar's avatar
John Koleszar committed
700 701 702
}
#endif

703
void vp9_tokenize_initialize() {
John Koleszar's avatar
John Koleszar committed
704
  fill_value_tokens();
John Koleszar's avatar
John Koleszar committed
705 706
}

707
static __inline void stuff_b(VP9_COMP *cpi,
708
                             MACROBLOCKD *xd,
Yaowu Xu's avatar
Yaowu Xu committed
709
                             const int ib,
710 711 712 713
                             TOKENEXTRA **tp,
                             PLANE_TYPE type,
                             TX_SIZE tx_size,
                             int dry_run) {
Yaowu Xu's avatar
Yaowu Xu committed
714
  const BLOCKD * const b = xd->block + ib;
715
  const int *bands;
716 717
  vp9_coeff_count *counts;
  vp9_coeff_probs *probs;
718 719 720 721
  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
722 723 724 725 726 727

  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;
John Koleszar's avatar
John Koleszar committed
728

729 730 731
  switch (tx_size) {
    default:
    case TX_4X4:
732
      bands = vp9_coef_bands;
733
      if (tx_type != DCT_DCT) {
734 735
        counts = cpi->hybrid_coef_counts_4x4;
        probs = cpi->common.fc.hybrid_coef_probs_4x4;
736
      } else {
737 738
        counts = cpi->coef_counts_4x4;
        probs = cpi->common.fc.coef_probs_4x4;
739 740 741
      }
      break;
    case TX_8X8:
Yaowu Xu's avatar
Yaowu Xu committed
742 743 744 745 746 747
#if CONFIG_CNVCONTEXT
      if (type != PLANE_TYPE_Y2) {
        a_ec = (a[0] + a[1]) != 0;
        l_ec = (l[0] + l[1]) != 0;
      }
#endif
748
      bands = vp9_coef_bands_8x8;
749 750 751 752 753 754 755 756 757
      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
758
#if CONFIG_CNVCONTEXT
Yaowu Xu's avatar
Yaowu Xu committed
759 760 761 762
      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;
      }
Yaowu Xu's avatar
Yaowu Xu committed
763
#endif
764
      bands = vp9_coef_bands_16x16;
765 766 767 768 769 770 771 772
      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;
773 774 775 776 777 778 779
#if CONFIG_TX32X32 && CONFIG_SUPERBLOCKS
    case TX_32X32:
      bands = vp9_coef_bands_32x32;
      counts = cpi->coef_counts_32x32;
      probs = cpi->common.fc.coef_probs_32x32;
      break;
#endif
780
  }
Yaowu Xu's avatar
Yaowu Xu committed
781 782 783

  VP9_COMBINEENTROPYCONTEXTS(pt, a_ec, l_ec);

784
  band = bands[(type == PLANE_TYPE_Y_NO_DC) ? 1 : 0];
John Koleszar's avatar
John Koleszar committed
785
  t->Token = DCT_EOB_TOKEN;
786
  t->context_tree = probs[type][band][pt];
John Koleszar's avatar
John Koleszar committed
787 788 789
  t->skip_eob_node = 0;
  ++t;
  *tp = t;
790
  *a = *l = 0;
Yaowu Xu's avatar
Yaowu Xu committed
791 792 793 794
  if (tx_size == TX_8X8 && type != PLANE_TYPE_Y2) {
    a[1] = 0;
    l[1] = 0;
  } else if (tx_size == TX_16X16) {
Yaowu Xu's avatar
Yaowu Xu committed
795 796 797 798 799 800 801 802 803
    if (type != PLANE_TYPE_UV) {
      a[1] = a[2] = a[3] = 0;
      l[1] = l[2] = l[3] = 0;
#if CONFIG_TX32X32 && CONFIG_SUPERBLOCKS
    } else {
      a[1] = 0;
      l[1] = 0;
#endif
    }
Yaowu Xu's avatar
Yaowu Xu committed
804 805
  }

806
  if (!dry_run) {
807
    ++counts[type][band][pt][DCT_EOB_TOKEN];
808
  }
809 810
}

811 812
static void stuff_mb_8x8(VP9_COMP *cpi, MACROBLOCKD *xd,
                         TOKENEXTRA **t, int dry_run) {
813
  PLANE_TYPE plane_type;
John Koleszar's avatar
John Koleszar committed
814
  int b;