vp9_detokenize.c 17.9 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) * dq[c > 0]; \
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
                        PLANE_TYPE type, int seg_eob, int16_t *qcoeff_ptr,
109
                        TX_SIZE txfm_size, const int16_t *dq) {
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
  } 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];
145
146
147
  } 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];
148
149
150
151
152
153
  } 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];
154
155
156
157
158
  } else {
    aidx = vp9_block2above[txfm_size][block_idx];
    lidx = vp9_block2left[txfm_size][block_idx];
  }

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

252
  pt = combine_entropy_contexts(above_ec, left_ec);
253
254
  nb = vp9_get_coef_neighbors_handle(scan, &pad);

John Koleszar's avatar
John Koleszar committed
255
256
  while (1) {
    int val;
257
    int band;
John Koleszar's avatar
John Koleszar committed
258
    const uint8_t *cat6 = cat6_prob;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
259
260
    if (c >= seg_eob)
      break;
261
262
263
264
265
266
    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]++;
267
268
    if (!vp9_read(r, prob[EOB_CONTEXT_NODE]))
      break;
269
#if CONFIG_CODE_ZEROGROUP
270
271
272
273
274
275
    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;
276
277
278
    }
#endif

Daniel Kang's avatar
Daniel Kang committed
279
SKIP_START:
Dmitry Kovalev's avatar
Dmitry Kovalev committed
280
281
    if (c >= seg_eob)
      break;
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
    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)];
297
#endif
298
    if (!vp9_read(r, prob[ZERO_CONTEXT_NODE])) {
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
#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
316
      INCREMENT_COUNT(ZERO_TOKEN);
John Koleszar's avatar
John Koleszar committed
317
318
319
320
      ++c;
      goto SKIP_START;
    }
    // ONE_CONTEXT_NODE_0_
321
    if (!vp9_read(r, prob[ONE_CONTEXT_NODE])) {
322
      WRITE_COEF_CONTINUE(1, ONE_TOKEN);
John Koleszar's avatar
John Koleszar committed
323
324
    }
    // LOW_VAL_CONTEXT_NODE_0_
325
326
    if (!vp9_read(r, prob[LOW_VAL_CONTEXT_NODE])) {
      if (!vp9_read(r, prob[TWO_CONTEXT_NODE])) {
327
        WRITE_COEF_CONTINUE(2, TWO_TOKEN);
John Koleszar's avatar
John Koleszar committed
328
      }
329
      if (!vp9_read(r, prob[THREE_CONTEXT_NODE])) {
330
        WRITE_COEF_CONTINUE(3, THREE_TOKEN);
John Koleszar's avatar
John Koleszar committed
331
      }
332
      WRITE_COEF_CONTINUE(4, FOUR_TOKEN);
John Koleszar's avatar
John Koleszar committed
333
334
    }
    // HIGH_LOW_CONTEXT_NODE_0_
335
336
    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
337
338
        val = CAT1_MIN_VAL;
        ADJUST_COEF(CAT1_PROB0, 0);
339
        WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY1);
John Koleszar's avatar
John Koleszar committed
340
341
342
343
      }
      val = CAT2_MIN_VAL;
      ADJUST_COEF(CAT2_PROB1, 1);
      ADJUST_COEF(CAT2_PROB0, 0);
344
      WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY2);
Daniel Kang's avatar
Daniel Kang committed
345
    }
John Koleszar's avatar
John Koleszar committed
346
    // CAT_THREEFOUR_CONTEXT_NODE_0_
347
348
    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
349
350
351
352
        val = CAT3_MIN_VAL;
        ADJUST_COEF(CAT3_PROB2, 2);
        ADJUST_COEF(CAT3_PROB1, 1);
        ADJUST_COEF(CAT3_PROB0, 0);
353
        WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY3);
John Koleszar's avatar
John Koleszar committed
354
355
356
357
358
359
      }
      val = CAT4_MIN_VAL;
      ADJUST_COEF(CAT4_PROB3, 3);
      ADJUST_COEF(CAT4_PROB2, 2);
      ADJUST_COEF(CAT4_PROB1, 1);
      ADJUST_COEF(CAT4_PROB0, 0);
360
      WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY4);
John Koleszar's avatar
John Koleszar committed
361
362
    }
    // CAT_FIVE_CONTEXT_NODE_0_:
363
    if (!vp9_read(r, prob[CAT_FIVE_CONTEXT_NODE])) {
John Koleszar's avatar
John Koleszar committed
364
365
366
367
368
369
      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);
370
      WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY5);
John Koleszar's avatar
John Koleszar committed
371
372
373
    }
    val = 0;
    while (*cat6) {
374
      val = (val << 1) | vp9_read(r, *cat6++);
John Koleszar's avatar
John Koleszar committed
375
376
    }
    val += CAT6_MIN_VAL;
377
    WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY6);
John Koleszar's avatar
John Koleszar committed
378
  }
Jingning Han's avatar
Jingning Han committed
379

380
381
382
  if (c < seg_eob)
    coef_counts[type][ref][get_coef_band(scan, txfm_size, c)]
        [pt][DCT_EOB_TOKEN]++;
383

Dmitry Kovalev's avatar
Dmitry Kovalev committed
384
  A0[aidx] = L0[lidx] = c > 0;
385
  if (txfm_size >= TX_8X8) {
386
387
388
389
390
    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);
391
        A1[aidx] = A1[aidx + 1] = L1[lidx] = L1[lidx + 1] = A0[aidx];
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
        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
411
  return c;
Daniel Kang's avatar
Daniel Kang committed
412
}
John Koleszar's avatar
John Koleszar committed
413

414
static int get_eob(MACROBLOCKD* const xd, int segment_id, int eob_max) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
415
  return vp9_get_segdata(xd, segment_id, SEG_LVL_SKIP) ? 0 : eob_max;
416
417
}

418

John Koleszar's avatar
John Koleszar committed
419
420
421
struct decode_block_args {
  VP9D_COMP *pbi;
  MACROBLOCKD *xd;
422
  vp9_reader *r;
John Koleszar's avatar
John Koleszar committed
423
  int *eobtotal;
424
  const int16_t *dq;
John Koleszar's avatar
John Koleszar committed
425
426
};
static void decode_block(int plane, int block,
427
                         BLOCK_SIZE_TYPE bsize,
John Koleszar's avatar
John Koleszar committed
428
429
430
                         int ss_txfrm_size,
                         void *argv) {
  const struct decode_block_args* const arg = argv;
431
432
  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
433
                                              plane, block);
434
435

  // find the maximum eob for this transform size, adjusted by segment
John Koleszar's avatar
John Koleszar committed
436
437
438
439
  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
440

441
  const int eob = decode_coefs(arg->pbi, arg->xd, arg->r, old_block_idx,
John Koleszar's avatar
John Koleszar committed
442
443
                               arg->xd->plane[plane].plane_type, seg_eob,
                               BLOCK_OFFSET(qcoeff_base, block, 16),
444
                               ss_tx_size, arg->dq);
445

John Koleszar's avatar
John Koleszar committed
446
447
  arg->xd->plane[plane].eobs[block] = eob;
  arg->eobtotal[0] += eob;
448
449
}

450
int vp9_decode_tokens(VP9D_COMP* const pbi,
451
                         MACROBLOCKD* const xd,
452
                         vp9_reader *r,
453
454
                         BLOCK_SIZE_TYPE bsize,
                         const int16_t *dq) {
John Koleszar's avatar
John Koleszar committed
455
  int eobtotal = 0;
456
  struct decode_block_args args = {pbi, xd, r, &eobtotal, dq};
457
  foreach_transformed_block(xd, bsize, decode_block, &args);
John Koleszar's avatar
John Koleszar committed
458
  return eobtotal;
459
460
}

461
#if CONFIG_NEWBINTRAMODES
462
static int decode_coefs_4x4(VP9D_COMP *dx, MACROBLOCKD *xd,
463
                            vp9_reader *r,
464
465
                            PLANE_TYPE type, int i, int seg_eob,
                            const int16_t *dq) {
John Koleszar's avatar
John Koleszar committed
466
  const struct plane_block_idx pb_idx = plane_block_idx(16, i);
467
  const int c = decode_coefs(dx, xd, r, i, type, seg_eob,
468
469
      BLOCK_OFFSET(xd->plane[pb_idx.plane].qcoeff, pb_idx.block, 16), TX_4X4,
      dq);
John Koleszar's avatar
John Koleszar committed
470
  xd->plane[pb_idx.plane].eobs[pb_idx.block] = c;
471
472
473
474
475
  return c;
}

static int decode_mb_tokens_4x4_uv(VP9D_COMP* const dx,
                                   MACROBLOCKD* const xd,
476
                                   vp9_reader *r,
477
478
                                   int seg_eob,
                                   const int16_t *dq) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
479
  int i, eobtotal = 0;
480

481
  // chroma blocks
Dmitry Kovalev's avatar
Dmitry Kovalev committed
482
  for (i = 16; i < 24; i++)
483
    eobtotal += decode_coefs_4x4(dx, xd, r, PLANE_TYPE_UV, i, seg_eob, dq);
484
485
486
487

  return eobtotal;
}

488
489
int vp9_decode_mb_tokens_4x4_uv(VP9D_COMP* const dx,
                                MACROBLOCKD* const xd,
490
                                vp9_reader *r, const int16_t *dq) {
491
492
493
  const int segment_id = xd->mode_info_context->mbmi.segment_id;
  const int seg_eob = get_eob(xd, segment_id, 16);

494
  return decode_mb_tokens_4x4_uv(dx, xd, r, seg_eob, dq);
495
496
}

497
int vp9_decode_coefs_4x4(VP9D_COMP *dx, MACROBLOCKD *xd,
498
                         vp9_reader *r,
499
                         PLANE_TYPE type, int i, const int16_t *dq) {
500
501
  const int segment_id = xd->mode_info_context->mbmi.segment_id;
  const int seg_eob = get_eob(xd, segment_id, 16);
502
  return decode_coefs_4x4(dx, xd, r, type, i, seg_eob, dq);
503
504
}
#endif