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


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

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

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

#ifdef ENTROPY_STATS
28
29
30
vp9_coeff_accum context_counters_4x4[BLOCK_TYPES];
vp9_coeff_accum context_counters_8x8[BLOCK_TYPES];
vp9_coeff_accum context_counters_16x16[BLOCK_TYPES];
31
vp9_coeff_accum context_counters_32x32[BLOCK_TYPES];
32

33
34
35
extern vp9_coeff_stats tree_update_hist_4x4[BLOCK_TYPES];
extern vp9_coeff_stats tree_update_hist_8x8[BLOCK_TYPES];
extern vp9_coeff_stats tree_update_hist_16x16[BLOCK_TYPES];
36
extern vp9_coeff_stats tree_update_hist_32x32[BLOCK_TYPES];
37
38
#endif  /* ENTROPY_STATS */

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#if CONFIG_CODE_NONZEROCOUNT
#ifdef NZC_STATS
unsigned int nzc_counts_4x4[MAX_NZC_CONTEXTS][REF_TYPES][BLOCK_TYPES]
                           [NZC4X4_TOKENS];
unsigned int nzc_counts_8x8[MAX_NZC_CONTEXTS][REF_TYPES][BLOCK_TYPES]
                           [NZC8X8_TOKENS];
unsigned int nzc_counts_16x16[MAX_NZC_CONTEXTS][REF_TYPES][BLOCK_TYPES]
                             [NZC16X16_TOKENS];
unsigned int nzc_counts_32x32[MAX_NZC_CONTEXTS][REF_TYPES][BLOCK_TYPES]
                             [NZC32X32_TOKENS];
unsigned int nzc_pcat_counts[MAX_NZC_CONTEXTS][NZC_TOKENS_EXTRA]
                            [NZC_BITS_EXTRA][2];
#endif
#endif

John Koleszar's avatar
John Koleszar committed
54
static TOKENVALUE dct_value_tokens[DCT_MAX_VALUE * 2];
55
const TOKENVALUE *vp9_dct_value_tokens_ptr;
John Koleszar's avatar
John Koleszar committed
56
static int dct_value_cost[DCT_MAX_VALUE * 2];
57
const int *vp9_dct_value_cost_ptr;
58

John Koleszar's avatar
John Koleszar committed
59
static void fill_value_tokens() {
John Koleszar's avatar
John Koleszar committed
60

John Koleszar's avatar
John Koleszar committed
61
  TOKENVALUE *const t = dct_value_tokens + DCT_MAX_VALUE;
62
  vp9_extra_bit_struct *const e = vp9_extra_bits;
John Koleszar's avatar
John Koleszar committed
63

John Koleszar's avatar
John Koleszar committed
64
65
  int i = -DCT_MAX_VALUE;
  int sign = 1;
John Koleszar's avatar
John Koleszar committed
66

John Koleszar's avatar
John Koleszar committed
67
68
69
  do {
    if (!i)
      sign = 0;
John Koleszar's avatar
John Koleszar committed
70

John Koleszar's avatar
John Koleszar committed
71
72
73
    {
      const int a = sign ? -i : i;
      int eb = sign;
John Koleszar's avatar
John Koleszar committed
74

John Koleszar's avatar
John Koleszar committed
75
76
      if (a > 4) {
        int j = 4;
John Koleszar's avatar
John Koleszar committed
77

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

John Koleszar's avatar
John Koleszar committed
80
81
82
83
        t[i].Token = --j;
        eb |= (a - e[j].base_val) << 1;
      } else
        t[i].Token = a;
John Koleszar's avatar
John Koleszar committed
84

John Koleszar's avatar
John Koleszar committed
85
86
      t[i].Extra = eb;
    }
John Koleszar's avatar
John Koleszar committed
87

John Koleszar's avatar
John Koleszar committed
88
89
90
    // initialize the cost for extra bits for all possible coefficient value.
    {
      int cost = 0;
91
      vp9_extra_bit_struct *p = vp9_extra_bits + t[i].Token;
John Koleszar's avatar
John Koleszar committed
92

John Koleszar's avatar
John Koleszar committed
93
94
95
      if (p->base_val) {
        const int extra = t[i].Extra;
        const int Length = p->Len;
John Koleszar's avatar
John Koleszar committed
96

John Koleszar's avatar
John Koleszar committed
97
        if (Length)
98
          cost += treed_cost(p->tree, p->prob, extra >> 1, Length);
John Koleszar's avatar
John Koleszar committed
99

100
        cost += vp9_cost_bit(vp9_prob_half, extra & 1); /* sign */
John Koleszar's avatar
John Koleszar committed
101
102
        dct_value_cost[i + DCT_MAX_VALUE] = cost;
      }
John Koleszar's avatar
John Koleszar committed
103
104
105

    }

John Koleszar's avatar
John Koleszar committed
106
107
  } while (++i < DCT_MAX_VALUE);

108
109
  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
110
}
111

112
113
extern const int *vp9_get_coef_neighbors_handle(const int *scan, int *pad);

114
static void tokenize_b(VP9_COMP *cpi,
115
                       MACROBLOCKD *xd,
Yaowu Xu's avatar
Yaowu Xu committed
116
                       const int ib,
117
118
119
                       TOKENEXTRA **tp,
                       PLANE_TYPE type,
                       TX_SIZE tx_size,
John Koleszar's avatar
John Koleszar committed
120
                       int y_blocks,
121
                       int dry_run) {
122
  MB_MODE_INFO *mbmi = &xd->mode_info_context->mbmi;
Daniel Kang's avatar
Daniel Kang committed
123
  int pt; /* near block/prev token context index */
124
  int c = 0;
Daniel Kang's avatar
Daniel Kang committed
125
  TOKENEXTRA *t = *tp;        /* store tokens starting here */
John Koleszar's avatar
John Koleszar committed
126
127
  const struct plane_block_idx pb_idx = plane_block_idx(y_blocks, ib);
  const int eob = xd->plane[pb_idx.plane].eobs[pb_idx.block];
128
129
  const int16_t *qcoeff_ptr = BLOCK_OFFSET(xd->plane[pb_idx.plane].qcoeff,
                                           pb_idx.block, 16);
130
  int seg_eob, default_eob, pad;
131
132
  const int segment_id = mbmi->segment_id;
  const BLOCK_SIZE_TYPE sb_type = mbmi->sb_type;
133
  const int *scan, *nb;
134
135
  vp9_coeff_count *counts;
  vp9_coeff_probs *probs;
136
137
  const int ref = mbmi->ref_frame != INTRA_FRAME;
  ENTROPY_CONTEXT *a, *l, *a1, *l1, *a2, *l2, *a3, *l3, a_ec, l_ec;
138
  uint8_t token_cache[1024];
139
#if CONFIG_CODE_NONZEROCOUNT
140
141
  const int nzc_used = get_nzc_used(tx_size);
  int zerosleft = 0, nzc = 0;
142
143
144
  if (eob == 0)
    assert(xd->nzcs[ib] == 0);
#endif
145

John Koleszar's avatar
John Koleszar committed
146
  assert((!type && !pb_idx.plane) || (type && pb_idx.plane));
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
  if (sb_type == BLOCK_SIZE_SB64X64) {
    a = (ENTROPY_CONTEXT *)xd->above_context +
                                             vp9_block2above_sb64[tx_size][ib];
    l = (ENTROPY_CONTEXT *)xd->left_context + vp9_block2left_sb64[tx_size][ib];
    a1 = a + sizeof(ENTROPY_CONTEXT_PLANES) / sizeof(ENTROPY_CONTEXT);
    l1 = l + sizeof(ENTROPY_CONTEXT_PLANES) / sizeof(ENTROPY_CONTEXT);
    a2 = a1 + sizeof(ENTROPY_CONTEXT_PLANES) / sizeof(ENTROPY_CONTEXT);
    l2 = l1 + sizeof(ENTROPY_CONTEXT_PLANES) / sizeof(ENTROPY_CONTEXT);
    a3 = a2 + sizeof(ENTROPY_CONTEXT_PLANES) / sizeof(ENTROPY_CONTEXT);
    l3 = l2 + sizeof(ENTROPY_CONTEXT_PLANES) / sizeof(ENTROPY_CONTEXT);
  } else if (sb_type == BLOCK_SIZE_SB32X32) {
    a = (ENTROPY_CONTEXT *)xd->above_context + vp9_block2above_sb[tx_size][ib];
    l = (ENTROPY_CONTEXT *)xd->left_context + vp9_block2left_sb[tx_size][ib];
    a1 = a + sizeof(ENTROPY_CONTEXT_PLANES) / sizeof(ENTROPY_CONTEXT);
    l1 = l + sizeof(ENTROPY_CONTEXT_PLANES) / sizeof(ENTROPY_CONTEXT);
    a2 = a3 = l2 = l3 = NULL;
  } else {
    a = (ENTROPY_CONTEXT *)xd->above_context + vp9_block2above[tx_size][ib];
    l = (ENTROPY_CONTEXT *)xd->left_context + vp9_block2left[tx_size][ib];
    a1 = l1 = a2 = l2 = a3 = l3 = NULL;
  }
168

169
170
  switch (tx_size) {
    default:
171
172
173
    case TX_4X4: {
      const TX_TYPE tx_type = (type == PLANE_TYPE_Y_WITH_DC) ?
                              get_tx_type_4x4(xd, ib) : DCT_DCT;
174
175
      a_ec = *a;
      l_ec = *l;
176
      seg_eob = 16;
177
      scan = vp9_default_zig_zag1d_4x4;
178
179
      if (tx_type != DCT_DCT) {
        if (tx_type == ADST_DCT) {
180
          scan = vp9_row_scan_4x4;
181
        } else if (tx_type == DCT_ADST) {
182
          scan = vp9_col_scan_4x4;
183
184
        }
      }
185
186
      counts = cpi->coef_counts_4x4;
      probs = cpi->common.fc.coef_probs_4x4;
187
      break;
188
    }
189
190
191
192
    case TX_8X8: {
      const int sz = 3 + sb_type, x = ib & ((1 << sz) - 1), y = ib - x;
      const TX_TYPE tx_type = (type == PLANE_TYPE_Y_WITH_DC) ?
                              get_tx_type_8x8(xd, y + (x >> 1)) : DCT_DCT;
193
194
195
196
      a_ec = (a[0] + a[1]) != 0;
      l_ec = (l[0] + l[1]) != 0;
      seg_eob = 64;
      scan = vp9_default_zig_zag1d_8x8;
197
198
199
200
201
202
203
      if (tx_type != DCT_DCT) {
        if (tx_type == ADST_DCT) {
          scan = vp9_row_scan_8x8;
        } else if (tx_type == DCT_ADST) {
          scan = vp9_col_scan_8x8;
        }
      }
204
205
      counts = cpi->coef_counts_8x8;
      probs = cpi->common.fc.coef_probs_8x8;
206
      break;
207
208
209
210
211
    }
    case TX_16X16: {
      const int sz = 4 + sb_type, x = ib & ((1 << sz) - 1), y = ib - x;
      const TX_TYPE tx_type = (type == PLANE_TYPE_Y_WITH_DC) ?
                              get_tx_type_16x16(xd, y + (x >> 2)) : DCT_DCT;
Yaowu Xu's avatar
Yaowu Xu committed
212
213
214
      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;
215
216
217
      } 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
218
      }
219
      seg_eob = 256;
220
      scan = vp9_default_zig_zag1d_16x16;
221
222
223
224
225
226
227
      if (tx_type != DCT_DCT) {
        if (tx_type == ADST_DCT) {
          scan = vp9_row_scan_16x16;
        } else if (tx_type == DCT_ADST) {
          scan = vp9_col_scan_16x16;
        }
      }
228
229
      counts = cpi->coef_counts_16x16;
      probs = cpi->common.fc.coef_probs_16x16;
230
      break;
231
    }
232
    case TX_32X32:
233
234
235
236
237
238
239
240
241
242
243
      if (type != PLANE_TYPE_UV) {
        a_ec = (a[0] + a[1] + a[2] + a[3] +
                a1[0] + a1[1] + a1[2] + a1[3]) != 0;
        l_ec = (l[0] + l[1] + l[2] + l[3] +
                l1[0] + l1[1] + l1[2] + l1[3]) != 0;
      } else {
        a_ec = (a[0] + a[1] + a1[0] + a1[1] +
                a2[0] + a2[1] + a3[0] + a3[1]) != 0;
        l_ec = (l[0] + l[1] + l1[0] + l1[1] +
                l2[0] + l2[1] + l3[0] + l3[1]) != 0;
      }
244
245
246
247
      seg_eob = 1024;
      scan = vp9_default_zig_zag1d_32x32;
      counts = cpi->coef_counts_32x32;
      probs = cpi->common.fc.coef_probs_32x32;
248
      break;
John Koleszar's avatar
John Koleszar committed
249
250
  }

Yaowu Xu's avatar
Yaowu Xu committed
251
  VP9_COMBINEENTROPYCONTEXTS(pt, a_ec, l_ec);
252
253
  nb = vp9_get_coef_neighbors_handle(scan, &pad);
  default_eob = seg_eob;
Yaowu Xu's avatar
Yaowu Xu committed
254

Paul Wilkins's avatar
Paul Wilkins committed
255
256
  if (vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP))
    seg_eob = 0;
John Koleszar's avatar
John Koleszar committed
257

258
  do {
259
    const int band = get_coef_band(scan, tx_size, c);
260
    int token;
261
262
    int v = 0;
#if CONFIG_CODE_NONZEROCOUNT
263
264
    if (nzc_used)
      zerosleft = seg_eob - xd->nzcs[ib] - c + nzc;
265
#endif
266
    if (c < eob) {
267
      const int rc = scan[c];
268
      v = qcoeff_ptr[rc];
269
270
      assert(-DCT_MAX_VALUE <= v  &&  v < DCT_MAX_VALUE);

271
272
      t->Extra = vp9_dct_value_tokens_ptr[v].Extra;
      token    = vp9_dct_value_tokens_ptr[v].Token;
273
    } else {
274
#if CONFIG_CODE_NONZEROCOUNT
275
276
277
      if (nzc_used)
        break;
      else
278
#endif
279
        token = DCT_EOB_TOKEN;
280
    }
John Koleszar's avatar
John Koleszar committed
281
282

    t->Token = token;
283
    t->context_tree = probs[type][ref][band][pt];
284
285
#if CONFIG_CODE_NONZEROCOUNT
    // Skip zero node if there are no zeros left
286
287
288
    if (nzc_used)
      t->skip_eob_node = 1 + (zerosleft == 0);
    else
289
#endif
290
      t->skip_eob_node = (c > 0) && (token_cache[c - 1] == 0);
291
    assert(vp9_coef_encodings[t->Token].Len - t->skip_eob_node > 0);
292
    if (!dry_run) {
293
      ++counts[type][ref][band][pt][token];
294
295
      if (!t->skip_eob_node)
        ++cpi->common.fc.eob_branch_counts[tx_size][type][ref][band][pt];
296
    }
297
298
299
#if CONFIG_CODE_NONZEROCOUNT
    nzc += (v != 0);
#endif
300
    token_cache[c] = token;
301

302
    pt = vp9_get_coef_context(scan, nb, pad, token_cache, c + 1, default_eob);
303
    ++t;
304
  } while (c < eob && ++c < seg_eob);
305
306
307
#if CONFIG_CODE_NONZEROCOUNT
  assert(nzc == xd->nzcs[ib]);
#endif
308
309

  *tp = t;
310
  a_ec = l_ec = (c > 0); /* 0 <-> all coeff data is zero */
Yaowu Xu's avatar
Yaowu Xu committed
311
312
313
  a[0] = a_ec;
  l[0] = l_ec;

314
  if (tx_size == TX_8X8) {
Yaowu Xu's avatar
Yaowu Xu committed
315
316
317
    a[1] = a_ec;
    l[1] = l_ec;
  } else if (tx_size == TX_16X16) {
Yaowu Xu's avatar
Yaowu Xu committed
318
319
320
321
    if (type != PLANE_TYPE_UV) {
      a[1] = a[2] = a[3] = a_ec;
      l[1] = l[2] = l[3] = l_ec;
    } else {
322
323
      a1[0] = a1[1] = a[1] = a_ec;
      l1[0] = l1[1] = l[1] = l_ec;
Yaowu Xu's avatar
Yaowu Xu committed
324
    }
325
  } else if (tx_size == TX_32X32) {
326
327
328
329
330
331
332
333
334
335
336
    if (type != PLANE_TYPE_UV) {
      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;
    } else {
      a[1] = a1[0] = a1[1] = a_ec;
      l[1] = l1[0] = l1[1] = l_ec;
      a2[0] = a2[1] = a3[0] = a3[1] = a_ec;
      l2[0] = l2[1] = l3[0] = l3[1] = l_ec;
    }
Yaowu Xu's avatar
Yaowu Xu committed
337
  }
John Koleszar's avatar
John Koleszar committed
338
339
}

340
int vp9_mby_is_skippable_4x4(MACROBLOCKD *xd) {
John Koleszar's avatar
John Koleszar committed
341
342
  int skip = 1;
  int i = 0;
343

344
  for (i = 0; i < 16; i++)
John Koleszar's avatar
John Koleszar committed
345
    skip &= (!xd->plane[0].eobs[i]);
346

John Koleszar's avatar
John Koleszar committed
347
  return skip;
348
}
349

350
int vp9_mbuv_is_skippable_4x4(MACROBLOCKD *xd) {
John Koleszar's avatar
John Koleszar committed
351
352
  int skip = 1;
  int i;
353

John Koleszar's avatar
John Koleszar committed
354
355
356
357
  for (i = 0; i < 4; i++)
    skip &= (!xd->plane[1].eobs[i]);
  for (i = 0; i < 4; i++)
    skip &= (!xd->plane[2].eobs[i]);
John Koleszar's avatar
John Koleszar committed
358
  return skip;
359
360
}

361
362
static int mb_is_skippable_4x4(MACROBLOCKD *xd) {
  return (vp9_mby_is_skippable_4x4(xd) &
363
          vp9_mbuv_is_skippable_4x4(xd));
364
}
Yaowu Xu's avatar
Yaowu Xu committed
365

366
int vp9_mby_is_skippable_8x8(MACROBLOCKD *xd) {
John Koleszar's avatar
John Koleszar committed
367
368
  int skip = 1;
  int i = 0;
369

370
  for (i = 0; i < 16; i += 4)
John Koleszar's avatar
John Koleszar committed
371
    skip &= (!xd->plane[0].eobs[i]);
372

John Koleszar's avatar
John Koleszar committed
373
  return skip;
374
}
375

376
int vp9_mbuv_is_skippable_8x8(MACROBLOCKD *xd) {
John Koleszar's avatar
John Koleszar committed
377
  return (!xd->plane[1].eobs[0]) & (!xd->plane[2].eobs[0]);
378
}
379

380
381
static int mb_is_skippable_8x8(MACROBLOCKD *xd) {
  return (vp9_mby_is_skippable_8x8(xd) &
382
          vp9_mbuv_is_skippable_8x8(xd));
Deb Mukherjee's avatar
Deb Mukherjee committed
383
384
}

385
386
static int mb_is_skippable_8x8_4x4uv(MACROBLOCKD *xd) {
  return (vp9_mby_is_skippable_8x8(xd) &
387
          vp9_mbuv_is_skippable_4x4(xd));
388
}
Yaowu Xu's avatar
Yaowu Xu committed
389

390
int vp9_mby_is_skippable_16x16(MACROBLOCKD *xd) {
John Koleszar's avatar
John Koleszar committed
391
  return (!xd->plane[0].eobs[0]);
Daniel Kang's avatar
Daniel Kang committed
392
393
}

394
395
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
396
}
397

398
int vp9_sby_is_skippable_32x32(MACROBLOCKD *xd) {
John Koleszar's avatar
John Koleszar committed
399
  return (!xd->plane[0].eobs[0]);
400
401
402
}

int vp9_sbuv_is_skippable_16x16(MACROBLOCKD *xd) {
John Koleszar's avatar
John Koleszar committed
403
  return (!xd->plane[1].eobs[0]) & (!xd->plane[2].eobs[0]);
404
405
406
407
408
409
410
}

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

411
int vp9_sby_is_skippable_16x16(MACROBLOCKD *xd) {
412
413
414
415
  int skip = 1;
  int i = 0;

  for (i = 0; i < 64; i += 16)
John Koleszar's avatar
John Koleszar committed
416
    skip &= (!xd->plane[0].eobs[i]);
417
418
419
420
421

  return skip;
}

static int sb_is_skippable_16x16(MACROBLOCKD *xd) {
422
  return vp9_sby_is_skippable_16x16(xd) & vp9_sbuv_is_skippable_16x16(xd);
423
424
}

425
int vp9_sby_is_skippable_8x8(MACROBLOCKD *xd) {
426
427
428
429
  int skip = 1;
  int i = 0;

  for (i = 0; i < 64; i += 4)
John Koleszar's avatar
John Koleszar committed
430
    skip &= (!xd->plane[0].eobs[i]);
431
432
433
434

  return skip;
}

435
int vp9_sbuv_is_skippable_8x8(MACROBLOCKD *xd) {
436
437
438
  int skip = 1;
  int i = 0;

John Koleszar's avatar
John Koleszar committed
439
440
441
442
  for (i = 0; i < 16; i += 4)
    skip &= (!xd->plane[1].eobs[i]);
  for (i = 0; i < 16; i += 4)
    skip &= (!xd->plane[2].eobs[i]);
443
444
445
446
447

  return skip;
}

static int sb_is_skippable_8x8(MACROBLOCKD *xd) {
448
  return vp9_sby_is_skippable_8x8(xd) & vp9_sbuv_is_skippable_8x8(xd);
449
450
}

451
int vp9_sby_is_skippable_4x4(MACROBLOCKD *xd) {
452
453
454
455
  int skip = 1;
  int i = 0;

  for (i = 0; i < 64; i++)
John Koleszar's avatar
John Koleszar committed
456
    skip &= (!xd->plane[0].eobs[i]);
457
458
459
460

  return skip;
}

461
int vp9_sbuv_is_skippable_4x4(MACROBLOCKD *xd) {
462
463
464
  int skip = 1;
  int i = 0;

John Koleszar's avatar
John Koleszar committed
465
466
467
468
  for (i = 0; i < 16; i++)
    skip &= (!xd->plane[1].eobs[i]);
  for (i = 0; i < 16; i++)
    skip &= (!xd->plane[2].eobs[i]);
469
470
471
472
473

  return skip;
}

static int sb_is_skippable_4x4(MACROBLOCKD *xd) {
474
  return vp9_sby_is_skippable_4x4(xd) & vp9_sbuv_is_skippable_4x4(xd);
475
476
}

477
478
479
480
481
482
483
484
485
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;
  const int mb_skip_context = vp9_get_pred_context(cm, xd, PRED_MBSKIP);
  const int segment_id = mbmi->segment_id;
Paul Wilkins's avatar
Paul Wilkins committed
486
  const int skip_inc = !vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP);
487
488
  int b;

489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
  switch (mbmi->txfm_size) {
    case TX_32X32:
      mbmi->mb_skip_coeff = sb_is_skippable_32x32(xd);
      break;
    case TX_16X16:
      mbmi->mb_skip_coeff = sb_is_skippable_16x16(xd);
      break;
    case TX_8X8:
      mbmi->mb_skip_coeff = sb_is_skippable_8x8(xd);
      break;
    case TX_4X4:
      mbmi->mb_skip_coeff = sb_is_skippable_4x4(xd);
      break;
    default: assert(0);
  }
504
505
506
507
508
509
510

  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 {
511
      vp9_reset_sb_tokens_context(xd);
512
513
514
515
516
517
518
519
520
    }
    if (dry_run)
      *t = t_backup;
    return;
  }

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

521
522
523
  switch (mbmi->txfm_size) {
    case TX_32X32:
      tokenize_b(cpi, xd, 0, t, PLANE_TYPE_Y_WITH_DC,
John Koleszar's avatar
John Koleszar committed
524
                 TX_32X32, 64, dry_run);
525
526
      for (b = 64; b < 96; b += 16)
        tokenize_b(cpi, xd, b, t, PLANE_TYPE_UV,
John Koleszar's avatar
John Koleszar committed
527
                   TX_16X16, 64, dry_run);
528
529
530
531
      break;
    case TX_16X16:
      for (b = 0; b < 64; b += 16)
        tokenize_b(cpi, xd, b, t, PLANE_TYPE_Y_WITH_DC,
John Koleszar's avatar
John Koleszar committed
532
                   TX_16X16, 64, dry_run);
533
534
      for (b = 64; b < 96; b += 16)
        tokenize_b(cpi, xd, b, t, PLANE_TYPE_UV,
John Koleszar's avatar
John Koleszar committed
535
                   TX_16X16, 64, dry_run);
536
537
538
539
      break;
    case TX_8X8:
      for (b = 0; b < 64; b += 4)
        tokenize_b(cpi, xd, b, t, PLANE_TYPE_Y_WITH_DC,
John Koleszar's avatar
John Koleszar committed
540
                   TX_8X8, 64, dry_run);
541
542
      for (b = 64; b < 96; b += 4)
        tokenize_b(cpi, xd, b, t, PLANE_TYPE_UV,
John Koleszar's avatar
John Koleszar committed
543
                   TX_8X8, 64, dry_run);
544
545
546
547
      break;
    case TX_4X4:
      for (b = 0; b < 64; b++)
        tokenize_b(cpi, xd, b, t, PLANE_TYPE_Y_WITH_DC,
John Koleszar's avatar
John Koleszar committed
548
                   TX_4X4, 64, dry_run);
549
550
      for (b = 64; b < 96; b++)
        tokenize_b(cpi, xd, b, t, PLANE_TYPE_UV,
John Koleszar's avatar
John Koleszar committed
551
                   TX_4X4, 64, dry_run);
552
553
554
      break;
    default: assert(0);
  }
555

556
557
558
559
  if (dry_run)
    *t = t_backup;
}

560
int vp9_sb64y_is_skippable_32x32(MACROBLOCKD *xd) {
561
562
563
564
  int skip = 1;
  int i = 0;

  for (i = 0; i < 256; i += 64)
John Koleszar's avatar
John Koleszar committed
565
    skip &= (!xd->plane[0].eobs[i]);
566
567
568
569
570

  return skip;
}

int vp9_sb64uv_is_skippable_32x32(MACROBLOCKD *xd) {
John Koleszar's avatar
John Koleszar committed
571
  return (!xd->plane[1].eobs[0]) & (!xd->plane[2].eobs[0]);
572
573
574
}

static int sb64_is_skippable_32x32(MACROBLOCKD *xd) {
575
  return vp9_sb64y_is_skippable_32x32(xd) & vp9_sb64uv_is_skippable_32x32(xd);
576
577
}

578
int vp9_sb64y_is_skippable_16x16(MACROBLOCKD *xd) {
579
580
581
582
  int skip = 1;
  int i = 0;

  for (i = 0; i < 256; i += 16)
John Koleszar's avatar
John Koleszar committed
583
    skip &= (!xd->plane[0].eobs[i]);
584
585
586
587

  return skip;
}

588
int vp9_sb64uv_is_skippable_16x16(MACROBLOCKD *xd) {
589
590
591
  int skip = 1;
  int i = 0;

John Koleszar's avatar
John Koleszar committed
592
593
594
595
  for (i = 0; i < 64; i += 16)
    skip &= (!xd->plane[1].eobs[i]);
  for (i = 0; i < 64; i += 16)
    skip &= (!xd->plane[2].eobs[i]);
596
597
598
599
600

  return skip;
}

static int sb64_is_skippable_16x16(MACROBLOCKD *xd) {
601
  return vp9_sb64y_is_skippable_16x16(xd) & vp9_sb64uv_is_skippable_16x16(xd);
602
603
}

604
int vp9_sb64y_is_skippable_8x8(MACROBLOCKD *xd) {
605
606
607
608
  int skip = 1;
  int i = 0;

  for (i = 0; i < 256; i += 4)
John Koleszar's avatar
John Koleszar committed
609
    skip &= (!xd->plane[0].eobs[i]);
610
611
612
613

  return skip;
}

614
int vp9_sb64uv_is_skippable_8x8(MACROBLOCKD *xd) {
615
616
617
  int skip = 1;
  int i = 0;

John Koleszar's avatar
John Koleszar committed
618
619
620
621
  for (i = 0; i < 64; i += 4)
    skip &= (!xd->plane[1].eobs[i]);
  for (i = 0; i < 64; i += 4)
    skip &= (!xd->plane[2].eobs[i]);
622
623
624
625
626

  return skip;
}

static int sb64_is_skippable_8x8(MACROBLOCKD *xd) {
627
  return vp9_sb64y_is_skippable_8x8(xd) & vp9_sb64uv_is_skippable_8x8(xd);
628
629
}

630
int vp9_sb64y_is_skippable_4x4(MACROBLOCKD *xd) {
631
632
633
634
  int skip = 1;
  int i = 0;

  for (i = 0; i < 256; i++)
John Koleszar's avatar
John Koleszar committed
635
    skip &= (!xd->plane[0].eobs[i]);
636
637
638
639

  return skip;
}

640
int vp9_sb64uv_is_skippable_4x4(MACROBLOCKD *xd) {
641
642
643
  int skip = 1;
  int i = 0;

John Koleszar's avatar
John Koleszar committed
644
645
646
647
  for (i = 0; i < 64; i++)
    skip &= (!xd->plane[1].eobs[i]);
  for (i = 0; i < 64; i++)
    skip &= (!xd->plane[2].eobs[i]);
648
649
650
651
652

  return skip;
}

static int sb64_is_skippable_4x4(MACROBLOCKD *xd) {
653
  return vp9_sb64y_is_skippable_4x4(xd) & vp9_sb64uv_is_skippable_4x4(xd);
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
}

void vp9_tokenize_sb64(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;
  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_SKIP);
  int b;

  switch (mbmi->txfm_size) {
    case TX_32X32:
      mbmi->mb_skip_coeff = sb64_is_skippable_32x32(xd);
      break;
    case TX_16X16:
      mbmi->mb_skip_coeff = sb64_is_skippable_16x16(xd);
      break;
    case TX_8X8:
      mbmi->mb_skip_coeff = sb64_is_skippable_8x8(xd);
      break;
    case TX_4X4:
      mbmi->mb_skip_coeff = sb64_is_skippable_4x4(xd);
      break;
    default: assert(0);
  }

  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_sb64(cpi, xd, t, dry_run);
    } else {
      vp9_reset_sb64_tokens_context(xd);
    }
    if (dry_run)
      *t = t_backup;
    return;
  }

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

  switch (mbmi->txfm_size) {
    case TX_32X32:
      for (b = 0; b < 256; b += 64)
        tokenize_b(cpi, xd, b, t, PLANE_TYPE_Y_WITH_DC,
John Koleszar's avatar
John Koleszar committed
704
                   TX_32X32, 256, dry_run);
705
706
      for (b = 256; b < 384; b += 64)
        tokenize_b(cpi, xd, b, t, PLANE_TYPE_UV,
John Koleszar's avatar
John Koleszar committed
707
                   TX_32X32, 256, dry_run);
708
709
710
711
      break;
    case TX_16X16:
      for (b = 0; b < 256; b += 16)
        tokenize_b(cpi, xd, b, t, PLANE_TYPE_Y_WITH_DC,
John Koleszar's avatar
John Koleszar committed
712
                   TX_16X16, 256, dry_run);
713
714
      for (b = 256; b < 384; b += 16)
        tokenize_b(cpi, xd, b, t, PLANE_TYPE_UV,
John Koleszar's avatar
John Koleszar committed
715
                   TX_16X16, 256, dry_run);
716
717
718
719
      break;
    case TX_8X8:
      for (b = 0; b < 256; b += 4)
        tokenize_b(cpi, xd, b, t, PLANE_TYPE_Y_WITH_DC,
John Koleszar's avatar
John Koleszar committed
720
                   TX_8X8, 256, dry_run);
721
722
      for (b = 256; b < 384; b += 4)
        tokenize_b(cpi, xd, b, t, PLANE_TYPE_UV,
John Koleszar's avatar
John Koleszar committed
723
                   TX_8X8, 256, dry_run);
724
725
726
727
      break;
    case TX_4X4:
      for (b = 0; b < 256; b++)
        tokenize_b(cpi, xd, b, t, PLANE_TYPE_Y_WITH_DC,
John Koleszar's avatar
John Koleszar committed
728
                   TX_4X4, 256, dry_run);
729
730
      for (b = 256; b < 384; b++)
        tokenize_b(cpi, xd, b, t, PLANE_TYPE_UV,
John Koleszar's avatar
John Koleszar committed
731
                   TX_4X4, 256, dry_run);
732
733
      break;
    default: assert(0);
734
  }
735

736
737
738
739
  if (dry_run)
    *t = t_backup;
}

740
void vp9_tokenize_mb(VP9_COMP *cpi,
Paul Wilkins's avatar
Paul Wilkins committed
741
                     MACROBLOCKD *xd,
742
743
                     TOKENEXTRA **t,
                     int dry_run) {
John Koleszar's avatar
John Koleszar committed
744
  int b;
745
  int tx_size = xd->mode_info_context->mbmi.txfm_size;
Paul Wilkins's avatar
Paul Wilkins committed
746
  int mb_skip_context = vp9_get_pred_context(&cpi->common, xd, PRED_MBSKIP);
747
  TOKENEXTRA *t_backup = *t;
Paul Wilkins's avatar
Paul Wilkins committed
748

John Koleszar's avatar
John Koleszar committed
749
750
751
752
  // 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
753
  int segment_id = xd->mode_info_context->mbmi.segment_id;
754

Paul Wilkins's avatar
Paul Wilkins committed
755
  if (!vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)) {
John Koleszar's avatar
John Koleszar committed
756
757
758
    skip_inc = 1;
  } else
    skip_inc = 0;
759

760
  switch (tx_size) {
Daniel Kang's avatar
Daniel Kang committed
761
    case TX_16X16:
762

Daniel Kang's avatar
Daniel Kang committed
763
      xd->mode_info_context->mbmi.mb_skip_coeff = mb_is_skippable_16x16(xd);
Daniel Kang's avatar
Daniel Kang committed
764
765
      break;
    case TX_8X8:
766
767
      if (xd->mode_info_context->mbmi.mode == I8X8_PRED ||
          xd->mode_info_context->mbmi.mode == SPLITMV)
768
        xd->mode_info_context->mbmi.mb_skip_coeff =
769
            mb_is_skippable_8x8_4x4uv(xd);
Deb Mukherjee's avatar
Deb Mukherjee committed
770
      else
771
        xd->mode_info_context->mbmi.mb_skip_coeff =
772
            mb_is_skippable_8x8(xd);
Daniel Kang's avatar
Daniel Kang committed
773
      break;
Deb Mukherjee's avatar
Deb Mukherjee committed
774

Daniel Kang's avatar
Daniel Kang committed
775
    default:
776
      xd->mode_info_context->mbmi.mb_skip_coeff =
777
          mb_is_skippable_4x4(xd);
Daniel Kang's avatar
Daniel Kang committed
778
779
      break;
  }
780

Paul Wilkins's avatar
Paul Wilkins committed
781
  if (xd->mode_info_context->mbmi.mb_skip_coeff) {
782
783
    if (!dry_run)
      cpi->skip_true_count[mb_skip_context] += skip_inc;
John Koleszar's avatar
John Koleszar committed
784
    if (!cpi->common.mb_no_coeff_skip) {
785
      vp9_stuff_mb(cpi, xd, t, dry_run);
John Koleszar's avatar
John Koleszar committed
786
    } else {
Yaowu Xu's avatar
Yaowu Xu committed
787
      vp9_reset_mb_tokens_context(xd);
John Koleszar's avatar
John Koleszar committed
788
    }
Yaowu Xu's avatar
Yaowu Xu committed
789

790
791
    if (dry_run)
      *t = t_backup;
John Koleszar's avatar
John Koleszar committed
792
793
794
    return;
  }

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

798
  if (tx_size == TX_16X16) {
John Koleszar's avatar
John Koleszar committed
799
    tokenize_b(cpi, xd, 0, t, PLANE_TYPE_Y_WITH_DC, TX_16X16, 16, dry_run);
Daniel Kang's avatar
Daniel Kang committed
800
    for (b = 16; b < 24; b += 4) {
John Koleszar's avatar
John Koleszar committed
801
      tokenize_b(cpi, xd, b, t, PLANE_TYPE_UV, TX_8X8, 16, dry_run);
Daniel Kang's avatar
Daniel Kang committed
802
    }
803
  } else if (tx_size == TX_8X8) {
John Koleszar's avatar
John Koleszar committed
804
    for (b = 0; b < 16; b += 4) {
John Koleszar's avatar
John Koleszar committed
805
      tokenize_b(cpi, xd, b, t, PLANE_TYPE_Y_WITH_DC, TX_8X8, 16, dry_run);
John Koleszar's avatar
John Koleszar committed
806
    }
807
808
    if (xd->mode_info_context->mbmi.mode == I8X8_PRED ||
        xd->mode_info_context->mbmi.mode == SPLITMV) {
809
      for (b = 16; b < 24; b++) {
John Koleszar's avatar
John Koleszar committed
810
        tokenize_b(cpi, xd, b, t, PLANE_TYPE_UV, TX_4X4, 16, dry_run);
811
      }
812
    } else {
Deb Mukherjee's avatar
Deb Mukherjee committed
813
      for (b = 16; b < 24; b += 4) {
John Koleszar's avatar
John Koleszar committed
814
        tokenize_b(cpi, xd, b, t, PLANE_TYPE_UV, TX_8X8, 16, dry_run);
Deb Mukherjee's avatar
Deb Mukherjee committed
815
      }
816
    }
Jingning Han's avatar
Jingning Han committed
817
  } else {
818
    for (b = 0; b < 16; b++)
John Koleszar's avatar
John Koleszar committed
819
      tokenize_b(cpi, xd, b, t, PLANE_TYPE_Y_WITH_DC, TX_4X4, 16, dry_run);
820
    for (b = 16; b < 24; b++)
John Koleszar's avatar
John Koleszar committed
821
      tokenize_b(cpi, xd, b, t, PLANE_TYPE_UV, TX_4X4, 16, dry_run);
Jingning Han's avatar
Jingning Han committed
822
  }
823
824
  if (dry_run)
    *t = t_backup;
John Koleszar's avatar
John Koleszar committed
825
}
826

John Koleszar's avatar
John Koleszar committed
827
#ifdef ENTROPY_STATS
John Koleszar's avatar
John Koleszar committed
828
829
830
void init_context_counters(void) {
  FILE *f = fopen("context.bin", "rb");
  if (!f) {
831
    vpx_memset(context_counters_4x4, 0, sizeof(context_counters_4x4));
John Koleszar's avatar
John Koleszar committed
832
    vpx_memset(context_counters_8x8, 0, sizeof(context_counters_8x8));
Daniel Kang's avatar
Daniel Kang committed
833
    vpx_memset(context_counters_16x16, 0, sizeof(context_counters_16x16));
834
    vpx_memset(context_counters_32x32, 0, sizeof(context_counters_32x32));
John Koleszar's avatar
John Koleszar committed
835
  } else {
836
    fread(context_counters_4x4, sizeof(context_counters_4x4), 1, f);
John Koleszar's avatar
John Koleszar committed
837
    fread(context_counters_8x8, sizeof(context_counters_8x8), 1, f);
Daniel Kang's avatar
Daniel Kang committed
838
    fread(context_counters_16x16, sizeof(context_counters_16x16), 1, f);
839
    fread(context_counters_32x32, sizeof(context_counters_32x32), 1, f);
John Koleszar's avatar
John Koleszar committed
840
841
842
843
844
    fclose(f);
  }

  f = fopen("treeupdate.bin", "rb");
  if (!f) {
845
    vpx_memset(tree_update_hist_4x4, 0, sizeof(tree_update_hist_4x4));
John Koleszar's avatar
John Koleszar committed
846
    vpx_memset(tree_update_hist_8x8, 0, sizeof(tree_update_hist_8x8));
Daniel Kang's avatar
Daniel Kang committed
847
    vpx_memset(tree_update_hist_16x16, 0, sizeof(tree_update_hist_16x16));
848
    vpx_memset(tree_update_hist_32x32, 0, sizeof(tree_update_hist_32x32));
John Koleszar's avatar
John Koleszar committed
849
  } else {
850
    fread(tree_update_hist_4x4, sizeof(tree_update_hist_4x4), 1, f);
John Koleszar's avatar
John Koleszar committed
851
    fread(tree_update_hist_8x8, sizeof(tree_update_hist_8x8), 1, f);
Daniel Kang's avatar
Daniel Kang committed
852
    fread(tree_update_hist_16x16, sizeof(tree_update_hist_16x16), 1, f);
853
    fread(tree_update_hist_32x32, sizeof(tree_update_hist_32x32), 1, f);
John Koleszar's avatar
John Koleszar committed
854
855
    fclose(f);
  }
John Koleszar's avatar
John Koleszar committed
856
857
}

858
859
static void print_counter(FILE *f, vp9_coeff_accum *context_counters,
                          int block_types, const char *header) {
860
  int type, ref, band, pt, t;
John Koleszar's avatar
John Koleszar committed
861

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

864
#define Comma(X) (X ? "," : "")
John Koleszar's avatar
John Koleszar committed
865
866
  type = 0;
  do {
867
    ref = 0;
John Koleszar's avatar
John Koleszar committed
868
869
    fprintf(f, "%s\n  { /* block Type %d */", Comma(type), type);
    do {
870
871
      fprintf(f, "%s\n    { /* %s */", Comma(type), ref ? "Inter" : "Intra");
      band = 0;
John Koleszar's avatar
John Koleszar committed
872
      do {
873
874
        fprintf(f, "%s\n      { /* Coeff Band %d */", Comma(band), band);
        pt = 0;
John Koleszar's avatar
John Koleszar committed
875
        do {
876
877
878
879
880
881
882
883
884
          fprintf(f, "%s\n        {", Comma(pt));

          t = 0;
          do {
            const int64_t x = context_counters[type][ref][band][pt][t];
            const int y = (int) x;

            assert(x == (int64_t) y);  /* no overflow handling yet */
            fprintf(f, "%s %d", Comma(t), y);
885
          } while (++t < 1 + MAX_ENTROPY_TOKENS);
886
887
888
889
          fprintf(f, "}");
        } while (++pt < PREV_COEF_CONTEXTS);
        fprintf(f, "\n      }");
      } while (++band < COEF_BANDS);
John Koleszar's avatar
John Koleszar committed
890
      fprintf(f, "\n    }");
891
    } while (++ref < REF_TYPES);
John Koleszar's avatar
John Koleszar committed
892
    fprintf(f, "\n  }");
893
  } while (++type < block_types);
Daniel Kang's avatar
Daniel Kang committed
894
  fprintf(f, "\n};\n");
895
}
896

897
898
static void print_probs(FILE *f, vp9_coeff_accum *context_counters,
                        int block_types, const char *header) {
899
  int type, ref, band, pt, t;
Daniel Kang's avatar
Daniel Kang committed
900

901
  fprintf(f, "static const vp9_coeff_probs %s = {", header);
902

John Koleszar's avatar
John Koleszar committed
903
  type