txb_common.h 16.6 KB
Newer Older
Angie Chiang's avatar
Angie Chiang committed
1 2 3 4 5 6 7 8 9 10 11 12 13
/*
 * 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.
 */

#ifndef AV1_COMMON_TXB_COMMON_H_
#define AV1_COMMON_TXB_COMMON_H_
14

Dake He's avatar
Dake He committed
15 16 17
extern const int16_t k_eob_group_start[12];
extern const int16_t k_eob_offset_bits[12];
int16_t get_eob_pos_token(int eob, int16_t *extra);
Jingning Han's avatar
Jingning Han committed
18
int av1_get_eob_pos_ctx(TX_TYPE tx_type, int eob_token);
Dake He's avatar
Dake He committed
19

20
extern const int16_t av1_coeff_band_4x4[16];
Angie Chiang's avatar
Angie Chiang committed
21

22
extern const int16_t av1_coeff_band_8x8[64];
Angie Chiang's avatar
Angie Chiang committed
23

24 25 26
extern const int16_t av1_coeff_band_16x16[256];

extern const int16_t av1_coeff_band_32x32[1024];
Angie Chiang's avatar
Angie Chiang committed
27

28 29 30 31 32
typedef struct txb_ctx {
  int txb_skip_ctx;
  int dc_sign_ctx;
} TXB_CTX;

33 34 35 36
static INLINE TX_SIZE get_txsize_context(TX_SIZE tx_size) {
  return txsize_sqr_up_map[tx_size];
}

37 38 39 40
static const int base_level_count_to_index[13] = {
  0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
};

41
static const int base_ref_offset[BASE_CONTEXT_POSITION_NUM][2] = {
Angie Chiang's avatar
Angie Chiang committed
42 43 44 45 46 47
  /* clang-format off*/
  { -2, 0 }, { -1, -1 }, { -1, 0 }, { -1, 1 }, { 0, -2 }, { 0, -1 }, { 0, 1 },
  { 0, 2 },  { 1, -1 },  { 1, 0 },  { 1, 1 },  { 2, 0 }
  /* clang-format on*/
};

Angie Chiang's avatar
Angie Chiang committed
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
static INLINE void get_base_count_mag(int *mag, int *count,
                                      const tran_low_t *tcoeffs, int bwl,
                                      int height, int row, int col) {
  mag[0] = 0;
  mag[1] = 0;
  for (int i = 0; i < NUM_BASE_LEVELS; ++i) count[i] = 0;
  for (int idx = 0; idx < BASE_CONTEXT_POSITION_NUM; ++idx) {
    const int ref_row = row + base_ref_offset[idx][0];
    const int ref_col = col + base_ref_offset[idx][1];
    if (ref_row < 0 || ref_col < 0 || ref_row >= height ||
        ref_col >= (1 << bwl))
      continue;
    const int pos = (ref_row << bwl) + ref_col;
    tran_low_t abs_coeff = abs(tcoeffs[pos]);
    // count
    for (int i = 0; i < NUM_BASE_LEVELS; ++i) {
      count[i] += abs_coeff > i;
    }
    // mag
    if (base_ref_offset[idx][0] >= 0 && base_ref_offset[idx][1] >= 0) {
      if (abs_coeff > mag[0]) {
        mag[0] = abs_coeff;
        mag[1] = 1;
      } else if (abs_coeff == mag[0]) {
        ++mag[1];
      }
    }
  }
}

78 79 80 81 82 83
static INLINE int get_level_count_mag(
    int *const mag, const uint8_t *const levels, const int bwl,
    const int height, const int row, const int col, const int level,
    const int (*nb_offset)[2], const int nb_num) {
  const int stride = 1 << bwl;
  int count = 0;
84

85 86 87 88 89 90 91
  for (int idx = 0; idx < nb_num; ++idx) {
    const int ref_row = row + nb_offset[idx][0];
    const int ref_col = col + nb_offset[idx][1];
    if (ref_row < 0 || ref_col < 0 || ref_row >= height || ref_col >= stride)
      continue;
    const int pos = (ref_row << bwl) + ref_col;
    count += levels[pos] > level;
92 93 94
    if (nb_offset[idx][0] == 0 && nb_offset[idx][1] == 1) mag[0] = levels[pos];
    if (nb_offset[idx][0] == 1 && nb_offset[idx][1] == 0) mag[1] = levels[pos];
    if (nb_offset[idx][0] == 1 && nb_offset[idx][1] == 1) mag[2] = levels[pos];
95 96 97 98
  }
  return count;
}

99
static INLINE int get_base_ctx_from_count_mag(int row, int col, int count,
100
                                              int sig_mag) {
101
  const int ctx = base_level_count_to_index[count];
Angie Chiang's avatar
Angie Chiang committed
102
  int ctx_idx = -1;
103

Angie Chiang's avatar
Angie Chiang committed
104
  if (row == 0 && col == 0) {
105 106 107 108 109 110 111 112 113 114 115 116 117
    if (sig_mag >= 2) return ctx_idx = 0;
    if (sig_mag == 1) {
      if (count >= 2)
        ctx_idx = 1;
      else
        ctx_idx = 2;

      return ctx_idx;
    }

    ctx_idx = 3 + ctx;
    assert(ctx_idx <= 6);
    return ctx_idx;
Angie Chiang's avatar
Angie Chiang committed
118
  } else if (row == 0) {
119 120 121 122 123 124 125 126 127 128
    if (sig_mag >= 2) return ctx_idx = 6;
    if (sig_mag == 1) {
      if (count >= 2)
        ctx_idx = 7;
      else
        ctx_idx = 8;
      return ctx_idx;
    }

    ctx_idx = 9 + ctx;
129
    assert(ctx_idx <= 11);
130
    return ctx_idx;
Angie Chiang's avatar
Angie Chiang committed
131
  } else if (col == 0) {
132
    if (sig_mag >= 2) return ctx_idx = 12;
133 134
    if (sig_mag == 1) {
      if (count >= 2)
135
        ctx_idx = 13;
136
      else
137
        ctx_idx = 14;
138 139 140 141

      return ctx_idx;
    }

142 143
    ctx_idx = 15 + ctx;
    assert(ctx_idx <= 17);
144 145
    // TODO(angiebird): turn this on once the optimization is finalized
    // assert(ctx_idx < 28);
Angie Chiang's avatar
Angie Chiang committed
146
  } else {
147
    if (sig_mag >= 2) return ctx_idx = 18;
148 149
    if (sig_mag == 1) {
      if (count >= 2)
150
        ctx_idx = 19;
151
      else
152
        ctx_idx = 20;
153 154 155
      return ctx_idx;
    }

156
    ctx_idx = 21 + ctx;
157

158
    assert(ctx_idx <= 24);
Angie Chiang's avatar
Angie Chiang committed
159 160 161 162
  }
  return ctx_idx;
}

163 164
static INLINE int get_base_ctx(const uint8_t *const levels,
                               const int c,  // raster order
165 166
                               const int bwl, const int height,
                               const int level) {
167 168 169
  const int row = c >> bwl;
  const int col = c - (row << bwl);
  const int level_minus_1 = level - 1;
170 171
  int mag_count = 0;
  int nb_mag[3] = { 0 };
172
  const int count =
173
      get_level_count_mag(nb_mag, levels, bwl, height, row, col, level_minus_1,
174
                          base_ref_offset, BASE_CONTEXT_POSITION_NUM);
175 176 177 178

  for (int idx = 0; idx < 3; ++idx) mag_count += nb_mag[idx] > level;
  const int ctx_idx =
      get_base_ctx_from_count_mag(row, col, count, AOMMIN(2, mag_count));
179 180 181
  return ctx_idx;
}

Angie Chiang's avatar
Angie Chiang committed
182
#define BR_CONTEXT_POSITION_NUM 8  // Base range coefficient context
183
static const int br_ref_offset[BR_CONTEXT_POSITION_NUM][2] = {
Angie Chiang's avatar
Angie Chiang committed
184 185 186 187 188 189
  /* clang-format off*/
  { -1, -1 }, { -1, 0 }, { -1, 1 }, { 0, -1 },
  { 0, 1 },   { 1, -1 }, { 1, 0 },  { 1, 1 },
  /* clang-format on*/
};

190
static const int br_level_map[9] = {
Angie Chiang's avatar
Angie Chiang committed
191 192 193
  0, 0, 1, 1, 2, 2, 3, 3, 3,
};

194 195 196 197 198 199 200 201 202 203 204 205
static const int coeff_to_br_index[COEFF_BASE_RANGE] = {
  0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2,
};

static const int br_index_to_coeff[BASE_RANGE_SETS] = {
  0, 2, 6,
};

static const int br_extra_bits[BASE_RANGE_SETS] = {
  1, 2, 3,
};

206 207 208
#define BR_MAG_OFFSET 1
// TODO(angiebird): optimize this function by using a table to map from
// count/mag to ctx
Angie Chiang's avatar
Angie Chiang committed
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235

static INLINE int get_br_count_mag(int *mag, const tran_low_t *tcoeffs, int bwl,
                                   int height, int row, int col, int level) {
  mag[0] = 0;
  mag[1] = 0;
  int count = 0;
  for (int idx = 0; idx < BR_CONTEXT_POSITION_NUM; ++idx) {
    const int ref_row = row + br_ref_offset[idx][0];
    const int ref_col = col + br_ref_offset[idx][1];
    if (ref_row < 0 || ref_col < 0 || ref_row >= height ||
        ref_col >= (1 << bwl))
      continue;
    const int pos = (ref_row << bwl) + ref_col;
    tran_low_t abs_coeff = abs(tcoeffs[pos]);
    count += abs_coeff > level;
    if (br_ref_offset[idx][0] >= 0 && br_ref_offset[idx][1] >= 0) {
      if (abs_coeff > mag[0]) {
        mag[0] = abs_coeff;
        mag[1] = 1;
      } else if (abs_coeff == mag[0]) {
        ++mag[1];
      }
    }
  }
  return count;
}

236 237
static INLINE int get_br_ctx_from_count_mag(int row, int col, int count,
                                            int mag) {
238
  int offset = 0;
239
  if (mag <= BR_MAG_OFFSET)
Angie Chiang's avatar
Angie Chiang committed
240 241 242
    offset = 0;
  else if (mag <= 3)
    offset = 1;
243
  else if (mag <= 5)
Angie Chiang's avatar
Angie Chiang committed
244 245 246 247
    offset = 2;
  else
    offset = 3;

248
  int ctx = br_level_map[count];
Angie Chiang's avatar
Angie Chiang committed
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
  ctx += offset * BR_TMP_OFFSET;

  // DC: 0 - 1
  if (row == 0 && col == 0) return ctx;

  // Top row: 2 - 4
  if (row == 0) return 2 + ctx;

  // Left column: 5 - 7
  if (col == 0) return 5 + ctx;

  // others: 8 - 11
  return 8 + ctx;
}

264
static INLINE int get_br_ctx(const uint8_t *const levels,
265
                             const int c,  // raster order
266
                             const int bwl, const int height) {
267 268 269
  const int row = c >> bwl;
  const int col = c - (row << bwl);
  const int level_minus_1 = NUM_BASE_LEVELS;
270 271
  int mag = 0;
  int nb_mag[3] = { 0 };
272
  const int count =
273
      get_level_count_mag(nb_mag, levels, bwl, height, row, col, level_minus_1,
274
                          br_ref_offset, BR_CONTEXT_POSITION_NUM);
275
  for (int idx = 0; idx < 3; ++idx) mag = AOMMAX(mag, nb_mag[idx]);
276 277 278 279
  const int ctx = get_br_ctx_from_count_mag(row, col, count, mag);
  return ctx;
}

Angie Chiang's avatar
Angie Chiang committed
280
#define SIG_REF_OFFSET_NUM 7
Jingning Han's avatar
Jingning Han committed
281

282
static const int sig_ref_offset[SIG_REF_OFFSET_NUM][2] = {
283
  { 0, 1 }, { 1, 0 }, { 1, 1 }, { 0, 2 }, { 2, 0 }, { 1, 2 }, { 2, 1 },
Dake He's avatar
Dake He committed
284 285
};

286
static const int sig_ref_offset_vert[SIG_REF_OFFSET_NUM][2] = {
287
  { 1, 0 }, { 2, 0 }, { 0, 1 }, { 3, 0 }, { 4, 0 }, { 1, 1 }, { 2, 1 },
Dake He's avatar
Dake He committed
288 289
};

290
static const int sig_ref_offset_horiz[SIG_REF_OFFSET_NUM][2] = {
291
  { 0, 1 }, { 0, 2 }, { 1, 0 }, { 0, 3 }, { 0, 4 }, { 1, 1 }, { 1, 2 },
Dake He's avatar
Dake He committed
292 293
};

294
#if USE_CAUSAL_BASE_CTX
295 296 297 298
static INLINE int get_nz_count_mag(const uint8_t *const levels, const int bwl,
                                   const int height, const int row,
                                   const int col, const TX_CLASS tx_class,
                                   int *const mag) {
299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317
  int count = 0;
  *mag = 0;
  for (int idx = 0; idx < SIG_REF_OFFSET_NUM; ++idx) {
    const int row_offset =
        ((tx_class == TX_CLASS_2D)
             ? sig_ref_offset[idx][0]
             : ((tx_class == TX_CLASS_VERT) ? sig_ref_offset_vert[idx][0]
                                            : sig_ref_offset_horiz[idx][0]));
    const int col_offset =
        ((tx_class == TX_CLASS_2D)
             ? sig_ref_offset[idx][1]
             : ((tx_class == TX_CLASS_VERT) ? sig_ref_offset_vert[idx][1]
                                            : sig_ref_offset_horiz[idx][1]));
    const int ref_row = row + row_offset;
    const int ref_col = col + col_offset;
    if (ref_row < 0 || ref_col < 0 || ref_row >= height ||
        ref_col >= (1 << bwl))
      continue;
    const int nb_pos = (ref_row << bwl) + ref_col;
318
    const int level = levels[nb_pos];
319 320 321 322 323 324 325 326 327 328
    count += (level != 0);
#if 1
    if (idx < 5) {
      *mag += AOMMIN(level, 3);
    }
#endif
  }
  return count;
}
#endif
329 330 331
static INLINE int get_nz_count(const uint8_t *const levels, const int bwl,
                               const int height, const int row, const int col,
                               const TX_CLASS tx_class) {
Dake He's avatar
Dake He committed
332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347
  int count = 0;
  for (int idx = 0; idx < SIG_REF_OFFSET_NUM; ++idx) {
    const int ref_row = row + ((tx_class == TX_CLASS_2D)
                                   ? sig_ref_offset[idx][0]
                                   : ((tx_class == TX_CLASS_VERT)
                                          ? sig_ref_offset_vert[idx][0]
                                          : sig_ref_offset_horiz[idx][0]));
    const int ref_col = col + ((tx_class == TX_CLASS_2D)
                                   ? sig_ref_offset[idx][1]
                                   : ((tx_class == TX_CLASS_VERT)
                                          ? sig_ref_offset_vert[idx][1]
                                          : sig_ref_offset_horiz[idx][1]));
    if (ref_row < 0 || ref_col < 0 || ref_row >= height ||
        ref_col >= (1 << bwl))
      continue;
    const int nb_pos = (ref_row << bwl) + ref_col;
348
    count += (levels[nb_pos] != 0);
Dake He's avatar
Dake He committed
349 350 351 352
  }
  return count;
}

353 354 355 356 357 358 359 360 361 362 363 364
static INLINE TX_CLASS get_tx_class(TX_TYPE tx_type) {
  switch (tx_type) {
    case V_DCT:
    case V_ADST:
    case V_FLIPADST: return TX_CLASS_VERT;
    case H_DCT:
    case H_ADST:
    case H_FLIPADST: return TX_CLASS_HORIZ;
    default: return TX_CLASS_2D;
  }
}

365 366 367 368
// TODO(angiebird): optimize this function by generate a table that maps from
// count to ctx
static INLINE int get_nz_map_ctx_from_count(int count,
                                            int coeff_idx,  // raster order
Jingning Han's avatar
Jingning Han committed
369
                                            int bwl, int height,
370 371 372
#if USE_CAUSAL_BASE_CTX
                                            const int mag,
#endif
Dake He's avatar
Dake He committed
373
                                            TX_TYPE tx_type) {
374
  (void)tx_type;
375 376
  const int row = coeff_idx >> bwl;
  const int col = coeff_idx - (row << bwl);
377 378
  const int width = 1 << bwl;

379
  int ctx = 0;
380 381 382 383 384 385 386
  int tx_class = get_tx_class(tx_type);
  int offset;
  if (tx_class == TX_CLASS_2D)
    offset = 0;
  else if (tx_class == TX_CLASS_VERT)
    offset = SIG_COEF_CONTEXTS_2D;
  else
387 388 389
#if USE_CAUSAL_BASE_CTX
    offset = SIG_COEF_CONTEXTS_2D;
#else
390
    offset = SIG_COEF_CONTEXTS_2D + SIG_COEF_CONTEXTS_1D;
391
#endif
392

393 394 395 396
#if USE_CAUSAL_BASE_CTX
  (void)count;
  ctx = AOMMIN((mag + 1) >> 1, 4);
#else
Dake He's avatar
Dake He committed
397
  ctx = (count + 1) >> 1;
398
#endif
Dake He's avatar
Dake He committed
399 400 401 402 403

  if (tx_class == TX_CLASS_2D) {
    {
      if (row == 0 && col == 0) return offset + 0;

404 405
      if (width < height)
        if (row < 2) return offset + 11 + ctx;
Dake He's avatar
Dake He committed
406

407 408 409 410
      if (width > height)
        if (col < 2) return offset + 16 + ctx;

      if (row + col < 2) return offset + ctx + 1;
Dake He's avatar
Dake He committed
411 412
      if (row + col < 4) return offset + 5 + ctx + 1;

413
      return offset + 21 + AOMMIN(ctx, 4);
Dake He's avatar
Dake He committed
414 415 416 417 418 419 420 421 422 423 424 425
    }
  } else {
    if (tx_class == TX_CLASS_VERT) {
      if (row == 0) return offset + ctx;
      if (row < 2) return offset + 5 + ctx;
      return offset + 10 + ctx;
    } else {
      if (col == 0) return offset + ctx;
      if (col < 2) return offset + 5 + ctx;
      return offset + 10 + ctx;
    }
  }
426 427
}

428 429 430 431
static INLINE int get_nz_map_ctx(const uint8_t *const levels,
                                 const int scan_idx, const int16_t *const scan,
                                 const int bwl, const int height,
                                 const TX_TYPE tx_type) {
432
  const int coeff_idx = scan[scan_idx];
433 434
  const int row = coeff_idx >> bwl;
  const int col = coeff_idx - (row << bwl);
Jingning Han's avatar
Jingning Han committed
435

Dake He's avatar
Dake He committed
436
  int tx_class = get_tx_class(tx_type);
437 438
#if USE_CAUSAL_BASE_CTX
  int mag = 0;
439
  int count = get_nz_count_mag(levels, bwl, height, row, col, tx_class, &mag);
440 441
  return get_nz_map_ctx_from_count(count, coeff_idx, bwl, height, mag, tx_type);
#else
442
  int count = get_nz_count(levels, bwl, height, row, col, tx_class);
Jingning Han's avatar
Jingning Han committed
443
  return get_nz_map_ctx_from_count(count, coeff_idx, bwl, height, tx_type);
444
#endif
445 446
}

Linfeng Zhang's avatar
Linfeng Zhang committed
447 448
static INLINE int get_eob_ctx(const int coeff_idx,  // raster order
                              const TX_SIZE txs_ctx, const TX_TYPE tx_type) {
449 450
  int offset = 0;
#if CONFIG_CTX1D
Linfeng Zhang's avatar
Linfeng Zhang committed
451
  const TX_CLASS tx_class = get_tx_class(tx_type);
452 453 454 455 456
  if (tx_class == TX_CLASS_VERT)
    offset = EOB_COEF_CONTEXTS_2D;
  else if (tx_class == TX_CLASS_HORIZ)
    offset = EOB_COEF_CONTEXTS_2D + EOB_COEF_CONTEXTS_1D;
#else
Angie Chiang's avatar
Angie Chiang committed
457
  (void)tx_type;
458 459 460 461 462 463
#endif

  if (txs_ctx == TX_4X4) return offset + av1_coeff_band_4x4[coeff_idx];
  if (txs_ctx == TX_8X8) return offset + av1_coeff_band_8x8[coeff_idx];
  if (txs_ctx == TX_16X16) return offset + av1_coeff_band_16x16[coeff_idx];
  if (txs_ctx == TX_32X32) return offset + av1_coeff_band_32x32[coeff_idx];
Angie Chiang's avatar
Angie Chiang committed
464

465 466
  assert(0);
  return 0;
Angie Chiang's avatar
Angie Chiang committed
467 468
}

469 470 471 472 473 474
static INLINE void set_dc_sign(int *cul_level, tran_low_t v) {
  if (v < 0)
    *cul_level |= 1 << COEFF_CONTEXT_BITS;
  else if (v > 0)
    *cul_level += 2 << COEFF_CONTEXT_BITS;
}
Angie Chiang's avatar
Angie Chiang committed
475 476 477 478 479 480 481 482 483 484 485

static INLINE int get_dc_sign_ctx(int dc_sign) {
  int dc_sign_ctx = 0;
  if (dc_sign < 0)
    dc_sign_ctx = 1;
  else if (dc_sign > 0)
    dc_sign_ctx = 2;

  return dc_sign_ctx;
}

486 487
static INLINE void get_txb_ctx(BLOCK_SIZE plane_bsize, TX_SIZE tx_size,
                               int plane, const ENTROPY_CONTEXT *a,
488
                               const ENTROPY_CONTEXT *l, TXB_CTX *txb_ctx) {
489 490
  const int txb_w_unit = tx_size_wide_unit[tx_size];
  const int txb_h_unit = tx_size_high_unit[tx_size];
Angie Chiang's avatar
Angie Chiang committed
491 492
  int ctx_offset = (plane == 0) ? 0 : 7;

493
  if (plane_bsize > txsize_to_bsize[tx_size]) ctx_offset += 3;
Angie Chiang's avatar
Angie Chiang committed
494

495
  int dc_sign = 0;
496
  for (int k = 0; k < txb_w_unit; ++k) {
Angie Chiang's avatar
Angie Chiang committed
497
    int sign = ((uint8_t)a[k]) >> COEFF_CONTEXT_BITS;
Angie Chiang's avatar
Angie Chiang committed
498
    if (sign == 1)
499
      --dc_sign;
Angie Chiang's avatar
Angie Chiang committed
500
    else if (sign == 2)
501
      ++dc_sign;
Angie Chiang's avatar
Angie Chiang committed
502
    else if (sign != 0)
Angie Chiang's avatar
Angie Chiang committed
503
      assert(0);
504
  }
Angie Chiang's avatar
Angie Chiang committed
505

506 507
  for (int k = 0; k < txb_h_unit; ++k) {
    int sign = ((uint8_t)l[k]) >> COEFF_CONTEXT_BITS;
Angie Chiang's avatar
Angie Chiang committed
508
    if (sign == 1)
509
      --dc_sign;
Angie Chiang's avatar
Angie Chiang committed
510
    else if (sign == 2)
511
      ++dc_sign;
Angie Chiang's avatar
Angie Chiang committed
512
    else if (sign != 0)
Angie Chiang's avatar
Angie Chiang committed
513
      assert(0);
Angie Chiang's avatar
Angie Chiang committed
514
  }
515

516
  txb_ctx->dc_sign_ctx = get_dc_sign_ctx(dc_sign);
Angie Chiang's avatar
Angie Chiang committed
517 518 519 520

  if (plane == 0) {
    int top = 0;
    int left = 0;
521 522

    for (int k = 0; k < txb_w_unit; ++k) {
Angie Chiang's avatar
Angie Chiang committed
523
      top = AOMMAX(top, ((uint8_t)a[k] & COEFF_CONTEXT_MASK));
524 525 526
    }

    for (int k = 0; k < txb_h_unit; ++k) {
Angie Chiang's avatar
Angie Chiang committed
527
      left = AOMMAX(left, ((uint8_t)l[k] & COEFF_CONTEXT_MASK));
Angie Chiang's avatar
Angie Chiang committed
528
    }
529

Angie Chiang's avatar
Angie Chiang committed
530 531 532
    top = AOMMIN(top, 255);
    left = AOMMIN(left, 255);

533
    if (plane_bsize == txsize_to_bsize[tx_size])
534
      txb_ctx->txb_skip_ctx = 0;
Angie Chiang's avatar
Angie Chiang committed
535
    else if (top == 0 && left == 0)
536
      txb_ctx->txb_skip_ctx = 1;
Angie Chiang's avatar
Angie Chiang committed
537
    else if (top == 0 || left == 0)
538
      txb_ctx->txb_skip_ctx = 2 + (AOMMAX(top, left) > 3);
Angie Chiang's avatar
Angie Chiang committed
539
    else if (AOMMAX(top, left) <= 3)
540
      txb_ctx->txb_skip_ctx = 4;
Angie Chiang's avatar
Angie Chiang committed
541
    else if (AOMMIN(top, left) <= 3)
542
      txb_ctx->txb_skip_ctx = 5;
Angie Chiang's avatar
Angie Chiang committed
543
    else
544
      txb_ctx->txb_skip_ctx = 6;
Angie Chiang's avatar
Angie Chiang committed
545 546
  } else {
    int ctx_base = get_entropy_context(tx_size, a, l);
547
    txb_ctx->txb_skip_ctx = ctx_offset + ctx_base;
Angie Chiang's avatar
Angie Chiang committed
548 549
  }
}
Angie Chiang's avatar
Angie Chiang committed
550

551
void av1_init_txb_probs(FRAME_CONTEXT *fc);
552 553

void av1_init_lv_map(AV1_COMMON *cm);
554

Angie Chiang's avatar
Angie Chiang committed
555
#endif  // AV1_COMMON_TXB_COMMON_H_