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


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

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

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

#ifdef ENTROPY_STATS
28 29 30 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 137 138 139 140
#if CONFIG_SUPERBLOCKS && CONFIG_TX32X32
  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];
#endif


141 142 143 144
  switch (tx_size) {
    default:
    case TX_4X4:
      seg_eob = 16;
145 146
      bands = vp9_coef_bands_4x4;
      scan = vp9_default_zig_zag1d_4x4;
147
      if (tx_type != DCT_DCT) {
148 149
        counts = cpi->hybrid_coef_counts_4x4;
        probs = cpi->common.fc.hybrid_coef_probs_4x4;
150
        if (tx_type == ADST_DCT) {
151
          scan = vp9_row_scan_4x4;
152
        } else if (tx_type == DCT_ADST) {
153
          scan = vp9_col_scan_4x4;
154 155
        }
      } else {
156 157
        counts = cpi->coef_counts_4x4;
        probs = cpi->common.fc.coef_probs_4x4;
158 159 160 161 162
      }
      break;
    case TX_8X8:
      if (type == PLANE_TYPE_Y2) {
        seg_eob = 4;
163 164
        bands = vp9_coef_bands_4x4;
        scan = vp9_default_zig_zag1d_4x4;
165
      } else {
Yaowu Xu's avatar
Yaowu Xu committed
166 167 168 169
#if CONFIG_CNVCONTEXT
        a_ec = (a[0] + a[1]) != 0;
        l_ec = (l[0] + l[1]) != 0;
#endif
170
        seg_eob = 64;
171 172
        bands = vp9_coef_bands_8x8;
        scan = vp9_default_zig_zag1d_8x8;
173 174 175 176 177 178 179 180 181 182
      }
      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
183
#if CONFIG_CNVCONTEXT
Yaowu Xu's avatar
Yaowu Xu committed
184 185 186
      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;
187 188 189 190 191
#if CONFIG_SUPERBLOCKS && CONFIG_TX32X32
      } else {
        a_ec = (a[0] + a[1] + a1[0] + a1[1]) != 0;
        l_ec = (l[0] + l[1] + l1[0] + l1[1]) != 0;
#endif
Yaowu Xu's avatar
Yaowu Xu committed
192
      }
Yaowu Xu's avatar
Yaowu Xu committed
193
#endif
194
      seg_eob = 256;
195 196
      bands = vp9_coef_bands_16x16;
      scan = vp9_default_zig_zag1d_16x16;
197 198 199 200 201 202 203
      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;
      }
204 205 206 207 208 209 210 211 212
#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:
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;
228
#endif
John Koleszar's avatar
John Koleszar committed
229 230
  }

Yaowu Xu's avatar
Yaowu Xu committed
231 232
  VP9_COMBINEENTROPYCONTEXTS(pt, a_ec, l_ec);

233 234
  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
235

236
  do {
237
    const int band = bands[c];
238 239 240
    int token;

    if (c < eob) {
241
      const int rc = scan[c];
242
      const int v = qcoeff_ptr[rc];
243 244
      assert(-DCT_MAX_VALUE <= v  &&  v < DCT_MAX_VALUE);

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

    t->Token = token;
252 253 254
    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));
255
    assert(vp9_coef_encodings[t->Token].Len - t->skip_eob_node > 0);
256
    if (!dry_run) {
257
      ++counts[type][band][pt][token];
258
    }
259
    pt = vp9_prev_token_class[token];
260
    ++t;
261 262 263
  } while (c < eob && ++c < seg_eob);

  *tp = t;
Yaowu Xu's avatar
Yaowu Xu committed
264 265 266 267 268 269 270 271
  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
272 273 274 275 276
    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 {
277 278
      a1[0] = a1[1] = a[1] = a_ec;
      l1[0] = l1[1] = l[1] = l_ec;
Yaowu Xu's avatar
Yaowu Xu committed
279 280
#endif
    }
281 282 283 284 285 286 287
#if CONFIG_TX32X32 && CONFIG_SUPERBLOCKS
  } 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;
#endif
Yaowu Xu's avatar
Yaowu Xu committed
288
  }
John Koleszar's avatar
John Koleszar committed
289 290
}

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

295
  if (has_2nd_order) {
John Koleszar's avatar
John Koleszar committed
296
    for (i = 0; i < 16; i++)
Paul Wilkins's avatar
Paul Wilkins committed
297 298
      skip &= (xd->block[i].eob < 2);
    skip &= (!xd->block[24].eob);
John Koleszar's avatar
John Koleszar committed
299 300
  } else {
    for (i = 0; i < 16; i++)
Paul Wilkins's avatar
Paul Wilkins committed
301
      skip &= (!xd->block[i].eob);
John Koleszar's avatar
John Koleszar committed
302 303
  }
  return skip;
304
}
305

306
int vp9_mbuv_is_skippable_4x4(MACROBLOCKD *xd) {
John Koleszar's avatar
John Koleszar committed
307 308
  int skip = 1;
  int i;
309

John Koleszar's avatar
John Koleszar committed
310
  for (i = 16; i < 24; i++)
Paul Wilkins's avatar
Paul Wilkins committed
311
    skip &= (!xd->block[i].eob);
John Koleszar's avatar
John Koleszar committed
312
  return skip;
313 314
}

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

320
int vp9_mby_is_skippable_8x8(MACROBLOCKD *xd, int has_2nd_order) {
John Koleszar's avatar
John Koleszar committed
321 322
  int skip = 1;
  int i = 0;
323

324
  if (has_2nd_order) {
Deb Mukherjee's avatar
Deb Mukherjee committed
325 326 327 328 329 330 331
    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
332
  return skip;
333
}
334

335
int vp9_mbuv_is_skippable_8x8(MACROBLOCKD *xd) {
Paul Wilkins's avatar
Paul Wilkins committed
336
  return (!xd->block[16].eob) & (!xd->block[20].eob);
337
}
338

339 340
static int mb_is_skippable_8x8(MACROBLOCKD *xd, int has_2nd_order) {
  return (vp9_mby_is_skippable_8x8(xd, has_2nd_order) &
341
          vp9_mbuv_is_skippable_8x8(xd));
Deb Mukherjee's avatar
Deb Mukherjee committed
342 343
}

344 345
static int mb_is_skippable_8x8_4x4uv(MACROBLOCKD *xd, int has_2nd_order) {
  return (vp9_mby_is_skippable_8x8(xd, has_2nd_order) &
346
          vp9_mbuv_is_skippable_4x4(xd));
347
}
Yaowu Xu's avatar
Yaowu Xu committed
348

349
int vp9_mby_is_skippable_16x16(MACROBLOCKD *xd) {
Daniel Kang's avatar
Daniel Kang committed
350
  int skip = 1;
Paul Wilkins's avatar
Paul Wilkins committed
351
  skip &= !xd->block[0].eob;
Daniel Kang's avatar
Daniel Kang committed
352 353 354
  return skip;
}

355 356
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
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 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
#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;

410 411
  tokenize_b(cpi, xd, 0, t, PLANE_TYPE_Y_WITH_DC,
             TX_32X32, dry_run);
412 413

  for (b = 16; b < 24; b += 4) {
414
    tokenize_b(cpi, xd, b, t, PLANE_TYPE_UV,
415 416
               TX_16X16, dry_run);
  }
417
  A[0][8] = L[0][8] = A[1][8] = L[1][8] = 0;
418 419 420 421 422
  if (dry_run)
    *t = t_backup;
}
#endif

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

John Koleszar's avatar
John Koleszar committed
434 435 436 437
  // 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
438
  int segment_id = xd->mode_info_context->mbmi.segment_id;
439

440 441
  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
442 443 444
    skip_inc = 1;
  } else
    skip_inc = 0;
445

446
  has_2nd_order = get_2nd_order_usage(xd);
John Koleszar's avatar
John Koleszar committed
447

448
  switch (tx_size) {
Daniel Kang's avatar
Daniel Kang committed
449
    case TX_16X16:
450

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

Daniel Kang's avatar
Daniel Kang committed
463
    default:
464 465
      xd->mode_info_context->mbmi.mb_skip_coeff =
          mb_is_skippable_4x4(xd, has_2nd_order);
Daniel Kang's avatar
Daniel Kang committed
466 467
      break;
  }
468

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

478 479
    if (dry_run)
      *t = t_backup;
John Koleszar's avatar
John Koleszar committed
480 481 482
    return;
  }

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

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

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

John Koleszar's avatar
John Koleszar committed
525
#ifdef ENTROPY_STATS
John Koleszar's avatar
John Koleszar committed
526 527 528
void init_context_counters(void) {
  FILE *f = fopen("context.bin", "rb");
  if (!f) {
529 530 531
    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
532
    vpx_memset(context_counters_8x8, 0, sizeof(context_counters_8x8));
533 534
    vpx_memset(hybrid_context_counters_8x8, 0,
               sizeof(hybrid_context_counters_8x8));
Daniel Kang's avatar
Daniel Kang committed
535
    vpx_memset(context_counters_16x16, 0, sizeof(context_counters_16x16));
536 537 538 539 540
    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
541
  } else {
542 543 544
    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
545
    fread(context_counters_8x8, sizeof(context_counters_8x8), 1, f);
546 547
    fread(hybrid_context_counters_8x8,
          sizeof(hybrid_context_counters_8x8), 1, f);
Daniel Kang's avatar
Daniel Kang committed
548
    fread(context_counters_16x16, sizeof(context_counters_16x16), 1, f);
549 550 551 552 553
    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
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 569 570
    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
571
  } else {
572 573 574
    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
575
    fread(tree_update_hist_8x8, sizeof(tree_update_hist_8x8), 1, f);
576 577
    fread(hybrid_tree_update_hist_8x8,
          sizeof(hybrid_tree_update_hist_8x8), 1, f);
Daniel Kang's avatar
Daniel Kang committed
578
    fread(tree_update_hist_16x16, sizeof(tree_update_hist_16x16), 1, f);
579 580 581 582 583
    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
584 585
    fclose(f);
  }
John Koleszar's avatar
John Koleszar committed
586 587
}

588 589
static void print_counter(FILE *f, vp9_coeff_accum *context_counters,
                          int block_types, const char *header) {
John Koleszar's avatar
John Koleszar committed
590
  int type, band, pt, t;
John Koleszar's avatar
John Koleszar committed
591

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

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

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

622 623 624
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
625

626
  fprintf(f, "static const vp9_coeff_probs %s = {", header);
627

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

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

John Koleszar's avatar
John Koleszar committed
650 651
        t = 0;
        do {
652
          fprintf(f, "%s %3d", Comma(t), coef_probs[t]);
John Koleszar's avatar
John Koleszar committed
653
        } while (++t < ENTROPY_NODES);
654

655
        fprintf(f, " }");
John Koleszar's avatar
John Koleszar committed
656 657 658 659
      } while (++pt < PREV_COEF_CONTEXTS);
      fprintf(f, "\n    }");
    } while (++band < COEF_BANDS);
    fprintf(f, "\n  }");
660
  } while (++type < block_types);
John Koleszar's avatar
John Koleszar committed
661
  fprintf(f, "\n};\n");
662
}
663

664 665
void print_context_counters() {
  FILE *f = fopen("vp9_context.c", "w");
666

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

670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686
  /* 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
687

688 689
  /* print coefficient probabilities */
  print_probs(f, context_counters_4x4, BLOCK_TYPES_4X4,
690
              "default_coef_probs_4x4[BLOCK_TYPES_4X4]");
691
  print_probs(f, hybrid_context_counters_4x4, BLOCK_TYPES_4X4,
692
              "default_hybrid_coef_probs_4x4[BLOCK_TYPES_4X4]");
693
  print_probs(f, context_counters_8x8, BLOCK_TYPES_8X8,
694
              "default_coef_probs_8x8[BLOCK_TYPES_8X8]");
695
  print_probs(f, hybrid_context_counters_8x8, BLOCK_TYPES_8X8,
696
              "default_hybrid_coef_probs_8x8[BLOCK_TYPES_8X8]");
697
  print_probs(f, context_counters_16x16, BLOCK_TYPES_16X16,
698
              "default_coef_probs_16x16[BLOCK_TYPES_16X16]");
699
  print_probs(f, hybrid_context_counters_16x16, BLOCK_TYPES_16X16,
700
              "default_hybrid_coef_probs_16x16[BLOCK_TYPES_16X16]");
701 702
#if CONFIG_TX32X32
  print_probs(f, context_counters_32x32, BLOCK_TYPES_32X32,
703
              "default_coef_probs_32x32[BLOCK_TYPES_32X32]");
704
#endif
Daniel Kang's avatar
Daniel Kang committed
705

John Koleszar's avatar
John Koleszar committed
706 707 708
  fclose(f);

  f = fopen("context.bin", "wb");
709 710 711
  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
712
  fwrite(context_counters_8x8, sizeof(context_counters_8x8), 1, f);
713 714
  fwrite(hybrid_context_counters_8x8,
         sizeof(hybrid_context_counters_8x8), 1, f);
Daniel Kang's avatar
Daniel Kang committed
715
  fwrite(context_counters_16x16, sizeof(context_counters_16x16), 1, f);
716 717 718 719 720
  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
721
  fclose(f);
John Koleszar's avatar
John Koleszar committed
722 723 724
}
#endif

725
void vp9_tokenize_initialize() {
John Koleszar's avatar
John Koleszar committed
726
  fill_value_tokens();
John Koleszar's avatar
John Koleszar committed
727 728
}

729
static __inline void stuff_b(VP9_COMP *cpi,
730
                             MACROBLOCKD *xd,
Yaowu Xu's avatar
Yaowu Xu committed
731
                             const int ib,
732 733 734 735
                             TOKENEXTRA **tp,
                             PLANE_TYPE type,
                             TX_SIZE tx_size,
                             int dry_run) {
Yaowu Xu's avatar
Yaowu Xu committed
736
  const BLOCKD * const b = xd->block + ib;
737
  const int *bands;
738 739
  vp9_coeff_count *counts;
  vp9_coeff_probs *probs;
740 741 742 743
  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
744 745 746 747 748
  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;
749 750 751 752 753 754
#if CONFIG_SUPERBLOCKS && CONFIG_TX32X32
  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];
#endif
John Koleszar's avatar
John Koleszar committed
755

756 757 758
  switch (tx_size) {
    default:
    case TX_4X4:
759
      bands = vp9_coef_bands_4x4;
760
      if (tx_type != DCT_DCT) {
761 762
        counts = cpi->hybrid_coef_counts_4x4;
        probs = cpi->common.fc.hybrid_coef_probs_4x4;
763
      } else {
764 765
        counts = cpi->coef_counts_4x4;
        probs = cpi->common.fc.coef_probs_4x4;
766 767 768
      }
      break;
    case TX_8X8:
Yaowu Xu's avatar
Yaowu Xu committed
769 770 771 772 773 774
#if CONFIG_CNVCONTEXT
      if (type != PLANE_TYPE_Y2) {
        a_ec = (a[0] + a[1]) != 0;
        l_ec = (l[0] + l[1]) != 0;
      }
#endif
775
      bands = vp9_coef_bands_8x8;
776 777 778 779 780 781 782 783 784
      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
785
#if CONFIG_CNVCONTEXT
Yaowu Xu's avatar
Yaowu Xu committed
786 787 788
      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;
789 790 791 792 793
#if CONFIG_SUPERBLOCKS && CONFIG_TX32X32
      } else {
        a_ec = (a[0] + a[1] + a1[0] + a1[1]) != 0;
        l_ec = (l[0] + l[1] + l1[0] + l1[1]) != 0;
#endif
Yaowu Xu's avatar
Yaowu Xu committed
794
      }
Yaowu Xu's avatar
Yaowu Xu committed
795
#endif
796
      bands = vp9_coef_bands_16x16;
797 798 799 800 801 802 803 804
      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;
805 806
#if CONFIG_TX32X32 && CONFIG_SUPERBLOCKS
    case TX_32X32:
807 808 809 810 811 812 813 814
#if CONFIG_CNVCONTEXT
      a_ec = a[0] + a[1] + a[2] + a[3] +
             a1[0] + a1[1] + a1[2] + a1[3