vp9_detokenize.c 18.4 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
#include "vp9/common/vp9_blockd.h"
John Koleszar's avatar
John Koleszar committed
13
#include "vp9/common/vp9_common.h"
14
#include "vp9/decoder/vp9_onyxd_int.h"
John Koleszar's avatar
John Koleszar committed
15
16
#include "vpx_mem/vpx_mem.h"
#include "vpx_ports/mem.h"
17
#include "vp9/decoder/vp9_detokenize.h"
18
#include "vp9/common/vp9_seg_common.h"
19

John Koleszar's avatar
John Koleszar committed
20
21
22
23
24
25
26
27
28
29
30
31
#define EOB_CONTEXT_NODE            0
#define ZERO_CONTEXT_NODE           1
#define ONE_CONTEXT_NODE            2
#define LOW_VAL_CONTEXT_NODE        3
#define TWO_CONTEXT_NODE            4
#define THREE_CONTEXT_NODE          5
#define HIGH_LOW_CONTEXT_NODE       6
#define CAT_ONE_CONTEXT_NODE        7
#define CAT_THREEFOUR_CONTEXT_NODE  8
#define CAT_THREE_CONTEXT_NODE      9
#define CAT_FIVE_CONTEXT_NODE       10

Scott LaVarnway's avatar
Scott LaVarnway committed
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#define CAT1_MIN_VAL    5
#define CAT2_MIN_VAL    7
#define CAT3_MIN_VAL   11
#define CAT4_MIN_VAL   19
#define CAT5_MIN_VAL   35
#define CAT6_MIN_VAL   67
#define CAT1_PROB0    159
#define CAT2_PROB0    145
#define CAT2_PROB1    165

#define CAT3_PROB0 140
#define CAT3_PROB1 148
#define CAT3_PROB2 173

#define CAT4_PROB0 135
#define CAT4_PROB1 140
#define CAT4_PROB2 155
#define CAT4_PROB3 176

#define CAT5_PROB0 130
#define CAT5_PROB1 134
#define CAT5_PROB2 141
#define CAT5_PROB3 157
#define CAT5_PROB4 180

57
static const vp9_prob cat6_prob[15] = {
58
59
  254, 254, 254, 252, 249, 243, 230, 196, 177, 153, 140, 133, 130, 129, 0
};
John Koleszar's avatar
John Koleszar committed
60

61
DECLARE_ALIGNED(16, extern const uint8_t, vp9_norm[256]);
62

63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#if CONFIG_CODE_ZEROGROUP
#define ZEROGROUP_ADVANCE()                \
  do {                                     \
    token_cache[scan[c]] = ZERO_TOKEN;     \
    is_last_zero[o] = 1;                   \
    c++;                                   \
  } while (0)
#define INCREMENT_COUNT(token)             \
  do {                                     \
    coef_counts[type][ref][get_coef_band(scan, txfm_size, c)] \
               [pt][token]++;     \
    token_cache[scan[c]] = token; \
    is_last_zero[o] = (token == ZERO_TOKEN);    \
  } while (0)
#else
78
79
#define INCREMENT_COUNT(token)               \
  do {                                       \
80
81
    coef_counts[type][ref][get_coef_band(scan, txfm_size, c)] \
               [pt][token]++;     \
82
    token_cache[scan[c]] = token; \
83
  } while (0)
84
#endif
85

Dmitry Kovalev's avatar
Dmitry Kovalev committed
86
87
#define WRITE_COEF_CONTINUE(val, token)                  \
  {                                                      \
88
    qcoeff_ptr[scan[c]] = vp9_read_and_apply_sign(r, val); \
Dmitry Kovalev's avatar
Dmitry Kovalev committed
89
90
91
    INCREMENT_COUNT(token);                              \
    c++;                                                 \
    continue;                                            \
92
  }
John Koleszar's avatar
John Koleszar committed
93

94
95
96
97
98
99
#define WRITE_COEF_ONE()                                 \
{                                                        \
  qcoeff_ptr[scan[c]] = vp9_read_and_apply_sign(br, 1);  \
  INCREMENT_COUNT(ONE_TOKEN);                            \
}

Daniel Kang's avatar
Daniel Kang committed
100
101
#define ADJUST_COEF(prob, bits_count)  \
  do {                                 \
102
    if (vp9_read(r, prob))             \
Dmitry Kovalev's avatar
Dmitry Kovalev committed
103
      val += 1 << bits_count;          \
John Koleszar's avatar
John Koleszar committed
104
  } while (0);
John Koleszar's avatar
John Koleszar committed
105

106
static int decode_coefs(VP9D_COMP *dx, const MACROBLOCKD *xd,
107
                        vp9_reader *r, int block_idx,
108
109
                        PLANE_TYPE type, int seg_eob, int16_t *qcoeff_ptr,
                        TX_SIZE txfm_size) {
110
111
  ENTROPY_CONTEXT* const A0 = (ENTROPY_CONTEXT *) xd->above_context;
  ENTROPY_CONTEXT* const L0 = (ENTROPY_CONTEXT *) xd->left_context;
112
113
  int aidx, lidx;
  ENTROPY_CONTEXT above_ec, left_ec;
John Koleszar's avatar
John Koleszar committed
114
  FRAME_CONTEXT *const fc = &dx->common.fc;
115
  int pt, c = 0, pad, default_eob;
116
117
118
  vp9_coeff_probs *coef_probs;
  vp9_prob *prob;
  vp9_coeff_count *coef_counts;
119
  const int ref = xd->mode_info_context->mbmi.ref_frame != INTRA_FRAME;
120
121
122
123
124
125
126
127
128
  TX_TYPE tx_type = DCT_DCT;
#if CONFIG_CODE_ZEROGROUP
  int is_eoo[3] = {0, 0, 0};
  int is_last_zero[3] = {0, 0, 0};
  int o, rc;
  vp9_zpc_probs *zpc_probs;
  vp9_zpc_count *zpc_count;
  vp9_prob *zprobs;
  int eoo = 0, use_eoo;
129
#endif
130
131
  const int *scan, *nb;
  uint8_t token_cache[1024];
132
133
134
#if CONFIG_CODE_ZEROGROUP
  vpx_memset(token_cache, UNKNOWN_TOKEN, sizeof(token_cache));
#endif
Daniel Kang's avatar
Daniel Kang committed
135

136
137
138
  if (xd->mode_info_context->mbmi.sb_type == BLOCK_SIZE_SB64X64) {
    aidx = vp9_block2above_sb64[txfm_size][block_idx];
    lidx = vp9_block2left_sb64[txfm_size][block_idx];
139
140
141
142
143
144
145
146
#if CONFIG_SBSEGMENT
  } else if (xd->mode_info_context->mbmi.sb_type == BLOCK_SIZE_SB64X32) {
    aidx = vp9_block2above_sb64x32[txfm_size][block_idx];
    lidx = vp9_block2left_sb64x32[txfm_size][block_idx];
  } else if (xd->mode_info_context->mbmi.sb_type == BLOCK_SIZE_SB32X64) {
    aidx = vp9_block2above_sb32x64[txfm_size][block_idx];
    lidx = vp9_block2left_sb32x64[txfm_size][block_idx];
#endif
147
148
149
  } else if (xd->mode_info_context->mbmi.sb_type == BLOCK_SIZE_SB32X32) {
    aidx = vp9_block2above_sb[txfm_size][block_idx];
    lidx = vp9_block2left_sb[txfm_size][block_idx];
150
151
152
153
154
155
156
157
#if CONFIG_SBSEGMENT
  } else if (xd->mode_info_context->mbmi.sb_type == BLOCK_SIZE_SB32X16) {
    aidx = vp9_block2above_sb32x16[txfm_size][block_idx];
    lidx = vp9_block2left_sb32x16[txfm_size][block_idx];
  } else if (xd->mode_info_context->mbmi.sb_type == BLOCK_SIZE_SB16X32) {
    aidx = vp9_block2above_sb16x32[txfm_size][block_idx];
    lidx = vp9_block2left_sb16x32[txfm_size][block_idx];
#endif
158
159
160
161
162
  } else {
    aidx = vp9_block2above[txfm_size][block_idx];
    lidx = vp9_block2left[txfm_size][block_idx];
  }

163
  switch (txfm_size) {
Daniel Kang's avatar
Daniel Kang committed
164
    default:
165
    case TX_4X4: {
166
167
      tx_type = (type == PLANE_TYPE_Y_WITH_DC) ?
          get_tx_type_4x4(xd, block_idx) : DCT_DCT;
168
169
170
171
172
173
174
175
176
177
178
      switch (tx_type) {
        default:
          scan = vp9_default_zig_zag1d_4x4;
          break;
        case ADST_DCT:
          scan = vp9_row_scan_4x4;
          break;
        case DCT_ADST:
          scan = vp9_col_scan_4x4;
          break;
      }
179
180
      above_ec = A0[aidx] != 0;
      left_ec = L0[lidx] != 0;
181
182
      coef_probs  = fc->coef_probs_4x4;
      coef_counts = fc->coef_counts_4x4;
183
      default_eob = 16;
184
185
186
187
#if CONFIG_CODE_ZEROGROUP
      zpc_probs = &(fc->zpc_probs_4x4);
      zpc_count = &(fc->zpc_counts_4x4);
#endif
Daniel Kang's avatar
Daniel Kang committed
188
      break;
189
    }
190
191
    case TX_8X8: {
      const BLOCK_SIZE_TYPE sb_type = xd->mode_info_context->mbmi.sb_type;
192
193
      const int sz = 3 + mb_width_log2(sb_type);
      const int x = block_idx & ((1 << sz) - 1);
194
      const int y = block_idx - x;
195
196
      tx_type = (type == PLANE_TYPE_Y_WITH_DC) ?
          get_tx_type_8x8(xd, y + (x >> 1)) : DCT_DCT;
197
198
199
200
201
202
203
204
205
206
207
      switch (tx_type) {
        default:
          scan = vp9_default_zig_zag1d_8x8;
          break;
        case ADST_DCT:
          scan = vp9_row_scan_8x8;
          break;
        case DCT_ADST:
          scan = vp9_col_scan_8x8;
          break;
      }
208
209
      coef_probs  = fc->coef_probs_8x8;
      coef_counts = fc->coef_counts_8x8;
210
211
      above_ec = (A0[aidx] + A0[aidx + 1]) != 0;
      left_ec  = (L0[lidx] + L0[lidx + 1]) != 0;
212
      default_eob = 64;
213
214
215
216
#if CONFIG_CODE_ZEROGROUP
      zpc_probs = &(fc->zpc_probs_8x8);
      zpc_count = &(fc->zpc_counts_8x8);
#endif
Daniel Kang's avatar
Daniel Kang committed
217
      break;
218
219
220
    }
    case TX_16X16: {
      const BLOCK_SIZE_TYPE sb_type = xd->mode_info_context->mbmi.sb_type;
221
222
      const int sz = 4 + mb_width_log2(sb_type);
      const int x = block_idx & ((1 << sz) - 1);
223
      const int y = block_idx - x;
224
225
      tx_type = (type == PLANE_TYPE_Y_WITH_DC) ?
          get_tx_type_16x16(xd, y + (x >> 2)) : DCT_DCT;
226
227
228
229
230
231
232
233
234
235
236
      switch (tx_type) {
        default:
          scan = vp9_default_zig_zag1d_16x16;
          break;
        case ADST_DCT:
          scan = vp9_row_scan_16x16;
          break;
        case DCT_ADST:
          scan = vp9_col_scan_16x16;
          break;
      }
237
238
      coef_probs  = fc->coef_probs_16x16;
      coef_counts = fc->coef_counts_16x16;
239
240
241
242
243
      if (type == PLANE_TYPE_UV) {
        ENTROPY_CONTEXT *A1 = (ENTROPY_CONTEXT *) (xd->above_context + 1);
        ENTROPY_CONTEXT *L1 = (ENTROPY_CONTEXT *) (xd->left_context + 1);
        above_ec = (A0[aidx] + A0[aidx + 1] + A1[aidx] + A1[aidx + 1]) != 0;
        left_ec  = (L0[lidx] + L0[lidx + 1] + L1[lidx] + L1[lidx + 1]) != 0;
244
      } else {
245
246
247
        above_ec = (A0[aidx] + A0[aidx + 1] + A0[aidx + 2] + A0[aidx + 3]) != 0;
        left_ec  = (L0[lidx] + L0[lidx + 1] + L0[lidx + 2] + L0[lidx + 3]) != 0;
      }
248
      default_eob = 256;
249
250
251
252
#if CONFIG_CODE_ZEROGROUP
      zpc_probs = &(fc->zpc_probs_16x16);
      zpc_count = &(fc->zpc_counts_16x16);
#endif
Daniel Kang's avatar
Daniel Kang committed
253
      break;
254
    }
255
    case TX_32X32:
256
      scan = vp9_default_zig_zag1d_32x32;
257
258
      coef_probs = fc->coef_probs_32x32;
      coef_counts = fc->coef_counts_32x32;
259
260
261
262
263
264
265
266
267
268
269
      if (type == PLANE_TYPE_UV) {
        ENTROPY_CONTEXT *A1 = (ENTROPY_CONTEXT *) (xd->above_context + 1);
        ENTROPY_CONTEXT *L1 = (ENTROPY_CONTEXT *) (xd->left_context + 1);
        ENTROPY_CONTEXT *A2 = (ENTROPY_CONTEXT *) (xd->above_context + 2);
        ENTROPY_CONTEXT *L2 = (ENTROPY_CONTEXT *) (xd->left_context + 2);
        ENTROPY_CONTEXT *A3 = (ENTROPY_CONTEXT *) (xd->above_context + 3);
        ENTROPY_CONTEXT *L3 = (ENTROPY_CONTEXT *) (xd->left_context + 3);
        above_ec = (A0[aidx] + A0[aidx + 1] + A1[aidx] + A1[aidx + 1] +
                    A2[aidx] + A2[aidx + 1] + A3[aidx] + A3[aidx + 1]) != 0;
        left_ec  = (L0[lidx] + L0[lidx + 1] + L1[lidx] + L1[lidx + 1] +
                    L2[lidx] + L2[lidx + 1] + L3[lidx] + L3[lidx + 1]) != 0;
270
      } else {
271
272
273
274
275
276
277
        ENTROPY_CONTEXT *A1 = (ENTROPY_CONTEXT *) (xd->above_context + 1);
        ENTROPY_CONTEXT *L1 = (ENTROPY_CONTEXT *) (xd->left_context + 1);
        above_ec = (A0[aidx] + A0[aidx + 1] + A0[aidx + 2] + A0[aidx + 3] +
                    A1[aidx] + A1[aidx + 1] + A1[aidx + 2] + A1[aidx + 3]) != 0;
        left_ec  = (L0[lidx] + L0[lidx + 1] + L0[lidx + 2] + L0[lidx + 3] +
                    L1[lidx] + L1[lidx + 1] + L1[lidx + 2] + L1[lidx + 3]) != 0;
      }
278
      default_eob = 1024;
279
280
281
282
#if CONFIG_CODE_ZEROGROUP
      zpc_probs = &fc->zpc_probs_32x32;
      zpc_count = &fc->zpc_counts_32x32;
#endif
283
      break;
Daniel Kang's avatar
Daniel Kang committed
284
  }
John Koleszar's avatar
John Koleszar committed
285

286
  pt = combine_entropy_contexts(above_ec, left_ec);
287
288
  nb = vp9_get_coef_neighbors_handle(scan, &pad);

John Koleszar's avatar
John Koleszar committed
289
290
  while (1) {
    int val;
291
    int band;
John Koleszar's avatar
John Koleszar committed
292
    const uint8_t *cat6 = cat6_prob;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
293
294
    if (c >= seg_eob)
      break;
295
296
297
298
299
300
    if (c)
      pt = vp9_get_coef_context(scan, nb, pad, token_cache,
                                c, default_eob);
    band = get_coef_band(scan, txfm_size, c);
    prob = coef_probs[type][ref][band][pt];
    fc->eob_branch_counts[txfm_size][type][ref][band][pt]++;
301
302
    if (!vp9_read(r, prob[EOB_CONTEXT_NODE]))
      break;
303
#if CONFIG_CODE_ZEROGROUP
304
305
306
307
308
309
    rc = scan[c];
    o = vp9_get_orientation(rc, txfm_size);
    if (token_cache[rc] == ZERO_TOKEN || is_eoo[o]) {
      coef_counts[type][ref][band][pt][ZERO_TOKEN]++;
      ZEROGROUP_ADVANCE();
      goto SKIP_START;
310
311
312
    }
#endif

Daniel Kang's avatar
Daniel Kang committed
313
SKIP_START:
Dmitry Kovalev's avatar
Dmitry Kovalev committed
314
315
    if (c >= seg_eob)
      break;
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
    if (c)
      pt = vp9_get_coef_context(scan, nb, pad, token_cache,
                                c, default_eob);
    band = get_coef_band(scan, txfm_size, c);
    prob = coef_probs[type][ref][band][pt];
#if CONFIG_CODE_ZEROGROUP
    rc = scan[c];
    o = vp9_get_orientation(rc, txfm_size);
    if (token_cache[rc] == ZERO_TOKEN || is_eoo[o]) {
      ZEROGROUP_ADVANCE();
      goto SKIP_START;
    }
    zprobs = (*zpc_probs)[ref]
             [coef_to_zpc_band(band)]
             [coef_to_zpc_ptok(pt)];
331
#endif
332
    if (!vp9_read(r, prob[ZERO_CONTEXT_NODE])) {
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
#if CONFIG_CODE_ZEROGROUP
      eoo = 0;
#if USE_ZPC_EOORIENT == 1
      use_eoo = vp9_use_eoo(c, seg_eob, scan, txfm_size, is_last_zero, is_eoo);
#else
      use_eoo = 0;
#endif
      if (use_eoo) {
        eoo = !vp9_read(r, zprobs[0]);
        ++(*zpc_count)[ref]
                      [coef_to_zpc_band(band)]
                      [coef_to_zpc_ptok(pt)][0][!eoo];
        if (eoo) {
          is_eoo[o] = 1;
        }
      }
#endif
350
      INCREMENT_COUNT(ZERO_TOKEN);
John Koleszar's avatar
John Koleszar committed
351
352
353
354
      ++c;
      goto SKIP_START;
    }
    // ONE_CONTEXT_NODE_0_
355
    if (!vp9_read(r, prob[ONE_CONTEXT_NODE])) {
356
      WRITE_COEF_CONTINUE(1, ONE_TOKEN);
John Koleszar's avatar
John Koleszar committed
357
358
    }
    // LOW_VAL_CONTEXT_NODE_0_
359
360
    if (!vp9_read(r, prob[LOW_VAL_CONTEXT_NODE])) {
      if (!vp9_read(r, prob[TWO_CONTEXT_NODE])) {
361
        WRITE_COEF_CONTINUE(2, TWO_TOKEN);
John Koleszar's avatar
John Koleszar committed
362
      }
363
      if (!vp9_read(r, prob[THREE_CONTEXT_NODE])) {
364
        WRITE_COEF_CONTINUE(3, THREE_TOKEN);
John Koleszar's avatar
John Koleszar committed
365
      }
366
      WRITE_COEF_CONTINUE(4, FOUR_TOKEN);
John Koleszar's avatar
John Koleszar committed
367
368
    }
    // HIGH_LOW_CONTEXT_NODE_0_
369
370
    if (!vp9_read(r, prob[HIGH_LOW_CONTEXT_NODE])) {
      if (!vp9_read(r, prob[CAT_ONE_CONTEXT_NODE])) {
John Koleszar's avatar
John Koleszar committed
371
372
        val = CAT1_MIN_VAL;
        ADJUST_COEF(CAT1_PROB0, 0);
373
        WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY1);
John Koleszar's avatar
John Koleszar committed
374
375
376
377
      }
      val = CAT2_MIN_VAL;
      ADJUST_COEF(CAT2_PROB1, 1);
      ADJUST_COEF(CAT2_PROB0, 0);
378
      WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY2);
Daniel Kang's avatar
Daniel Kang committed
379
    }
John Koleszar's avatar
John Koleszar committed
380
    // CAT_THREEFOUR_CONTEXT_NODE_0_
381
382
    if (!vp9_read(r, prob[CAT_THREEFOUR_CONTEXT_NODE])) {
      if (!vp9_read(r, prob[CAT_THREE_CONTEXT_NODE])) {
John Koleszar's avatar
John Koleszar committed
383
384
385
386
        val = CAT3_MIN_VAL;
        ADJUST_COEF(CAT3_PROB2, 2);
        ADJUST_COEF(CAT3_PROB1, 1);
        ADJUST_COEF(CAT3_PROB0, 0);
387
        WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY3);
John Koleszar's avatar
John Koleszar committed
388
389
390
391
392
393
      }
      val = CAT4_MIN_VAL;
      ADJUST_COEF(CAT4_PROB3, 3);
      ADJUST_COEF(CAT4_PROB2, 2);
      ADJUST_COEF(CAT4_PROB1, 1);
      ADJUST_COEF(CAT4_PROB0, 0);
394
      WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY4);
John Koleszar's avatar
John Koleszar committed
395
396
    }
    // CAT_FIVE_CONTEXT_NODE_0_:
397
    if (!vp9_read(r, prob[CAT_FIVE_CONTEXT_NODE])) {
John Koleszar's avatar
John Koleszar committed
398
399
400
401
402
403
      val = CAT5_MIN_VAL;
      ADJUST_COEF(CAT5_PROB4, 4);
      ADJUST_COEF(CAT5_PROB3, 3);
      ADJUST_COEF(CAT5_PROB2, 2);
      ADJUST_COEF(CAT5_PROB1, 1);
      ADJUST_COEF(CAT5_PROB0, 0);
404
      WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY5);
John Koleszar's avatar
John Koleszar committed
405
406
407
    }
    val = 0;
    while (*cat6) {
408
      val = (val << 1) | vp9_read(r, *cat6++);
John Koleszar's avatar
John Koleszar committed
409
410
    }
    val += CAT6_MIN_VAL;
411
    WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY6);
John Koleszar's avatar
John Koleszar committed
412
  }
Jingning Han's avatar
Jingning Han committed
413

414
415
416
  if (c < seg_eob)
    coef_counts[type][ref][get_coef_band(scan, txfm_size, c)]
        [pt][DCT_EOB_TOKEN]++;
417

Dmitry Kovalev's avatar
Dmitry Kovalev committed
418
  A0[aidx] = L0[lidx] = c > 0;
419
  if (txfm_size >= TX_8X8) {
420
421
422
423
424
    A0[aidx + 1] = L0[lidx + 1] = A0[aidx];
    if (txfm_size >= TX_16X16) {
      if (type == PLANE_TYPE_UV) {
        ENTROPY_CONTEXT *A1 = (ENTROPY_CONTEXT *) (xd->above_context + 1);
        ENTROPY_CONTEXT *L1 = (ENTROPY_CONTEXT *) (xd->left_context + 1);
425
        A1[aidx] = A1[aidx + 1] = L1[lidx] = L1[lidx + 1] = A0[aidx];
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
        if (txfm_size >= TX_32X32) {
          ENTROPY_CONTEXT *A2 = (ENTROPY_CONTEXT *) (xd->above_context + 2);
          ENTROPY_CONTEXT *L2 = (ENTROPY_CONTEXT *) (xd->left_context + 2);
          ENTROPY_CONTEXT *A3 = (ENTROPY_CONTEXT *) (xd->above_context + 3);
          ENTROPY_CONTEXT *L3 = (ENTROPY_CONTEXT *) (xd->left_context + 3);
          A2[aidx] = A2[aidx + 1] = A3[aidx] = A3[aidx + 1] = A0[aidx];
          L2[lidx] = L2[lidx + 1] = L3[lidx] = L3[lidx + 1] = A0[aidx];
        }
      } else {
        A0[aidx + 2] = A0[aidx + 3] = L0[lidx + 2] = L0[lidx + 3] = A0[aidx];
        if (txfm_size >= TX_32X32) {
          ENTROPY_CONTEXT *A1 = (ENTROPY_CONTEXT *) (xd->above_context + 1);
          ENTROPY_CONTEXT *L1 = (ENTROPY_CONTEXT *) (xd->left_context + 1);
          A1[aidx] = A1[aidx + 1] = A1[aidx + 2] = A1[aidx + 3] = A0[aidx];
          L1[lidx] = L1[lidx + 1] = L1[lidx + 2] = L1[lidx + 3] = A0[aidx];
        }
      }
    }
  }
John Koleszar's avatar
John Koleszar committed
445
  return c;
Daniel Kang's avatar
Daniel Kang committed
446
}
John Koleszar's avatar
John Koleszar committed
447

448
static int get_eob(MACROBLOCKD* const xd, int segment_id, int eob_max) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
449
  return vp9_get_segdata(xd, segment_id, SEG_LVL_SKIP) ? 0 : eob_max;
450
451
}

452

John Koleszar's avatar
John Koleszar committed
453
454
455
struct decode_block_args {
  VP9D_COMP *pbi;
  MACROBLOCKD *xd;
456
  vp9_reader *r;
John Koleszar's avatar
John Koleszar committed
457
458
459
  int *eobtotal;
};
static void decode_block(int plane, int block,
460
                         BLOCK_SIZE_TYPE bsize,
John Koleszar's avatar
John Koleszar committed
461
462
463
                         int ss_txfrm_size,
                         void *argv) {
  const struct decode_block_args* const arg = argv;
464
465
  const int bw = b_width_log2(bsize), bh = b_height_log2(bsize);
  const int old_block_idx = old_block_idx_4x4(arg->xd, bw + bh,
John Koleszar's avatar
John Koleszar committed
466
                                              plane, block);
467
468

  // find the maximum eob for this transform size, adjusted by segment
John Koleszar's avatar
John Koleszar committed
469
470
471
472
  const int segment_id = arg->xd->mode_info_context->mbmi.segment_id;
  const TX_SIZE ss_tx_size = ss_txfrm_size / 2;
  const int seg_eob = get_eob(arg->xd, segment_id, 16 << ss_txfrm_size);
  int16_t* const qcoeff_base = arg->xd->plane[plane].qcoeff;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
473

474
  const int eob = decode_coefs(arg->pbi, arg->xd, arg->r, old_block_idx,
John Koleszar's avatar
John Koleszar committed
475
476
                               arg->xd->plane[plane].plane_type, seg_eob,
                               BLOCK_OFFSET(qcoeff_base, block, 16),
477
478
                               ss_tx_size);

John Koleszar's avatar
John Koleszar committed
479
480
  arg->xd->plane[plane].eobs[block] = eob;
  arg->eobtotal[0] += eob;
481
482
}

483
int vp9_decode_tokens(VP9D_COMP* const pbi,
484
                         MACROBLOCKD* const xd,
485
                         vp9_reader *r,
486
                         BLOCK_SIZE_TYPE bsize) {
John Koleszar's avatar
John Koleszar committed
487
  int eobtotal = 0;
488
  struct decode_block_args args = {pbi, xd, r, &eobtotal};
489
  foreach_transformed_block(xd, bsize, decode_block, &args);
John Koleszar's avatar
John Koleszar committed
490
  return eobtotal;
491
492
}

493
#if CONFIG_NEWBINTRAMODES
494
static int decode_coefs_4x4(VP9D_COMP *dx, MACROBLOCKD *xd,
495
                            vp9_reader *r,
496
                            PLANE_TYPE type, int i, int seg_eob) {
John Koleszar's avatar
John Koleszar committed
497
  const struct plane_block_idx pb_idx = plane_block_idx(16, i);
498
  const int c = decode_coefs(dx, xd, r, i, type, seg_eob,
John Koleszar's avatar
John Koleszar committed
499
500
      BLOCK_OFFSET(xd->plane[pb_idx.plane].qcoeff, pb_idx.block, 16), TX_4X4);
  xd->plane[pb_idx.plane].eobs[pb_idx.block] = c;
501
502
503
504
505
  return c;
}

static int decode_mb_tokens_4x4_uv(VP9D_COMP* const dx,
                                   MACROBLOCKD* const xd,
506
                                   vp9_reader *r,
507
                                   int seg_eob) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
508
  int i, eobtotal = 0;
509

510
  // chroma blocks
Dmitry Kovalev's avatar
Dmitry Kovalev committed
511
  for (i = 16; i < 24; i++)
512
    eobtotal += decode_coefs_4x4(dx, xd, r, PLANE_TYPE_UV, i, seg_eob);
513
514
515
516

  return eobtotal;
}

517
518
int vp9_decode_mb_tokens_4x4_uv(VP9D_COMP* const dx,
                                MACROBLOCKD* const xd,
519
                                vp9_reader *r) {
520
521
522
  const int segment_id = xd->mode_info_context->mbmi.segment_id;
  const int seg_eob = get_eob(xd, segment_id, 16);

523
  return decode_mb_tokens_4x4_uv(dx, xd, r, seg_eob);
524
525
}

526
int vp9_decode_coefs_4x4(VP9D_COMP *dx, MACROBLOCKD *xd,
527
                         vp9_reader *r,
528
529
530
                         PLANE_TYPE type, int i) {
  const int segment_id = xd->mode_info_context->mbmi.segment_id;
  const int seg_eob = get_eob(xd, segment_id, 16);
531
  return decode_coefs_4x4(dx, xd, r, type, i, seg_eob);
532
533
}
#endif