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

John Koleszar's avatar
John Koleszar committed
19 20 21 22 23 24 25 26 27 28 29 30
#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
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
#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

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

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

62
static int get_signed(BOOL_DECODER *br, int value_to_sign) {
63
  return decode_bool(br, 128) ? -value_to_sign : value_to_sign;
Daniel Kang's avatar
Daniel Kang committed
64
}
John Koleszar's avatar
John Koleszar committed
65

66 67
#define INCREMENT_COUNT(token)               \
  do {                                       \
68 69
    coef_counts[type][ref][get_coef_band(scan, txfm_size, c)] \
               [pt][token]++;     \
70
    token_cache[c] = token; \
71 72
    pt = vp9_get_coef_context(scan, nb, pad, token_cache,     \
                              c, default_eob); \
73 74
  } while (0)

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

Daniel Kang's avatar
Daniel Kang committed
94 95
#define ADJUST_COEF(prob, bits_count)  \
  do {                                 \
96
    if (vp9_read(br, prob))            \
John Koleszar's avatar
John Koleszar committed
97
      val += (uint16_t)(1 << bits_count);\
John Koleszar's avatar
John Koleszar committed
98
  } while (0);
John Koleszar's avatar
John Koleszar committed
99

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

121 122 123 124 125 126 127 128 129 130 131
  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];
  } 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];
  } else {
    aidx = vp9_block2above[txfm_size][block_idx];
    lidx = vp9_block2left[txfm_size][block_idx];
  }

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

237
  VP9_COMBINEENTROPYCONTEXTS(pt, above_ec, left_ec);
238 239
  nb = vp9_get_coef_neighbors_handle(scan, &pad);

John Koleszar's avatar
John Koleszar committed
240 241 242
  while (1) {
    int val;
    const uint8_t *cat6 = cat6_prob;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
243 244 245

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

332
#if CONFIG_CODE_NONZEROCOUNT == 0
333
  if (c < seg_eob)
334 335
    coef_counts[type][ref][get_coef_band(scan, txfm_size, c)]
               [pt][DCT_EOB_TOKEN]++;
336
#endif
337

Dmitry Kovalev's avatar
Dmitry Kovalev committed
338
  A0[aidx] = L0[lidx] = c > 0;
339
  if (txfm_size >= TX_8X8) {
340 341 342 343 344
    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);
345
        A1[aidx] = A1[aidx + 1] = L1[lidx] = L1[lidx + 1] = A0[aidx];
346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364
        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
365
  return c;
Daniel Kang's avatar
Daniel Kang committed
366
}
John Koleszar's avatar
John Koleszar committed
367

368
static int get_eob(MACROBLOCKD* const xd, int segment_id, int eob_max) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
369
  return vp9_get_segdata(xd, segment_id, SEG_LVL_SKIP) ? 0 : eob_max;
370 371
}

372 373 374 375
int vp9_decode_sb_tokens(VP9D_COMP* const pbi,
                         MACROBLOCKD* const xd,
                         BOOL_DECODER* const bc) {
  const int segment_id = xd->mode_info_context->mbmi.segment_id;
376
  int i, eobtotal = 0, seg_eob, c;
377

378 379 380 381
  switch (xd->mode_info_context->mbmi.txfm_size) {
    case TX_32X32:
      // Luma block
      c = decode_coefs(pbi, xd, bc, 0, PLANE_TYPE_Y_WITH_DC,
382
                       get_eob(xd, segment_id, 1024), xd->qcoeff, TX_32X32);
383 384 385 386 387 388
      xd->eobs[0] = c;
      eobtotal += c;

      // 16x16 chroma blocks
      seg_eob = get_eob(xd, segment_id, 256);
      for (i = 64; i < 96; i += 16) {
389 390
        c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_UV, seg_eob,
                         xd->qcoeff + i * 16, TX_16X16);
391 392 393 394 395 396 397 398 399
        xd->eobs[i] = c;
        eobtotal += c;
      }
      break;
    case TX_16X16:
      // 16x16 luma blocks
      seg_eob = get_eob(xd, segment_id, 256);
      for (i = 0; i < 64; i += 16) {
        c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_Y_WITH_DC,
400
                         seg_eob, xd->qcoeff + i * 16, TX_16X16);
401 402 403 404 405 406
        xd->eobs[i] = c;
        eobtotal += c;
      }

      // 16x16 chroma blocks
      for (i = 64; i < 96; i += 16) {
407 408
        c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_UV, seg_eob,
                         xd->qcoeff + i * 16, TX_16X16);
409 410 411 412 413 414 415 416 417
        xd->eobs[i] = c;
        eobtotal += c;
      }
      break;
    case TX_8X8:
      // 8x8 luma blocks
      seg_eob = get_eob(xd, segment_id, 64);
      for (i = 0; i < 64; i += 4) {
        c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_Y_WITH_DC,
418
                         seg_eob, xd->qcoeff + i * 16, TX_8X8);
419 420 421 422 423 424
        xd->eobs[i] = c;
        eobtotal += c;
      }

      // 8x8 chroma blocks
      for (i = 64; i < 96; i += 4) {
425 426
        c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_UV, seg_eob,
                         xd->qcoeff + i * 16, TX_8X8);
427 428 429 430 431 432 433 434 435
        xd->eobs[i] = c;
        eobtotal += c;
      }
      break;
    case TX_4X4:
      // 4x4 luma blocks
      seg_eob = get_eob(xd, segment_id, 16);
      for (i = 0; i < 64; i++) {
        c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_Y_WITH_DC,
436
                         seg_eob, xd->qcoeff + i * 16, TX_4X4);
437 438 439 440 441 442
        xd->eobs[i] = c;
        eobtotal += c;
      }

      // 4x4 chroma blocks
      for (i = 64; i < 96; i++) {
443 444
        c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_UV, seg_eob,
                         xd->qcoeff + i * 16, TX_4X4);
445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466
        xd->eobs[i] = c;
        eobtotal += c;
      }
      break;
    default: assert(0);
  }

  return eobtotal;
}

int vp9_decode_sb64_tokens(VP9D_COMP* const pbi,
                           MACROBLOCKD* const xd,
                           BOOL_DECODER* const bc) {
  const int segment_id = xd->mode_info_context->mbmi.segment_id;
  int i, eobtotal = 0, seg_eob, c;

  switch (xd->mode_info_context->mbmi.txfm_size) {
    case TX_32X32:
      // Luma block
      seg_eob = get_eob(xd, segment_id, 1024);
      for (i = 0; i < 256; i += 64) {
        c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_Y_WITH_DC,
467
                         seg_eob, xd->qcoeff + i * 16, TX_32X32);
468 469 470 471 472 473
        xd->eobs[i] = c;
        eobtotal += c;
      }

      // 32x32 chroma blocks
      for (i = 256; i < 384; i += 64) {
474 475
        c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_UV, seg_eob,
                         xd->qcoeff + i * 16, TX_32X32);
476 477 478 479 480 481 482 483 484
        xd->eobs[i] = c;
        eobtotal += c;
      }
      break;
    case TX_16X16:
      // 16x16 luma blocks
      seg_eob = get_eob(xd, segment_id, 256);
      for (i = 0; i < 256; i += 16) {
        c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_Y_WITH_DC,
485
                         seg_eob, xd->qcoeff + i * 16, TX_16X16);
486 487 488 489 490 491
        xd->eobs[i] = c;
        eobtotal += c;
      }

      // 16x16 chroma blocks
      for (i = 256; i < 384; i += 16) {
492 493
        c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_UV, seg_eob,
                         xd->qcoeff + i * 16, TX_16X16);
494 495 496 497 498 499 500 501 502
        xd->eobs[i] = c;
        eobtotal += c;
      }
      break;
    case TX_8X8:
      // 8x8 luma blocks
      seg_eob = get_eob(xd, segment_id, 64);
      for (i = 0; i < 256; i += 4) {
        c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_Y_WITH_DC,
503
                         seg_eob, xd->qcoeff + i * 16, TX_8X8);
504 505 506 507 508 509
        xd->eobs[i] = c;
        eobtotal += c;
      }

      // 8x8 chroma blocks
      for (i = 256; i < 384; i += 4) {
510 511
        c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_UV, seg_eob,
                         xd->qcoeff + i * 16, TX_8X8);
512 513 514 515 516 517 518 519 520
        xd->eobs[i] = c;
        eobtotal += c;
      }
      break;
    case TX_4X4:
      // 4x4 luma blocks
      seg_eob = get_eob(xd, segment_id, 16);
      for (i = 0; i < 256; i++) {
        c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_Y_WITH_DC,
521
                         seg_eob, xd->qcoeff + i * 16, TX_4X4);
522 523 524 525 526 527
        xd->eobs[i] = c;
        eobtotal += c;
      }

      // 4x4 chroma blocks
      for (i = 256; i < 384; i++) {
528 529
        c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_UV, seg_eob,
                         xd->qcoeff + i * 16, TX_4X4);
530 531 532 533 534
        xd->eobs[i] = c;
        eobtotal += c;
      }
      break;
    default: assert(0);
535
  }
536

537 538
  return eobtotal;
}
539

540 541 542
static int vp9_decode_mb_tokens_16x16(VP9D_COMP* const pbi,
                                      MACROBLOCKD* const xd,
                                      BOOL_DECODER* const bc) {
Daniel Kang's avatar
Daniel Kang committed
543
  const int segment_id = xd->mode_info_context->mbmi.segment_id;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
544
  int i, eobtotal = 0, seg_eob;
Yaowu Xu's avatar
Yaowu Xu committed
545

546
  // Luma block
Dmitry Kovalev's avatar
Dmitry Kovalev committed
547
  int c = decode_coefs(pbi, xd, bc, 0, PLANE_TYPE_Y_WITH_DC,
548
                       get_eob(xd, segment_id, 256), xd->qcoeff, TX_16X16);
549
  xd->eobs[0] = c;
550
  eobtotal += c;
Daniel Kang's avatar
Daniel Kang committed
551 552

  // 8x8 chroma blocks
553
  seg_eob = get_eob(xd, segment_id, 64);
Daniel Kang's avatar
Daniel Kang committed
554
  for (i = 16; i < 24; i += 4) {
555
    c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_UV,
556
                     seg_eob, xd->block[i].qcoeff, TX_8X8);
557
    xd->eobs[i] = c;
Daniel Kang's avatar
Daniel Kang committed
558 559 560 561 562
    eobtotal += c;
  }
  return eobtotal;
}

563 564 565
static int vp9_decode_mb_tokens_8x8(VP9D_COMP* const pbi,
                                    MACROBLOCKD* const xd,
                                    BOOL_DECODER* const bc) {
566
  int c, i, eobtotal = 0, seg_eob;
John Koleszar's avatar
John Koleszar committed
567
  const int segment_id = xd->mode_info_context->mbmi.segment_id;
568

569
  // luma blocks
570
  seg_eob = get_eob(xd, segment_id, 64);
571
  for (i = 0; i < 16; i += 4) {
572
    c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_Y_WITH_DC,
573
                     seg_eob, xd->block[i].qcoeff, TX_8X8);
574
    xd->eobs[i] = c;
John Koleszar's avatar
John Koleszar committed
575 576 577
    eobtotal += c;
  }

578 579 580 581
  // chroma blocks
  if (xd->mode_info_context->mbmi.mode == I8X8_PRED ||
      xd->mode_info_context->mbmi.mode == SPLITMV) {
    // use 4x4 transform for U, V components in I8X8/splitmv prediction mode
582
    seg_eob = get_eob(xd, segment_id, 16);
583
    for (i = 16; i < 24; i++) {
584
      c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_UV,
585
                       seg_eob, xd->block[i].qcoeff, TX_4X4);
586
      xd->eobs[i] = c;
587 588 589 590
      eobtotal += c;
    }
  } else {
    for (i = 16; i < 24; i += 4) {
591
      c = decode_coefs(pbi, xd, bc, i, PLANE_TYPE_UV,
592
                       seg_eob, xd->block[i].qcoeff, TX_8X8);
593
      xd->eobs[i] = c;
594 595 596 597
      eobtotal += c;
    }
  }

John Koleszar's avatar
John Koleszar committed
598
  return eobtotal;
599 600
}

601 602
static int decode_coefs_4x4(VP9D_COMP *dx, MACROBLOCKD *xd,
                            BOOL_DECODER* const bc,
603 604 605
                            PLANE_TYPE type, int i, int seg_eob) {
  int c = decode_coefs(dx, xd, bc, i, type, seg_eob,
                       xd->block[i].qcoeff, TX_4X4);
606
  xd->eobs[i] = c;
607 608 609 610 611 612 613 614 615
  return c;
}

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);

616
  return decode_coefs_4x4(dx, xd, bc, type, i, seg_eob);
617 618 619 620 621 622
}

static int decode_mb_tokens_4x4_uv(VP9D_COMP* const dx,
                                   MACROBLOCKD* const xd,
                                   BOOL_DECODER* const bc,
                                   int seg_eob) {
623 624
  int eobtotal = 0, i;

625 626
  // chroma blocks
  for (i = 16; i < 24; i++) {
627
    eobtotal += decode_coefs_4x4(dx, xd, bc, PLANE_TYPE_UV, i, seg_eob);
628
  }
629 630 631 632

  return eobtotal;
}

633 634 635 636 637 638 639 640 641
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);
}

642 643 644
static int vp9_decode_mb_tokens_4x4(VP9D_COMP* const dx,
                                    MACROBLOCKD* const xd,
                                    BOOL_DECODER* const bc) {
645
  int i, eobtotal = 0;
646 647
  const int segment_id = xd->mode_info_context->mbmi.segment_id;
  const int seg_eob = get_eob(xd, segment_id, 16);
John Koleszar's avatar
John Koleszar committed
648

649
  // luma blocks
650
  for (i = 0; i < 16; ++i) {
651
    eobtotal += decode_coefs_4x4(dx, xd, bc, PLANE_TYPE_Y_WITH_DC, i, seg_eob);
John Koleszar's avatar
John Koleszar committed
652
  }
653

654 655 656 657
  // chroma blocks
  eobtotal += decode_mb_tokens_4x4_uv(dx, xd, bc, seg_eob);

  return eobtotal;
John Koleszar's avatar
John Koleszar committed
658
}
659 660 661 662 663

int vp9_decode_mb_tokens(VP9D_COMP* const dx,
                         MACROBLOCKD* const xd,
                         BOOL_DECODER* const bc) {
  const TX_SIZE tx_size = xd->mode_info_context->mbmi.txfm_size;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
664 665 666 667 668 669 670 671
  switch (tx_size) {
    case TX_16X16:
      return vp9_decode_mb_tokens_16x16(dx, xd, bc);
    case TX_8X8:
      return vp9_decode_mb_tokens_8x8(dx, xd, bc);
    default:
      assert(tx_size == TX_4X4);
      return vp9_decode_mb_tokens_4x4(dx, xd, bc);
672 673
  }
}