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


12
#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 424 425
  int *eobtotal;
};
static void decode_block(int plane, int block,
426
                         BLOCK_SIZE_TYPE bsize,
John Koleszar's avatar
John Koleszar committed
427 428 429
                         int ss_txfrm_size,
                         void *argv) {
  const struct decode_block_args* const arg = argv;
430 431
  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
432
                                              plane, block);
433 434

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

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

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

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

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

static int decode_mb_tokens_4x4_uv(VP9D_COMP* const dx,
                                   MACROBLOCKD* const xd,
473
                                   vp9_reader *r,
474
                                   int seg_eob) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
475
  int i, eobtotal = 0;
476

477
  // chroma blocks
Dmitry Kovalev's avatar
Dmitry Kovalev committed
478
  for (i = 16; i < 24; i++)
479
    eobtotal += decode_coefs_4x4(dx, xd, r, PLANE_TYPE_UV, i, seg_eob);
480 481 482 483

  return eobtotal;
}

484 485
int vp9_decode_mb_tokens_4x4_uv(VP9D_COMP* const dx,
                                MACROBLOCKD* const xd,
486
                                vp9_reader *r) {
487 488 489
  const int segment_id = xd->mode_info_context->mbmi.segment_id;
  const int seg_eob = get_eob(xd, segment_id, 16);

490
  return decode_mb_tokens_4x4_uv(dx, xd, r, seg_eob);
491 492
}

493
int vp9_decode_coefs_4x4(VP9D_COMP *dx, MACROBLOCKD *xd,
494
                         vp9_reader *r,
495
                         PLANE_TYPE type, int i) {
496 497
  const int segment_id = xd->mode_info_context->mbmi.segment_id;
  const int seg_eob = get_eob(xd, segment_id, 16);
498
  return decode_coefs_4x4(dx, xd, r, type, i, seg_eob);
499 500
}
#endif