blob: 7072f9fc5c861b6e3428c4f952721a6550a3e0ef [file] [log] [blame]
Yaowu Xuc27fc142016-08-22 16:08:15 -07001/*
Yaowu Xubde4ac82016-11-28 15:26:06 -08002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Yaowu Xuc27fc142016-08-22 16:08:15 -07003 *
Yaowu Xubde4ac82016-11-28 15:26:06 -08004 * 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.
Yaowu Xuc27fc142016-08-22 16:08:15 -070010 */
Yaowu Xubde4ac82016-11-28 15:26:06 -080011
Yaowu Xuf883b422016-08-30 14:01:10 -070012#ifndef AV1_TXFM_H_
13#define AV1_TXFM_H_
Yaowu Xuc27fc142016-08-22 16:08:15 -070014
15#include <assert.h>
16#include <math.h>
17#include <stdio.h>
18
19#include "av1/common/enums.h"
Angie Chiang155bf9a2017-08-06 19:52:57 -070020#include "av1/common/blockd.h"
Yaowu Xuf883b422016-08-30 14:01:10 -070021#include "aom/aom_integer.h"
22#include "aom_dsp/aom_dsp_common.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070023
Angie Chiang9c7089a2017-08-08 16:21:11 -070024#ifdef __cplusplus
25extern "C" {
26#endif
27
Angie Chiangce3ad282017-08-08 09:51:54 -070028#define MAX_TXFM_STAGE_NUM 12
Sarah Parkera0972042017-11-10 16:35:46 -080029#define DIVIDE_AND_ROUND(x, y) (((x) + ((y) >> 1)) / (y))
Angie Chiangce3ad282017-08-08 09:51:54 -070030
Yaowu Xuc27fc142016-08-22 16:08:15 -070031static const int cos_bit_min = 10;
32static const int cos_bit_max = 16;
33
34// cospi_arr[i][j] = (int)round(cos(M_PI*j/128) * (1<<(cos_bit_min+i)));
Frederic Barbierbbf7bb02017-05-05 09:37:40 +020035static const int32_t cospi_arr_data[7][64] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -070036 { 1024, 1024, 1023, 1021, 1019, 1016, 1013, 1009, 1004, 999, 993, 987, 980,
clang-format67948d32016-09-07 22:40:40 -070037 972, 964, 955, 946, 936, 926, 915, 903, 891, 878, 865, 851, 837,
38 822, 807, 792, 775, 759, 742, 724, 706, 688, 669, 650, 630, 610,
39 590, 569, 548, 526, 505, 483, 460, 438, 415, 392, 369, 345, 321,
40 297, 273, 249, 224, 200, 175, 150, 125, 100, 75, 50, 25 },
41 { 2048, 2047, 2046, 2042, 2038, 2033, 2026, 2018, 2009, 1998, 1987,
42 1974, 1960, 1945, 1928, 1911, 1892, 1872, 1851, 1829, 1806, 1782,
43 1757, 1730, 1703, 1674, 1645, 1615, 1583, 1551, 1517, 1483, 1448,
44 1412, 1375, 1338, 1299, 1260, 1220, 1179, 1138, 1096, 1053, 1009,
45 965, 921, 876, 830, 784, 737, 690, 642, 595, 546, 498,
46 449, 400, 350, 301, 251, 201, 151, 100, 50 },
47 { 4096, 4095, 4091, 4085, 4076, 4065, 4052, 4036, 4017, 3996, 3973,
48 3948, 3920, 3889, 3857, 3822, 3784, 3745, 3703, 3659, 3612, 3564,
49 3513, 3461, 3406, 3349, 3290, 3229, 3166, 3102, 3035, 2967, 2896,
50 2824, 2751, 2675, 2598, 2520, 2440, 2359, 2276, 2191, 2106, 2019,
51 1931, 1842, 1751, 1660, 1567, 1474, 1380, 1285, 1189, 1092, 995,
52 897, 799, 700, 601, 501, 401, 301, 201, 101 },
53 { 8192, 8190, 8182, 8170, 8153, 8130, 8103, 8071, 8035, 7993, 7946,
54 7895, 7839, 7779, 7713, 7643, 7568, 7489, 7405, 7317, 7225, 7128,
55 7027, 6921, 6811, 6698, 6580, 6458, 6333, 6203, 6070, 5933, 5793,
56 5649, 5501, 5351, 5197, 5040, 4880, 4717, 4551, 4383, 4212, 4038,
57 3862, 3683, 3503, 3320, 3135, 2948, 2760, 2570, 2378, 2185, 1990,
58 1795, 1598, 1401, 1202, 1003, 803, 603, 402, 201 },
Yaowu Xuc27fc142016-08-22 16:08:15 -070059 { 16384, 16379, 16364, 16340, 16305, 16261, 16207, 16143, 16069, 15986, 15893,
60 15791, 15679, 15557, 15426, 15286, 15137, 14978, 14811, 14635, 14449, 14256,
61 14053, 13842, 13623, 13395, 13160, 12916, 12665, 12406, 12140, 11866, 11585,
clang-format67948d32016-09-07 22:40:40 -070062 11297, 11003, 10702, 10394, 10080, 9760, 9434, 9102, 8765, 8423, 8076,
63 7723, 7366, 7005, 6639, 6270, 5897, 5520, 5139, 4756, 4370, 3981,
64 3590, 3196, 2801, 2404, 2006, 1606, 1205, 804, 402 },
Yaowu Xuc27fc142016-08-22 16:08:15 -070065 { 32768, 32758, 32729, 32679, 32610, 32522, 32413, 32286, 32138, 31972, 31786,
66 31581, 31357, 31114, 30853, 30572, 30274, 29957, 29622, 29269, 28899, 28511,
67 28106, 27684, 27246, 26791, 26320, 25833, 25330, 24812, 24279, 23732, 23170,
68 22595, 22006, 21403, 20788, 20160, 19520, 18868, 18205, 17531, 16846, 16151,
clang-format67948d32016-09-07 22:40:40 -070069 15447, 14733, 14010, 13279, 12540, 11793, 11039, 10279, 9512, 8740, 7962,
70 7180, 6393, 5602, 4808, 4011, 3212, 2411, 1608, 804 },
Yaowu Xuc27fc142016-08-22 16:08:15 -070071 { 65536, 65516, 65457, 65358, 65220, 65043, 64827, 64571, 64277, 63944, 63572,
72 63162, 62714, 62228, 61705, 61145, 60547, 59914, 59244, 58538, 57798, 57022,
73 56212, 55368, 54491, 53581, 52639, 51665, 50660, 49624, 48559, 47464, 46341,
74 45190, 44011, 42806, 41576, 40320, 39040, 37736, 36410, 35062, 33692, 32303,
75 30893, 29466, 28020, 26558, 25080, 23586, 22078, 20557, 19024, 17479, 15924,
clang-format67948d32016-09-07 22:40:40 -070076 14359, 12785, 11204, 9616, 8022, 6424, 4821, 3216, 1608 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070077};
78
Frederic Barbierbbf7bb02017-05-05 09:37:40 +020079static INLINE const int32_t *cospi_arr(int n) {
80 return cospi_arr_data[n - cos_bit_min];
81}
82
Yaowu Xuc27fc142016-08-22 16:08:15 -070083static INLINE int32_t round_shift(int32_t value, int bit) {
Yaowu Xu637590c2016-11-16 15:15:46 -080084 assert(bit >= 1);
James Zerna60e26d2017-11-15 12:11:17 -080085 return (int32_t)(((int64_t)value + (1ll << (bit - 1))) >> bit);
Yaowu Xuc27fc142016-08-22 16:08:15 -070086}
87
88static INLINE void round_shift_array(int32_t *arr, int size, int bit) {
89 int i;
90 if (bit == 0) {
91 return;
92 } else {
93 if (bit > 0) {
94 for (i = 0; i < size; i++) {
95 arr[i] = round_shift(arr[i], bit);
96 }
97 } else {
98 for (i = 0; i < size; i++) {
Yaowu Xu4d341542016-11-15 20:47:52 -080099 arr[i] = arr[i] * (1 << (-bit));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700100 }
101 }
102 }
103}
104
105static INLINE int32_t half_btf(int32_t w0, int32_t in0, int32_t w1, int32_t in1,
106 int bit) {
Hui Su8e739bc2017-11-09 14:37:50 -0800107 int32_t result_32 = (int32_t)clamp64((int64_t)w0 * in0 + (int64_t)w1 * in1,
Yaowu Xuea691052017-11-26 16:46:50 -0800108 (int64_t)INT32_MIN, (int64_t)INT32_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700109 return round_shift(result_32, bit);
110}
111
Yaowu Xuc27fc142016-08-22 16:08:15 -0700112typedef void (*TxfmFunc)(const int32_t *input, int32_t *output,
113 const int8_t *cos_bit, const int8_t *stage_range);
114
115typedef enum TXFM_TYPE {
116 TXFM_TYPE_DCT4,
117 TXFM_TYPE_DCT8,
118 TXFM_TYPE_DCT16,
119 TXFM_TYPE_DCT32,
120 TXFM_TYPE_DCT64,
121 TXFM_TYPE_ADST4,
122 TXFM_TYPE_ADST8,
123 TXFM_TYPE_ADST16,
124 TXFM_TYPE_ADST32,
Sarah Parker3eed4172017-05-15 20:49:22 -0700125 TXFM_TYPE_IDENTITY4,
126 TXFM_TYPE_IDENTITY8,
127 TXFM_TYPE_IDENTITY16,
128 TXFM_TYPE_IDENTITY32,
Debargha Mukherjee570423c2017-10-01 00:35:20 -0700129 TXFM_TYPE_IDENTITY64,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700130} TXFM_TYPE;
131
Sarah Parkereec47e62017-05-15 20:49:22 -0700132typedef struct TXFM_1D_CFG {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700133 const int txfm_size;
Sarah Parkereec47e62017-05-15 20:49:22 -0700134 const int stage_num;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700135
136 const int8_t *shift;
Sarah Parkereec47e62017-05-15 20:49:22 -0700137 const int8_t *stage_range;
138 const int8_t *cos_bit;
139 const TXFM_TYPE txfm_type;
140} TXFM_1D_CFG;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700141
142typedef struct TXFM_2D_FLIP_CFG {
143 int ud_flip; // flip upside down
144 int lr_flip; // flip left to right
Sarah Parkereec47e62017-05-15 20:49:22 -0700145 const TXFM_1D_CFG *col_cfg;
146 const TXFM_1D_CFG *row_cfg;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700147} TXFM_2D_FLIP_CFG;
148
Urvang Joshi2283d372017-10-02 17:16:45 -0700149static INLINE void set_flip_cfg(TX_TYPE tx_type, TXFM_2D_FLIP_CFG *cfg) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700150 switch (tx_type) {
151 case DCT_DCT:
152 case ADST_DCT:
153 case DCT_ADST:
154 case ADST_ADST:
155 cfg->ud_flip = 0;
156 cfg->lr_flip = 0;
157 break;
Sarah Parker3eed4172017-05-15 20:49:22 -0700158 case IDTX:
159 case V_DCT:
160 case H_DCT:
161 case V_ADST:
162 case H_ADST:
163 cfg->ud_flip = 0;
164 cfg->lr_flip = 0;
165 break;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700166 case FLIPADST_DCT:
Sarah Parkereec47e62017-05-15 20:49:22 -0700167 case FLIPADST_ADST:
Sarah Parker3eed4172017-05-15 20:49:22 -0700168 case V_FLIPADST:
Yaowu Xuc27fc142016-08-22 16:08:15 -0700169 cfg->ud_flip = 1;
170 cfg->lr_flip = 0;
171 break;
172 case DCT_FLIPADST:
Sarah Parkereec47e62017-05-15 20:49:22 -0700173 case ADST_FLIPADST:
Sarah Parker3eed4172017-05-15 20:49:22 -0700174 case H_FLIPADST:
Yaowu Xuc27fc142016-08-22 16:08:15 -0700175 cfg->ud_flip = 0;
176 cfg->lr_flip = 1;
177 break;
178 case FLIPADST_FLIPADST:
179 cfg->ud_flip = 1;
180 cfg->lr_flip = 1;
181 break;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700182 default:
183 cfg->ud_flip = 0;
184 cfg->lr_flip = 0;
185 assert(0);
186 }
187}
188
Angie Chiang155bf9a2017-08-06 19:52:57 -0700189#if CONFIG_TXMG
Urvang Joshi9752a2e2017-10-02 17:32:27 -0700190static INLINE TX_SIZE av1_rotate_tx_size(TX_SIZE tx_size) {
Angie Chiang155bf9a2017-08-06 19:52:57 -0700191 switch (tx_size) {
Angie Chiang155bf9a2017-08-06 19:52:57 -0700192 case TX_4X4: return TX_4X4;
193 case TX_8X8: return TX_8X8;
194 case TX_16X16: return TX_16X16;
195 case TX_32X32: return TX_32X32;
196#if CONFIG_TX64X64
197 case TX_64X64: return TX_64X64;
Debargha Mukherjee2b435012017-09-28 08:30:35 -0700198 case TX_32X64: return TX_64X32;
199 case TX_64X32: return TX_32X64;
Angie Chiang155bf9a2017-08-06 19:52:57 -0700200#endif
201 case TX_4X8: return TX_8X4;
202 case TX_8X4: return TX_4X8;
203 case TX_8X16: return TX_16X8;
204 case TX_16X8: return TX_8X16;
205 case TX_16X32: return TX_32X16;
206 case TX_32X16: return TX_16X32;
207 case TX_4X16: return TX_16X4;
208 case TX_16X4: return TX_4X16;
209 case TX_8X32: return TX_32X8;
210 case TX_32X8: return TX_8X32;
211 default: assert(0); return TX_INVALID;
212 }
213}
214
Urvang Joshi2283d372017-10-02 17:16:45 -0700215static INLINE TX_TYPE av1_rotate_tx_type(TX_TYPE tx_type) {
Angie Chiang155bf9a2017-08-06 19:52:57 -0700216 switch (tx_type) {
217 case DCT_DCT: return DCT_DCT;
218 case ADST_DCT: return DCT_ADST;
219 case DCT_ADST: return ADST_DCT;
220 case ADST_ADST: return ADST_ADST;
Angie Chiang155bf9a2017-08-06 19:52:57 -0700221 case FLIPADST_DCT: return DCT_FLIPADST;
222 case DCT_FLIPADST: return FLIPADST_DCT;
223 case FLIPADST_FLIPADST: return FLIPADST_FLIPADST;
224 case ADST_FLIPADST: return FLIPADST_ADST;
225 case FLIPADST_ADST: return ADST_FLIPADST;
226 case IDTX: return IDTX;
227 case V_DCT: return H_DCT;
228 case H_DCT: return V_DCT;
229 case V_ADST: return H_ADST;
230 case H_ADST: return V_ADST;
231 case V_FLIPADST: return H_FLIPADST;
232 case H_FLIPADST: return V_FLIPADST;
Angie Chiang155bf9a2017-08-06 19:52:57 -0700233 default: assert(0); return TX_TYPES;
234 }
235}
236#endif // CONFIG_TXMG
237
Debargha Mukherjee9eabd692017-11-16 12:44:31 -0800238// Utility function that returns the log of the ratio of the col and row
239// sizes.
240static INLINE int get_rect_tx_log_ratio(int col, int row) {
241 if (col == row) return 0;
242 if (col > row) {
243 if (col == row * 2) return 1;
244 if (col == row * 4) return 2;
245 assert(0 && "Unsupported transform size");
246 } else {
247 if (row == col * 2) return -1;
248 if (row == col * 4) return -2;
249 assert(0 && "Unsupported transform size");
250 }
251 return 0; // Invalid
252}
253
Angie Chiangce3ad282017-08-08 09:51:54 -0700254void av1_gen_fwd_stage_range(int8_t *stage_range_col, int8_t *stage_range_row,
255 const TXFM_2D_FLIP_CFG *cfg, int bd);
256
257void av1_gen_inv_stage_range(int8_t *stage_range_col, int8_t *stage_range_row,
258 const TXFM_2D_FLIP_CFG *cfg, int8_t fwd_shift,
259 int bd);
260
Urvang Joshic5022162017-11-21 15:57:42 -0800261void av1_get_fwd_txfm_cfg(TX_TYPE tx_type, TX_SIZE tx_size,
262 TXFM_2D_FLIP_CFG *cfg);
263void av1_get_inv_txfm_cfg(TX_TYPE tx_type, TX_SIZE tx_size,
264 TXFM_2D_FLIP_CFG *cfg);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700265#ifdef __cplusplus
266}
267#endif // __cplusplus
268
Yaowu Xuf883b422016-08-30 14:01:10 -0700269#endif // AV1_TXFM_H_