detokenize.c 14.2 KB
Newer Older
Jingning Han's avatar
Jingning Han committed
1
/*
Yaowu Xu's avatar
Yaowu Xu committed
2
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Jingning Han's avatar
Jingning Han committed
3
 *
Yaowu Xu's avatar
Yaowu Xu committed
4 5 6 7 8 9
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
Jingning Han's avatar
Jingning Han committed
10 11
 */

12
#include "./aom_config.h"
13
#if !CONFIG_PVQ
Yaowu Xu's avatar
Yaowu Xu committed
14
#include "aom_mem/aom_mem.h"
15
#include "aom_ports/mem.h"
16 17
#endif  // !CONFIG_PVQ

18
#include "av1/common/blockd.h"
19

20 21
#define ACCT_STR __func__

22
#if !CONFIG_PVQ || CONFIG_VAR_TX
23 24 25 26
#include "av1/common/common.h"
#include "av1/common/entropy.h"
#include "av1/common/idct.h"
#include "av1/decoder/detokenize.h"
Jingning Han's avatar
Jingning Han committed
27

28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
#define EOB_CONTEXT_NODE 0
#define ZERO_CONTEXT_NODE 1
#define ONE_CONTEXT_NODE 2
#define LOW_VAL_CONTEXT_NODE 0
#define TWO_CONTEXT_NODE 1
#define THREE_CONTEXT_NODE 2
#define HIGH_LOW_CONTEXT_NODE 3
#define CAT_ONE_CONTEXT_NODE 4
#define CAT_THREEFOUR_CONTEXT_NODE 5
#define CAT_THREE_CONTEXT_NODE 6
#define CAT_FIVE_CONTEXT_NODE 7

#define INCREMENT_COUNT(token)                   \
  do {                                           \
    if (counts) ++coef_counts[band][ctx][token]; \
Jingning Han's avatar
Jingning Han committed
43 44
  } while (0)

45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
#if CONFIG_NEW_MULTISYMBOL
#define READ_COEFF(prob_name, cdf_name, num, r) read_coeff(cdf_name, num, r);
static INLINE int read_coeff(const aom_cdf_prob *const *cdf, int n,
                             aom_reader *r) {
  int val = 0;
  int i = 0;
  int count = 0;
  while (count < n) {
    const int size = AOMMIN(n - count, 4);
    val |= aom_read_cdf(r, cdf[i++], 1 << size, ACCT_STR) << count;
    count += size;
  }
  return val;
}
#else
#define READ_COEFF(prob_name, cdf_name, num, r) read_coeff(prob_name, num, r);
Yaowu Xu's avatar
Yaowu Xu committed
61
static INLINE int read_coeff(const aom_prob *probs, int n, aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
62
  int i, val = 0;
Michael Bebenita's avatar
Michael Bebenita committed
63
  for (i = 0; i < n; ++i) val = (val << 1) | aom_read(r, probs[i], ACCT_STR);
Jingning Han's avatar
Jingning Han committed
64 65 66
  return val;
}

67 68
#endif

69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
static int token_to_value(aom_reader *const r, int token, TX_SIZE tx_size,
                          int bit_depth) {
#if !CONFIG_HIGHBITDEPTH
  assert(bit_depth == 8);
#endif  // !CONFIG_HIGHBITDEPTH

  switch (token) {
    case ZERO_TOKEN:
    case ONE_TOKEN:
    case TWO_TOKEN:
    case THREE_TOKEN:
    case FOUR_TOKEN: return token;
    case CATEGORY1_TOKEN:
      return CAT1_MIN_VAL + READ_COEFF(av1_cat1_prob, av1_cat1_cdf, 1, r);
    case CATEGORY2_TOKEN:
      return CAT2_MIN_VAL + READ_COEFF(av1_cat2_prob, av1_cat2_cdf, 2, r);
    case CATEGORY3_TOKEN:
      return CAT3_MIN_VAL + READ_COEFF(av1_cat3_prob, av1_cat3_cdf, 3, r);
    case CATEGORY4_TOKEN:
      return CAT4_MIN_VAL + READ_COEFF(av1_cat4_prob, av1_cat4_cdf, 4, r);
    case CATEGORY5_TOKEN:
      return CAT5_MIN_VAL + READ_COEFF(av1_cat5_prob, av1_cat5_cdf, 5, r);
    case CATEGORY6_TOKEN: {
      const int skip_bits = (int)sizeof(av1_cat6_prob) -
                            av1_get_cat6_extrabits_size(tx_size, bit_depth);
      return CAT6_MIN_VAL + READ_COEFF(av1_cat6_prob + skip_bits, av1_cat6_cdf,
                                       18 - skip_bits, r);
    }
    default:
      assert(0);  // Invalid token.
      return -1;
  }
}

103 104
static int decode_coefs(MACROBLOCKD *xd, PLANE_TYPE type, tran_low_t *dqcoeff,
                        TX_SIZE tx_size, TX_TYPE tx_type, const int16_t *dq,
105 106 107
#if CONFIG_NEW_QUANT
                        dequant_val_type_nuq *dq_val,
#endif  // CONFIG_NEW_QUANT
108 109
#if CONFIG_AOM_QM
                        const qm_val_t *iqm[2][TX_SIZES],
110
#endif  // CONFIG_AOM_QM
111 112
                        int ctx, const int16_t *scan, const int16_t *nb,
                        int16_t *max_scan_line, aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
113
  FRAME_COUNTS *counts = xd->counts;
114 115 116 117 118
#if CONFIG_EC_ADAPT
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
#else
  FRAME_CONTEXT *const ec_ctx = xd->fc;
#endif
119
  const int max_eob = tx_size_2d[tx_size];
Jingning Han's avatar
Jingning Han committed
120
  const int ref = is_inter_block(&xd->mi[0]->mbmi);
121 122
#if CONFIG_AOM_QM
  const qm_val_t *iqmatrix = iqm[!ref][tx_size];
123
#endif  // CONFIG_AOM_QM
Jingning Han's avatar
Jingning Han committed
124
  int band, c = 0;
125
  const int tx_size_ctx = txsize_sqr_map[tx_size];
126
#if CONFIG_DAALA_EC || CONFIG_ANS
127
  aom_cdf_prob(*coef_head_cdfs)[COEFF_CONTEXTS][CDF_SIZE(ENTROPY_TOKENS)] =
128
      ec_ctx->coef_head_cdfs[tx_size_ctx][type][ref];
129
  aom_cdf_prob(*coef_tail_cdfs)[COEFF_CONTEXTS][CDF_SIZE(ENTROPY_TOKENS)] =
130 131
      ec_ctx->coef_tail_cdfs[tx_size_ctx][type][ref];
  int val = 0;
132

133
#if !CONFIG_EC_ADAPT
134
  unsigned int *blockz_count;
135 136
  unsigned int(*coef_counts)[COEFF_CONTEXTS][UNCONSTRAINED_NODES + 1] = NULL;
  unsigned int(*eob_branch_count)[COEFF_CONTEXTS] = NULL;
137
#endif
138 139 140 141
#else
  aom_prob(*coef_probs)[COEFF_CONTEXTS][UNCONSTRAINED_NODES] =
      ec_ctx->coef_probs[tx_size_ctx][type][ref];
  const aom_prob *prob;
Thomas Davies's avatar
Thomas Davies committed
142
  unsigned int(*coef_counts)[COEFF_CONTEXTS][UNCONSTRAINED_NODES + 1] = NULL;
143
  unsigned int(*eob_branch_count)[COEFF_CONTEXTS] = NULL;
144
#endif  // CONFIG_DAALA_EC || CONFIG_ANS
145
  uint8_t token_cache[MAX_TX_SQUARE];
Jingning Han's avatar
Jingning Han committed
146
  const uint8_t *band_translate = get_band_translate(tx_size);
147
  int dq_shift;
Jingning Han's avatar
Jingning Han committed
148 149
  int v, token;
  int16_t dqv = dq[0];
150 151 152
#if CONFIG_NEW_QUANT
  const tran_low_t *dqv_val = &dq_val[0][0];
#endif  // CONFIG_NEW_QUANT
153
  (void)tx_type;
154 155 156
#if CONFIG_AOM_QM
  (void)iqmatrix;
#endif  // CONFIG_AOM_QM
Jingning Han's avatar
Jingning Han committed
157 158

  if (counts) {
159
#if !(CONFIG_DAALA_EC || CONFIG_ANS) || !CONFIG_EC_ADAPT
160 161
    coef_counts = counts->coef[tx_size_ctx][type][ref];
    eob_branch_count = counts->eob_branch[tx_size_ctx][type][ref];
162 163
#endif
#if (CONFIG_DAALA_EC || CONFIG_ANS) && !CONFIG_EC_ADAPT
164 165
    blockz_count = counts->blockz_count[tx_size_ctx][type][ref][ctx];
#endif
Jingning Han's avatar
Jingning Han committed
166 167
  }

168
  dq_shift = av1_get_tx_scale(tx_size);
169

170
#if CONFIG_DAALA_EC || CONFIG_ANS
171 172
  band = *band_translate++;

173
  int more_data = 1;
174
  while (more_data) {
175
    int comb_token;
176
    int last_pos = (c + 1 == max_eob);
177
    int first_pos = (c == 0);
Jingning Han's avatar
Jingning Han committed
178

179 180 181 182
#if CONFIG_NEW_QUANT
    dqv_val = &dq_val[band][0];
#endif  // CONFIG_NEW_QUANT

183
    comb_token = last_pos ? 2 * aom_read_bit(r, ACCT_STR) + 2
184
                          : aom_read_symbol(r, coef_head_cdfs[band][ctx],
185 186 187
                                            HEAD_TOKENS + first_pos, ACCT_STR) +
                                !first_pos;
    if (first_pos) {
188
#if !CONFIG_EC_ADAPT
189
      if (counts) ++blockz_count[comb_token != 0];
190
#endif
191 192 193
      if (comb_token == 0) return 0;
    }
    token = comb_token >> 1;
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216

    while (!token) {
      *max_scan_line = AOMMAX(*max_scan_line, scan[c]);
      token_cache[scan[c]] = 0;
#if !CONFIG_EC_ADAPT
      if (counts && !last_pos) {
        ++coef_counts[band][ctx][ZERO_TOKEN];
      }
#endif
      ++c;
      dqv = dq[1];
      ctx = get_coef_context(nb, token_cache, c);
      band = *band_translate++;

      last_pos = (c + 1 == max_eob);

      comb_token = last_pos ? 2 * aom_read_bit(r, ACCT_STR) + 2
                            : aom_read_symbol(r, coef_head_cdfs[band][ctx],
                                              HEAD_TOKENS, ACCT_STR) +
                                  1;
      token = comb_token >> 1;
    }

217 218
    more_data = comb_token & 1;
#if !CONFIG_EC_ADAPT
219
    if (counts && !last_pos) {
220
      ++coef_counts[band][ctx][token];
221 222
      ++eob_branch_count[band][ctx];
      if (!more_data) ++coef_counts[band][ctx][EOB_MODEL_TOKEN];
223
    }
224
#endif
225

226
    if (token > ONE_TOKEN)
227 228
      token +=
          aom_read_symbol(r, coef_tail_cdfs[band][ctx], TAIL_TOKENS, ACCT_STR);
229
#if CONFIG_NEW_QUANT
230
    dqv_val = &dq_val[band][0];
231
#endif  // CONFIG_NEW_QUANT
232 233

    *max_scan_line = AOMMAX(*max_scan_line, scan[c]);
234
    token_cache[scan[c]] = av1_pt_energy_class[token];
235

236
    val = token_to_value(r, token, tx_size, xd->bd);
237 238 239 240 241 242 243 244 245 246 247

#if CONFIG_NEW_QUANT
    v = av1_dequant_abscoeff_nuq(val, dqv, dqv_val);
    v = dq_shift ? ROUND_POWER_OF_TWO(v, dq_shift) : v;
#else
#if CONFIG_AOM_QM
    dqv = ((iqmatrix[scan[c]] * (int)dqv) + (1 << (AOM_QM_BITS - 1))) >>
          AOM_QM_BITS;
#endif
    v = (val * dqv) >> dq_shift;
#endif
248

249
    v = aom_read_bit(r, ACCT_STR) ? -v : v;
250
#if CONFIG_COEFFICIENT_RANGE_CHECKING
251
    check_range(v, xd->bd);
252 253
#endif  // CONFIG_COEFFICIENT_RANGE_CHECKING

254
    dqcoeff[scan[c]] = v;
255

256
    ++c;
257 258
    more_data &= (c < max_eob);
    if (!more_data) break;
259 260
    dqv = dq[1];
    ctx = get_coef_context(nb, token_cache, c);
261
    band = *band_translate++;
262

263
#else  // CONFIG_DAALA_EC || CONFIG_ANS
264 265 266 267 268 269 270 271 272 273 274 275 276
  while (c < max_eob) {
    int val = -1;
    band = *band_translate++;
    prob = coef_probs[band][ctx];
    if (counts) ++eob_branch_count[band][ctx];
    if (!aom_read(r, prob[EOB_CONTEXT_NODE], ACCT_STR)) {
      INCREMENT_COUNT(EOB_MODEL_TOKEN);
      break;
    }

#if CONFIG_NEW_QUANT
    dqv_val = &dq_val[band][0];
#endif  // CONFIG_NEW_QUANT
277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293

    while (!aom_read(r, prob[ZERO_CONTEXT_NODE], ACCT_STR)) {
      INCREMENT_COUNT(ZERO_TOKEN);
      dqv = dq[1];
      token_cache[scan[c]] = 0;
      ++c;
      if (c >= max_eob) return c;  // zero tokens at the end (no eob token)
      ctx = get_coef_context(nb, token_cache, c);
      band = *band_translate++;
      prob = coef_probs[band][ctx];
#if CONFIG_NEW_QUANT
      dqv_val = &dq_val[band][0];
#endif  // CONFIG_NEW_QUANT
    }

    *max_scan_line = AOMMAX(*max_scan_line, scan[c]);

Michael Bebenita's avatar
Michael Bebenita committed
294
    if (!aom_read(r, prob[ONE_CONTEXT_NODE], ACCT_STR)) {
Jingning Han's avatar
Jingning Han committed
295 296 297 298 299
      INCREMENT_COUNT(ONE_TOKEN);
      token = ONE_TOKEN;
      val = 1;
    } else {
      INCREMENT_COUNT(TWO_TOKEN);
Yaowu Xu's avatar
Yaowu Xu committed
300
      token = aom_read_tree(r, av1_coef_con_tree,
Michael Bebenita's avatar
Michael Bebenita committed
301
                            av1_pareto8_full[prob[PIVOT_NODE] - 1], ACCT_STR);
302
      assert(token != ZERO_TOKEN && token != ONE_TOKEN);
303
      val = token_to_value(r, token, tx_size, xd->bd);
Jingning Han's avatar
Jingning Han committed
304
    }
305
#if CONFIG_NEW_QUANT
Yaowu Xu's avatar
Yaowu Xu committed
306
    v = av1_dequant_abscoeff_nuq(val, dqv, dqv_val);
307 308
    v = dq_shift ? ROUND_POWER_OF_TWO(v, dq_shift) : v;
#else
309 310 311 312
#if CONFIG_AOM_QM
    dqv = ((iqmatrix[scan[c]] * (int)dqv) + (1 << (AOM_QM_BITS - 1))) >>
          AOM_QM_BITS;
#endif
Jingning Han's avatar
Jingning Han committed
313
    v = (val * dqv) >> dq_shift;
314 315
#endif  // CONFIG_NEW_QUANT

Jingning Han's avatar
Jingning Han committed
316
#if CONFIG_COEFFICIENT_RANGE_CHECKING
Michael Bebenita's avatar
Michael Bebenita committed
317
    dqcoeff[scan[c]] =
318
        check_range((aom_read_bit(r, ACCT_STR) ? -v : v), xd->bd);
Jingning Han's avatar
Jingning Han committed
319
#else
Michael Bebenita's avatar
Michael Bebenita committed
320
    dqcoeff[scan[c]] = aom_read_bit(r, ACCT_STR) ? -v : v;
Jingning Han's avatar
Jingning Han committed
321
#endif  // CONFIG_COEFFICIENT_RANGE_CHECKING
Yaowu Xu's avatar
Yaowu Xu committed
322
    token_cache[scan[c]] = av1_pt_energy_class[token];
Jingning Han's avatar
Jingning Han committed
323 324 325
    ++c;
    ctx = get_coef_context(nb, token_cache, c);
    dqv = dq[1];
326
#endif  // CONFIG_DAALA_EC || CONFIG_ANS
Jingning Han's avatar
Jingning Han committed
327 328 329 330
  }

  return c;
}
331
#endif  // !CONFIG_PVQ
Jingning Han's avatar
Jingning Han committed
332

333
#if CONFIG_PALETTE
Fangwen Fu's avatar
Fangwen Fu committed
334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350
void av1_decode_palette_tokens(MACROBLOCKD *const xd, int plane,
                               aom_reader *r) {
  const MODE_INFO *const mi = xd->mi[0];
  const MB_MODE_INFO *const mbmi = &mi->mbmi;
  uint8_t color_order[PALETTE_MAX_SIZE];
  const int n = mbmi->palette_mode_info.palette_size[plane];
  int i, j;
  uint8_t *const color_map = xd->plane[plane].color_index_map;
  const aom_prob(
      *const prob)[PALETTE_COLOR_INDEX_CONTEXTS][PALETTE_COLORS - 1] =
      plane ? av1_default_palette_uv_color_index_prob
            : av1_default_palette_y_color_index_prob;
  int plane_block_width, plane_block_height, rows, cols;
  av1_get_block_dimensions(mbmi->sb_type, plane, xd, &plane_block_width,
                           &plane_block_height, &rows, &cols);
  assert(plane == 0 || plane == 1);

Fangwen Fu's avatar
Fangwen Fu committed
351 352 353 354
#if CONFIG_PALETTE_THROUGHPUT
  // Run wavefront on the palette map index decoding.
  for (i = 1; i < rows + cols - 1; ++i) {
    for (j = AOMMIN(i, cols - 1); j >= AOMMAX(0, i - rows + 1); --j) {
Fangwen Fu's avatar
Fangwen Fu committed
355
      const int color_ctx = av1_get_palette_color_index_context(
Fangwen Fu's avatar
Fangwen Fu committed
356
          color_map, plane_block_width, (i - j), j, n, color_order, NULL);
Fangwen Fu's avatar
Fangwen Fu committed
357 358 359 360
      const int color_idx =
          aom_read_tree(r, av1_palette_color_index_tree[n - 2],
                        prob[n - 2][color_ctx], ACCT_STR);
      assert(color_idx >= 0 && color_idx < n);
Fangwen Fu's avatar
Fangwen Fu committed
361
      color_map[(i - j) * plane_block_width + j] = color_order[color_idx];
Fangwen Fu's avatar
Fangwen Fu committed
362 363 364
    }
  }
  // Copy last column to extra columns.
Fangwen Fu's avatar
Fangwen Fu committed
365 366 367 368 369
  if (cols < plane_block_width) {
    for (i = 0; i < plane_block_height; ++i) {
      memset(color_map + i * plane_block_width + cols,
             color_map[i * plane_block_width + cols - 1],
             (plane_block_width - cols));
Fangwen Fu's avatar
Fangwen Fu committed
370 371 372
    }
  }
#else
hui su's avatar
hui su committed
373 374
  for (i = 0; i < rows; ++i) {
    for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
375
      const int color_ctx = av1_get_palette_color_index_context(
376
          color_map, plane_block_width, i, j, n, color_order, NULL);
377
      const int color_idx =
378 379
          aom_read_tree(r, av1_palette_color_index_tree[n - PALETTE_MIN_SIZE],
                        prob[n - PALETTE_MIN_SIZE][color_ctx], ACCT_STR);
hui su's avatar
hui su committed
380
      assert(color_idx >= 0 && color_idx < n);
381
      color_map[i * plane_block_width + j] = color_order[color_idx];
hui su's avatar
hui su committed
382
    }
383 384 385 386
    memset(color_map + i * plane_block_width + cols,
           color_map[i * plane_block_width + cols - 1],
           (plane_block_width - cols));  // Copy last column to extra columns.
  }
Fangwen Fu's avatar
Fangwen Fu committed
387
#endif  // CONFIG_PALETTE_THROUGHPUT
388 389 390 391
  // Copy last row to extra rows.
  for (i = rows; i < plane_block_height; ++i) {
    memcpy(color_map + i * plane_block_width,
           color_map + (rows - 1) * plane_block_width, plane_block_width);
hui su's avatar
hui su committed
392 393
  }
}
394
#endif  // CONFIG_PALETTE
hui su's avatar
hui su committed
395

396
#if !CONFIG_PVQ || CONFIG_VAR_TX
397
int av1_decode_block_tokens(AV1_COMMON *cm, MACROBLOCKD *const xd, int plane,
398
                            const SCAN_ORDER *sc, int x, int y, TX_SIZE tx_size,
399
                            TX_TYPE tx_type, int16_t *max_scan_line,
400
                            aom_reader *r, int seg_id) {
Jingning Han's avatar
Jingning Han committed
401 402
  struct macroblockd_plane *const pd = &xd->plane[plane];
  const int16_t *const dequant = pd->seg_dequant[seg_id];
403 404
  const int ctx =
      get_entropy_context(tx_size, pd->above_context + x, pd->left_context + y);
405
#if CONFIG_NEW_QUANT
406
  const int ref = is_inter_block(&xd->mi[0]->mbmi);
407 408
  int dq =
      get_dq_profile_from_ctx(xd->qindex[seg_id], ctx, ref, pd->plane_type);
409 410
#endif  //  CONFIG_NEW_QUANT

411 412
  const int eob =
      decode_coefs(xd, pd->plane_type, pd->dqcoeff, tx_size, tx_type, dequant,
413
#if CONFIG_NEW_QUANT
414
                   pd->seg_dequant_nuq[seg_id][dq],
415
#endif  // CONFIG_NEW_QUANT
416 417
#if CONFIG_AOM_QM
                   pd->seg_iqmatrix[seg_id],
418
#endif  // CONFIG_AOM_QM
419
                   ctx, sc->scan, sc->neighbors, max_scan_line, r);
420
  av1_set_contexts(xd, pd, plane, tx_size, eob > 0, x, y);
421 422 423 424
#if CONFIG_ADAPT_SCAN
  if (xd->counts)
    av1_update_scan_count_facade(cm, xd->counts, tx_size, tx_type, pd->dqcoeff,
                                 eob);
425 426
#else
  (void)cm;
427
#endif
Jingning Han's avatar
Jingning Han committed
428 429
  return eob;
}
430
#endif  // !CONFIG_PVQ