blob: b341cb73db615d92331c16d23976940c9f7e37aa [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"
Yaowu Xuf883b422016-08-30 14:01:10 -070020#include "aom/aom_integer.h"
21#include "aom_dsp/aom_dsp_common.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070022
23static const int cos_bit_min = 10;
24static const int cos_bit_max = 16;
25
26// cospi_arr[i][j] = (int)round(cos(M_PI*j/128) * (1<<(cos_bit_min+i)));
Frederic Barbierbbf7bb02017-05-05 09:37:40 +020027static const int32_t cospi_arr_data[7][64] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -070028 { 1024, 1024, 1023, 1021, 1019, 1016, 1013, 1009, 1004, 999, 993, 987, 980,
clang-format67948d32016-09-07 22:40:40 -070029 972, 964, 955, 946, 936, 926, 915, 903, 891, 878, 865, 851, 837,
30 822, 807, 792, 775, 759, 742, 724, 706, 688, 669, 650, 630, 610,
31 590, 569, 548, 526, 505, 483, 460, 438, 415, 392, 369, 345, 321,
32 297, 273, 249, 224, 200, 175, 150, 125, 100, 75, 50, 25 },
33 { 2048, 2047, 2046, 2042, 2038, 2033, 2026, 2018, 2009, 1998, 1987,
34 1974, 1960, 1945, 1928, 1911, 1892, 1872, 1851, 1829, 1806, 1782,
35 1757, 1730, 1703, 1674, 1645, 1615, 1583, 1551, 1517, 1483, 1448,
36 1412, 1375, 1338, 1299, 1260, 1220, 1179, 1138, 1096, 1053, 1009,
37 965, 921, 876, 830, 784, 737, 690, 642, 595, 546, 498,
38 449, 400, 350, 301, 251, 201, 151, 100, 50 },
39 { 4096, 4095, 4091, 4085, 4076, 4065, 4052, 4036, 4017, 3996, 3973,
40 3948, 3920, 3889, 3857, 3822, 3784, 3745, 3703, 3659, 3612, 3564,
41 3513, 3461, 3406, 3349, 3290, 3229, 3166, 3102, 3035, 2967, 2896,
42 2824, 2751, 2675, 2598, 2520, 2440, 2359, 2276, 2191, 2106, 2019,
43 1931, 1842, 1751, 1660, 1567, 1474, 1380, 1285, 1189, 1092, 995,
44 897, 799, 700, 601, 501, 401, 301, 201, 101 },
45 { 8192, 8190, 8182, 8170, 8153, 8130, 8103, 8071, 8035, 7993, 7946,
46 7895, 7839, 7779, 7713, 7643, 7568, 7489, 7405, 7317, 7225, 7128,
47 7027, 6921, 6811, 6698, 6580, 6458, 6333, 6203, 6070, 5933, 5793,
48 5649, 5501, 5351, 5197, 5040, 4880, 4717, 4551, 4383, 4212, 4038,
49 3862, 3683, 3503, 3320, 3135, 2948, 2760, 2570, 2378, 2185, 1990,
50 1795, 1598, 1401, 1202, 1003, 803, 603, 402, 201 },
Yaowu Xuc27fc142016-08-22 16:08:15 -070051 { 16384, 16379, 16364, 16340, 16305, 16261, 16207, 16143, 16069, 15986, 15893,
52 15791, 15679, 15557, 15426, 15286, 15137, 14978, 14811, 14635, 14449, 14256,
53 14053, 13842, 13623, 13395, 13160, 12916, 12665, 12406, 12140, 11866, 11585,
clang-format67948d32016-09-07 22:40:40 -070054 11297, 11003, 10702, 10394, 10080, 9760, 9434, 9102, 8765, 8423, 8076,
55 7723, 7366, 7005, 6639, 6270, 5897, 5520, 5139, 4756, 4370, 3981,
56 3590, 3196, 2801, 2404, 2006, 1606, 1205, 804, 402 },
Yaowu Xuc27fc142016-08-22 16:08:15 -070057 { 32768, 32758, 32729, 32679, 32610, 32522, 32413, 32286, 32138, 31972, 31786,
58 31581, 31357, 31114, 30853, 30572, 30274, 29957, 29622, 29269, 28899, 28511,
59 28106, 27684, 27246, 26791, 26320, 25833, 25330, 24812, 24279, 23732, 23170,
60 22595, 22006, 21403, 20788, 20160, 19520, 18868, 18205, 17531, 16846, 16151,
clang-format67948d32016-09-07 22:40:40 -070061 15447, 14733, 14010, 13279, 12540, 11793, 11039, 10279, 9512, 8740, 7962,
62 7180, 6393, 5602, 4808, 4011, 3212, 2411, 1608, 804 },
Yaowu Xuc27fc142016-08-22 16:08:15 -070063 { 65536, 65516, 65457, 65358, 65220, 65043, 64827, 64571, 64277, 63944, 63572,
64 63162, 62714, 62228, 61705, 61145, 60547, 59914, 59244, 58538, 57798, 57022,
65 56212, 55368, 54491, 53581, 52639, 51665, 50660, 49624, 48559, 47464, 46341,
66 45190, 44011, 42806, 41576, 40320, 39040, 37736, 36410, 35062, 33692, 32303,
67 30893, 29466, 28020, 26558, 25080, 23586, 22078, 20557, 19024, 17479, 15924,
clang-format67948d32016-09-07 22:40:40 -070068 14359, 12785, 11204, 9616, 8022, 6424, 4821, 3216, 1608 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070069};
70
Frederic Barbierbbf7bb02017-05-05 09:37:40 +020071static INLINE const int32_t *cospi_arr(int n) {
72 return cospi_arr_data[n - cos_bit_min];
73}
74
Yaowu Xuc27fc142016-08-22 16:08:15 -070075static INLINE int32_t round_shift(int32_t value, int bit) {
Yaowu Xu637590c2016-11-16 15:15:46 -080076 assert(bit >= 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070077 return (value + (1 << (bit - 1))) >> bit;
78}
79
80static INLINE void round_shift_array(int32_t *arr, int size, int bit) {
81 int i;
82 if (bit == 0) {
83 return;
84 } else {
85 if (bit > 0) {
86 for (i = 0; i < size; i++) {
87 arr[i] = round_shift(arr[i], bit);
88 }
89 } else {
90 for (i = 0; i < size; i++) {
Yaowu Xu4d341542016-11-15 20:47:52 -080091 arr[i] = arr[i] * (1 << (-bit));
Yaowu Xuc27fc142016-08-22 16:08:15 -070092 }
93 }
94 }
95}
96
97static INLINE int32_t half_btf(int32_t w0, int32_t in0, int32_t w1, int32_t in1,
98 int bit) {
99 int32_t result_32 = w0 * in0 + w1 * in1;
100#if CONFIG_COEFFICIENT_RANGE_CHECKING
101 int64_t result_64 = (int64_t)w0 * (int64_t)in0 + (int64_t)w1 * (int64_t)in1;
Sebastien Alaiwana5d892b2017-02-03 10:25:51 +0100102 if (result_64 < INT32_MIN || result_64 > INT32_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700103 printf("%s %d overflow result_32: %d result_64: %" PRId64
104 " w0: %d in0: %d w1: %d in1: "
105 "%d\n",
106 __FILE__, __LINE__, result_32, result_64, w0, in0, w1, in1);
107 assert(0 && "half_btf overflow");
108 }
109#endif
110 return round_shift(result_32, bit);
111}
112
113static INLINE int get_max_bit(int x) {
114 int max_bit = -1;
115 while (x) {
116 x = x >> 1;
117 max_bit++;
118 }
119 return max_bit;
120}
121
122// TODO(angiebird): implement SSE
123static INLINE void clamp_block(int16_t *block, int block_size, int stride,
124 int low, int high) {
125 int i, j;
126 for (i = 0; i < block_size; ++i) {
127 for (j = 0; j < block_size; ++j) {
128 block[i * stride + j] = clamp(block[i * stride + j], low, high);
129 }
130 }
131}
132
133typedef void (*TxfmFunc)(const int32_t *input, int32_t *output,
134 const int8_t *cos_bit, const int8_t *stage_range);
135
136typedef enum TXFM_TYPE {
137 TXFM_TYPE_DCT4,
138 TXFM_TYPE_DCT8,
139 TXFM_TYPE_DCT16,
140 TXFM_TYPE_DCT32,
141 TXFM_TYPE_DCT64,
142 TXFM_TYPE_ADST4,
143 TXFM_TYPE_ADST8,
144 TXFM_TYPE_ADST16,
145 TXFM_TYPE_ADST32,
Sarah Parker3eed4172017-05-15 20:49:22 -0700146 TXFM_TYPE_IDENTITY4,
147 TXFM_TYPE_IDENTITY8,
148 TXFM_TYPE_IDENTITY16,
149 TXFM_TYPE_IDENTITY32,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700150} TXFM_TYPE;
151
Sarah Parkereec47e62017-05-15 20:49:22 -0700152typedef struct TXFM_1D_CFG {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700153 const int txfm_size;
Sarah Parkereec47e62017-05-15 20:49:22 -0700154 const int stage_num;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700155
156 const int8_t *shift;
Sarah Parkereec47e62017-05-15 20:49:22 -0700157 const int8_t *stage_range;
158 const int8_t *cos_bit;
159 const TXFM_TYPE txfm_type;
160} TXFM_1D_CFG;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700161
162typedef struct TXFM_2D_FLIP_CFG {
163 int ud_flip; // flip upside down
164 int lr_flip; // flip left to right
Sarah Parkereec47e62017-05-15 20:49:22 -0700165 const TXFM_1D_CFG *col_cfg;
166 const TXFM_1D_CFG *row_cfg;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700167} TXFM_2D_FLIP_CFG;
168
169static INLINE void set_flip_cfg(int tx_type, TXFM_2D_FLIP_CFG *cfg) {
170 switch (tx_type) {
171 case DCT_DCT:
172 case ADST_DCT:
173 case DCT_ADST:
174 case ADST_ADST:
175 cfg->ud_flip = 0;
176 cfg->lr_flip = 0;
177 break;
178#if CONFIG_EXT_TX
Sarah Parker3eed4172017-05-15 20:49:22 -0700179 case IDTX:
180 case V_DCT:
181 case H_DCT:
182 case V_ADST:
183 case H_ADST:
184 cfg->ud_flip = 0;
185 cfg->lr_flip = 0;
186 break;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700187 case FLIPADST_DCT:
Sarah Parkereec47e62017-05-15 20:49:22 -0700188 case FLIPADST_ADST:
Sarah Parker3eed4172017-05-15 20:49:22 -0700189 case V_FLIPADST:
Yaowu Xuc27fc142016-08-22 16:08:15 -0700190 cfg->ud_flip = 1;
191 cfg->lr_flip = 0;
192 break;
193 case DCT_FLIPADST:
Sarah Parkereec47e62017-05-15 20:49:22 -0700194 case ADST_FLIPADST:
Sarah Parker3eed4172017-05-15 20:49:22 -0700195 case H_FLIPADST:
Yaowu Xuc27fc142016-08-22 16:08:15 -0700196 cfg->ud_flip = 0;
197 cfg->lr_flip = 1;
198 break;
199 case FLIPADST_FLIPADST:
200 cfg->ud_flip = 1;
201 cfg->lr_flip = 1;
202 break;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700203#endif // CONFIG_EXT_TX
204 default:
205 cfg->ud_flip = 0;
206 cfg->lr_flip = 0;
207 assert(0);
208 }
209}
210
211#ifdef __cplusplus
212extern "C" {
213#endif
Yaowu Xuf883b422016-08-30 14:01:10 -0700214TXFM_2D_FLIP_CFG av1_get_fwd_txfm_cfg(int tx_type, int tx_size);
215TXFM_2D_FLIP_CFG av1_get_fwd_txfm_64x64_cfg(int tx_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700216#ifdef __cplusplus
217}
218#endif // __cplusplus
219
Yaowu Xuf883b422016-08-30 14:01:10 -0700220#endif // AV1_TXFM_H_