tor-browser

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

av1_txfm.h (7805B)


      1 /*
      2 * Copyright (c) 2016, 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_AV1_TXFM_H_
     13 #define AOM_AV1_COMMON_AV1_TXFM_H_
     14 
     15 #include <assert.h>
     16 #include <math.h>
     17 #include <stdio.h>
     18 
     19 #include "config/aom_config.h"
     20 
     21 #include "av1/common/enums.h"
     22 #include "av1/common/blockd.h"
     23 #include "aom/aom_integer.h"
     24 #include "aom_dsp/aom_dsp_common.h"
     25 
     26 #ifdef __cplusplus
     27 extern "C" {
     28 #endif
     29 
     30 #if !defined(DO_RANGE_CHECK_CLAMP)
     31 #define DO_RANGE_CHECK_CLAMP 0
     32 #endif
     33 
     34 extern const int32_t av1_cospi_arr_data[4][64];
     35 extern const int32_t av1_sinpi_arr_data[4][5];
     36 
     37 #define MAX_TXFM_STAGE_NUM 12
     38 
     39 static const int cos_bit_min = 10;
     40 
     41 #define NewSqrt2Bits ((int32_t)12)
     42 // 2^12 * sqrt(2)
     43 static const int32_t NewSqrt2 = 5793;
     44 // 2^12 / sqrt(2)
     45 static const int32_t NewInvSqrt2 = 2896;
     46 
     47 static inline const int32_t *cospi_arr(int n) {
     48  return av1_cospi_arr_data[n - cos_bit_min];
     49 }
     50 
     51 static inline const int32_t *sinpi_arr(int n) {
     52  return av1_sinpi_arr_data[n - cos_bit_min];
     53 }
     54 
     55 // The reduced bit-width and permuted arrays are only used in the Arm Neon
     56 // implementations in av1_fwd_txfm2d_neon.c and highbd_fwd_txfm_neon.c for now.
     57 #if HAVE_NEON
     58 // Store cospi/sinpi costants in Q2.13 format.
     59 // See: https://en.wikipedia.org/wiki/Q_(number_format)
     60 extern const int16_t av1_cospi_arr_q13_data[4][128];
     61 extern const int16_t av1_sinpi_arr_q13_data[4][4];
     62 
     63 extern const int32_t av1_cospi_arr_s32_data[4][66];
     64 
     65 static inline const int16_t *cospi_arr_q13(int n) {
     66  return av1_cospi_arr_q13_data[n - cos_bit_min];
     67 }
     68 
     69 static inline const int16_t *sinpi_arr_q13(int n) {
     70  return av1_sinpi_arr_q13_data[n - cos_bit_min];
     71 }
     72 
     73 static inline const int32_t *cospi_arr_s32(int n) {
     74  return av1_cospi_arr_s32_data[n - cos_bit_min];
     75 }
     76 #endif  // HAVE_NEON
     77 
     78 static inline int32_t range_check_value(int32_t value, int8_t bit) {
     79 #if CONFIG_COEFFICIENT_RANGE_CHECKING
     80  const int64_t max_value = (1LL << (bit - 1)) - 1;
     81  const int64_t min_value = -(1LL << (bit - 1));
     82  if (value < min_value || value > max_value) {
     83    fprintf(stderr, "coeff out of bit range, value: %d bit %d\n", value, bit);
     84 #if !CONFIG_AV1_ENCODER
     85    assert(0);
     86 #endif
     87  }
     88 #endif  // CONFIG_COEFFICIENT_RANGE_CHECKING
     89 #if DO_RANGE_CHECK_CLAMP
     90  bit = AOMMIN(bit, 31);
     91  return clamp(value, -(1 << (bit - 1)), (1 << (bit - 1)) - 1);
     92 #endif  // DO_RANGE_CHECK_CLAMP
     93  (void)bit;
     94  return value;
     95 }
     96 
     97 static inline int32_t round_shift(int64_t value, int bit) {
     98  assert(bit >= 1);
     99  return (int32_t)((value + (1ll << (bit - 1))) >> bit);
    100 }
    101 
    102 static inline int32_t half_btf(int32_t w0, int32_t in0, int32_t w1, int32_t in1,
    103                               int bit) {
    104  int64_t result_64 = (int64_t)(w0 * in0) + (int64_t)(w1 * in1);
    105  int64_t intermediate = result_64 + (1LL << (bit - 1));
    106  // NOTE(rachelbarker): The value 'result_64' may not necessarily fit
    107  // into 32 bits. However, the result of this function is nominally
    108  // ROUND_POWER_OF_TWO_64(result_64, bit)
    109  // and that is required to fit into stage_range[stage] many bits
    110  // (checked by range_check_buf()).
    111  //
    112  // Here we've unpacked that rounding operation, and it can be shown
    113  // that the value of 'intermediate' here *does* fit into 32 bits
    114  // for any conformant bitstream.
    115  // The upshot is that, if you do all this calculation using
    116  // wrapping 32-bit arithmetic instead of (non-wrapping) 64-bit arithmetic,
    117  // then you'll still get the correct result.
    118  // To provide a check on this logic, we assert that 'intermediate'
    119  // would fit into an int32 if range checking is enabled.
    120 #if CONFIG_COEFFICIENT_RANGE_CHECKING
    121  assert(intermediate >= INT32_MIN && intermediate <= INT32_MAX);
    122 #endif
    123  return (int32_t)(intermediate >> bit);
    124 }
    125 
    126 static inline uint16_t highbd_clip_pixel_add(uint16_t dest, tran_high_t trans,
    127                                             int bd) {
    128  return clip_pixel_highbd(dest + (int)trans, bd);
    129 }
    130 
    131 typedef void (*TxfmFunc)(const int32_t *input, int32_t *output, int8_t cos_bit,
    132                         const int8_t *stage_range);
    133 
    134 typedef void (*FwdTxfm2dFunc)(const int16_t *input, int32_t *output, int stride,
    135                              TX_TYPE tx_type, int bd);
    136 
    137 enum {
    138  TXFM_TYPE_DCT4,
    139  TXFM_TYPE_DCT8,
    140  TXFM_TYPE_DCT16,
    141  TXFM_TYPE_DCT32,
    142  TXFM_TYPE_DCT64,
    143  TXFM_TYPE_ADST4,
    144  TXFM_TYPE_ADST8,
    145  TXFM_TYPE_ADST16,
    146  TXFM_TYPE_IDENTITY4,
    147  TXFM_TYPE_IDENTITY8,
    148  TXFM_TYPE_IDENTITY16,
    149  TXFM_TYPE_IDENTITY32,
    150  TXFM_TYPES,
    151  TXFM_TYPE_INVALID,
    152 } UENUM1BYTE(TXFM_TYPE);
    153 
    154 typedef struct TXFM_2D_FLIP_CFG {
    155  TX_SIZE tx_size;
    156  int ud_flip;  // flip upside down
    157  int lr_flip;  // flip left to right
    158  const int8_t *shift;
    159  int8_t cos_bit_col;
    160  int8_t cos_bit_row;
    161  int8_t stage_range_col[MAX_TXFM_STAGE_NUM];
    162  int8_t stage_range_row[MAX_TXFM_STAGE_NUM];
    163  TXFM_TYPE txfm_type_col;
    164  TXFM_TYPE txfm_type_row;
    165  int stage_num_col;
    166  int stage_num_row;
    167 } TXFM_2D_FLIP_CFG;
    168 
    169 static inline void get_flip_cfg(TX_TYPE tx_type, int *ud_flip, int *lr_flip) {
    170  switch (tx_type) {
    171    case DCT_DCT:
    172    case ADST_DCT:
    173    case DCT_ADST:
    174    case ADST_ADST:
    175      *ud_flip = 0;
    176      *lr_flip = 0;
    177      break;
    178    case IDTX:
    179    case V_DCT:
    180    case H_DCT:
    181    case V_ADST:
    182    case H_ADST:
    183      *ud_flip = 0;
    184      *lr_flip = 0;
    185      break;
    186    case FLIPADST_DCT:
    187    case FLIPADST_ADST:
    188    case V_FLIPADST:
    189      *ud_flip = 1;
    190      *lr_flip = 0;
    191      break;
    192    case DCT_FLIPADST:
    193    case ADST_FLIPADST:
    194    case H_FLIPADST:
    195      *ud_flip = 0;
    196      *lr_flip = 1;
    197      break;
    198    case FLIPADST_FLIPADST:
    199      *ud_flip = 1;
    200      *lr_flip = 1;
    201      break;
    202    default:
    203      *ud_flip = 0;
    204      *lr_flip = 0;
    205      assert(0);
    206  }
    207 }
    208 
    209 static inline void set_flip_cfg(TX_TYPE tx_type, TXFM_2D_FLIP_CFG *cfg) {
    210  get_flip_cfg(tx_type, &cfg->ud_flip, &cfg->lr_flip);
    211 }
    212 
    213 // Utility function that returns the log of the ratio of the col and row
    214 // sizes.
    215 static inline int get_rect_tx_log_ratio(int col, int row) {
    216  if (col == row) return 0;
    217  if (col > row) {
    218    if (col == row * 2) return 1;
    219    if (col == row * 4) return 2;
    220    assert(0 && "Unsupported transform size");
    221  } else {
    222    if (row == col * 2) return -1;
    223    if (row == col * 4) return -2;
    224    assert(0 && "Unsupported transform size");
    225  }
    226  return 0;  // Invalid
    227 }
    228 
    229 void av1_gen_fwd_stage_range(int8_t *stage_range_col, int8_t *stage_range_row,
    230                             const TXFM_2D_FLIP_CFG *cfg, int bd);
    231 
    232 void av1_gen_inv_stage_range(int8_t *stage_range_col, int8_t *stage_range_row,
    233                             const TXFM_2D_FLIP_CFG *cfg, TX_SIZE tx_size,
    234                             int bd);
    235 
    236 void av1_get_fwd_txfm_cfg(TX_TYPE tx_type, TX_SIZE tx_size,
    237                          TXFM_2D_FLIP_CFG *cfg);
    238 void av1_get_inv_txfm_cfg(TX_TYPE tx_type, TX_SIZE tx_size,
    239                          TXFM_2D_FLIP_CFG *cfg);
    240 extern const TXFM_TYPE av1_txfm_type_ls[5][TX_TYPES_1D];
    241 extern const int8_t av1_txfm_stage_num_list[TXFM_TYPES];
    242 static inline int get_txw_idx(TX_SIZE tx_size) {
    243  return tx_size_wide_log2[tx_size] - tx_size_wide_log2[0];
    244 }
    245 static inline int get_txh_idx(TX_SIZE tx_size) {
    246  return tx_size_high_log2[tx_size] - tx_size_high_log2[0];
    247 }
    248 
    249 void av1_range_check_buf(int32_t stage, const int32_t *input,
    250                         const int32_t *buf, int32_t size, int8_t bit);
    251 #define MAX_TXWH_IDX 5
    252 #ifdef __cplusplus
    253 }
    254 #endif  // __cplusplus
    255 
    256 #endif  // AOM_AV1_COMMON_AV1_TXFM_H_