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


12
#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
#define INCREMENT_COUNT(token)               \
  do {                                       \
65
66
    coef_counts[type][ref][get_coef_band(scan, txfm_size, c)] \
               [pt][token]++;     \
67
    token_cache[c] = token; \
68
    pt = vp9_get_coef_context(scan, nb, pad, token_cache,     \
69
                              c + 1, default_eob); \
70
71
  } while (0)

72
#if CONFIG_CODE_NONZEROCOUNT
73
#define WRITE_COEF_CONTINUE(val, token)                       \
Daniel Kang's avatar
Daniel Kang committed
74
  {                                                           \
75
    qcoeff_ptr[scan[c]] = vp9_read_and_apply_sign(br, val);   \
76
    INCREMENT_COUNT(token);                                   \
John Koleszar's avatar
John Koleszar committed
77
    c++;                                                      \
Dmitry Kovalev's avatar
Dmitry Kovalev committed
78
    nzc++;                                                    \
John Koleszar's avatar
John Koleszar committed
79
80
    continue;                                                 \
  }
81
#else
Dmitry Kovalev's avatar
Dmitry Kovalev committed
82
83
#define WRITE_COEF_CONTINUE(val, token)                  \
  {                                                      \
84
    qcoeff_ptr[scan[c]] = vp9_read_and_apply_sign(br, val); \
Dmitry Kovalev's avatar
Dmitry Kovalev committed
85
86
87
    INCREMENT_COUNT(token);                              \
    c++;                                                 \
    continue;                                            \
88
89
  }
#endif  // CONFIG_CODE_NONZEROCOUNT
John Koleszar's avatar
John Koleszar committed
90

Daniel Kang's avatar
Daniel Kang committed
91
92
#define ADJUST_COEF(prob, bits_count)  \
  do {                                 \
93
    if (vp9_read(br, prob))            \
Dmitry Kovalev's avatar
Dmitry Kovalev committed
94
      val += 1 << bits_count;          \
John Koleszar's avatar
John Koleszar committed
95
  } while (0);
John Koleszar's avatar
John Koleszar committed
96

97
static int decode_coefs(VP9D_COMP *dx, const MACROBLOCKD *xd,
98
                        BOOL_DECODER* const br, int block_idx,
99
100
                        PLANE_TYPE type, int seg_eob, int16_t *qcoeff_ptr,
                        TX_SIZE txfm_size) {
101
102
  ENTROPY_CONTEXT* const A0 = (ENTROPY_CONTEXT *) xd->above_context;
  ENTROPY_CONTEXT* const L0 = (ENTROPY_CONTEXT *) xd->left_context;
103
104
  int aidx, lidx;
  ENTROPY_CONTEXT above_ec, left_ec;
John Koleszar's avatar
John Koleszar committed
105
  FRAME_CONTEXT *const fc = &dx->common.fc;
106
  int pt, c = 0, pad, default_eob;
107
108
109
  vp9_coeff_probs *coef_probs;
  vp9_prob *prob;
  vp9_coeff_count *coef_counts;
110
  const int ref = xd->mode_info_context->mbmi.ref_frame != INTRA_FRAME;
111
#if CONFIG_CODE_NONZEROCOUNT
112
  const int nzc_used = get_nzc_used(txfm_size);
113
  uint16_t nzc = 0;
114
115
  uint16_t nzc_expected =
      nzc_used ? xd->mode_info_context->mbmi.nzcs[block_idx] : 0;
116
#endif
117
118
  const int *scan, *nb;
  uint8_t token_cache[1024];
Daniel Kang's avatar
Daniel Kang committed
119

120
121
122
  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];
123
124
125
126
127
128
129
130
#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
131
132
133
  } 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];
134
135
136
137
138
139
140
141
#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
142
143
144
145
146
  } else {
    aidx = vp9_block2above[txfm_size][block_idx];
    lidx = vp9_block2left[txfm_size][block_idx];
  }

147
  switch (txfm_size) {
Daniel Kang's avatar
Daniel Kang committed
148
    default:
149
    case TX_4X4: {
150
151
      const TX_TYPE tx_type = (type == PLANE_TYPE_Y_WITH_DC) ?
                              get_tx_type_4x4(xd, block_idx) : DCT_DCT;
152
153
154
155
156
157
158
159
160
161
162
      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;
      }
163
164
      above_ec = A0[aidx] != 0;
      left_ec = L0[lidx] != 0;
165
166
      coef_probs  = fc->coef_probs_4x4;
      coef_counts = fc->coef_counts_4x4;
167
      default_eob = 16;
Daniel Kang's avatar
Daniel Kang committed
168
      break;
169
    }
170
171
    case TX_8X8: {
      const BLOCK_SIZE_TYPE sb_type = xd->mode_info_context->mbmi.sb_type;
172
173
      const int sz = 3 + mb_width_log2(sb_type);
      const int x = block_idx & ((1 << sz) - 1);
174
175
176
177
178
179
180
181
182
183
184
185
186
187
      const int y = block_idx - x;
      const TX_TYPE tx_type = (type == PLANE_TYPE_Y_WITH_DC) ?
                              get_tx_type_8x8(xd, y + (x >> 1)) : DCT_DCT;
      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;
      }
188
189
      coef_probs  = fc->coef_probs_8x8;
      coef_counts = fc->coef_counts_8x8;
190
191
      above_ec = (A0[aidx] + A0[aidx + 1]) != 0;
      left_ec  = (L0[lidx] + L0[lidx + 1]) != 0;
192
      default_eob = 64;
Daniel Kang's avatar
Daniel Kang committed
193
      break;
194
195
196
    }
    case TX_16X16: {
      const BLOCK_SIZE_TYPE sb_type = xd->mode_info_context->mbmi.sb_type;
197
198
      const int sz = 4 + mb_width_log2(sb_type);
      const int x = block_idx & ((1 << sz) - 1);
199
200
201
202
203
204
205
206
207
208
209
210
211
212
      const int y = block_idx - x;
      const TX_TYPE tx_type = (type == PLANE_TYPE_Y_WITH_DC) ?
                              get_tx_type_16x16(xd, y + (x >> 2)) : DCT_DCT;
      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;
      }
213
214
      coef_probs  = fc->coef_probs_16x16;
      coef_counts = fc->coef_counts_16x16;
215
216
217
218
219
      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;
220
      } else {
221
222
223
        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;
      }
224
      default_eob = 256;
Daniel Kang's avatar
Daniel Kang committed
225
      break;
226
    }
227
    case TX_32X32:
228
      scan = vp9_default_zig_zag1d_32x32;
229
230
      coef_probs = fc->coef_probs_32x32;
      coef_counts = fc->coef_counts_32x32;
231
232
233
234
235
236
237
238
239
240
241
      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;
242
      } else {
243
244
245
246
247
248
249
        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;
      }
250
      default_eob = 1024;
251
      break;
Daniel Kang's avatar
Daniel Kang committed
252
  }
John Koleszar's avatar
John Koleszar committed
253

254
  pt = combine_entropy_contexts(above_ec, left_ec);
255
256
  nb = vp9_get_coef_neighbors_handle(scan, &pad);

John Koleszar's avatar
John Koleszar committed
257
258
259
  while (1) {
    int val;
    const uint8_t *cat6 = cat6_prob;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
260
261
262

    if (c >= seg_eob)
      break;
263
#if CONFIG_CODE_NONZEROCOUNT
264
    if (nzc_used && nzc == nzc_expected)
265
266
      break;
#endif
267
    prob = coef_probs[type][ref][get_coef_band(scan, txfm_size, c)][pt];
268
    fc->eob_branch_counts[txfm_size][type][ref]
269
                         [get_coef_band(scan, txfm_size, c)][pt]++;
270
271
#if CONFIG_CODE_NONZEROCOUNT
    if (!nzc_used)
272
#endif
273
274
      if (!vp9_read(br, prob[EOB_CONTEXT_NODE]))
        break;
Daniel Kang's avatar
Daniel Kang committed
275
SKIP_START:
Dmitry Kovalev's avatar
Dmitry Kovalev committed
276
277
    if (c >= seg_eob)
      break;
278
#if CONFIG_CODE_NONZEROCOUNT
279
    if (nzc_used && nzc == nzc_expected)
280
281
      break;
    // decode zero node only if there are zeros left
282
    if (!nzc_used || seg_eob - nzc_expected - c + nzc > 0)
283
#endif
284
    if (!vp9_read(br, prob[ZERO_CONTEXT_NODE])) {
285
      INCREMENT_COUNT(ZERO_TOKEN);
John Koleszar's avatar
John Koleszar committed
286
      ++c;
287
      prob = coef_probs[type][ref][get_coef_band(scan, txfm_size, c)][pt];
John Koleszar's avatar
John Koleszar committed
288
289
290
      goto SKIP_START;
    }
    // ONE_CONTEXT_NODE_0_
291
    if (!vp9_read(br, prob[ONE_CONTEXT_NODE])) {
292
      WRITE_COEF_CONTINUE(1, ONE_TOKEN);
John Koleszar's avatar
John Koleszar committed
293
294
    }
    // LOW_VAL_CONTEXT_NODE_0_
295
296
    if (!vp9_read(br, prob[LOW_VAL_CONTEXT_NODE])) {
      if (!vp9_read(br, prob[TWO_CONTEXT_NODE])) {
297
        WRITE_COEF_CONTINUE(2, TWO_TOKEN);
John Koleszar's avatar
John Koleszar committed
298
      }
299
      if (!vp9_read(br, prob[THREE_CONTEXT_NODE])) {
300
        WRITE_COEF_CONTINUE(3, THREE_TOKEN);
John Koleszar's avatar
John Koleszar committed
301
      }
302
      WRITE_COEF_CONTINUE(4, FOUR_TOKEN);
John Koleszar's avatar
John Koleszar committed
303
304
    }
    // HIGH_LOW_CONTEXT_NODE_0_
305
306
    if (!vp9_read(br, prob[HIGH_LOW_CONTEXT_NODE])) {
      if (!vp9_read(br, prob[CAT_ONE_CONTEXT_NODE])) {
John Koleszar's avatar
John Koleszar committed
307
308
        val = CAT1_MIN_VAL;
        ADJUST_COEF(CAT1_PROB0, 0);
309
        WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY1);
John Koleszar's avatar
John Koleszar committed
310
311
312
313
      }
      val = CAT2_MIN_VAL;
      ADJUST_COEF(CAT2_PROB1, 1);
      ADJUST_COEF(CAT2_PROB0, 0);
314
      WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY2);
Daniel Kang's avatar
Daniel Kang committed
315
    }
John Koleszar's avatar
John Koleszar committed
316
    // CAT_THREEFOUR_CONTEXT_NODE_0_
317
318
    if (!vp9_read(br, prob[CAT_THREEFOUR_CONTEXT_NODE])) {
      if (!vp9_read(br, prob[CAT_THREE_CONTEXT_NODE])) {
John Koleszar's avatar
John Koleszar committed
319
320
321
322
        val = CAT3_MIN_VAL;
        ADJUST_COEF(CAT3_PROB2, 2);
        ADJUST_COEF(CAT3_PROB1, 1);
        ADJUST_COEF(CAT3_PROB0, 0);
323
        WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY3);
John Koleszar's avatar
John Koleszar committed
324
325
326
327
328
329
      }
      val = CAT4_MIN_VAL;
      ADJUST_COEF(CAT4_PROB3, 3);
      ADJUST_COEF(CAT4_PROB2, 2);
      ADJUST_COEF(CAT4_PROB1, 1);
      ADJUST_COEF(CAT4_PROB0, 0);
330
      WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY4);
John Koleszar's avatar
John Koleszar committed
331
332
    }
    // CAT_FIVE_CONTEXT_NODE_0_:
333
    if (!vp9_read(br, prob[CAT_FIVE_CONTEXT_NODE])) {
John Koleszar's avatar
John Koleszar committed
334
335
336
337
338
339
      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);
340
      WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY5);
John Koleszar's avatar
John Koleszar committed
341
342
343
    }
    val = 0;
    while (*cat6) {
344
      val = (val << 1) | vp9_read(br, *cat6++);
John Koleszar's avatar
John Koleszar committed
345
346
    }
    val += CAT6_MIN_VAL;
347
    WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY6);
John Koleszar's avatar
John Koleszar committed
348
  }
Jingning Han's avatar
Jingning Han committed
349

350
351
352
353
354
355
356
357
358
359
360
#if CONFIG_CODE_NONZEROCOUNT
  if (!nzc_used)
#endif
    if (c < seg_eob)
      coef_counts[type][ref][get_coef_band(scan, txfm_size, c)]
                 [pt][DCT_EOB_TOKEN]++;
#if CONFIG_CODE_NONZEROCOUNT
  if (!nzc_used)
    xd->mode_info_context->mbmi.nzcs[block_idx] = nzc;
  else
    assert(nzc == nzc_expected);
361
#endif
362

Dmitry Kovalev's avatar
Dmitry Kovalev committed
363
  A0[aidx] = L0[lidx] = c > 0;
364
  if (txfm_size >= TX_8X8) {
365
366
367
368
369
    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);
370
        A1[aidx] = A1[aidx + 1] = L1[lidx] = L1[lidx + 1] = A0[aidx];
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
        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
390
  return c;
Daniel Kang's avatar
Daniel Kang committed
391
}
John Koleszar's avatar
John Koleszar committed
392

393
static int get_eob(MACROBLOCKD* const xd, int segment_id, int eob_max) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
394
  return vp9_get_segdata(xd, segment_id, SEG_LVL_SKIP) ? 0 : eob_max;
395
396
}

397

John Koleszar's avatar
John Koleszar committed
398
399
400
401
402
403
404
struct decode_block_args {
  VP9D_COMP *pbi;
  MACROBLOCKD *xd;
  BOOL_DECODER *bc;
  int *eobtotal;
};
static void decode_block(int plane, int block,
405
                         BLOCK_SIZE_TYPE bsize,
John Koleszar's avatar
John Koleszar committed
406
407
408
                         int ss_txfrm_size,
                         void *argv) {
  const struct decode_block_args* const arg = argv;
409
410
  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
411
                                              plane, block);
412
413

  // find the maximum eob for this transform size, adjusted by segment
John Koleszar's avatar
John Koleszar committed
414
415
416
417
  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
418

John Koleszar's avatar
John Koleszar committed
419
420
421
  const int eob = decode_coefs(arg->pbi, arg->xd, arg->bc, old_block_idx,
                               arg->xd->plane[plane].plane_type, seg_eob,
                               BLOCK_OFFSET(qcoeff_base, block, 16),
422
423
                               ss_tx_size);

John Koleszar's avatar
John Koleszar committed
424
425
  arg->xd->plane[plane].eobs[block] = eob;
  arg->eobtotal[0] += eob;
426
427
}

428
int vp9_decode_tokens(VP9D_COMP* const pbi,
429
                         MACROBLOCKD* const xd,
430
431
                         BOOL_DECODER* const bc,
                         BLOCK_SIZE_TYPE bsize) {
John Koleszar's avatar
John Koleszar committed
432
433
  int eobtotal = 0;
  struct decode_block_args args = {pbi, xd, bc, &eobtotal};
434
  foreach_transformed_block(xd, bsize, decode_block, &args);
John Koleszar's avatar
John Koleszar committed
435
  return eobtotal;
436
437
}

438
#if CONFIG_NEWBINTRAMODES
439
440
static int decode_coefs_4x4(VP9D_COMP *dx, MACROBLOCKD *xd,
                            BOOL_DECODER* const bc,
441
                            PLANE_TYPE type, int i, int seg_eob) {
John Koleszar's avatar
John Koleszar committed
442
  const struct plane_block_idx pb_idx = plane_block_idx(16, i);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
443
  const int c = decode_coefs(dx, xd, bc, i, type, seg_eob,
John Koleszar's avatar
John Koleszar committed
444
445
      BLOCK_OFFSET(xd->plane[pb_idx.plane].qcoeff, pb_idx.block, 16), TX_4X4);
  xd->plane[pb_idx.plane].eobs[pb_idx.block] = c;
446
447
448
449
450
451
452
  return c;
}

static int decode_mb_tokens_4x4_uv(VP9D_COMP* const dx,
                                   MACROBLOCKD* const xd,
                                   BOOL_DECODER* const bc,
                                   int seg_eob) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
453
  int i, eobtotal = 0;
454

455
  // chroma blocks
Dmitry Kovalev's avatar
Dmitry Kovalev committed
456
  for (i = 16; i < 24; i++)
457
    eobtotal += decode_coefs_4x4(dx, xd, bc, PLANE_TYPE_UV, i, seg_eob);
458
459
460
461

  return eobtotal;
}

462
463
464
465
466
467
468
469
470
int vp9_decode_mb_tokens_4x4_uv(VP9D_COMP* const dx,
                                MACROBLOCKD* const xd,
                                BOOL_DECODER* const bc) {
  const int segment_id = xd->mode_info_context->mbmi.segment_id;
  const int seg_eob = get_eob(xd, segment_id, 16);

  return decode_mb_tokens_4x4_uv(dx, xd, bc, seg_eob);
}

471
472
473
474
475
476
477
478
int vp9_decode_coefs_4x4(VP9D_COMP *dx, MACROBLOCKD *xd,
                         BOOL_DECODER* const bc,
                         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);
  return decode_coefs_4x4(dx, xd, bc, type, i, seg_eob);
}
#endif