vp9_tokenize.c 29.6 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
#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;

373
374
  tokenize_b(cpi, xd, 0, t, PLANE_TYPE_Y_WITH_DC,
             TX_32X32, dry_run);
375
376
377
378
  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) {
379
    tokenize_b(cpi, xd, b, t, PLANE_TYPE_UV,
380
               TX_16X16, dry_run);
381
382
    A[0][vp9_block2above[TX_16X16][b] + 1] = A[0][vp9_block2above[TX_16X16][b]];
    L[0][vp9_block2left[TX_16X16][b] + 1]  = L[0][vp9_block2left[TX_16X16][b]];
383
384
385
386
387
388
389
390
391
392
393
  }
  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

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

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

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

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

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

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

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

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

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

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

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

John Koleszar's avatar
John Koleszar committed
495
496

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

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

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

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

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

John Koleszar's avatar
John Koleszar committed
581
582
583
584
585
586
587
588
          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  }");
589
  } while (++type < block_types);
Daniel Kang's avatar
Daniel Kang committed
590
  fprintf(f, "\n};\n");
591
}
592

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

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

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

John Koleszar's avatar
John Koleszar committed
614
        for (t = 0; t < MAX_ENTROPY_TOKENS; ++t)
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,
618
                                         coef_probs, branch_ct, coef_counts);
John Koleszar's avatar
John Koleszar committed
619
        fprintf(f, "%s\n      {", Comma(pt));
620

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

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

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

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

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

659
660
  /* print coefficient probabilities */
  print_probs(f, context_counters_4x4, BLOCK_TYPES_4X4,
661
              "default_coef_probs_4x4[BLOCK_TYPES_4X4]");
662
  print_probs(f, hybrid_context_counters_4x4, BLOCK_TYPES_4X4,
663
              "default_hybrid_coef_probs_4x4[BLOCK_TYPES_4X4]");
664
  print_probs(f, context_counters_8x8, BLOCK_TYPES_8X8,
665
              "default_coef_probs_8x8[BLOCK_TYPES_8X8]");
666
  print_probs(f, hybrid_context_counters_8x8, BLOCK_TYPES_8X8,
667
              "default_hybrid_coef_probs_8x8[BLOCK_TYPES_8X8]");
668
  print_probs(f, context_counters_16x16, BLOCK_TYPES_16X16,
669
              "default_coef_probs_16x16[BLOCK_TYPES_16X16]");
670
  print_probs(f, hybrid_context_counters_16x16, BLOCK_TYPES_16X16,
671
              "default_hybrid_coef_probs_16x16[BLOCK_TYPES_16X16]");
672
673
#if CONFIG_TX32X32
  print_probs(f, context_counters_32x32, BLOCK_TYPES_32X32,
674
              "default_coef_probs_32x32[BLOCK_TYPES_32X32]");
675
#endif
Daniel Kang's avatar
Daniel Kang committed
676

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

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

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

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

  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
721

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

  VP9_COMBINEENTROPYCONTEXTS(pt, a_ec, l_ec);

775
  band = bands[(type == PLANE_TYPE_Y_NO_DC) ? 1 : 0];
John Koleszar's avatar
John Koleszar committed
776
  t->Token = DCT_EOB_TOKEN;
777
  t->context_tree = probs[type][band][pt];
John Koleszar's avatar
John Koleszar committed
778
779
780
  t->skip_eob_node = 0;
  ++t;
  *tp = t;
781
  *a = *l = 0;
Yaowu Xu's avatar
Yaowu Xu committed
782
783
784
785
786
787
788
789
  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;
  }

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

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

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

Yaowu Xu's avatar
Yaowu Xu committed
812
813
814
815
  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
816
  }
Daniel Kang's avatar
Daniel Kang committed
817
818
}

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

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

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

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

Yaowu Xu's avatar
Yaowu Xu committed
848
849
850
851
852
  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
853
}
Deb Mukherjee's avatar
Deb Mukherjee committed
854

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

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

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

Yaowu Xu's avatar
Yaowu Xu committed
874
875
876
  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
877
878
}

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

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

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

901
902
903
904
905
906
907
908
909
#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;

910
  stuff_b(cpi, xd, 0, t, PLANE_TYPE_Y_WITH_DC, TX_32X32, dry_run);
911
912
913
  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) {
914
915
916
    stuff_b(cpi, xd, b, t, PLANE_TYPE_UV, TX_16X16, dry_run);
    A[0][vp9_block2above[TX_16X16][b] + 1] = A[0][vp9_block2above[TX_16X16][b]];
    L[0][vp9_block2left[TX_16X16][b] + 1]  = L[0][vp9_block2left[TX_16X16][b]];