vp9_tokenize.c 29.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 104 105 106 107 108

#if CONFIG_NEWCOEFCONTEXT
#define PT pn
#else
#define PT pt
#endif

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

Yaowu Xu's avatar
Yaowu Xu committed
134 135 136 137 138 139
  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;

140 141 142 143 144 145
  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];


146 147 148 149
  switch (tx_size) {
    default:
    case TX_4X4:
      seg_eob = 16;
150 151
      bands = vp9_coef_bands_4x4;
      scan = vp9_default_zig_zag1d_4x4;
152
      if (tx_type != DCT_DCT) {
153 154
        counts = cpi->hybrid_coef_counts_4x4;
        probs = cpi->common.fc.hybrid_coef_probs_4x4;
155
        if (tx_type == ADST_DCT) {
156
          scan = vp9_row_scan_4x4;
157
        } else if (tx_type == DCT_ADST) {
158
          scan = vp9_col_scan_4x4;
159 160
        }
      } else {
161 162
        counts = cpi->coef_counts_4x4;
        probs = cpi->common.fc.coef_probs_4x4;
163 164 165 166 167
      }
      break;
    case TX_8X8:
      if (type == PLANE_TYPE_Y2) {
        seg_eob = 4;
168 169
        bands = vp9_coef_bands_4x4;
        scan = vp9_default_zig_zag1d_4x4;
170
      } else {
Yaowu Xu's avatar
Yaowu Xu committed
171 172 173 174
#if CONFIG_CNVCONTEXT
        a_ec = (a[0] + a[1]) != 0;
        l_ec = (l[0] + l[1]) != 0;
#endif
175
        seg_eob = 64;
176 177
        bands = vp9_coef_bands_8x8;
        scan = vp9_default_zig_zag1d_8x8;
178 179 180 181 182 183 184 185 186 187
      }
      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
188
#if CONFIG_CNVCONTEXT
Yaowu Xu's avatar
Yaowu Xu committed
189 190 191
      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;
192 193 194
      } 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
195
      }
Yaowu Xu's avatar
Yaowu Xu committed
196
#endif
197
      seg_eob = 256;
198 199
      bands = vp9_coef_bands_16x16;
      scan = vp9_default_zig_zag1d_16x16;
200 201 202 203 204 205 206
      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;
      }
207
      if (type == PLANE_TYPE_UV) {
208
        int uv_idx = (ib - 16) >> 2;
209 210 211 212
        qcoeff_ptr = xd->sb_coeff_data.qcoeff + 1024 + 256 * uv_idx;
      }
      break;
    case TX_32X32:
213 214 215 216 217 218 219 220
#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
221 222 223 224 225 226
      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;
227
      break;
John Koleszar's avatar
John Koleszar committed
228 229
  }

Yaowu Xu's avatar
Yaowu Xu committed
230
  VP9_COMBINEENTROPYCONTEXTS(pt, a_ec, l_ec);
231 232 233 234
#if CONFIG_NEWCOEFCONTEXT
  neighbors = vp9_get_coef_neighbors_handle(scan);
  pn = pt;
#endif
Yaowu Xu's avatar
Yaowu Xu committed
235

236 237
  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
238

239
  do {
240
    const int band = bands[c];
241 242 243
    int token;

    if (c < eob) {
244
      const int rc = scan[c];
245
      const int v = qcoeff_ptr[rc];
246 247
      assert(-DCT_MAX_VALUE <= v  &&  v < DCT_MAX_VALUE);

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

    t->Token = token;
255
    t->context_tree = probs[type][band][PT];
256 257
    t->skip_eob_node = (pt == 0) && ((band > 0 && type != PLANE_TYPE_Y_NO_DC) ||
                                     (band > 1 && type == PLANE_TYPE_Y_NO_DC));
258
    assert(vp9_coef_encodings[t->Token].Len - t->skip_eob_node > 0);
259
    if (!dry_run) {
260
      ++counts[type][band][PT][token];
261
    }
262
    pt = vp9_prev_token_class[token];
263 264 265 266 267 268 269
#if CONFIG_NEWCOEFCONTEXT
    if (c < seg_eob - 1 && NEWCOEFCONTEXT_BAND_COND(bands[c + 1]))
      pn = vp9_get_coef_neighbor_context(
          qcoeff_ptr, (type == PLANE_TYPE_Y_NO_DC), neighbors, scan[c + 1]);
    else
      pn = pt;
#endif
270
    ++t;
271 272 273
  } while (c < eob && ++c < seg_eob);

  *tp = t;
Yaowu Xu's avatar
Yaowu Xu committed
274 275 276 277 278 279 280 281
  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
282 283 284 285
    if (type != PLANE_TYPE_UV) {
      a[1] = a[2] = a[3] = a_ec;
      l[1] = l[2] = l[3] = l_ec;
    } else {
286 287
      a1[0] = a1[1] = a[1] = a_ec;
      l1[0] = l1[1] = l[1] = l_ec;
Yaowu Xu's avatar
Yaowu Xu committed
288
    }
289 290 291 292 293
  } 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
294
  }
John Koleszar's avatar
John Koleszar committed
295 296
}

297
int vp9_mby_is_skippable_4x4(MACROBLOCKD *xd, int has_2nd_order) {
John Koleszar's avatar
John Koleszar committed
298 299
  int skip = 1;
  int i = 0;
300

301
  if (has_2nd_order) {
John Koleszar's avatar
John Koleszar committed
302
    for (i = 0; i < 16; i++)
Paul Wilkins's avatar
Paul Wilkins committed
303 304
      skip &= (xd->block[i].eob < 2);
    skip &= (!xd->block[24].eob);
John Koleszar's avatar
John Koleszar committed
305 306
  } else {
    for (i = 0; i < 16; i++)
Paul Wilkins's avatar
Paul Wilkins committed
307
      skip &= (!xd->block[i].eob);
John Koleszar's avatar
John Koleszar committed
308 309
  }
  return skip;
310
}
311

312
int vp9_mbuv_is_skippable_4x4(MACROBLOCKD *xd) {
John Koleszar's avatar
John Koleszar committed
313 314
  int skip = 1;
  int i;
315

John Koleszar's avatar
John Koleszar committed
316
  for (i = 16; i < 24; i++)
Paul Wilkins's avatar
Paul Wilkins committed
317
    skip &= (!xd->block[i].eob);
John Koleszar's avatar
John Koleszar committed
318
  return skip;
319 320
}

321 322
static int mb_is_skippable_4x4(MACROBLOCKD *xd, int has_2nd_order) {
  return (vp9_mby_is_skippable_4x4(xd, has_2nd_order) &
323
          vp9_mbuv_is_skippable_4x4(xd));
324
}
Yaowu Xu's avatar
Yaowu Xu committed
325

326
int vp9_mby_is_skippable_8x8(MACROBLOCKD *xd, int has_2nd_order) {
John Koleszar's avatar
John Koleszar committed
327 328
  int skip = 1;
  int i = 0;
329

330
  if (has_2nd_order) {
Deb Mukherjee's avatar
Deb Mukherjee committed
331 332 333 334 335 336 337
    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
338
  return skip;
339
}
340

341
int vp9_mbuv_is_skippable_8x8(MACROBLOCKD *xd) {
Paul Wilkins's avatar
Paul Wilkins committed
342
  return (!xd->block[16].eob) & (!xd->block[20].eob);
343
}
344

345 346
static int mb_is_skippable_8x8(MACROBLOCKD *xd, int has_2nd_order) {
  return (vp9_mby_is_skippable_8x8(xd, has_2nd_order) &
347
          vp9_mbuv_is_skippable_8x8(xd));
Deb Mukherjee's avatar
Deb Mukherjee committed
348 349
}

350 351
static int mb_is_skippable_8x8_4x4uv(MACROBLOCKD *xd, int has_2nd_order) {
  return (vp9_mby_is_skippable_8x8(xd, has_2nd_order) &
352
          vp9_mbuv_is_skippable_4x4(xd));
353
}
Yaowu Xu's avatar
Yaowu Xu committed
354

355
int vp9_mby_is_skippable_16x16(MACROBLOCKD *xd) {
Daniel Kang's avatar
Daniel Kang committed
356
  int skip = 1;
Paul Wilkins's avatar
Paul Wilkins committed
357
  skip &= !xd->block[0].eob;
Daniel Kang's avatar
Daniel Kang committed
358 359 360
  return skip;
}

361 362
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
363
}
364

365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414
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;

415 416
  tokenize_b(cpi, xd, 0, t, PLANE_TYPE_Y_WITH_DC,
             TX_32X32, dry_run);
417 418

  for (b = 16; b < 24; b += 4) {
419
    tokenize_b(cpi, xd, b, t, PLANE_TYPE_UV,
420 421
               TX_16X16, dry_run);
  }
422
  A[0][8] = L[0][8] = A[1][8] = L[1][8] = 0;
423 424 425 426
  if (dry_run)
    *t = t_backup;
}

427
void vp9_tokenize_mb(VP9_COMP *cpi,
Paul Wilkins's avatar
Paul Wilkins committed
428
                     MACROBLOCKD *xd,
429 430
                     TOKENEXTRA **t,
                     int dry_run) {
431
  PLANE_TYPE plane_type;
432
  int has_2nd_order;
John Koleszar's avatar
John Koleszar committed
433
  int b;
434
  int tx_size = xd->mode_info_context->mbmi.txfm_size;
Paul Wilkins's avatar
Paul Wilkins committed
435
  int mb_skip_context = vp9_get_pred_context(&cpi->common, xd, PRED_MBSKIP);
436
  TOKENEXTRA *t_backup = *t;
Paul Wilkins's avatar
Paul Wilkins committed
437

John Koleszar's avatar
John Koleszar committed
438 439 440 441
  // 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
442
  int segment_id = xd->mode_info_context->mbmi.segment_id;
443

444 445
  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
446 447 448
    skip_inc = 1;
  } else
    skip_inc = 0;
449

450
  has_2nd_order = get_2nd_order_usage(xd);
John Koleszar's avatar
John Koleszar committed
451

452
  switch (tx_size) {
Daniel Kang's avatar
Daniel Kang committed
453
    case TX_16X16:
454

Daniel Kang's avatar
Daniel Kang committed
455
      xd->mode_info_context->mbmi.mb_skip_coeff = mb_is_skippable_16x16(xd);
Daniel Kang's avatar
Daniel Kang committed
456 457
      break;
    case TX_8X8:
458 459
      if (xd->mode_info_context->mbmi.mode == I8X8_PRED ||
          xd->mode_info_context->mbmi.mode == SPLITMV)
460 461
        xd->mode_info_context->mbmi.mb_skip_coeff =
            mb_is_skippable_8x8_4x4uv(xd, 0);
Deb Mukherjee's avatar
Deb Mukherjee committed
462
      else
463 464
        xd->mode_info_context->mbmi.mb_skip_coeff =
            mb_is_skippable_8x8(xd, has_2nd_order);
Daniel Kang's avatar
Daniel Kang committed
465
      break;
Deb Mukherjee's avatar
Deb Mukherjee committed
466

Daniel Kang's avatar
Daniel Kang committed
467
    default:
468 469
      xd->mode_info_context->mbmi.mb_skip_coeff =
          mb_is_skippable_4x4(xd, has_2nd_order);
Daniel Kang's avatar
Daniel Kang committed
470 471
      break;
  }
472

Paul Wilkins's avatar
Paul Wilkins committed
473
  if (xd->mode_info_context->mbmi.mb_skip_coeff) {
474 475
    if (!dry_run)
      cpi->skip_true_count[mb_skip_context] += skip_inc;
John Koleszar's avatar
John Koleszar committed
476
    if (!cpi->common.mb_no_coeff_skip) {
477
      vp9_stuff_mb(cpi, xd, t, dry_run);
John Koleszar's avatar
John Koleszar committed
478
    } else {
Yaowu Xu's avatar
Yaowu Xu committed
479
      vp9_reset_mb_tokens_context(xd);
John Koleszar's avatar
John Koleszar committed
480
    }
Yaowu Xu's avatar
Yaowu Xu committed
481

482 483
    if (dry_run)
      *t = t_backup;
John Koleszar's avatar
John Koleszar committed
484 485 486
    return;
  }

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

490
  if (has_2nd_order) {
Yaowu Xu's avatar
Yaowu Xu committed
491
    tokenize_b(cpi, xd, 24, t, PLANE_TYPE_Y2, tx_size, dry_run);
492
    plane_type = PLANE_TYPE_Y_NO_DC;
Yaowu Xu's avatar
Yaowu Xu committed
493
  } else {
Yaowu Xu's avatar
Yaowu Xu committed
494 495
    xd->above_context->y2 = 0;
    xd->left_context->y2 = 0;
496
    plane_type = PLANE_TYPE_Y_WITH_DC;
Yaowu Xu's avatar
Yaowu Xu committed
497
  }
John Koleszar's avatar
John Koleszar committed
498

499
  if (tx_size == TX_16X16) {
Yaowu Xu's avatar
Yaowu Xu committed
500
    tokenize_b(cpi, xd, 0, t, PLANE_TYPE_Y_WITH_DC, TX_16X16, dry_run);
Daniel Kang's avatar
Daniel Kang committed
501
    for (b = 16; b < 24; b += 4) {
Yaowu Xu's avatar
Yaowu Xu committed
502
      tokenize_b(cpi, xd, b, t, PLANE_TYPE_UV, TX_8X8, dry_run);
Daniel Kang's avatar
Daniel Kang committed
503
    }
504
  } else if (tx_size == TX_8X8) {
John Koleszar's avatar
John Koleszar committed
505
    for (b = 0; b < 16; b += 4) {
Yaowu Xu's avatar
Yaowu Xu committed
506
      tokenize_b(cpi, xd, b, t, plane_type, TX_8X8, dry_run);
John Koleszar's avatar
John Koleszar committed
507
    }
508 509
    if (xd->mode_info_context->mbmi.mode == I8X8_PRED ||
        xd->mode_info_context->mbmi.mode == SPLITMV) {
510
      for (b = 16; b < 24; b++) {
Yaowu Xu's avatar
Yaowu Xu committed
511
        tokenize_b(cpi, xd, b, t, PLANE_TYPE_UV, TX_4X4, dry_run);
512
      }
513
    } else {
Deb Mukherjee's avatar
Deb Mukherjee committed
514
      for (b = 16; b < 24; b += 4) {
Yaowu Xu's avatar
Yaowu Xu committed
515
        tokenize_b(cpi, xd, b, t, PLANE_TYPE_UV, TX_8X8, dry_run);
Deb Mukherjee's avatar
Deb Mukherjee committed
516
      }
517
    }
Jingning Han's avatar
Jingning Han committed
518
  } else {
Yaowu Xu's avatar
Yaowu Xu committed
519 520 521 522
    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);
523
    }
Jingning Han's avatar
Jingning Han committed
524
  }
525 526
  if (dry_run)
    *t = t_backup;
John Koleszar's avatar
John Koleszar committed
527
}
528

John Koleszar's avatar
John Koleszar committed
529
#ifdef ENTROPY_STATS
John Koleszar's avatar
John Koleszar committed
530 531 532
void init_context_counters(void) {
  FILE *f = fopen("context.bin", "rb");
  if (!f) {
533 534 535
    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
536
    vpx_memset(context_counters_8x8, 0, sizeof(context_counters_8x8));
537 538
    vpx_memset(hybrid_context_counters_8x8, 0,
               sizeof(hybrid_context_counters_8x8));
Daniel Kang's avatar
Daniel Kang committed
539
    vpx_memset(context_counters_16x16, 0, sizeof(context_counters_16x16));
540 541 542
    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
543
  } else {
544 545 546
    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
547
    fread(context_counters_8x8, sizeof(context_counters_8x8), 1, f);
548 549
    fread(hybrid_context_counters_8x8,
          sizeof(hybrid_context_counters_8x8), 1, f);
Daniel Kang's avatar
Daniel Kang committed
550
    fread(context_counters_16x16, sizeof(context_counters_16x16), 1, f);
551 552 553
    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
554 555 556 557 558
    fclose(f);
  }

  f = fopen("treeupdate.bin", "rb");
  if (!f) {
559 560 561
    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
562
    vpx_memset(tree_update_hist_8x8, 0, sizeof(tree_update_hist_8x8));
563 564
    vpx_memset(hybrid_tree_update_hist_8x8, 0,
               sizeof(hybrid_tree_update_hist_8x8));
Daniel Kang's avatar
Daniel Kang committed
565
    vpx_memset(tree_update_hist_16x16, 0, sizeof(tree_update_hist_16x16));
566 567 568
    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
569
  } else {
570 571 572
    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
573
    fread(tree_update_hist_8x8, sizeof(tree_update_hist_8x8), 1, f);
574 575
    fread(hybrid_tree_update_hist_8x8,
          sizeof(hybrid_tree_update_hist_8x8), 1, f);
Daniel Kang's avatar
Daniel Kang committed
576
    fread(tree_update_hist_16x16, sizeof(tree_update_hist_16x16), 1, f);
577 578 579
    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
580 581
    fclose(f);
  }
John Koleszar's avatar
John Koleszar committed
582 583
}

584 585
static void print_counter(FILE *f, vp9_coeff_accum *context_counters,
                          int block_types, const char *header) {
John Koleszar's avatar
John Koleszar committed
586
  int type, band, pt, t;
John Koleszar's avatar
John Koleszar committed
587

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

590
#define Comma(X) (X ? "," : "")
John Koleszar's avatar
John Koleszar committed
591 592 593 594 595 596 597 598 599 600 601 602
  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
603
          const int64_t x = context_counters[type][band][pt][t];
John Koleszar's avatar
John Koleszar committed
604
          const int y = (int) x;
605

John Koleszar's avatar
John Koleszar committed
606
          assert(x == (int64_t) y);  /* no overflow handling yet */
John Koleszar's avatar
John Koleszar committed
607 608 609 610 611 612 613
          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  }");
614
  } while (++type < block_types);
Daniel Kang's avatar
Daniel Kang committed
615
  fprintf(f, "\n};\n");
616
}
617

618 619 620
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
621

622
  fprintf(f, "static const vp9_coeff_probs %s = {", header);
623

John Koleszar's avatar
John Koleszar committed
624
  type = 0;
625
#define Newline(x, spaces) (x ? " " : "\n" spaces)
John Koleszar's avatar
John Koleszar committed
626
  do {
627 628
    fprintf(f, "%s%s{ /* block Type %d */",
            Comma(type), Newline(type, "  "), type);
John Koleszar's avatar
John Koleszar committed
629 630
    band = 0;
    do {
631 632
      fprintf(f, "%s%s{ /* Coeff Band %d */",
              Comma(band), Newline(band, "    "), band);
John Koleszar's avatar
John Koleszar committed
633 634
      pt = 0;
      do {
635
        unsigned int branch_ct[ENTROPY_NODES][2];
John Koleszar's avatar
John Koleszar committed
636
        unsigned int coef_counts[MAX_ENTROPY_TOKENS];
637
        vp9_prob coef_probs[ENTROPY_NODES];
638

John Koleszar's avatar
John Koleszar committed
639
        for (t = 0; t < MAX_ENTROPY_TOKENS; ++t)
640 641 642
          coef_counts[t] = context_counters[type][band][pt][t];
        vp9_tree_probs_from_distribution(MAX_ENTROPY_TOKENS,
                                         vp9_coef_encodings, vp9_coef_tree,
643
                                         coef_probs, branch_ct, coef_counts);
John Koleszar's avatar
John Koleszar committed
644
        fprintf(f, "%s\n      {", Comma(pt));
645

John Koleszar's avatar
John Koleszar committed
646 647
        t = 0;
        do {
648
          fprintf(f, "%s %3d", Comma(t), coef_probs[t]);
John Koleszar's avatar
John Koleszar committed
649
        } while (++t < ENTROPY_NODES);
650

651
        fprintf(f, " }");
John Koleszar's avatar
John Koleszar committed
652 653 654 655
      } while (++pt < PREV_COEF_CONTEXTS);
      fprintf(f, "\n    }");
    } while (++band < COEF_BANDS);
    fprintf(f, "\n  }");
656
  } while (++type < block_types);
John Koleszar's avatar
John Koleszar committed
657
  fprintf(f, "\n};\n");
658
}
659

660 661
void print_context_counters() {
  FILE *f = fopen("vp9_context.c", "w");
662

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

666 667 668 669 670 671 672 673 674 675 676 677 678 679 680
  /* 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
681

682 683
  /* print coefficient probabilities */
  print_probs(f, context_counters_4x4, BLOCK_TYPES_4X4,
684
              "default_coef_probs_4x4[BLOCK_TYPES_4X4]");
685
  print_probs(f, hybrid_context_counters_4x4, BLOCK_TYPES_4X4,
686
              "default_hybrid_coef_probs_4x4[BLOCK_TYPES_4X4]");
687
  print_probs(f, context_counters_8x8, BLOCK_TYPES_8X8,
688
              "default_coef_probs_8x8[BLOCK_TYPES_8X8]");
689
  print_probs(f, hybrid_context_counters_8x8, BLOCK_TYPES_8X8,
690
              "default_hybrid_coef_probs_8x8[BLOCK_TYPES_8X8]");
691
  print_probs(f, context_counters_16x16, BLOCK_TYPES_16X16,
692
              "default_coef_probs_16x16[BLOCK_TYPES_16X16]");
693
  print_probs(f, hybrid_context_counters_16x16, BLOCK_TYPES_16X16,
694
              "default_hybrid_coef_probs_16x16[BLOCK_TYPES_16X16]");
695
  print_probs(f, context_counters_32x32, BLOCK_TYPES_32X32,
696
              "default_coef_probs_32x32[BLOCK_TYPES_32X32]");
Daniel Kang's avatar
Daniel Kang committed
697

John Koleszar's avatar
John Koleszar committed
698 699 700
  fclose(f);

  f = fopen("context.bin", "wb");
701 702 703
  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
704
  fwrite(context_counters_8x8, sizeof(context_counters_8x8), 1, f);
705 706
  fwrite(hybrid_context_counters_8x8,
         sizeof(hybrid_context_counters_8x8), 1, f);
Daniel Kang's avatar
Daniel Kang committed
707
  fwrite(context_counters_16x16, sizeof(context_counters_16x16), 1, f);
708 709 710
  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
711
  fclose(f);
John Koleszar's avatar
John Koleszar committed
712 713 714
}
#endif

715
void vp9_tokenize_initialize() {
John Koleszar's avatar
John Koleszar committed
716
  fill_value_tokens();
John Koleszar's avatar
John Koleszar committed
717 718
}

719
static __inline void stuff_b(VP9_COMP *cpi,
720
                             MACROBLOCKD *xd,
Yaowu Xu's avatar
Yaowu Xu committed
721
                             const int ib,
722 723 724 725
                             TOKENEXTRA **tp,
                             PLANE_TYPE type,
                             TX_SIZE tx_size,
                             int dry_run) {
Yaowu Xu's avatar
Yaowu Xu committed
726
  const BLOCKD * const b = xd->block + ib;
727
  const int *bands;
728 729
  vp9_coeff_count *counts;
  vp9_coeff_probs *probs;
730 731 732 733
  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
734 735 736 737 738
  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;
739 740 741 742
  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
743

744 745 746
  switch (tx_size) {
    default:
    case TX_4X4:
747
      bands = vp9_coef_bands_4x4;
748
      if (tx_type != DCT_DCT) {
749 750
        counts = cpi->hybrid_coef_counts_4x4;
        probs = cpi->common.fc.hybrid_coef_probs_4x4;
751
      } else {
752 753
        counts = cpi->coef_counts_4x4;
        probs = cpi->common.fc.coef_probs_4x4;
754 755 756
      }
      break;
    case TX_8X8:
Yaowu Xu's avatar
Yaowu Xu committed
757 758 759 760 761 762
#if CONFIG_CNVCONTEXT
      if (type != PLANE_TYPE_Y2) {
        a_ec = (a[0] + a[1]) != 0;
        l_ec = (l[0] + l[1]) != 0;
      }
#endif
763
      bands = vp9_coef_bands_8x8;
764 765 766 767 768 769 770 771 772
      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
773
#if CONFIG_CNVCONTEXT
Yaowu Xu's avatar
Yaowu Xu committed
774 775 776
      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;
777 778 779
      } 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
780
      }
Yaowu Xu's avatar
Yaowu Xu committed
781
#endif
782
      bands = vp9_coef_bands_16x16;
783 784 785 786 787 788 789 790
      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;