blob: 6987317aeef05a4510a6d4ec6d1775291c42259f [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)));
27static const int32_t cospi_arr[7][64] = {
28 { 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
71static INLINE int32_t round_shift(int32_t value, int bit) {
Yaowu Xu637590c2016-11-16 15:15:46 -080072 assert(bit >= 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070073 return (value + (1 << (bit - 1))) >> bit;
74}
75
76static INLINE void round_shift_array(int32_t *arr, int size, int bit) {
77 int i;
78 if (bit == 0) {
79 return;
80 } else {
81 if (bit > 0) {
82 for (i = 0; i < size; i++) {
83 arr[i] = round_shift(arr[i], bit);
84 }
85 } else {
86 for (i = 0; i < size; i++) {
Yaowu Xu4d341542016-11-15 20:47:52 -080087 arr[i] = arr[i] * (1 << (-bit));
Yaowu Xuc27fc142016-08-22 16:08:15 -070088 }
89 }
90 }
91}
92
93static INLINE int32_t half_btf(int32_t w0, int32_t in0, int32_t w1, int32_t in1,
94 int bit) {
95 int32_t result_32 = w0 * in0 + w1 * in1;
96#if CONFIG_COEFFICIENT_RANGE_CHECKING
97 int64_t result_64 = (int64_t)w0 * (int64_t)in0 + (int64_t)w1 * (int64_t)in1;
Sebastien Alaiwana5d892b2017-02-03 10:25:51 +010098 if (result_64 < INT32_MIN || result_64 > INT32_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070099 printf("%s %d overflow result_32: %d result_64: %" PRId64
100 " w0: %d in0: %d w1: %d in1: "
101 "%d\n",
102 __FILE__, __LINE__, result_32, result_64, w0, in0, w1, in1);
103 assert(0 && "half_btf overflow");
104 }
105#endif
106 return round_shift(result_32, bit);
107}
108
109static INLINE int get_max_bit(int x) {
110 int max_bit = -1;
111 while (x) {
112 x = x >> 1;
113 max_bit++;
114 }
115 return max_bit;
116}
117
118// TODO(angiebird): implement SSE
119static INLINE void clamp_block(int16_t *block, int block_size, int stride,
120 int low, int high) {
121 int i, j;
122 for (i = 0; i < block_size; ++i) {
123 for (j = 0; j < block_size; ++j) {
124 block[i * stride + j] = clamp(block[i * stride + j], low, high);
125 }
126 }
127}
128
129typedef void (*TxfmFunc)(const int32_t *input, int32_t *output,
130 const int8_t *cos_bit, const int8_t *stage_range);
131
132typedef enum TXFM_TYPE {
133 TXFM_TYPE_DCT4,
134 TXFM_TYPE_DCT8,
135 TXFM_TYPE_DCT16,
136 TXFM_TYPE_DCT32,
137 TXFM_TYPE_DCT64,
138 TXFM_TYPE_ADST4,
139 TXFM_TYPE_ADST8,
140 TXFM_TYPE_ADST16,
141 TXFM_TYPE_ADST32,
142} TXFM_TYPE;
143
144typedef struct TXFM_2D_CFG {
145 const int txfm_size;
146 const int stage_num_col;
147 const int stage_num_row;
148
149 const int8_t *shift;
150 const int8_t *stage_range_col;
151 const int8_t *stage_range_row;
152 const int8_t *cos_bit_col;
153 const int8_t *cos_bit_row;
154 const TXFM_TYPE txfm_type_col;
155 const TXFM_TYPE txfm_type_row;
156} TXFM_2D_CFG;
157
158typedef struct TXFM_2D_FLIP_CFG {
159 int ud_flip; // flip upside down
160 int lr_flip; // flip left to right
161 const TXFM_2D_CFG *cfg;
162} TXFM_2D_FLIP_CFG;
163
164static INLINE void set_flip_cfg(int tx_type, TXFM_2D_FLIP_CFG *cfg) {
165 switch (tx_type) {
166 case DCT_DCT:
167 case ADST_DCT:
168 case DCT_ADST:
169 case ADST_ADST:
170 cfg->ud_flip = 0;
171 cfg->lr_flip = 0;
172 break;
173#if CONFIG_EXT_TX
174 case FLIPADST_DCT:
175 cfg->ud_flip = 1;
176 cfg->lr_flip = 0;
177 break;
178 case DCT_FLIPADST:
179 cfg->ud_flip = 0;
180 cfg->lr_flip = 1;
181 break;
182 case FLIPADST_FLIPADST:
183 cfg->ud_flip = 1;
184 cfg->lr_flip = 1;
185 break;
186 case ADST_FLIPADST:
187 cfg->ud_flip = 0;
188 cfg->lr_flip = 1;
189 break;
190 case FLIPADST_ADST:
191 cfg->ud_flip = 1;
192 cfg->lr_flip = 0;
193 break;
194#endif // CONFIG_EXT_TX
195 default:
196 cfg->ud_flip = 0;
197 cfg->lr_flip = 0;
198 assert(0);
199 }
200}
201
202#ifdef __cplusplus
203extern "C" {
204#endif
Yaowu Xuf883b422016-08-30 14:01:10 -0700205TXFM_2D_FLIP_CFG av1_get_fwd_txfm_cfg(int tx_type, int tx_size);
206TXFM_2D_FLIP_CFG av1_get_fwd_txfm_64x64_cfg(int tx_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700207#ifdef __cplusplus
208}
209#endif // __cplusplus
210
Yaowu Xuf883b422016-08-30 14:01:10 -0700211#endif // AV1_TXFM_H_