tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

txb_common.h (20374B)


      1 /*
      2 * Copyright (c) 2017, Alliance for Open Media. All rights reserved.
      3 *
      4 * This source code is subject to the terms of the BSD 2 Clause License and
      5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
      6 * was not distributed with this source code in the LICENSE file, you can
      7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
      8 * Media Patent License 1.0 was not distributed with this source code in the
      9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
     10 */
     11 
     12 #ifndef AOM_AV1_COMMON_TXB_COMMON_H_
     13 #define AOM_AV1_COMMON_TXB_COMMON_H_
     14 
     15 #include "av1/common/av1_common_int.h"
     16 
     17 extern const int16_t av1_eob_group_start[12];
     18 extern const int16_t av1_eob_offset_bits[12];
     19 
     20 extern const int8_t *av1_nz_map_ctx_offset[TX_SIZES_ALL];
     21 
     22 typedef struct txb_ctx {
     23  int txb_skip_ctx;
     24  int dc_sign_ctx;
     25 } TXB_CTX;
     26 
     27 static const int base_level_count_to_index[13] = {
     28  0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
     29 };
     30 
     31 static const TX_CLASS tx_type_to_class[TX_TYPES] = {
     32  TX_CLASS_2D,     // DCT_DCT
     33  TX_CLASS_2D,     // ADST_DCT
     34  TX_CLASS_2D,     // DCT_ADST
     35  TX_CLASS_2D,     // ADST_ADST
     36  TX_CLASS_2D,     // FLIPADST_DCT
     37  TX_CLASS_2D,     // DCT_FLIPADST
     38  TX_CLASS_2D,     // FLIPADST_FLIPADST
     39  TX_CLASS_2D,     // ADST_FLIPADST
     40  TX_CLASS_2D,     // FLIPADST_ADST
     41  TX_CLASS_2D,     // IDTX
     42  TX_CLASS_VERT,   // V_DCT
     43  TX_CLASS_HORIZ,  // H_DCT
     44  TX_CLASS_VERT,   // V_ADST
     45  TX_CLASS_HORIZ,  // H_ADST
     46  TX_CLASS_VERT,   // V_FLIPADST
     47  TX_CLASS_HORIZ,  // H_FLIPADST
     48 };
     49 
     50 static inline int get_txb_bhl(TX_SIZE tx_size) {
     51  tx_size = av1_get_adjusted_tx_size(tx_size);
     52  return tx_size_high_log2[tx_size];
     53 }
     54 
     55 static inline int get_txb_wide(TX_SIZE tx_size) {
     56  tx_size = av1_get_adjusted_tx_size(tx_size);
     57  return tx_size_wide[tx_size];
     58 }
     59 
     60 static inline int get_txb_high(TX_SIZE tx_size) {
     61  tx_size = av1_get_adjusted_tx_size(tx_size);
     62  return tx_size_high[tx_size];
     63 }
     64 
     65 static inline uint8_t *set_levels(uint8_t *const levels_buf, const int height) {
     66  return levels_buf + TX_PAD_TOP * (height + TX_PAD_HOR);
     67 }
     68 
     69 static inline int get_padded_idx(const int idx, const int bhl) {
     70  return idx + ((idx >> bhl) << TX_PAD_HOR_LOG2);
     71 }
     72 
     73 static inline int get_br_ctx_2d(const uint8_t *const levels,
     74                                const int c,  // raster order
     75                                const int bhl) {
     76  assert(c > 0);
     77  const int col = c >> bhl;
     78  const int row = c - (col << bhl);
     79  const int stride = (1 << bhl) + TX_PAD_HOR;
     80  const int pos = col * stride + row;
     81  int mag = AOMMIN(levels[pos + 1], MAX_BASE_BR_RANGE) +
     82            AOMMIN(levels[pos + stride], MAX_BASE_BR_RANGE) +
     83            AOMMIN(levels[pos + 1 + stride], MAX_BASE_BR_RANGE);
     84  mag = AOMMIN((mag + 1) >> 1, 6);
     85  //((row | col) < 2) is equivalent to ((row < 2) && (col < 2))
     86  if ((row | col) < 2) return mag + 7;
     87  return mag + 14;
     88 }
     89 
     90 static AOM_FORCE_INLINE int get_br_ctx_eob(const int c,  // raster order
     91                                           const int bhl,
     92                                           const TX_CLASS tx_class) {
     93  const int col = c >> bhl;
     94  const int row = c - (col << bhl);
     95  if (c == 0) return 0;
     96  if ((tx_class == TX_CLASS_2D && row < 2 && col < 2) ||
     97      (tx_class == TX_CLASS_HORIZ && col == 0) ||
     98      (tx_class == TX_CLASS_VERT && row == 0))
     99    return 7;
    100  return 14;
    101 }
    102 
    103 static AOM_FORCE_INLINE int get_br_ctx(const uint8_t *const levels,
    104                                       const int c,  // raster order
    105                                       const int bhl, const TX_CLASS tx_class) {
    106  const int col = c >> bhl;
    107  const int row = c - (col << bhl);
    108  const int stride = (1 << bhl) + TX_PAD_HOR;
    109  const int pos = col * stride + row;
    110  int mag = levels[pos + 1];
    111  mag += levels[pos + stride];
    112  switch (tx_class) {
    113    case TX_CLASS_2D:
    114      mag += levels[pos + stride + 1];
    115      mag = AOMMIN((mag + 1) >> 1, 6);
    116      if (c == 0) return mag;
    117      if ((row < 2) && (col < 2)) return mag + 7;
    118      break;
    119    case TX_CLASS_HORIZ:
    120      mag += levels[pos + (stride << 1)];
    121      mag = AOMMIN((mag + 1) >> 1, 6);
    122      if (c == 0) return mag;
    123      if (col == 0) return mag + 7;
    124      break;
    125    case TX_CLASS_VERT:
    126      mag += levels[pos + 2];
    127      mag = AOMMIN((mag + 1) >> 1, 6);
    128      if (c == 0) return mag;
    129      if (row == 0) return mag + 7;
    130      break;
    131    default: break;
    132  }
    133 
    134  return mag + 14;
    135 }
    136 
    137 static const uint8_t clip_max3[256] = {
    138  0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    139  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    140  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    141  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    142  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    143  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    144  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    145  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    146  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    147  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
    148 };
    149 
    150 static AOM_FORCE_INLINE int get_nz_mag(const uint8_t *const levels,
    151                                       const int bhl, const TX_CLASS tx_class) {
    152  int mag;
    153 
    154  // Note: AOMMIN(level, 3) is useless for decoder since level < 3.
    155  mag = clip_max3[levels[(1 << bhl) + TX_PAD_HOR]];  // { 0, 1 }
    156  mag += clip_max3[levels[1]];                       // { 1, 0 }
    157 
    158  if (tx_class == TX_CLASS_2D) {
    159    mag += clip_max3[levels[(1 << bhl) + TX_PAD_HOR + 1]];          // { 1, 1 }
    160    mag += clip_max3[levels[(2 << bhl) + (2 << TX_PAD_HOR_LOG2)]];  // { 0, 2 }
    161    mag += clip_max3[levels[2]];                                    // { 2, 0 }
    162  } else if (tx_class == TX_CLASS_VERT) {
    163    mag += clip_max3[levels[2]];  // { 2, 0 }
    164    mag += clip_max3[levels[3]];  // { 3, 0 }
    165    mag += clip_max3[levels[4]];  // { 4, 0 }
    166  } else {
    167    mag += clip_max3[levels[(2 << bhl) + (2 << TX_PAD_HOR_LOG2)]];  // { 0, 2 }
    168    mag += clip_max3[levels[(3 << bhl) + (3 << TX_PAD_HOR_LOG2)]];  // { 0, 3 }
    169    mag += clip_max3[levels[(4 << bhl) + (4 << TX_PAD_HOR_LOG2)]];  // { 0, 4 }
    170  }
    171 
    172  return mag;
    173 }
    174 
    175 #define NZ_MAP_CTX_0 SIG_COEF_CONTEXTS_2D
    176 #define NZ_MAP_CTX_5 (NZ_MAP_CTX_0 + 5)
    177 #define NZ_MAP_CTX_10 (NZ_MAP_CTX_0 + 10)
    178 
    179 static const int nz_map_ctx_offset_1d[32] = {
    180  NZ_MAP_CTX_0,  NZ_MAP_CTX_5,  NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10,
    181  NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10,
    182  NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10,
    183  NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10,
    184  NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10,
    185  NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10,
    186  NZ_MAP_CTX_10, NZ_MAP_CTX_10,
    187 };
    188 
    189 static AOM_FORCE_INLINE int get_nz_map_ctx_from_stats(
    190    const int stats,
    191    const int coeff_idx,  // raster order
    192    const int bhl, const TX_SIZE tx_size, const TX_CLASS tx_class) {
    193  // tx_class == 0(TX_CLASS_2D)
    194  if ((tx_class | coeff_idx) == 0) return 0;
    195  int ctx = (stats + 1) >> 1;
    196  ctx = AOMMIN(ctx, 4);
    197  switch (tx_class) {
    198    case TX_CLASS_2D: {
    199      // This is the algorithm to generate av1_nz_map_ctx_offset[][]
    200      //   const int width = tx_size_wide[tx_size];
    201      //   const int height = tx_size_high[tx_size];
    202      //   if (width < height) {
    203      //     if (row < 2) return 11 + ctx;
    204      //   } else if (width > height) {
    205      //     if (col < 2) return 16 + ctx;
    206      //   }
    207      //   if (row + col < 2) return ctx + 1;
    208      //   if (row + col < 4) return 5 + ctx + 1;
    209      //   return 21 + ctx;
    210      return ctx + av1_nz_map_ctx_offset[tx_size][coeff_idx];
    211    }
    212    case TX_CLASS_HORIZ: {
    213      const int col = coeff_idx >> bhl;
    214      return ctx + nz_map_ctx_offset_1d[col];
    215    }
    216    case TX_CLASS_VERT: {
    217      const int col = coeff_idx >> bhl;
    218      const int row = coeff_idx - (col << bhl);
    219      return ctx + nz_map_ctx_offset_1d[row];
    220    }
    221    default: break;
    222  }
    223  return 0;
    224 }
    225 
    226 typedef aom_cdf_prob (*base_cdf_arr)[CDF_SIZE(4)];
    227 typedef aom_cdf_prob (*br_cdf_arr)[CDF_SIZE(BR_CDF_SIZE)];
    228 
    229 static inline int get_lower_levels_ctx_eob(int bhl, int width, int scan_idx) {
    230  if (scan_idx == 0) return 0;
    231  if (scan_idx <= (width << bhl) / 8) return 1;
    232  if (scan_idx <= (width << bhl) / 4) return 2;
    233  return 3;
    234 }
    235 
    236 static inline int get_lower_levels_ctx_2d(const uint8_t *levels, int coeff_idx,
    237                                          int bhl, TX_SIZE tx_size) {
    238  assert(coeff_idx > 0);
    239  int mag;
    240  // Note: AOMMIN(level, 3) is useless for decoder since level < 3.
    241  levels = levels + get_padded_idx(coeff_idx, bhl);
    242  mag = AOMMIN(levels[(1 << bhl) + TX_PAD_HOR], 3);               // { 0, 1 }
    243  mag += AOMMIN(levels[1], 3);                                    // { 1, 0 }
    244  mag += AOMMIN(levels[(1 << bhl) + TX_PAD_HOR + 1], 3);          // { 1, 1 }
    245  mag += AOMMIN(levels[(2 << bhl) + (2 << TX_PAD_HOR_LOG2)], 3);  // { 0, 2 }
    246  mag += AOMMIN(levels[2], 3);                                    // { 2, 0 }
    247 
    248  const int ctx = AOMMIN((mag + 1) >> 1, 4);
    249  return ctx + av1_nz_map_ctx_offset[tx_size][coeff_idx];
    250 }
    251 static AOM_FORCE_INLINE int get_lower_levels_ctx(const uint8_t *levels,
    252                                                 int coeff_idx, int bhl,
    253                                                 TX_SIZE tx_size,
    254                                                 TX_CLASS tx_class) {
    255  const int stats =
    256      get_nz_mag(levels + get_padded_idx(coeff_idx, bhl), bhl, tx_class);
    257  return get_nz_map_ctx_from_stats(stats, coeff_idx, bhl, tx_size, tx_class);
    258 }
    259 
    260 static inline int get_lower_levels_ctx_general(int is_last, int scan_idx,
    261                                               int bhl, int width,
    262                                               const uint8_t *levels,
    263                                               int coeff_idx, TX_SIZE tx_size,
    264                                               TX_CLASS tx_class) {
    265  if (is_last) {
    266    if (scan_idx == 0) return 0;
    267    if (scan_idx <= (width << bhl) >> 3) return 1;
    268    if (scan_idx <= (width << bhl) >> 2) return 2;
    269    return 3;
    270  }
    271  return get_lower_levels_ctx(levels, coeff_idx, bhl, tx_size, tx_class);
    272 }
    273 
    274 static inline void set_dc_sign(int *cul_level, int dc_val) {
    275  if (dc_val < 0)
    276    *cul_level |= 1 << COEFF_CONTEXT_BITS;
    277  else if (dc_val > 0)
    278    *cul_level += 2 << COEFF_CONTEXT_BITS;
    279 }
    280 
    281 static void get_txb_ctx_general(const BLOCK_SIZE plane_bsize,
    282                                const TX_SIZE tx_size, const int plane,
    283                                const ENTROPY_CONTEXT *const a,
    284                                const ENTROPY_CONTEXT *const l,
    285                                TXB_CTX *const txb_ctx) {
    286 #define MAX_TX_SIZE_UNIT 16
    287  static const int8_t signs[3] = { 0, -1, 1 };
    288  static const int8_t dc_sign_contexts[4 * MAX_TX_SIZE_UNIT + 1] = {
    289    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    290    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    291    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
    292  };
    293  const int txb_w_unit = tx_size_wide_unit[tx_size];
    294  const int txb_h_unit = tx_size_high_unit[tx_size];
    295  int dc_sign = 0;
    296  int k = 0;
    297 
    298  do {
    299    const unsigned int sign = ((uint8_t)a[k]) >> COEFF_CONTEXT_BITS;
    300    assert(sign <= 2);
    301    dc_sign += signs[sign];
    302  } while (++k < txb_w_unit);
    303 
    304  k = 0;
    305  do {
    306    const unsigned int sign = ((uint8_t)l[k]) >> COEFF_CONTEXT_BITS;
    307    assert(sign <= 2);
    308    dc_sign += signs[sign];
    309  } while (++k < txb_h_unit);
    310 
    311  txb_ctx->dc_sign_ctx = dc_sign_contexts[dc_sign + 2 * MAX_TX_SIZE_UNIT];
    312 
    313  if (plane == 0) {
    314    if (plane_bsize == txsize_to_bsize[tx_size]) {
    315      txb_ctx->txb_skip_ctx = 0;
    316    } else {
    317      // This is the algorithm to generate table skip_contexts[top][left].
    318      //    const int max = AOMMIN(top | left, 4);
    319      //    const int min = AOMMIN(AOMMIN(top, left), 4);
    320      //    if (!max)
    321      //      txb_skip_ctx = 1;
    322      //    else if (!min)
    323      //      txb_skip_ctx = 2 + (max > 3);
    324      //    else if (max <= 3)
    325      //      txb_skip_ctx = 4;
    326      //    else if (min <= 3)
    327      //      txb_skip_ctx = 5;
    328      //    else
    329      //      txb_skip_ctx = 6;
    330      static const uint8_t skip_contexts[5][5] = { { 1, 2, 2, 2, 3 },
    331                                                   { 2, 4, 4, 4, 5 },
    332                                                   { 2, 4, 4, 4, 5 },
    333                                                   { 2, 4, 4, 4, 5 },
    334                                                   { 3, 5, 5, 5, 6 } };
    335      // For top and left, we only care about which of the following three
    336      // categories they belong to: { 0 }, { 1, 2, 3 }, or { 4, 5, ... }. The
    337      // spec calculates top and left with the Max() function. We can calculate
    338      // an approximate max with bitwise OR because the real max and the
    339      // approximate max belong to the same category.
    340      int top = 0;
    341      int left = 0;
    342 
    343      k = 0;
    344      do {
    345        top |= a[k];
    346      } while (++k < txb_w_unit);
    347      top &= COEFF_CONTEXT_MASK;
    348      top = AOMMIN(top, 4);
    349 
    350      k = 0;
    351      do {
    352        left |= l[k];
    353      } while (++k < txb_h_unit);
    354      left &= COEFF_CONTEXT_MASK;
    355      left = AOMMIN(left, 4);
    356 
    357      txb_ctx->txb_skip_ctx = skip_contexts[top][left];
    358    }
    359  } else {
    360    const int ctx_base = get_entropy_context(tx_size, a, l);
    361    const int ctx_offset = (num_pels_log2_lookup[plane_bsize] >
    362                            num_pels_log2_lookup[txsize_to_bsize[tx_size]])
    363                               ? 10
    364                               : 7;
    365    txb_ctx->txb_skip_ctx = ctx_base + ctx_offset;
    366  }
    367 }
    368 
    369 #define SPECIALIZE_GET_TXB_CTX(w, h)                                          \
    370  static void get_txb_ctx_##w##x##h(                                          \
    371      const BLOCK_SIZE plane_bsize, const int plane,                          \
    372      const ENTROPY_CONTEXT *const a, const ENTROPY_CONTEXT *const l,         \
    373      TXB_CTX *const txb_ctx) {                                               \
    374    static const int8_t signs[3] = { 0, -1, 1 };                              \
    375    static const int8_t dc_sign_contexts[4 * MAX_TX_SIZE_UNIT + 1] = {        \
    376      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,       \
    377      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,       \
    378      2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2           \
    379    };                                                                        \
    380    const TX_SIZE tx_size = TX_##w##X##h;                                     \
    381    const int txb_w_unit = tx_size_wide_unit[tx_size];                        \
    382    const int txb_h_unit = tx_size_high_unit[tx_size];                        \
    383    int dc_sign = 0;                                                          \
    384    int k = 0;                                                                \
    385                                                                              \
    386    do {                                                                      \
    387      const unsigned int sign = ((uint8_t)a[k]) >> COEFF_CONTEXT_BITS;        \
    388      assert(sign <= 2);                                                      \
    389      dc_sign += signs[sign];                                                 \
    390    } while (++k < txb_w_unit);                                               \
    391                                                                              \
    392    k = 0;                                                                    \
    393    do {                                                                      \
    394      const unsigned int sign = ((uint8_t)l[k]) >> COEFF_CONTEXT_BITS;        \
    395      assert(sign <= 2);                                                      \
    396      dc_sign += signs[sign];                                                 \
    397    } while (++k < txb_h_unit);                                               \
    398                                                                              \
    399    txb_ctx->dc_sign_ctx = dc_sign_contexts[dc_sign + 2 * MAX_TX_SIZE_UNIT];  \
    400                                                                              \
    401    if (plane == 0) {                                                         \
    402      if (plane_bsize == txsize_to_bsize[tx_size]) {                          \
    403        txb_ctx->txb_skip_ctx = 0;                                            \
    404      } else {                                                                \
    405        static const uint8_t skip_contexts[5][5] = { { 1, 2, 2, 2, 3 },       \
    406                                                     { 2, 4, 4, 4, 5 },       \
    407                                                     { 2, 4, 4, 4, 5 },       \
    408                                                     { 2, 4, 4, 4, 5 },       \
    409                                                     { 3, 5, 5, 5, 6 } };     \
    410        int top = 0;                                                          \
    411        int left = 0;                                                         \
    412                                                                              \
    413        k = 0;                                                                \
    414        do {                                                                  \
    415          top |= a[k];                                                        \
    416        } while (++k < txb_w_unit);                                           \
    417        top &= COEFF_CONTEXT_MASK;                                            \
    418        top = AOMMIN(top, 4);                                                 \
    419                                                                              \
    420        k = 0;                                                                \
    421        do {                                                                  \
    422          left |= l[k];                                                       \
    423        } while (++k < txb_h_unit);                                           \
    424        left &= COEFF_CONTEXT_MASK;                                           \
    425        left = AOMMIN(left, 4);                                               \
    426                                                                              \
    427        txb_ctx->txb_skip_ctx = skip_contexts[top][left];                     \
    428      }                                                                       \
    429    } else {                                                                  \
    430      const int ctx_base = get_entropy_context(tx_size, a, l);                \
    431      const int ctx_offset = (num_pels_log2_lookup[plane_bsize] >             \
    432                              num_pels_log2_lookup[txsize_to_bsize[tx_size]]) \
    433                                 ? 10                                         \
    434                                 : 7;                                         \
    435      txb_ctx->txb_skip_ctx = ctx_base + ctx_offset;                          \
    436    }                                                                         \
    437  }
    438 
    439 SPECIALIZE_GET_TXB_CTX(4, 4)
    440 SPECIALIZE_GET_TXB_CTX(8, 8)
    441 SPECIALIZE_GET_TXB_CTX(16, 16)
    442 SPECIALIZE_GET_TXB_CTX(32, 32)
    443 
    444 // Wrapper for get_txb_ctx that calls the specialized version of get_txb_ctc_*
    445 // so that the compiler can compile away the while loops.
    446 static inline void get_txb_ctx(const BLOCK_SIZE plane_bsize,
    447                               const TX_SIZE tx_size, const int plane,
    448                               const ENTROPY_CONTEXT *const a,
    449                               const ENTROPY_CONTEXT *const l,
    450                               TXB_CTX *const txb_ctx) {
    451  switch (tx_size) {
    452    case TX_4X4: get_txb_ctx_4x4(plane_bsize, plane, a, l, txb_ctx); break;
    453    case TX_8X8: get_txb_ctx_8x8(plane_bsize, plane, a, l, txb_ctx); break;
    454    case TX_16X16: get_txb_ctx_16x16(plane_bsize, plane, a, l, txb_ctx); break;
    455    case TX_32X32: get_txb_ctx_32x32(plane_bsize, plane, a, l, txb_ctx); break;
    456    default:
    457      get_txb_ctx_general(plane_bsize, tx_size, plane, a, l, txb_ctx);
    458      break;
    459  }
    460 }
    461 #undef MAX_TX_SIZE_UNIT
    462 
    463 #endif  // AOM_AV1_COMMON_TXB_COMMON_H_