vp9_detokenize.c 14.3 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 110
                        TX_SIZE txfm_size, const int16_t *dq,
                        ENTROPY_CONTEXT *A, ENTROPY_CONTEXT *L) {
111
  ENTROPY_CONTEXT above_ec, left_ec;
John Koleszar's avatar
John Koleszar committed
112
  FRAME_CONTEXT *const fc = &dx->common.fc;
113
  int pt, c = 0, pad, default_eob;
114 115 116
  vp9_coeff_probs *coef_probs;
  vp9_prob *prob;
  vp9_coeff_count *coef_counts;
117
  const int ref = xd->mode_info_context->mbmi.ref_frame != INTRA_FRAME;
118 119 120 121 122 123 124 125 126
  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;
127
#endif
128 129
  const int *scan, *nb;
  uint8_t token_cache[1024];
130 131 132
#if CONFIG_CODE_ZEROGROUP
  vpx_memset(token_cache, UNKNOWN_TOKEN, sizeof(token_cache));
#endif
Daniel Kang's avatar
Daniel Kang committed
133

134
  switch (txfm_size) {
Daniel Kang's avatar
Daniel Kang committed
135
    default:
136
    case TX_4X4: {
137 138
      tx_type = (type == PLANE_TYPE_Y_WITH_DC) ?
          get_tx_type_4x4(xd, block_idx) : DCT_DCT;
139
      scan = get_scan_4x4(tx_type);
140 141
      above_ec = A[0] != 0;
      left_ec = L[0] != 0;
142 143
      coef_probs  = fc->coef_probs_4x4;
      coef_counts = fc->coef_counts_4x4;
144
      default_eob = 16;
145 146 147 148
#if CONFIG_CODE_ZEROGROUP
      zpc_probs = &(fc->zpc_probs_4x4);
      zpc_count = &(fc->zpc_counts_4x4);
#endif
Daniel Kang's avatar
Daniel Kang committed
149
      break;
150
    }
151 152
    case TX_8X8: {
      const BLOCK_SIZE_TYPE sb_type = xd->mode_info_context->mbmi.sb_type;
153
      const int sz = 1 + b_width_log2(sb_type);
154
      const int x = block_idx & ((1 << sz) - 1);
155
      const int y = block_idx - x;
156 157
      tx_type = (type == PLANE_TYPE_Y_WITH_DC) ?
          get_tx_type_8x8(xd, y + (x >> 1)) : DCT_DCT;
158
      scan = get_scan_8x8(tx_type);
159 160
      coef_probs  = fc->coef_probs_8x8;
      coef_counts = fc->coef_counts_8x8;
161 162
      above_ec = (A[0] + A[1]) != 0;
      left_ec = (L[0] + L[1]) != 0;
163
      default_eob = 64;
164 165 166 167
#if CONFIG_CODE_ZEROGROUP
      zpc_probs = &(fc->zpc_probs_8x8);
      zpc_count = &(fc->zpc_counts_8x8);
#endif
Daniel Kang's avatar
Daniel Kang committed
168
      break;
169 170 171
    }
    case TX_16X16: {
      const BLOCK_SIZE_TYPE sb_type = xd->mode_info_context->mbmi.sb_type;
172
      const int sz = 2 + b_width_log2(sb_type);
173
      const int x = block_idx & ((1 << sz) - 1);
174
      const int y = block_idx - x;
175 176
      tx_type = (type == PLANE_TYPE_Y_WITH_DC) ?
          get_tx_type_16x16(xd, y + (x >> 2)) : DCT_DCT;
177
      scan = get_scan_16x16(tx_type);
178 179
      coef_probs  = fc->coef_probs_16x16;
      coef_counts = fc->coef_counts_16x16;
180 181
      above_ec = (A[0] + A[1] + A[2] + A[3]) != 0;
      left_ec = (L[0] + L[1] + L[2] + L[3]) != 0;
182
      default_eob = 256;
183 184 185 186
#if CONFIG_CODE_ZEROGROUP
      zpc_probs = &(fc->zpc_probs_16x16);
      zpc_count = &(fc->zpc_counts_16x16);
#endif
Daniel Kang's avatar
Daniel Kang committed
187
      break;
188
    }
189
    case TX_32X32:
190
      scan = vp9_default_zig_zag1d_32x32;
191 192
      coef_probs = fc->coef_probs_32x32;
      coef_counts = fc->coef_counts_32x32;
193 194
      above_ec = (A[0] + A[1] + A[2] + A[3] + A[4] + A[5] + A[6] + A[7]) != 0;
      left_ec = (L[0] + L[1] + L[2] + L[3] + L[4] + L[5] + L[6] + L[7]) != 0;
195
      default_eob = 1024;
196 197 198 199
#if CONFIG_CODE_ZEROGROUP
      zpc_probs = &fc->zpc_probs_32x32;
      zpc_count = &fc->zpc_counts_32x32;
#endif
200
      break;
Daniel Kang's avatar
Daniel Kang committed
201
  }
John Koleszar's avatar
John Koleszar committed
202

203
  pt = combine_entropy_contexts(above_ec, left_ec);
204 205
  nb = vp9_get_coef_neighbors_handle(scan, &pad);

John Koleszar's avatar
John Koleszar committed
206 207
  while (1) {
    int val;
208
    int band;
John Koleszar's avatar
John Koleszar committed
209
    const uint8_t *cat6 = cat6_prob;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
210 211
    if (c >= seg_eob)
      break;
212 213 214 215 216 217
    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]++;
218 219
    if (!vp9_read(r, prob[EOB_CONTEXT_NODE]))
      break;
220
#if CONFIG_CODE_ZEROGROUP
221 222 223 224 225 226
    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;
227 228 229
    }
#endif

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

331 332 333
  if (c < seg_eob)
    coef_counts[type][ref][get_coef_band(scan, txfm_size, c)]
        [pt][DCT_EOB_TOKEN]++;
334

335 336
  for (pt = 0; pt < (1 << txfm_size); pt++) {
    A[pt] = L[pt] = c > 0;
337
  }
338

John Koleszar's avatar
John Koleszar committed
339
  return c;
Daniel Kang's avatar
Daniel Kang committed
340
}
John Koleszar's avatar
John Koleszar committed
341

342
static int get_eob(MACROBLOCKD* const xd, int segment_id, int eob_max) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
343
  return vp9_get_segdata(xd, segment_id, SEG_LVL_SKIP) ? 0 : eob_max;
344 345
}

346

John Koleszar's avatar
John Koleszar committed
347 348 349
struct decode_block_args {
  VP9D_COMP *pbi;
  MACROBLOCKD *xd;
350
  vp9_reader *r;
John Koleszar's avatar
John Koleszar committed
351 352 353
  int *eobtotal;
};
static void decode_block(int plane, int block,
354
                         BLOCK_SIZE_TYPE bsize,
John Koleszar's avatar
John Koleszar committed
355 356 357
                         int ss_txfrm_size,
                         void *argv) {
  const struct decode_block_args* const arg = argv;
358 359
  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
360
                                              plane, block);
361 362

  // find the maximum eob for this transform size, adjusted by segment
John Koleszar's avatar
John Koleszar committed
363 364 365 366
  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;
367 368 369 370
  const int off = block >> ss_txfrm_size;
  const int mod = bw - ss_tx_size - arg->xd->plane[plane].subsampling_x;
  const int aoff = (off & ((1 << mod) - 1)) << ss_tx_size;
  const int loff = (off >> mod) << ss_tx_size;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
371

372
  const int eob = decode_coefs(arg->pbi, arg->xd, arg->r, old_block_idx,
John Koleszar's avatar
John Koleszar committed
373 374
                               arg->xd->plane[plane].plane_type, seg_eob,
                               BLOCK_OFFSET(qcoeff_base, block, 16),
375 376 377
                               ss_tx_size, arg->xd->plane[plane].dequant,
                               arg->xd->plane[plane].above_context + aoff,
                               arg->xd->plane[plane].left_context + loff);
378

John Koleszar's avatar
John Koleszar committed
379 380
  arg->xd->plane[plane].eobs[block] = eob;
  arg->eobtotal[0] += eob;
381 382
}

383
int vp9_decode_tokens(VP9D_COMP* const pbi,
384
                         MACROBLOCKD* const xd,
385
                         vp9_reader *r,
386
                         BLOCK_SIZE_TYPE bsize) {
John Koleszar's avatar
John Koleszar committed
387
  int eobtotal = 0;
388
  struct decode_block_args args = {pbi, xd, r, &eobtotal};
389
  foreach_transformed_block(xd, bsize, decode_block, &args);
John Koleszar's avatar
John Koleszar committed
390
  return eobtotal;
391 392
}

393
#if CONFIG_NEWBINTRAMODES
394
static int decode_coefs_4x4(VP9D_COMP *dx, MACROBLOCKD *xd,
395
                            vp9_reader *r,
396
                            PLANE_TYPE type, int i, int seg_eob) {
John Koleszar's avatar
John Koleszar committed
397
  const struct plane_block_idx pb_idx = plane_block_idx(16, i);
398 399 400 401 402
  const int mod = 2 - xd->plane[pb_idx.plane].subsampling_x;
  const int aoff = pb_idx.block & ((1 << mod) - 1);
  const int loff = pb_idx.block >> mod;
  ENTROPY_CONTEXT *A = xd->plane[pb_idx.plane].above_context;
  ENTROPY_CONTEXT *L = xd->plane[pb_idx.plane].left_context;
403
  const int c = decode_coefs(dx, xd, r, i, type, seg_eob,
404
      BLOCK_OFFSET(xd->plane[pb_idx.plane].qcoeff, pb_idx.block, 16), TX_4X4,
405
      xd->plane[pb_idx.plane].dequant, A + aoff, L + loff);
John Koleszar's avatar
John Koleszar committed
406
  xd->plane[pb_idx.plane].eobs[pb_idx.block] = c;
407 408 409 410 411
  return c;
}

static int decode_mb_tokens_4x4_uv(VP9D_COMP* const dx,
                                   MACROBLOCKD* const xd,
412
                                   vp9_reader *r,
413
                                   int seg_eob) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
414
  int i, eobtotal = 0;
415

416
  // chroma blocks
Dmitry Kovalev's avatar
Dmitry Kovalev committed
417
  for (i = 16; i < 24; i++)
418
    eobtotal += decode_coefs_4x4(dx, xd, r, PLANE_TYPE_UV, i, seg_eob);
419 420 421 422

  return eobtotal;
}

423 424
int vp9_decode_mb_tokens_4x4_uv(VP9D_COMP* const dx,
                                MACROBLOCKD* const xd,
425
                                vp9_reader *r) {
426 427 428
  const int segment_id = xd->mode_info_context->mbmi.segment_id;
  const int seg_eob = get_eob(xd, segment_id, 16);

429
  return decode_mb_tokens_4x4_uv(dx, xd, r, seg_eob);
430 431
}

432
int vp9_decode_coefs_4x4(VP9D_COMP *dx, MACROBLOCKD *xd,
433
                         vp9_reader *r,
434
                         PLANE_TYPE type, int i) {
435 436
  const int segment_id = xd->mode_info_context->mbmi.segment_id;
  const int seg_eob = get_eob(xd, segment_id, 16);
437
  return decode_coefs_4x4(dx, xd, r, type, i, seg_eob);
438 439
}
#endif