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


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

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

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

#ifdef ENTROPY_STATS
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
vp9_coeff_accum context_counters_4x4[BLOCK_TYPES_4X4];
vp9_coeff_accum hybrid_context_counters_4x4[BLOCK_TYPES_4X4];
vp9_coeff_accum context_counters_8x8[BLOCK_TYPES_8X8];
vp9_coeff_accum hybrid_context_counters_8x8[BLOCK_TYPES_8X8];
vp9_coeff_accum context_counters_16x16[BLOCK_TYPES_16X16];
vp9_coeff_accum hybrid_context_counters_16x16[BLOCK_TYPES_16X16];
#if CONFIG_TX32X32
vp9_coeff_accum context_counters_32x32[BLOCK_TYPES_32X32];
#endif

extern vp9_coeff_stats tree_update_hist_4x4[BLOCK_TYPES_4X4];
extern vp9_coeff_stats hybrid_tree_update_hist_4x4[BLOCK_TYPES_4X4];
extern vp9_coeff_stats tree_update_hist_8x8[BLOCK_TYPES_8X8];
extern vp9_coeff_stats hybrid_tree_update_hist_8x8[BLOCK_TYPES_8X8];
extern vp9_coeff_stats tree_update_hist_16x16[BLOCK_TYPES_16X16];
extern vp9_coeff_stats hybrid_tree_update_hist_16x16[BLOCK_TYPES_16X16];
#if CONFIG_TX32X32
extern vp9_coeff_stats tree_update_hist_32x32[BLOCK_TYPES_32X32];
#endif
47
48
#endif  /* ENTROPY_STATS */

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    }

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

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

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

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

Yaowu Xu's avatar
Yaowu Xu committed
208
209
  VP9_COMBINEENTROPYCONTEXTS(pt, a_ec, l_ec);

210
211
  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
212

213
  do {
214
    const int band = bands[c];
215
216
217
    int token;

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

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

    t->Token = token;
229
230
231
    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));
232
    assert(vp9_coef_encodings[t->Token].Len - t->skip_eob_node > 0);
233
    if (!dry_run) {
234
      ++counts[type][band][pt][token];
235
    }
236
    pt = vp9_prev_token_class[token];
237
    ++t;
238
239
240
  } while (c < eob && ++c < seg_eob);

  *tp = t;
Yaowu Xu's avatar
Yaowu Xu committed
241
242
243
244
245
246
247
248
249
250
251
  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) {
    a[1] = a[2] = a[3] = a_ec;
    l[1] = l[2] = l[3] = l_ec;
  }
John Koleszar's avatar
John Koleszar committed
252
253
}

254
int vp9_mby_is_skippable_4x4(MACROBLOCKD *xd, int has_2nd_order) {
John Koleszar's avatar
John Koleszar committed
255
256
  int skip = 1;
  int i = 0;
257

258
  if (has_2nd_order) {
John Koleszar's avatar
John Koleszar committed
259
    for (i = 0; i < 16; i++)
Paul Wilkins's avatar
Paul Wilkins committed
260
261
      skip &= (xd->block[i].eob < 2);
    skip &= (!xd->block[24].eob);
John Koleszar's avatar
John Koleszar committed
262
263
  } else {
    for (i = 0; i < 16; i++)
Paul Wilkins's avatar
Paul Wilkins committed
264
      skip &= (!xd->block[i].eob);
John Koleszar's avatar
John Koleszar committed
265
266
  }
  return skip;
267
}
268

269
int vp9_mbuv_is_skippable_4x4(MACROBLOCKD *xd) {
John Koleszar's avatar
John Koleszar committed
270
271
  int skip = 1;
  int i;
272

John Koleszar's avatar
John Koleszar committed
273
  for (i = 16; i < 24; i++)
Paul Wilkins's avatar
Paul Wilkins committed
274
    skip &= (!xd->block[i].eob);
John Koleszar's avatar
John Koleszar committed
275
  return skip;
276
277
}

278
279
static int mb_is_skippable_4x4(MACROBLOCKD *xd, int has_2nd_order) {
  return (vp9_mby_is_skippable_4x4(xd, has_2nd_order) &
280
          vp9_mbuv_is_skippable_4x4(xd));
281
}
Yaowu Xu's avatar
Yaowu Xu committed
282

283
int vp9_mby_is_skippable_8x8(MACROBLOCKD *xd, int has_2nd_order) {
John Koleszar's avatar
John Koleszar committed
284
285
  int skip = 1;
  int i = 0;
286

287
  if (has_2nd_order) {
Deb Mukherjee's avatar
Deb Mukherjee committed
288
289
290
291
292
293
294
    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
295
  return skip;
296
}
297

298
int vp9_mbuv_is_skippable_8x8(MACROBLOCKD *xd) {
Paul Wilkins's avatar
Paul Wilkins committed
299
  return (!xd->block[16].eob) & (!xd->block[20].eob);
300
}
301

302
303
static int mb_is_skippable_8x8(MACROBLOCKD *xd, int has_2nd_order) {
  return (vp9_mby_is_skippable_8x8(xd, has_2nd_order) &
304
          vp9_mbuv_is_skippable_8x8(xd));
Deb Mukherjee's avatar
Deb Mukherjee committed
305
306
}

307
308
static int mb_is_skippable_8x8_4x4uv(MACROBLOCKD *xd, int has_2nd_order) {
  return (vp9_mby_is_skippable_8x8(xd, has_2nd_order) &
309
          vp9_mbuv_is_skippable_4x4(xd));
310
}
Yaowu Xu's avatar
Yaowu Xu committed
311

312
int vp9_mby_is_skippable_16x16(MACROBLOCKD *xd) {
Daniel Kang's avatar
Daniel Kang committed
313
  int skip = 1;
Paul Wilkins's avatar
Paul Wilkins committed
314
  skip &= !xd->block[0].eob;
Daniel Kang's avatar
Daniel Kang committed
315
316
317
  return skip;
}

318
319
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
320
}
321

322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
#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;

  tokenize_b(cpi, xd, xd->block, t, PLANE_TYPE_Y_WITH_DC,
             A[0], L[0], TX_32X32, dry_run);
  A[0][1] = A[0][2] = A[0][3] = A[0][0];
  L[0][1] = L[0][2] = L[0][3] = L[0][0];

  for (b = 16; b < 24; b += 4) {
    tokenize_b(cpi, xd, xd->block + b, t, PLANE_TYPE_UV,
               A[0] + vp9_block2above_8x8[b], L[0] + vp9_block2left_8x8[b],
               TX_16X16, dry_run);
    A[0][vp9_block2above_8x8[b] + 1] = A[0][vp9_block2above_8x8[b]];
    L[0][vp9_block2left_8x8[b] + 1]  = L[0][vp9_block2left_8x8[b]];
  }
  vpx_memset(&A[0][8], 0, sizeof(A[0][8]));
  vpx_memset(&L[0][8], 0, sizeof(L[0][8]));
  vpx_memcpy(A[1], A[0], sizeof(ENTROPY_CONTEXT_PLANES));
  vpx_memcpy(L[1], L[0], sizeof(ENTROPY_CONTEXT_PLANES));

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

395
void vp9_tokenize_mb(VP9_COMP *cpi,
Paul Wilkins's avatar
Paul Wilkins committed
396
                     MACROBLOCKD *xd,
397
398
                     TOKENEXTRA **t,
                     int dry_run) {
399
  PLANE_TYPE plane_type;
400
  int has_2nd_order;
John Koleszar's avatar
John Koleszar committed
401
  int b;
402
  int tx_size = xd->mode_info_context->mbmi.txfm_size;
Paul Wilkins's avatar
Paul Wilkins committed
403
  int mb_skip_context = vp9_get_pred_context(&cpi->common, xd, PRED_MBSKIP);
404
  TOKENEXTRA *t_backup = *t;
Paul Wilkins's avatar
Paul Wilkins committed
405

John Koleszar's avatar
John Koleszar committed
406
407
408
409
  // 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
410
  int segment_id = xd->mode_info_context->mbmi.segment_id;
411

412
413
  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
414
415
416
    skip_inc = 1;
  } else
    skip_inc = 0;
417

418
  has_2nd_order = get_2nd_order_usage(xd);
John Koleszar's avatar
John Koleszar committed
419

420
  switch (tx_size) {
Daniel Kang's avatar
Daniel Kang committed
421
    case TX_16X16:
Daniel Kang's avatar
Daniel Kang committed
422
      xd->mode_info_context->mbmi.mb_skip_coeff = mb_is_skippable_16x16(xd);
Daniel Kang's avatar
Daniel Kang committed
423
424
      break;
    case TX_8X8:
425
426
      if (xd->mode_info_context->mbmi.mode == I8X8_PRED ||
          xd->mode_info_context->mbmi.mode == SPLITMV)
427
428
        xd->mode_info_context->mbmi.mb_skip_coeff =
            mb_is_skippable_8x8_4x4uv(xd, 0);
Deb Mukherjee's avatar
Deb Mukherjee committed
429
      else
430
431
        xd->mode_info_context->mbmi.mb_skip_coeff =
            mb_is_skippable_8x8(xd, has_2nd_order);
Daniel Kang's avatar
Daniel Kang committed
432
      break;
Deb Mukherjee's avatar
Deb Mukherjee committed
433

Daniel Kang's avatar
Daniel Kang committed
434
    default:
435
436
      xd->mode_info_context->mbmi.mb_skip_coeff =
          mb_is_skippable_4x4(xd, has_2nd_order);
Daniel Kang's avatar
Daniel Kang committed
437
438
      break;
  }
439

Paul Wilkins's avatar
Paul Wilkins committed
440
  if (xd->mode_info_context->mbmi.mb_skip_coeff) {
441
442
    if (!dry_run)
      cpi->skip_true_count[mb_skip_context] += skip_inc;
John Koleszar's avatar
John Koleszar committed
443
    if (!cpi->common.mb_no_coeff_skip) {
444
      vp9_stuff_mb(cpi, xd, t, dry_run);
John Koleszar's avatar
John Koleszar committed
445
    } else {
Yaowu Xu's avatar
Yaowu Xu committed
446
      vp9_reset_mb_tokens_context(xd);
John Koleszar's avatar
John Koleszar committed
447
    }
Yaowu Xu's avatar
Yaowu Xu committed
448

449
450
    if (dry_run)
      *t = t_backup;
John Koleszar's avatar
John Koleszar committed
451
452
453
    return;
  }

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

457
  if (has_2nd_order) {
Yaowu Xu's avatar
Yaowu Xu committed
458
    tokenize_b(cpi, xd, 24, t, PLANE_TYPE_Y2, tx_size, dry_run);
459
    plane_type = PLANE_TYPE_Y_NO_DC;
Yaowu Xu's avatar
Yaowu Xu committed
460
  } else {
Yaowu Xu's avatar
Yaowu Xu committed
461
462
    xd->above_context->y2 = 0;
    xd->left_context->y2 = 0;
463
    plane_type = PLANE_TYPE_Y_WITH_DC;
Yaowu Xu's avatar
Yaowu Xu committed
464
  }
John Koleszar's avatar
John Koleszar committed
465

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

John Koleszar's avatar
John Koleszar committed
496
497

#ifdef ENTROPY_STATS
John Koleszar's avatar
John Koleszar committed
498
499
500
void init_context_counters(void) {
  FILE *f = fopen("context.bin", "rb");
  if (!f) {
501
502
503
    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
504
    vpx_memset(context_counters_8x8, 0, sizeof(context_counters_8x8));
505
506
    vpx_memset(hybrid_context_counters_8x8, 0,
               sizeof(hybrid_context_counters_8x8));
Daniel Kang's avatar
Daniel Kang committed
507
    vpx_memset(context_counters_16x16, 0, sizeof(context_counters_16x16));
508
509
510
511
512
    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
513
  } else {
514
515
516
    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
517
    fread(context_counters_8x8, sizeof(context_counters_8x8), 1, f);
518
519
    fread(hybrid_context_counters_8x8,
          sizeof(hybrid_context_counters_8x8), 1, f);
Daniel Kang's avatar
Daniel Kang committed
520
    fread(context_counters_16x16, sizeof(context_counters_16x16), 1, f);
521
522
523
524
525
    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
526
527
528
529
530
    fclose(f);
  }

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

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

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

# define Comma( X) (X? ",":"")
John Koleszar's avatar
John Koleszar committed
567
568
569
570
571
572
573
574
575
576
577
578
579
580
  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 {
          const INT64 x = context_counters [type] [band] [pt] [t];
          const int y = (int) x;
581

John Koleszar's avatar
John Koleszar committed
582
583
584
585
586
587
588
589
          assert(x == (INT64) y);  /* no overflow handling yet */
          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  }");
590
  } while (++type < block_types);
Daniel Kang's avatar
Daniel Kang committed
591
  fprintf(f, "\n};\n");
592
}
593

594
595
596
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
597

598
  fprintf(f, "static const vp9_coeff_probs %s = {\n", header);
599

John Koleszar's avatar
John Koleszar committed
600
601
602
603
604
605
606
607
608
609
  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 {
        unsigned int branch_ct [ENTROPY_NODES] [2];
        unsigned int coef_counts[MAX_ENTROPY_TOKENS];
610
        vp9_prob coef_probs[ENTROPY_NODES];
611

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

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

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

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

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

640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
  /* 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
657

658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
  /* print coefficient probabilities */
  print_probs(f, context_counters_4x4, BLOCK_TYPES_4X4,
              "vp9_default_coef_probs_4x4[BLOCK_TYPES_4X4]");
  print_probs(f, hybrid_context_counters_4x4, BLOCK_TYPES_4X4,
              "vp9_default_hybrid_coef_probs_4x4[BLOCK_TYPES_4X4]");
  print_probs(f, context_counters_8x8, BLOCK_TYPES_8X8,
              "vp9_default_coef_probs_8x8[BLOCK_TYPES_8X8]");
  print_probs(f, hybrid_context_counters_8x8, BLOCK_TYPES_8X8,
              "vp9_default_hybrid_coef_probs_8x8[BLOCK_TYPES_8X8]");
  print_probs(f, context_counters_16x16, BLOCK_TYPES_16X16,
              "vp9_default_coef_probs_16x16[BLOCK_TYPES_16X16]");
  print_probs(f, hybrid_context_counters_16x16, BLOCK_TYPES_16X16,
              "vp9_default_hybrid_coef_probs_16x16[BLOCK_TYPES_16X16]");
#if CONFIG_TX32X32
  print_probs(f, context_counters_32x32, BLOCK_TYPES_32X32,
              "vp9_default_coef_probs_32x32[BLOCK_TYPES_32X32]");
#endif
Daniel Kang's avatar
Daniel Kang committed
675

John Koleszar's avatar
John Koleszar committed
676
677
678
  fclose(f);

  f = fopen("context.bin", "wb");
679
680
681
  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
682
  fwrite(context_counters_8x8, sizeof(context_counters_8x8), 1, f);
683
684
  fwrite(hybrid_context_counters_8x8,
         sizeof(hybrid_context_counters_8x8), 1, f);
Daniel Kang's avatar
Daniel Kang committed
685
  fwrite(context_counters_16x16, sizeof(context_counters_16x16), 1, f);
686
687
688
689
690
  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
691
  fclose(f);
John Koleszar's avatar
John Koleszar committed
692
693
694
}
#endif

695
void vp9_tokenize_initialize() {
John Koleszar's avatar
John Koleszar committed
696
  fill_value_tokens();
John Koleszar's avatar
John Koleszar committed
697
698
}

699
static __inline void stuff_b(VP9_COMP *cpi,
700
                             MACROBLOCKD *xd,
Yaowu Xu's avatar
Yaowu Xu committed
701
                             const int ib,
702
703
704
705
                             TOKENEXTRA **tp,
                             PLANE_TYPE type,
                             TX_SIZE tx_size,
                             int dry_run) {
Yaowu Xu's avatar
Yaowu Xu committed
706
  const BLOCKD * const b = xd->block + ib;
707
  const int *bands;
708
709
  vp9_coeff_count *counts;
  vp9_coeff_probs *probs;
710
711
712
713
  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
714
715
716
717
718
719

  ENTROPY_CONTEXT *const a = (ENTROPY_CONTEXT *)xd->above_context +
      vp9_block2above[tx_size][ib];
  ENTROPY_CONTEXT *const l = (ENTROPY_CONTEXT *)xd->left_context +
      vp9_block2left[tx_size][ib];
  ENTROPY_CONTEXT a_ec = *a, l_ec = *l;
John Koleszar's avatar
John Koleszar committed
720

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

  VP9_COMBINEENTROPYCONTEXTS(pt, a_ec, l_ec);

774
  band = bands[(type == PLANE_TYPE_Y_NO_DC) ? 1 : 0];
John Koleszar's avatar
John Koleszar committed
775
  t->Token = DCT_EOB_TOKEN;
776
  t->context_tree = probs[type][band][pt];
John Koleszar's avatar
John Koleszar committed
777
778
779
  t->skip_eob_node = 0;
  ++t;
  *tp = t;
780
  *a = *l = 0;
Yaowu Xu's avatar
Yaowu Xu committed
781
782
783
784
785
786
787
788
  if (tx_size == TX_8X8 && type != PLANE_TYPE_Y2) {
    a[1] = 0;
    l[1] = 0;
  } else if (tx_size == TX_16X16) {
    a[1] = a[2] = a[3] = 0;
    l[1] = l[2] = l[3] = 0;
  }

789
  if (!dry_run) {
790
    ++counts[type][band][pt][DCT_EOB_TOKEN];
791
  }
792
793
}

794
795
static void stuff_mb_8x8(VP9_COMP *cpi, MACROBLOCKD *xd,
                         TOKENEXTRA **t, int dry_run) {
796
  PLANE_TYPE plane_type;
John Koleszar's avatar
John Koleszar committed
797
  int b;
798
  int has_2nd_order = get_2nd_order_usage(xd);
John Koleszar's avatar
John Koleszar committed
799

800
  if (has_2nd_order) {
Yaowu Xu's avatar
Yaowu Xu committed
801
    stuff_b(cpi, xd, 24, t, PLANE_TYPE_Y2, TX_8X8, dry_run);
802
803
    plane_type = PLANE_TYPE_Y_NO_DC;
  } else {
Yaowu Xu's avatar
Yaowu Xu committed
804
805
806
807
#if CONFIG_CNVCONTEXT
    xd->above_context->y2 = 0;
    xd->left_context->y2 = 0;
#endif
808
809
    plane_type = PLANE_TYPE_Y_WITH_DC;
  }
John Koleszar's avatar
John Koleszar committed
810

Yaowu Xu's avatar
Yaowu Xu committed
811
812
813
814
  for (b = 0; b < 24; b += 4) {
    if (b >= 16)
      plane_type = PLANE_TYPE_UV;
    stuff_b(cpi, xd, b, t, plane_type, TX_8X8, dry_run);
John Koleszar's avatar
John Koleszar committed
815
  }
Daniel Kang's avatar
Daniel Kang committed
816
817
}

818
819
static void stuff_mb_16x16(VP9_COMP *cpi, MACROBLOCKD *xd,
                           TOKENEXTRA **t, int dry_run) {
820
  int b;
Yaowu Xu's avatar
Yaowu Xu committed
821
  stuff_b(cpi, xd, 0, t, PLANE_TYPE_Y_WITH_DC, TX_16X16, dry_run);
Daniel Kang's avatar
Daniel Kang committed
822
823

  for (b = 16; b < 24; b += 4) {
Yaowu Xu's avatar
Yaowu Xu committed
824
825
    stuff_b(cpi, xd, b, t, PLANE_TYPE_UV, TX_8X8, dry_run);
  }
Yaowu Xu's avatar
Yaowu Xu committed
826
#if CONFIG_CNVCONTEXT
Yaowu Xu's avatar
Yaowu Xu committed
827
828
  xd->above_context->y2 = 0;
  xd->left_context->y2 = 0;
Yaowu Xu's avatar
Yaowu Xu committed
829
#endif
John Koleszar's avatar
John Koleszar committed
830
831
}

832
833
static void stuff_mb_4x4(VP9_COMP *cpi, MACROBLOCKD *xd,
                         TOKENEXTRA **t, int dry_run) {
John Koleszar's avatar
John Koleszar committed
834
  int b;
835
  PLANE_TYPE plane_type;
Yaowu Xu's avatar
Yaowu Xu committed
836
  int has_2nd_order = get_2nd_order_usage(xd);
John Koleszar's avatar
John Koleszar committed
837

838
  if (has_2nd_order) {
Yaowu Xu's avatar
Yaowu Xu committed
839
    stuff_b(cpi, xd, 24, t, PLANE_TYPE_Y2, TX_4X4, dry_run);
840
841
    plane_type = PLANE_TYPE_Y_NO_DC;
  } else {
Yaowu Xu's avatar
Yaowu Xu committed
842
843
    xd->above_context->y2 = 0;
    xd->left_context->y2 = 0;
844
845
    plane_type = PLANE_TYPE_Y_WITH_DC;
  }
John Koleszar's avatar
John Koleszar committed
846

Yaowu Xu's avatar
Yaowu Xu committed
847
848
849
850
851
  for (b = 0; b < 24; b++) {
    if (b >= 16)
      plane_type = PLANE_TYPE_UV;
    stuff_b(cpi, xd, b, t, plane_type, TX_4X4, dry_run);
  }
John Koleszar's avatar
John Koleszar committed
852
}
Deb Mukherjee's avatar
Deb Mukherjee committed
853

854
855
static void stuff_mb_8x8_4x4uv(VP9_COMP *cpi, MACROBLOCKD *xd,
                               TOKENEXTRA **t, int dry_run) {
856
  PLANE_TYPE plane_type;
Deb Mukherjee's avatar
Deb Mukherjee committed
857
858
  int b;

859
860
  int has_2nd_order = get_2nd_order_usage(xd);
  if (has_2nd_order) {
Yaowu Xu's avatar
Yaowu Xu committed
861
    stuff_b(cpi, xd, 24, t, PLANE_TYPE_Y2, TX_8X8, dry_run);
862
863
    plane_type = PLANE_TYPE_Y_NO_DC;
  } else {
Yaowu Xu's avatar
Yaowu Xu committed
864
865
    xd->above_context->y2 = 0;
    xd->left_context->y2 = 0;
866
867
868
    plane_type = PLANE_TYPE_Y_WITH_DC;
  }

Deb Mukherjee's avatar
Deb Mukherjee committed
869
  for (b = 0; b < 16; b += 4) {
Yaowu Xu's avatar
Yaowu Xu committed
870
    stuff_b(cpi, xd, b, t, plane_type, TX_8X8, dry_run);
Deb Mukherjee's avatar
Deb Mukherjee committed
871
872
  }

Yaowu Xu's avatar
Yaowu Xu committed
873
874
875
  for (b = 16; b < 24; b++) {
    stuff_b(cpi, xd, b, t, PLANE_TYPE_UV, TX_4X4, dry_run);
  }
Deb Mukherjee's avatar
Deb Mukherjee committed
876
877
}

878
void vp9_stuff_mb(VP9_COMP *cpi, MACROBLOCKD *xd, TOKENEXTRA **t, int dry_run) {
879
  TX_SIZE tx_size = xd->mode_info_context->mbmi.txfm_size;
880
  TOKENEXTRA * const t_backup = *t;
881
882

  if (tx_size == TX_16X16) {
883
    stuff_mb_16x16(cpi, xd, t, dry_run);
884
  } else if (tx_size == TX_8X8) {
885
886
    if (xd->mode_info_context->mbmi.mode == I8X8_PRED ||
        xd->mode_info_context->mbmi.mode == SPLITMV) {
887
      stuff_mb_8x8_4x4uv(cpi, xd, t, dry_run);
888
    } else {
889
      stuff_mb_8x8(cpi, xd, t, dry_run);
890
891
    }
  } else {
892
    stuff_mb_4x4(cpi, xd, t, dry_run);
893
  }
894
895
896
897

  if (dry_run) {
    *t = t_backup;
  }
898
899
}

900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
#if CONFIG_TX32X32 && CONFIG_SUPERBLOCKS
static void stuff_sb_32x32(VP9_COMP *cpi, MACROBLOCKD *xd,
                               TOKENEXTRA **t, int dry_run) {
  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), };
  int b;

  stuff_b(cpi, xd, xd->block, t, PLANE_TYPE_Y_WITH_DC,
          A[0], L[0], TX_32X32, dry_run);
  A[0][1] = A[0][2] = A[0][3] = A[0][0];
  L[0][1] = L[0][2] = L[0][3] = L[0][0];
  for (b = 16; b < 24; b += 4) {
    stuff_b(cpi, xd, xd->block + b, t, PLANE_TYPE_UV,
            A[0] + vp9_block2above_8x8[b],
            L[0] + vp9_block2above_8x8[b], TX_16X16, dry_run);
    A[0][vp9_block2above_8x8[b] + 1] = A[0][vp9_block2above_8x8[b]];
    L[0][vp9_block2left_8x8[b] + 1]  = L[0][vp9_block2left_8x8[b]];
  }
  vpx_memset(&A[0][8], 0, sizeof(A[0][8]));
  vpx_memset(&L[0][8], 0, sizeof(L[0][8]));
  vpx_memcpy(A[1], A[0], sizeof(ENTROPY_CONTEXT_PLANES));
  vpx_memcpy(L[1], L[0], sizeof(ENTROPY_CONTEXT_PLANES));
}

void vp9_stuff_sb(VP9_COMP *cpi, MACROBLOCKD *xd, TOKENEXTRA **t, int dry_run) {
  TOKENEXTRA * const t_backup = *t;

  stuff_sb_32x32(cpi, xd, t, dry_run);

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

937
void vp9_fix_contexts(MACROBLOCKD *xd) {
938
  /* Clear entropy contexts for blocks */
Paul Wilkins's avatar
Paul Wilkins committed
939
  if ((xd->mode_info_context->mbmi.mode != B_PRED
940
941
       && xd->mode_info_context->mbmi.mode != I8X8_PRED
       && xd->mode_info_context->mbmi.mode != SPLITMV)
Paul Wilkins's avatar
Paul Wilkins committed
942
      || xd->mode_info_context->mbmi.txfm_size == TX_16X16
Daniel Kang's avatar
Daniel Kang committed
943
      ) {
Paul Wilkins's avatar
Paul Wilkins committed
944
945
    vpx_memset(xd->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES));
    vpx_memset(xd->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES));
John Koleszar's avatar
John Koleszar committed
946
  } else {
Paul Wilkins's avatar
Paul Wilkins committed
947
948
    vpx_memset(xd->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES) - 1);
    vpx_memset(xd->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES) - 1);
Yaowu Xu's avatar
Yaowu Xu committed
949
950
    xd->above_context->y2 = 1;
    xd->left_context->y2 = 1;
John Koleszar's avatar
John Koleszar committed
951
  }
John Koleszar's avatar
John Koleszar committed
952
}
953
954
955
956
957
958
959

#if CONFIG_TX32X32 && CONFIG_SUPERBLOCKS
void vp9_fix_contexts_sb(MACROBLOCKD *xd) {
  vpx_memset(xd->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES) * 2);
  vpx_memset(xd->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES) * 2);
}
#endif