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_