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 #include "config/aom_config.h"
13 #include "config/av1_rtcd.h"
14 #include "config/aom_dsp_rtcd.h"
15
16 #include "av1/common/idct.h"
17 #include "av1/encoder/hybrid_fwd_txfm.h"
18
19 /* 4-point reversible, orthonormal Walsh-Hadamard in 3.5 adds, 0.5 shifts per
20 pixel. */
av1_fwht4x4_c(const int16_t * input,tran_low_t * output,int stride)21 void av1_fwht4x4_c(const int16_t *input, tran_low_t *output, int stride) {
22 int i;
23 tran_high_t a1, b1, c1, d1, e1;
24 const int16_t *ip_pass0 = input;
25 const tran_low_t *ip = NULL;
26 tran_low_t *op = output;
27
28 for (i = 0; i < 4; i++) {
29 a1 = ip_pass0[0 * stride];
30 b1 = ip_pass0[1 * stride];
31 c1 = ip_pass0[2 * stride];
32 d1 = ip_pass0[3 * stride];
33
34 a1 += b1;
35 d1 = d1 - c1;
36 e1 = (a1 - d1) >> 1;
37 b1 = e1 - b1;
38 c1 = e1 - c1;
39 a1 -= c1;
40 d1 += b1;
41 op[0] = (tran_low_t)a1;
42 op[4] = (tran_low_t)c1;
43 op[8] = (tran_low_t)d1;
44 op[12] = (tran_low_t)b1;
45
46 ip_pass0++;
47 op++;
48 }
49 ip = output;
50 op = output;
51
52 for (i = 0; i < 4; i++) {
53 a1 = ip[0];
54 b1 = ip[1];
55 c1 = ip[2];
56 d1 = ip[3];
57
58 a1 += b1;
59 d1 -= c1;
60 e1 = (a1 - d1) >> 1;
61 b1 = e1 - b1;
62 c1 = e1 - c1;
63 a1 -= c1;
64 d1 += b1;
65 op[0] = (tran_low_t)(a1 * UNIT_QUANT_FACTOR);
66 op[1] = (tran_low_t)(c1 * UNIT_QUANT_FACTOR);
67 op[2] = (tran_low_t)(d1 * UNIT_QUANT_FACTOR);
68 op[3] = (tran_low_t)(b1 * UNIT_QUANT_FACTOR);
69
70 ip += 4;
71 op += 4;
72 }
73 }
74
av1_highbd_fwht4x4_c(const int16_t * input,tran_low_t * output,int stride)75 void av1_highbd_fwht4x4_c(const int16_t *input, tran_low_t *output,
76 int stride) {
77 av1_fwht4x4_c(input, output, stride);
78 }
79
highbd_fwd_txfm_4x4(const int16_t * src_diff,tran_low_t * coeff,int diff_stride,TxfmParam * txfm_param)80 static void highbd_fwd_txfm_4x4(const int16_t *src_diff, tran_low_t *coeff,
81 int diff_stride, TxfmParam *txfm_param) {
82 int32_t *dst_coeff = (int32_t *)coeff;
83 const TX_TYPE tx_type = txfm_param->tx_type;
84 const int bd = txfm_param->bd;
85 if (txfm_param->lossless) {
86 assert(tx_type == DCT_DCT);
87 av1_highbd_fwht4x4(src_diff, coeff, diff_stride);
88 return;
89 }
90 av1_fwd_txfm2d_4x4(src_diff, dst_coeff, diff_stride, tx_type, bd);
91 }
92
highbd_fwd_txfm_4x8(const int16_t * src_diff,tran_low_t * coeff,int diff_stride,TxfmParam * txfm_param)93 static void highbd_fwd_txfm_4x8(const int16_t *src_diff, tran_low_t *coeff,
94 int diff_stride, TxfmParam *txfm_param) {
95 int32_t *dst_coeff = (int32_t *)coeff;
96 av1_fwd_txfm2d_4x8(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
97 txfm_param->bd);
98 }
99
highbd_fwd_txfm_8x4(const int16_t * src_diff,tran_low_t * coeff,int diff_stride,TxfmParam * txfm_param)100 static void highbd_fwd_txfm_8x4(const int16_t *src_diff, tran_low_t *coeff,
101 int diff_stride, TxfmParam *txfm_param) {
102 int32_t *dst_coeff = (int32_t *)coeff;
103 av1_fwd_txfm2d_8x4(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
104 txfm_param->bd);
105 }
106
highbd_fwd_txfm_8x16(const int16_t * src_diff,tran_low_t * coeff,int diff_stride,TxfmParam * txfm_param)107 static void highbd_fwd_txfm_8x16(const int16_t *src_diff, tran_low_t *coeff,
108 int diff_stride, TxfmParam *txfm_param) {
109 int32_t *dst_coeff = (int32_t *)coeff;
110 const TX_TYPE tx_type = txfm_param->tx_type;
111 const int bd = txfm_param->bd;
112 av1_fwd_txfm2d_8x16(src_diff, dst_coeff, diff_stride, tx_type, bd);
113 }
114
highbd_fwd_txfm_16x8(const int16_t * src_diff,tran_low_t * coeff,int diff_stride,TxfmParam * txfm_param)115 static void highbd_fwd_txfm_16x8(const int16_t *src_diff, tran_low_t *coeff,
116 int diff_stride, TxfmParam *txfm_param) {
117 int32_t *dst_coeff = (int32_t *)coeff;
118 const TX_TYPE tx_type = txfm_param->tx_type;
119 const int bd = txfm_param->bd;
120 av1_fwd_txfm2d_16x8(src_diff, dst_coeff, diff_stride, tx_type, bd);
121 }
122
highbd_fwd_txfm_16x32(const int16_t * src_diff,tran_low_t * coeff,int diff_stride,TxfmParam * txfm_param)123 static void highbd_fwd_txfm_16x32(const int16_t *src_diff, tran_low_t *coeff,
124 int diff_stride, TxfmParam *txfm_param) {
125 int32_t *dst_coeff = (int32_t *)coeff;
126 av1_fwd_txfm2d_16x32(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
127 txfm_param->bd);
128 }
129
highbd_fwd_txfm_32x16(const int16_t * src_diff,tran_low_t * coeff,int diff_stride,TxfmParam * txfm_param)130 static void highbd_fwd_txfm_32x16(const int16_t *src_diff, tran_low_t *coeff,
131 int diff_stride, TxfmParam *txfm_param) {
132 int32_t *dst_coeff = (int32_t *)coeff;
133 av1_fwd_txfm2d_32x16(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
134 txfm_param->bd);
135 }
136
highbd_fwd_txfm_16x4(const int16_t * src_diff,tran_low_t * coeff,int diff_stride,TxfmParam * txfm_param)137 static void highbd_fwd_txfm_16x4(const int16_t *src_diff, tran_low_t *coeff,
138 int diff_stride, TxfmParam *txfm_param) {
139 int32_t *dst_coeff = (int32_t *)coeff;
140 av1_fwd_txfm2d_16x4(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
141 txfm_param->bd);
142 }
143
highbd_fwd_txfm_4x16(const int16_t * src_diff,tran_low_t * coeff,int diff_stride,TxfmParam * txfm_param)144 static void highbd_fwd_txfm_4x16(const int16_t *src_diff, tran_low_t *coeff,
145 int diff_stride, TxfmParam *txfm_param) {
146 int32_t *dst_coeff = (int32_t *)coeff;
147 av1_fwd_txfm2d_4x16(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
148 txfm_param->bd);
149 }
150
highbd_fwd_txfm_32x8(const int16_t * src_diff,tran_low_t * coeff,int diff_stride,TxfmParam * txfm_param)151 static void highbd_fwd_txfm_32x8(const int16_t *src_diff, tran_low_t *coeff,
152 int diff_stride, TxfmParam *txfm_param) {
153 int32_t *dst_coeff = (int32_t *)coeff;
154 av1_fwd_txfm2d_32x8(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
155 txfm_param->bd);
156 }
157
highbd_fwd_txfm_8x32(const int16_t * src_diff,tran_low_t * coeff,int diff_stride,TxfmParam * txfm_param)158 static void highbd_fwd_txfm_8x32(const int16_t *src_diff, tran_low_t *coeff,
159 int diff_stride, TxfmParam *txfm_param) {
160 int32_t *dst_coeff = (int32_t *)coeff;
161 av1_fwd_txfm2d_8x32(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
162 txfm_param->bd);
163 }
164
highbd_fwd_txfm_8x8(const int16_t * src_diff,tran_low_t * coeff,int diff_stride,TxfmParam * txfm_param)165 static void highbd_fwd_txfm_8x8(const int16_t *src_diff, tran_low_t *coeff,
166 int diff_stride, TxfmParam *txfm_param) {
167 int32_t *dst_coeff = (int32_t *)coeff;
168 const TX_TYPE tx_type = txfm_param->tx_type;
169 const int bd = txfm_param->bd;
170 av1_fwd_txfm2d_8x8(src_diff, dst_coeff, diff_stride, tx_type, bd);
171 }
172
highbd_fwd_txfm_16x16(const int16_t * src_diff,tran_low_t * coeff,int diff_stride,TxfmParam * txfm_param)173 static void highbd_fwd_txfm_16x16(const int16_t *src_diff, tran_low_t *coeff,
174 int diff_stride, TxfmParam *txfm_param) {
175 int32_t *dst_coeff = (int32_t *)coeff;
176 const TX_TYPE tx_type = txfm_param->tx_type;
177 const int bd = txfm_param->bd;
178 av1_fwd_txfm2d_16x16(src_diff, dst_coeff, diff_stride, tx_type, bd);
179 }
180
highbd_fwd_txfm_32x32(const int16_t * src_diff,tran_low_t * coeff,int diff_stride,TxfmParam * txfm_param)181 static void highbd_fwd_txfm_32x32(const int16_t *src_diff, tran_low_t *coeff,
182 int diff_stride, TxfmParam *txfm_param) {
183 int32_t *dst_coeff = (int32_t *)coeff;
184 const TX_TYPE tx_type = txfm_param->tx_type;
185 const int bd = txfm_param->bd;
186 av1_fwd_txfm2d_32x32(src_diff, dst_coeff, diff_stride, tx_type, bd);
187 }
188
highbd_fwd_txfm_32x64(const int16_t * src_diff,tran_low_t * coeff,int diff_stride,TxfmParam * txfm_param)189 static void highbd_fwd_txfm_32x64(const int16_t *src_diff, tran_low_t *coeff,
190 int diff_stride, TxfmParam *txfm_param) {
191 assert(txfm_param->tx_type == DCT_DCT);
192 int32_t *dst_coeff = (int32_t *)coeff;
193 const int bd = txfm_param->bd;
194 av1_fwd_txfm2d_32x64(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
195 bd);
196 }
197
highbd_fwd_txfm_64x32(const int16_t * src_diff,tran_low_t * coeff,int diff_stride,TxfmParam * txfm_param)198 static void highbd_fwd_txfm_64x32(const int16_t *src_diff, tran_low_t *coeff,
199 int diff_stride, TxfmParam *txfm_param) {
200 assert(txfm_param->tx_type == DCT_DCT);
201 int32_t *dst_coeff = (int32_t *)coeff;
202 const int bd = txfm_param->bd;
203 av1_fwd_txfm2d_64x32(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
204 bd);
205 }
206
highbd_fwd_txfm_16x64(const int16_t * src_diff,tran_low_t * coeff,int diff_stride,TxfmParam * txfm_param)207 static void highbd_fwd_txfm_16x64(const int16_t *src_diff, tran_low_t *coeff,
208 int diff_stride, TxfmParam *txfm_param) {
209 assert(txfm_param->tx_type == DCT_DCT);
210 int32_t *dst_coeff = (int32_t *)coeff;
211 const int bd = txfm_param->bd;
212 av1_fwd_txfm2d_16x64(src_diff, dst_coeff, diff_stride, DCT_DCT, bd);
213 }
214
highbd_fwd_txfm_64x16(const int16_t * src_diff,tran_low_t * coeff,int diff_stride,TxfmParam * txfm_param)215 static void highbd_fwd_txfm_64x16(const int16_t *src_diff, tran_low_t *coeff,
216 int diff_stride, TxfmParam *txfm_param) {
217 assert(txfm_param->tx_type == DCT_DCT);
218 int32_t *dst_coeff = (int32_t *)coeff;
219 const int bd = txfm_param->bd;
220 av1_fwd_txfm2d_64x16(src_diff, dst_coeff, diff_stride, DCT_DCT, bd);
221 }
222
highbd_fwd_txfm_64x64(const int16_t * src_diff,tran_low_t * coeff,int diff_stride,TxfmParam * txfm_param)223 static void highbd_fwd_txfm_64x64(const int16_t *src_diff, tran_low_t *coeff,
224 int diff_stride, TxfmParam *txfm_param) {
225 assert(txfm_param->tx_type == DCT_DCT);
226 int32_t *dst_coeff = (int32_t *)coeff;
227 const int bd = txfm_param->bd;
228 av1_fwd_txfm2d_64x64(src_diff, dst_coeff, diff_stride, DCT_DCT, bd);
229 }
230
av1_fwd_txfm(const int16_t * src_diff,tran_low_t * coeff,int diff_stride,TxfmParam * txfm_param)231 void av1_fwd_txfm(const int16_t *src_diff, tran_low_t *coeff, int diff_stride,
232 TxfmParam *txfm_param) {
233 if (txfm_param->bd == 8)
234 av1_lowbd_fwd_txfm(src_diff, coeff, diff_stride, txfm_param);
235 else
236 av1_highbd_fwd_txfm(src_diff, coeff, diff_stride, txfm_param);
237 }
238
av1_lowbd_fwd_txfm_c(const int16_t * src_diff,tran_low_t * coeff,int diff_stride,TxfmParam * txfm_param)239 void av1_lowbd_fwd_txfm_c(const int16_t *src_diff, tran_low_t *coeff,
240 int diff_stride, TxfmParam *txfm_param) {
241 av1_highbd_fwd_txfm(src_diff, coeff, diff_stride, txfm_param);
242 }
243
av1_highbd_fwd_txfm(const int16_t * src_diff,tran_low_t * coeff,int diff_stride,TxfmParam * txfm_param)244 void av1_highbd_fwd_txfm(const int16_t *src_diff, tran_low_t *coeff,
245 int diff_stride, TxfmParam *txfm_param) {
246 assert(av1_ext_tx_used[txfm_param->tx_set_type][txfm_param->tx_type]);
247 const TX_SIZE tx_size = txfm_param->tx_size;
248 switch (tx_size) {
249 case TX_64X64:
250 highbd_fwd_txfm_64x64(src_diff, coeff, diff_stride, txfm_param);
251 break;
252 case TX_32X64:
253 highbd_fwd_txfm_32x64(src_diff, coeff, diff_stride, txfm_param);
254 break;
255 case TX_64X32:
256 highbd_fwd_txfm_64x32(src_diff, coeff, diff_stride, txfm_param);
257 break;
258 case TX_16X64:
259 highbd_fwd_txfm_16x64(src_diff, coeff, diff_stride, txfm_param);
260 break;
261 case TX_64X16:
262 highbd_fwd_txfm_64x16(src_diff, coeff, diff_stride, txfm_param);
263 break;
264 case TX_32X32:
265 highbd_fwd_txfm_32x32(src_diff, coeff, diff_stride, txfm_param);
266 break;
267 case TX_16X16:
268 highbd_fwd_txfm_16x16(src_diff, coeff, diff_stride, txfm_param);
269 break;
270 case TX_8X8:
271 highbd_fwd_txfm_8x8(src_diff, coeff, diff_stride, txfm_param);
272 break;
273 case TX_4X8:
274 highbd_fwd_txfm_4x8(src_diff, coeff, diff_stride, txfm_param);
275 break;
276 case TX_8X4:
277 highbd_fwd_txfm_8x4(src_diff, coeff, diff_stride, txfm_param);
278 break;
279 case TX_8X16:
280 highbd_fwd_txfm_8x16(src_diff, coeff, diff_stride, txfm_param);
281 break;
282 case TX_16X8:
283 highbd_fwd_txfm_16x8(src_diff, coeff, diff_stride, txfm_param);
284 break;
285 case TX_16X32:
286 highbd_fwd_txfm_16x32(src_diff, coeff, diff_stride, txfm_param);
287 break;
288 case TX_32X16:
289 highbd_fwd_txfm_32x16(src_diff, coeff, diff_stride, txfm_param);
290 break;
291 case TX_4X4:
292 highbd_fwd_txfm_4x4(src_diff, coeff, diff_stride, txfm_param);
293 break;
294 case TX_4X16:
295 highbd_fwd_txfm_4x16(src_diff, coeff, diff_stride, txfm_param);
296 break;
297 case TX_16X4:
298 highbd_fwd_txfm_16x4(src_diff, coeff, diff_stride, txfm_param);
299 break;
300 case TX_8X32:
301 highbd_fwd_txfm_8x32(src_diff, coeff, diff_stride, txfm_param);
302 break;
303 case TX_32X8:
304 highbd_fwd_txfm_32x8(src_diff, coeff, diff_stride, txfm_param);
305 break;
306 default: assert(0); break;
307 }
308 }
309