• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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