decodetxb.c 10 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12
/*
 * Copyright (c) 2017, Alliance for Open Media. All rights reserved
 *
 * 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.
 */

#include "av1/common/scan.h"
Angie Chiang's avatar
Angie Chiang committed
13
#include "av1/common/idct.h"
14
#include "av1/common/txb_common.h"
15
#include "av1/decoder/decodemv.h"
16
#include "av1/decoder/decodetxb.h"
17
#include "av1/decoder/dsubexp.h"
18
#include "av1/decoder/symbolrate.h"
19 20 21

#define ACCT_STR __func__

22 23 24 25
static int read_golomb(MACROBLOCKD *xd, aom_reader *r, FRAME_COUNTS *counts) {
#if !CONFIG_SYMBOLRATE
  (void)counts;
#endif
26 27 28 29 30
  int x = 1;
  int length = 0;
  int i = 0;

  while (!i) {
31
    i = av1_read_record_bit(counts, r, ACCT_STR);
32
    ++length;
33 34 35 36 37
    if (length >= 32) {
      aom_internal_error(xd->error_info, AOM_CODEC_CORRUPT_FRAME,
                         "Invalid length in read_golomb");
      break;
    }
38 39 40 41
  }

  for (i = 0; i < length - 1; ++i) {
    x <<= 1;
42
    x += av1_read_record_bit(counts, r, ACCT_STR);
43 44 45 46 47
  }

  return x - 1;
}

Dake He's avatar
Dake He committed
48 49 50 51 52 53 54 55
static INLINE int rec_eob_pos(int16_t eob_token, int16_t extra) {
  int eob = k_eob_group_start[eob_token];
  if (eob > 2) {
    eob += extra;
  }
  return eob;
}

56
uint8_t av1_read_coeffs_txb(const AV1_COMMON *const cm, MACROBLOCKD *xd,
Jingning Han's avatar
Jingning Han committed
57 58
                            aom_reader *r, int blk_row, int blk_col, int block,
                            int plane, tran_low_t *tcoeffs, TXB_CTX *txb_ctx,
Jingning Han's avatar
Jingning Han committed
59
                            TX_SIZE tx_size, int16_t *max_scan_line, int *eob) {
60
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
61
  FRAME_COUNTS *counts = xd->counts;
62
  TX_SIZE txs_ctx = get_txsize_context(tx_size);
63 64
  PLANE_TYPE plane_type = get_plane_type(plane);
  MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
65
  const int seg_eob = tx_size_2d[tx_size];
66
  int c = 0;
67
  int update_eob = -1;
68
  const int16_t *const dequant = xd->plane[plane].seg_dequant[mbmi->segment_id];
69
  const int shift = av1_get_tx_scale(tx_size);
70
  const int bwl = b_width_log2_lookup[txsize_to_bsize[tx_size]] + 2;
71
  const int height = tx_size_high[tx_size];
72
  int cul_level = 0;
73 74 75
  uint8_t levels[64 * 64];
  int8_t signs[64 * 64];

76 77
  memset(tcoeffs, 0, sizeof(*tcoeffs) * seg_eob);

78
  int all_zero = av1_read_record_bin(
79 80
      counts, r, ec_ctx->txb_skip_cdf[txs_ctx][txb_ctx->txb_skip_ctx], 2,
      ACCT_STR);
Angie Chiang's avatar
Angie Chiang committed
81
  if (xd->counts)
82
    ++xd->counts->txb_skip[txs_ctx][txb_ctx->txb_skip_ctx][all_zero];
Angie Chiang's avatar
Angie Chiang committed
83

84
  *eob = 0;
Angie Chiang's avatar
Angie Chiang committed
85 86
  if (all_zero) {
    *max_scan_line = 0;
87 88 89
#if CONFIG_TXK_SEL
    if (plane == 0) mbmi->txk_type[(blk_row << 4) + blk_col] = DCT_DCT;
#endif
Angie Chiang's avatar
Angie Chiang committed
90 91 92
    return 0;
  }

Linfeng Zhang's avatar
Linfeng Zhang committed
93
  memset(levels, 0, sizeof(levels[0]) * seg_eob);
94 95
  memset(signs, 0, sizeof(signs[0]) * seg_eob);

Jingning Han's avatar
Jingning Han committed
96 97
  (void)blk_row;
  (void)blk_col;
Angie Chiang's avatar
Angie Chiang committed
98
#if CONFIG_TXK_SEL
99 100
  av1_read_tx_type(cm, xd, blk_row, blk_col, block, plane,
                   get_min_tx_size(tx_size), r);
Angie Chiang's avatar
Angie Chiang committed
101
#endif
102 103
  const TX_TYPE tx_type =
      av1_get_tx_type(plane_type, xd, blk_row, blk_col, block, tx_size);
Angie Chiang's avatar
Angie Chiang committed
104
  const SCAN_ORDER *const scan_order = get_scan(cm, tx_size, tx_type, mbmi);
105
  const int16_t *scan = scan_order->scan;
Angie Chiang's avatar
Angie Chiang committed
106

Dake He's avatar
Dake He committed
107 108 109 110 111 112 113 114 115 116
  unsigned int(*nz_map_count)[SIG_COEF_CONTEXTS][2] =
      (counts) ? &counts->nz_map[txs_ctx][plane_type] : NULL;
  int16_t dummy;
  int16_t max_eob_pt = get_eob_pos_token(seg_eob, &dummy);

  int16_t eob_extra = 0;
  int16_t eob_pt = 0;
  int is_equal = 0;

  for (int i = 1; i < max_eob_pt; i++) {
Jingning Han's avatar
Jingning Han committed
117
    int eob_pos_ctx = av1_get_eob_pos_ctx(tx_type, i);
Dake He's avatar
Dake He committed
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
    is_equal = av1_read_record_bin(
        counts, r, ec_ctx->eob_flag_cdf[txs_ctx][plane_type][eob_pos_ctx], 2,
        ACCT_STR);

    // aom_read_symbol(r,
    // ec_ctx->eob_flag_cdf[AOMMIN(txs_ctx,3)][plane_type][eob_pos_ctx], 2,
    // ACCT_STR);
    if (counts) ++counts->eob_flag[txs_ctx][plane_type][eob_pos_ctx][is_equal];

    if (is_equal) {
      eob_pt = i;
      break;
    }
  }
  if (is_equal == 0) {
    eob_pt = max_eob_pt;
  }

  // printf("Dec: ");
  if (k_eob_offset_bits[eob_pt] > 0) {
Angie Chiang's avatar
Angie Chiang committed
138 139 140 141
    int eob_shift = k_eob_offset_bits[eob_pt] - 1;
    int bit = av1_read_record_bin(
        counts, r, ec_ctx->eob_extra_cdf[txs_ctx][plane_type][eob_pt], 2,
        ACCT_STR);
Angie Chiang's avatar
Angie Chiang committed
142
    if (counts) ++counts->eob_extra[txs_ctx][plane_type][eob_pt][bit];
Angie Chiang's avatar
Angie Chiang committed
143 144 145 146 147 148 149
    if (bit) {
      eob_extra += (1 << eob_shift);
    }

    for (int i = 1; i < k_eob_offset_bits[eob_pt]; i++) {
      eob_shift = k_eob_offset_bits[eob_pt] - 1 - i;
      bit = av1_read_record_bit(counts, r, ACCT_STR);
Dake He's avatar
Dake He committed
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
      if (bit) {
        eob_extra += (1 << eob_shift);
      }
      //  printf("%d ", bit);
    }
  }
  *eob = rec_eob_pos(eob_pt, eob_extra);
  // printf("=>[%d, %d], (%d, %d)\n", seg_eob, *eob, eob_pt, eob_extra);

  for (int i = 0; i < *eob; ++i) {
    c = *eob - 1 - i;
    int is_nz;
    int coeff_ctx = get_nz_map_ctx(levels, c, scan, bwl, height, tx_type, 1);
    // int eob_ctx = get_eob_ctx(tcoeffs, scan[c], txs_ctx, tx_type);

    if (c < *eob - 1) {
      is_nz = av1_read_record_bin(
          counts, r, ec_ctx->nz_map_cdf[txs_ctx][plane_type][coeff_ctx], 2,
          ACCT_STR);
    } else {
      is_nz = 1;
    }

    // set non-zero coefficient map.
    levels[scan[c]] = is_nz;

    if (counts) ++(*nz_map_count)[coeff_ctx][is_nz];
  }

179
  *max_scan_line = *eob;
180 181 182 183

  int i;
  for (i = 0; i < NUM_BASE_LEVELS; ++i) {
    update_eob = 0;
184
    for (c = *eob - 1; c >= 0; --c) {
185
      uint8_t *const level = &levels[scan[c]];
186 187
      int ctx;

188
      if (*level <= i) continue;
189

190
      ctx = get_base_ctx(levels, scan[c], bwl, height, i + 1);
191

192
      if (av1_read_record_bin(
193
              counts, r, ec_ctx->coeff_base_cdf[txs_ctx][plane_type][i][ctx], 2,
Jingning Han's avatar
Jingning Han committed
194
              ACCT_STR)) {
195
        assert(*level == i + 1);
196 197
        cul_level += i + 1;

198
        if (counts) ++counts->coeff_base[txs_ctx][plane_type][i][ctx][1];
199 200 201

        continue;
      }
202
      *level = i + 2;
203
      if (counts) ++counts->coeff_base[txs_ctx][plane_type][i][ctx][0];
204 205 206 207 208 209

      // update the eob flag for coefficients with magnitude above 1.
      update_eob = AOMMAX(update_eob, c);
    }
  }

210 211 212
  // Loop to decode all signs in the transform block,
  // starting with the sign of the DC (if applicable)
  for (c = 0; c < *eob; ++c) {
213
    int8_t *const sign = &signs[scan[c]];
214
    if (levels[scan[c]] == 0) continue;
215 216
    if (c == 0) {
      int dc_sign_ctx = txb_ctx->dc_sign_ctx;
217
#if LV_MAP_PROB
218
      *sign = av1_read_record_bin(
219
          counts, r, ec_ctx->dc_sign_cdf[plane_type][dc_sign_ctx], 2, ACCT_STR);
220 221 222
#else
      *sign = aom_read(r, ec_ctx->dc_sign[plane_type][dc_sign_ctx], ACCT_STR);
#endif
223
      if (counts) ++counts->dc_sign[plane_type][dc_sign_ctx][*sign];
224
    } else {
225
      *sign = av1_read_record_bit(counts, r, ACCT_STR);
226
    }
227 228 229 230 231 232 233 234
  }

  for (c = update_eob; c >= 0; --c) {
    uint8_t *const level = &levels[scan[c]];
    int idx;
    int ctx;

    if (*level <= NUM_BASE_LEVELS) continue;
235

236
    ctx = get_br_ctx(levels, scan[c], bwl, height);
237

238
    for (idx = 0; idx < BASE_RANGE_SETS; ++idx) {
239
      if (av1_read_record_bin(
240
              counts, r, ec_ctx->coeff_br_cdf[txs_ctx][plane_type][idx][ctx], 2,
Jingning Han's avatar
Jingning Han committed
241
              ACCT_STR)) {
242 243 244 245
        int extra_bits = (1 << br_extra_bits[idx]) - 1;
        //        int br_offset = aom_read_literal(r, extra_bits, ACCT_STR);
        int br_offset = 0;
        int tok;
246
        if (counts) ++counts->coeff_br[txs_ctx][plane_type][idx][ctx][1];
247
        for (tok = 0; tok < extra_bits; ++tok) {
248
          if (av1_read_record_bin(
249
                  counts, r, ec_ctx->coeff_lps_cdf[txs_ctx][plane_type][ctx], 2,
Jingning Han's avatar
Jingning Han committed
250
                  ACCT_STR)) {
251 252 253 254 255 256 257 258 259 260
            br_offset = tok;
            if (counts) ++counts->coeff_lps[txs_ctx][plane_type][ctx][1];
            break;
          }
          if (counts) ++counts->coeff_lps[txs_ctx][plane_type][ctx][0];
        }
        if (tok == extra_bits) br_offset = extra_bits;

        int br_base = br_index_to_coeff[idx];

261 262
        *level = NUM_BASE_LEVELS + 1 + br_base + br_offset;
        cul_level += *level;
263 264
        break;
      }
265
      if (counts) ++counts->coeff_br[txs_ctx][plane_type][idx][ctx][0];
266 267 268
    }

    if (idx < BASE_RANGE_SETS) continue;
269 270

    // decode 0-th order Golomb code
271 272 273 274
    *level = COEFF_BASE_RANGE + 1 + NUM_BASE_LEVELS;
    // Save golomb in tcoeffs because adding it to level may incur overflow
    tcoeffs[scan[c]] = read_golomb(xd, r, counts);
    cul_level += *level + tcoeffs[scan[c]];
275 276
  }

277
  for (c = 0; c < *eob; ++c) {
278 279
    const int16_t dqv = (c == 0) ? dequant[0] : dequant[1];
    const int level = levels[scan[c]];
280
    const tran_low_t t = ((level + tcoeffs[scan[c]]) * dqv) >> shift;
281
#if CONFIG_SYMBOLRATE
282
    av1_record_coeff(counts, level);
283
#endif
284
    tcoeffs[scan[c]] = signs[scan[c]] ? -t : t;
285 286 287 288 289 290 291 292 293
  }

  cul_level = AOMMIN(63, cul_level);

  // DC value
  set_dc_sign(&cul_level, tcoeffs[0]);

  return cul_level;
}
Angie Chiang's avatar
Angie Chiang committed
294

295
uint8_t av1_read_coeffs_txb_facade(AV1_COMMON *cm, MACROBLOCKD *xd,
Angie Chiang's avatar
Angie Chiang committed
296 297
                                   aom_reader *r, int row, int col, int block,
                                   int plane, tran_low_t *tcoeffs,
Jingning Han's avatar
Jingning Han committed
298 299
                                   TX_SIZE tx_size, int16_t *max_scan_line,
                                   int *eob) {
Angie Chiang's avatar
Angie Chiang committed
300
  MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
301
  struct macroblockd_plane *pd = &xd->plane[plane];
Angie Chiang's avatar
Angie Chiang committed
302 303 304 305 306 307 308 309

  const BLOCK_SIZE bsize = mbmi->sb_type;
  const BLOCK_SIZE plane_bsize =
      AOMMAX(BLOCK_4X4, get_plane_block_size(bsize, pd));

  TXB_CTX txb_ctx;
  get_txb_ctx(plane_bsize, tx_size, plane, pd->above_context + col,
              pd->left_context + row, &txb_ctx);
Jingning Han's avatar
Jingning Han committed
310 311 312
  uint8_t cul_level =
      av1_read_coeffs_txb(cm, xd, r, row, col, block, plane, tcoeffs, &txb_ctx,
                          tx_size, max_scan_line, eob);
313 314
#if CONFIG_ADAPT_SCAN
  PLANE_TYPE plane_type = get_plane_type(plane);
315
  TX_TYPE tx_type = av1_get_tx_type(plane_type, xd, row, col, block, tx_size);
316 317 318 319
  if (xd->counts && *eob > 0)
    av1_update_scan_count_facade(cm, xd->counts, tx_size, tx_type, pd->dqcoeff,
                                 *eob);
#endif
320 321
  av1_set_contexts(xd, pd, plane, tx_size, cul_level, col, row);
  return cul_level;
Angie Chiang's avatar
Angie Chiang committed
322
}