xref: /aosp_15_r20/external/libaom/av1/common/av1_txfm.h (revision 77c1e3ccc04c968bd2bc212e87364f250e820521)
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 
cospi_arr(int n)47 static inline const int32_t *cospi_arr(int n) {
48   return av1_cospi_arr_data[n - cos_bit_min];
49 }
50 
sinpi_arr(int n)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 
cospi_arr_q13(int n)65 static inline const int16_t *cospi_arr_q13(int n) {
66   return av1_cospi_arr_q13_data[n - cos_bit_min];
67 }
68 
sinpi_arr_q13(int n)69 static inline const int16_t *sinpi_arr_q13(int n) {
70   return av1_sinpi_arr_q13_data[n - cos_bit_min];
71 }
72 
cospi_arr_s32(int n)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 
range_check_value(int32_t value,int8_t bit)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 
round_shift(int64_t value,int bit)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 
half_btf(int32_t w0,int32_t in0,int32_t w1,int32_t in1,int bit)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 
highbd_clip_pixel_add(uint16_t dest,tran_high_t trans,int bd)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 
get_flip_cfg(TX_TYPE tx_type,int * ud_flip,int * lr_flip)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 
set_flip_cfg(TX_TYPE tx_type,TXFM_2D_FLIP_CFG * cfg)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.
get_rect_tx_log_ratio(int col,int row)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];
get_txw_idx(TX_SIZE tx_size)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 }
get_txh_idx(TX_SIZE tx_size)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_
257