Home | History | Annotate | Download | only in common
      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/onyxc_int.h"
     16 
     17 extern const int16_t k_eob_group_start[12];
     18 extern const int16_t k_eob_offset_bits[12];
     19 
     20 extern const int8_t av1_coeff_band_4x4[16];
     21 
     22 extern const int8_t av1_coeff_band_8x8[64];
     23 
     24 extern const int8_t av1_coeff_band_16x16[256];
     25 
     26 extern const int8_t av1_coeff_band_32x32[1024];
     27 
     28 extern const int8_t *av1_nz_map_ctx_offset[TX_SIZES_ALL];
     29 
     30 typedef struct txb_ctx {
     31   int txb_skip_ctx;
     32   int dc_sign_ctx;
     33 } TXB_CTX;
     34 
     35 static const int base_level_count_to_index[13] = {
     36   0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
     37 };
     38 
     39 static const TX_CLASS tx_type_to_class[TX_TYPES] = {
     40   TX_CLASS_2D,     // DCT_DCT
     41   TX_CLASS_2D,     // ADST_DCT
     42   TX_CLASS_2D,     // DCT_ADST
     43   TX_CLASS_2D,     // ADST_ADST
     44   TX_CLASS_2D,     // FLIPADST_DCT
     45   TX_CLASS_2D,     // DCT_FLIPADST
     46   TX_CLASS_2D,     // FLIPADST_FLIPADST
     47   TX_CLASS_2D,     // ADST_FLIPADST
     48   TX_CLASS_2D,     // FLIPADST_ADST
     49   TX_CLASS_2D,     // IDTX
     50   TX_CLASS_VERT,   // V_DCT
     51   TX_CLASS_HORIZ,  // H_DCT
     52   TX_CLASS_VERT,   // V_ADST
     53   TX_CLASS_HORIZ,  // H_ADST
     54   TX_CLASS_VERT,   // V_FLIPADST
     55   TX_CLASS_HORIZ,  // H_FLIPADST
     56 };
     57 
     58 static INLINE int get_txb_bwl(TX_SIZE tx_size) {
     59   tx_size = av1_get_adjusted_tx_size(tx_size);
     60   return tx_size_wide_log2[tx_size];
     61 }
     62 
     63 static INLINE int get_txb_wide(TX_SIZE tx_size) {
     64   tx_size = av1_get_adjusted_tx_size(tx_size);
     65   return tx_size_wide[tx_size];
     66 }
     67 
     68 static INLINE int get_txb_high(TX_SIZE tx_size) {
     69   tx_size = av1_get_adjusted_tx_size(tx_size);
     70   return tx_size_high[tx_size];
     71 }
     72 
     73 static INLINE uint8_t *set_levels(uint8_t *const levels_buf, const int width) {
     74   return levels_buf + TX_PAD_TOP * (width + TX_PAD_HOR);
     75 }
     76 
     77 static INLINE int get_padded_idx(const int idx, const int bwl) {
     78   return idx + ((idx >> bwl) << TX_PAD_HOR_LOG2);
     79 }
     80 
     81 static INLINE int get_base_ctx_from_count_mag(int row, int col, int count,
     82                                               int sig_mag) {
     83   const int ctx = base_level_count_to_index[count];
     84   int ctx_idx = -1;
     85 
     86   if (row == 0 && col == 0) {
     87     if (sig_mag >= 2) return ctx_idx = 0;
     88     if (sig_mag == 1) {
     89       if (count >= 2)
     90         ctx_idx = 1;
     91       else
     92         ctx_idx = 2;
     93 
     94       return ctx_idx;
     95     }
     96 
     97     ctx_idx = 3 + ctx;
     98     assert(ctx_idx <= 6);
     99     return ctx_idx;
    100   } else if (row == 0) {
    101     if (sig_mag >= 2) return ctx_idx = 6;
    102     if (sig_mag == 1) {
    103       if (count >= 2)
    104         ctx_idx = 7;
    105       else
    106         ctx_idx = 8;
    107       return ctx_idx;
    108     }
    109 
    110     ctx_idx = 9 + ctx;
    111     assert(ctx_idx <= 11);
    112     return ctx_idx;
    113   } else if (col == 0) {
    114     if (sig_mag >= 2) return ctx_idx = 12;
    115     if (sig_mag == 1) {
    116       if (count >= 2)
    117         ctx_idx = 13;
    118       else
    119         ctx_idx = 14;
    120 
    121       return ctx_idx;
    122     }
    123 
    124     ctx_idx = 15 + ctx;
    125     assert(ctx_idx <= 17);
    126     // TODO(angiebird): turn this on once the optimization is finalized
    127     // assert(ctx_idx < 28);
    128   } else {
    129     if (sig_mag >= 2) return ctx_idx = 18;
    130     if (sig_mag == 1) {
    131       if (count >= 2)
    132         ctx_idx = 19;
    133       else
    134         ctx_idx = 20;
    135       return ctx_idx;
    136     }
    137 
    138     ctx_idx = 21 + ctx;
    139 
    140     assert(ctx_idx <= 24);
    141   }
    142   return ctx_idx;
    143 }
    144 
    145 static INLINE int get_br_ctx_2d(const uint8_t *const levels,
    146                                 const int c,  // raster order
    147                                 const int bwl) {
    148   assert(c > 0);
    149   const int row = c >> bwl;
    150   const int col = c - (row << bwl);
    151   const int stride = (1 << bwl) + TX_PAD_HOR;
    152   const int pos = row * stride + col;
    153   int mag = AOMMIN(levels[pos + 1], MAX_BASE_BR_RANGE) +
    154             AOMMIN(levels[pos + stride], MAX_BASE_BR_RANGE) +
    155             AOMMIN(levels[pos + 1 + stride], MAX_BASE_BR_RANGE);
    156   mag = AOMMIN((mag + 1) >> 1, 6);
    157   //((row | col) < 2) is equivalent to ((row < 2) && (col < 2))
    158   if ((row | col) < 2) return mag + 7;
    159   return mag + 14;
    160 }
    161 
    162 static AOM_FORCE_INLINE int get_br_ctx_eob(const int c,  // raster order
    163                                            const int bwl,
    164                                            const TX_CLASS tx_class) {
    165   const int row = c >> bwl;
    166   const int col = c - (row << bwl);
    167   if (c == 0) return 0;
    168   if ((tx_class == TX_CLASS_2D && row < 2 && col < 2) ||
    169       (tx_class == TX_CLASS_HORIZ && col == 0) ||
    170       (tx_class == TX_CLASS_VERT && row == 0))
    171     return 7;
    172   return 14;
    173 }
    174 
    175 static AOM_FORCE_INLINE int get_br_ctx(const uint8_t *const levels,
    176                                        const int c,  // raster order
    177                                        const int bwl, const TX_CLASS tx_class) {
    178   const int row = c >> bwl;
    179   const int col = c - (row << bwl);
    180   const int stride = (1 << bwl) + TX_PAD_HOR;
    181   const int pos = row * stride + col;
    182   int mag = levels[pos + 1];
    183   mag += levels[pos + stride];
    184   switch (tx_class) {
    185     case TX_CLASS_2D:
    186       mag += levels[pos + stride + 1];
    187       mag = AOMMIN((mag + 1) >> 1, 6);
    188       if (c == 0) return mag;
    189       if ((row < 2) && (col < 2)) return mag + 7;
    190       break;
    191     case TX_CLASS_HORIZ:
    192       mag += levels[pos + 2];
    193       mag = AOMMIN((mag + 1) >> 1, 6);
    194       if (c == 0) return mag;
    195       if (col == 0) return mag + 7;
    196       break;
    197     case TX_CLASS_VERT:
    198       mag += levels[pos + (stride << 1)];
    199       mag = AOMMIN((mag + 1) >> 1, 6);
    200       if (c == 0) return mag;
    201       if (row == 0) return mag + 7;
    202       break;
    203     default: break;
    204   }
    205 
    206   return mag + 14;
    207 }
    208 
    209 static const uint8_t clip_max3[256] = {
    210   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,
    211   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,
    212   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,
    213   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,
    214   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,
    215   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,
    216   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,
    217   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,
    218   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,
    219   3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
    220 };
    221 
    222 static AOM_FORCE_INLINE int get_nz_mag(const uint8_t *const levels,
    223                                        const int bwl, const TX_CLASS tx_class) {
    224   int mag;
    225 
    226   // Note: AOMMIN(level, 3) is useless for decoder since level < 3.
    227   mag = clip_max3[levels[1]];                         // { 0, 1 }
    228   mag += clip_max3[levels[(1 << bwl) + TX_PAD_HOR]];  // { 1, 0 }
    229 
    230   if (tx_class == TX_CLASS_2D) {
    231     mag += clip_max3[levels[(1 << bwl) + TX_PAD_HOR + 1]];          // { 1, 1 }
    232     mag += clip_max3[levels[2]];                                    // { 0, 2 }
    233     mag += clip_max3[levels[(2 << bwl) + (2 << TX_PAD_HOR_LOG2)]];  // { 2, 0 }
    234   } else if (tx_class == TX_CLASS_VERT) {
    235     mag += clip_max3[levels[(2 << bwl) + (2 << TX_PAD_HOR_LOG2)]];  // { 2, 0 }
    236     mag += clip_max3[levels[(3 << bwl) + (3 << TX_PAD_HOR_LOG2)]];  // { 3, 0 }
    237     mag += clip_max3[levels[(4 << bwl) + (4 << TX_PAD_HOR_LOG2)]];  // { 4, 0 }
    238   } else {
    239     mag += clip_max3[levels[2]];  // { 0, 2 }
    240     mag += clip_max3[levels[3]];  // { 0, 3 }
    241     mag += clip_max3[levels[4]];  // { 0, 4 }
    242   }
    243 
    244   return mag;
    245 }
    246 
    247 #define NZ_MAP_CTX_0 SIG_COEF_CONTEXTS_2D
    248 #define NZ_MAP_CTX_5 (NZ_MAP_CTX_0 + 5)
    249 #define NZ_MAP_CTX_10 (NZ_MAP_CTX_0 + 10)
    250 
    251 static const int nz_map_ctx_offset_1d[32] = {
    252   NZ_MAP_CTX_0,  NZ_MAP_CTX_5,  NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10,
    253   NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10,
    254   NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10,
    255   NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10,
    256   NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10,
    257   NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10,
    258   NZ_MAP_CTX_10, NZ_MAP_CTX_10,
    259 };
    260 
    261 static AOM_FORCE_INLINE int get_nz_map_ctx_from_stats(
    262     const int stats,
    263     const int coeff_idx,  // raster order
    264     const int bwl, const TX_SIZE tx_size, const TX_CLASS tx_class) {
    265   // tx_class == 0(TX_CLASS_2D)
    266   if ((tx_class | coeff_idx) == 0) return 0;
    267   int ctx = (stats + 1) >> 1;
    268   ctx = AOMMIN(ctx, 4);
    269   switch (tx_class) {
    270     case TX_CLASS_2D: {
    271       // This is the algorithm to generate av1_nz_map_ctx_offset[][]
    272       //   const int width = tx_size_wide[tx_size];
    273       //   const int height = tx_size_high[tx_size];
    274       //   if (width < height) {
    275       //     if (row < 2) return 11 + ctx;
    276       //   } else if (width > height) {
    277       //     if (col < 2) return 16 + ctx;
    278       //   }
    279       //   if (row + col < 2) return ctx + 1;
    280       //   if (row + col < 4) return 5 + ctx + 1;
    281       //   return 21 + ctx;
    282       return ctx + av1_nz_map_ctx_offset[tx_size][coeff_idx];
    283     }
    284     case TX_CLASS_HORIZ: {
    285       const int row = coeff_idx >> bwl;
    286       const int col = coeff_idx - (row << bwl);
    287       return ctx + nz_map_ctx_offset_1d[col];
    288     }
    289     case TX_CLASS_VERT: {
    290       const int row = coeff_idx >> bwl;
    291       return ctx + nz_map_ctx_offset_1d[row];
    292     }
    293     default: break;
    294   }
    295   return 0;
    296 }
    297 
    298 typedef aom_cdf_prob (*base_cdf_arr)[CDF_SIZE(4)];
    299 typedef aom_cdf_prob (*br_cdf_arr)[CDF_SIZE(BR_CDF_SIZE)];
    300 
    301 static INLINE int get_lower_levels_ctx_eob(int bwl, int height, int scan_idx) {
    302   if (scan_idx == 0) return 0;
    303   if (scan_idx <= (height << bwl) / 8) return 1;
    304   if (scan_idx <= (height << bwl) / 4) return 2;
    305   return 3;
    306 }
    307 
    308 static INLINE int get_lower_levels_ctx_2d(const uint8_t *levels, int coeff_idx,
    309                                           int bwl, TX_SIZE tx_size) {
    310   assert(coeff_idx > 0);
    311   int mag;
    312   // Note: AOMMIN(level, 3) is useless for decoder since level < 3.
    313   levels = levels + get_padded_idx(coeff_idx, bwl);
    314   mag = AOMMIN(levels[1], 3);                                     // { 0, 1 }
    315   mag += AOMMIN(levels[(1 << bwl) + TX_PAD_HOR], 3);              // { 1, 0 }
    316   mag += AOMMIN(levels[(1 << bwl) + TX_PAD_HOR + 1], 3);          // { 1, 1 }
    317   mag += AOMMIN(levels[2], 3);                                    // { 0, 2 }
    318   mag += AOMMIN(levels[(2 << bwl) + (2 << TX_PAD_HOR_LOG2)], 3);  // { 2, 0 }
    319 
    320   const int ctx = AOMMIN((mag + 1) >> 1, 4);
    321   return ctx + av1_nz_map_ctx_offset[tx_size][coeff_idx];
    322 }
    323 static AOM_FORCE_INLINE int get_lower_levels_ctx(const uint8_t *levels,
    324                                                  int coeff_idx, int bwl,
    325                                                  TX_SIZE tx_size,
    326                                                  TX_CLASS tx_class) {
    327   const int stats =
    328       get_nz_mag(levels + get_padded_idx(coeff_idx, bwl), bwl, tx_class);
    329   return get_nz_map_ctx_from_stats(stats, coeff_idx, bwl, tx_size, tx_class);
    330 }
    331 
    332 static INLINE int get_lower_levels_ctx_general(int is_last, int scan_idx,
    333                                                int bwl, int height,
    334                                                const uint8_t *levels,
    335                                                int coeff_idx, TX_SIZE tx_size,
    336                                                TX_CLASS tx_class) {
    337   if (is_last) {
    338     if (scan_idx == 0) return 0;
    339     if (scan_idx <= (height << bwl) >> 3) return 1;
    340     if (scan_idx <= (height << bwl) >> 2) return 2;
    341     return 3;
    342   }
    343   return get_lower_levels_ctx(levels, coeff_idx, bwl, tx_size, tx_class);
    344 }
    345 
    346 static INLINE void set_dc_sign(int *cul_level, int dc_val) {
    347   if (dc_val < 0)
    348     *cul_level |= 1 << COEFF_CONTEXT_BITS;
    349   else if (dc_val > 0)
    350     *cul_level += 2 << COEFF_CONTEXT_BITS;
    351 }
    352 
    353 static INLINE void get_txb_ctx(const BLOCK_SIZE plane_bsize,
    354                                const TX_SIZE tx_size, const int plane,
    355                                const ENTROPY_CONTEXT *const a,
    356                                const ENTROPY_CONTEXT *const l,
    357                                TXB_CTX *const txb_ctx) {
    358 #define MAX_TX_SIZE_UNIT 16
    359   static const int8_t signs[3] = { 0, -1, 1 };
    360   static const int8_t dc_sign_contexts[4 * MAX_TX_SIZE_UNIT + 1] = {
    361     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    362     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    363     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
    364   };
    365   const int txb_w_unit = tx_size_wide_unit[tx_size];
    366   const int txb_h_unit = tx_size_high_unit[tx_size];
    367   int dc_sign = 0;
    368   int k = 0;
    369 
    370   do {
    371     const unsigned int sign = ((uint8_t)a[k]) >> COEFF_CONTEXT_BITS;
    372     assert(sign <= 2);
    373     dc_sign += signs[sign];
    374   } while (++k < txb_w_unit);
    375 
    376   k = 0;
    377   do {
    378     const unsigned int sign = ((uint8_t)l[k]) >> COEFF_CONTEXT_BITS;
    379     assert(sign <= 2);
    380     dc_sign += signs[sign];
    381   } while (++k < txb_h_unit);
    382 
    383   txb_ctx->dc_sign_ctx = dc_sign_contexts[dc_sign + 2 * MAX_TX_SIZE_UNIT];
    384 
    385   if (plane == 0) {
    386     if (plane_bsize == txsize_to_bsize[tx_size]) {
    387       txb_ctx->txb_skip_ctx = 0;
    388     } else {
    389       // This is the algorithm to generate table skip_contexts[min][max].
    390       //    if (!max)
    391       //      txb_skip_ctx = 1;
    392       //    else if (!min)
    393       //      txb_skip_ctx = 2 + (max > 3);
    394       //    else if (max <= 3)
    395       //      txb_skip_ctx = 4;
    396       //    else if (min <= 3)
    397       //      txb_skip_ctx = 5;
    398       //    else
    399       //      txb_skip_ctx = 6;
    400       static const uint8_t skip_contexts[5][5] = { { 1, 2, 2, 2, 3 },
    401                                                    { 1, 4, 4, 4, 5 },
    402                                                    { 1, 4, 4, 4, 5 },
    403                                                    { 1, 4, 4, 4, 5 },
    404                                                    { 1, 4, 4, 4, 6 } };
    405       int top = 0;
    406       int left = 0;
    407 
    408       k = 0;
    409       do {
    410         top |= a[k];
    411       } while (++k < txb_w_unit);
    412       top &= COEFF_CONTEXT_MASK;
    413 
    414       k = 0;
    415       do {
    416         left |= l[k];
    417       } while (++k < txb_h_unit);
    418       left &= COEFF_CONTEXT_MASK;
    419       const int max = AOMMIN(top | left, 4);
    420       const int min = AOMMIN(AOMMIN(top, left), 4);
    421 
    422       txb_ctx->txb_skip_ctx = skip_contexts[min][max];
    423     }
    424   } else {
    425     const int ctx_base = get_entropy_context(tx_size, a, l);
    426     const int ctx_offset = (num_pels_log2_lookup[plane_bsize] >
    427                             num_pels_log2_lookup[txsize_to_bsize[tx_size]])
    428                                ? 10
    429                                : 7;
    430     txb_ctx->txb_skip_ctx = ctx_base + ctx_offset;
    431   }
    432 #undef MAX_TX_SIZE_UNIT
    433 }
    434 
    435 #endif  // AOM_AV1_COMMON_TXB_COMMON_H_
    436