blob: 34d6beaced7ef7e8f7f1a5f86cad1935705caf0d [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
James Zerndc857592018-02-01 19:21:48 -080019#include "./aom_config.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070020#include "av1/common/enums.h"
Angie Chiang155bf9a2017-08-06 19:52:57 -070021#include "av1/common/blockd.h"
Yaowu Xuf883b422016-08-30 14:01:10 -070022#include "aom/aom_integer.h"
23#include "aom_dsp/aom_dsp_common.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070024
Angie Chiang9c7089a2017-08-08 16:21:11 -070025#ifdef __cplusplus
26extern "C" {
27#endif
28
Yue Chen5b53ea12018-03-09 11:26:43 -080029extern const int32_t av1_cospi_arr_data[7][64];
30extern const int32_t av1_sinpi_arr_data[7][5];
31
Angie Chiangce3ad282017-08-08 09:51:54 -070032#define MAX_TXFM_STAGE_NUM 12
33
Yaowu Xuc27fc142016-08-22 16:08:15 -070034static const int cos_bit_min = 10;
35static const int cos_bit_max = 16;
36
Angie Chiangc8d6c082018-02-06 14:26:55 -080037static const int NewSqrt2Bits = 12;
38// 2^12 * sqrt(2)
39static const int32_t NewSqrt2 = 5793;
40// 2^12 / sqrt(2)
41static const int32_t NewInvSqrt2 = 2896;
42
Frederic Barbierbbf7bb02017-05-05 09:37:40 +020043static INLINE const int32_t *cospi_arr(int n) {
Yue Chen5b53ea12018-03-09 11:26:43 -080044 return av1_cospi_arr_data[n - cos_bit_min];
Frederic Barbierbbf7bb02017-05-05 09:37:40 +020045}
46
Angie Chiang82517362018-01-17 17:31:54 -080047static INLINE const int32_t *sinpi_arr(int n) {
Yue Chen5b53ea12018-03-09 11:26:43 -080048 return av1_sinpi_arr_data[n - cos_bit_min];
Angie Chiang82517362018-01-17 17:31:54 -080049}
50
James Zerndc857592018-02-01 19:21:48 -080051static INLINE int32_t range_check_value(int32_t value, int8_t bit) {
52#if CONFIG_COEFFICIENT_RANGE_CHECKING
James Zernb785b952018-02-01 19:27:09 -080053 const int64_t max_value = (1LL << (bit - 1)) - 1;
54 const int64_t min_value = -(1LL << (bit - 1));
55 if (value < min_value || value > max_value) {
James Zerndc857592018-02-01 19:21:48 -080056 fprintf(stderr, "coeff out of bit range, value: %d bit %d\n", value, bit);
57 assert(0);
58 }
59#else
60 (void)bit;
61#endif
62 return value;
63}
64
Yaowu Xuc27fc142016-08-22 16:08:15 -070065static INLINE int32_t round_shift(int32_t value, int bit) {
Yaowu Xu637590c2016-11-16 15:15:46 -080066 assert(bit >= 1);
James Zerna60e26d2017-11-15 12:11:17 -080067 return (int32_t)(((int64_t)value + (1ll << (bit - 1))) >> bit);
Yaowu Xuc27fc142016-08-22 16:08:15 -070068}
69
Yaowu Xuc27fc142016-08-22 16:08:15 -070070static INLINE int32_t half_btf(int32_t w0, int32_t in0, int32_t w1, int32_t in1,
71 int bit) {
Angie Chiangd1c222d2018-02-28 19:41:01 -080072 int64_t result_64 = (int64_t)(w0 * in0) + (int64_t)(w1 * in1);
73#if CONFIG_COEFFICIENT_RANGE_CHECKING
74 assert(result_64 >= INT32_MIN && result_64 <= INT32_MAX);
75#endif
76 return round_shift((int32_t)result_64, bit);
Yaowu Xuc27fc142016-08-22 16:08:15 -070077}
78
Angie Chiangd4327bc2018-01-22 20:54:04 -080079typedef void (*TxfmFunc)(const int32_t *input, int32_t *output, int8_t cos_bit,
80 const int8_t *stage_range);
Yaowu Xuc27fc142016-08-22 16:08:15 -070081
82typedef enum TXFM_TYPE {
83 TXFM_TYPE_DCT4,
84 TXFM_TYPE_DCT8,
85 TXFM_TYPE_DCT16,
86 TXFM_TYPE_DCT32,
87 TXFM_TYPE_DCT64,
88 TXFM_TYPE_ADST4,
89 TXFM_TYPE_ADST8,
90 TXFM_TYPE_ADST16,
91 TXFM_TYPE_ADST32,
Sarah Parker3eed4172017-05-15 20:49:22 -070092 TXFM_TYPE_IDENTITY4,
93 TXFM_TYPE_IDENTITY8,
94 TXFM_TYPE_IDENTITY16,
95 TXFM_TYPE_IDENTITY32,
Debargha Mukherjee570423c2017-10-01 00:35:20 -070096 TXFM_TYPE_IDENTITY64,
Angie Chiang0c7b8d82018-01-23 19:20:44 -080097 TXFM_TYPES,
98 TXFM_TYPE_INVALID,
Yaowu Xuc27fc142016-08-22 16:08:15 -070099} TXFM_TYPE;
100
Yaowu Xuc27fc142016-08-22 16:08:15 -0700101typedef struct TXFM_2D_FLIP_CFG {
Angie Chiang0c7b8d82018-01-23 19:20:44 -0800102 TX_SIZE tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700103 int ud_flip; // flip upside down
104 int lr_flip; // flip left to right
Angie Chiang4a75b5a2018-01-10 17:19:06 -0800105 const int8_t *shift;
Angie Chiangd4327bc2018-01-22 20:54:04 -0800106 int8_t cos_bit_col;
107 int8_t cos_bit_row;
Angie Chiang0c7b8d82018-01-23 19:20:44 -0800108 int8_t stage_range_col[MAX_TXFM_STAGE_NUM];
109 int8_t stage_range_row[MAX_TXFM_STAGE_NUM];
110 TXFM_TYPE txfm_type_col;
111 TXFM_TYPE txfm_type_row;
112 int stage_num_col;
113 int stage_num_row;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700114} TXFM_2D_FLIP_CFG;
115
Angie Chiangeae82082018-02-05 16:49:33 -0800116static INLINE void get_flip_cfg(TX_TYPE tx_type, int *ud_flip, int *lr_flip) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700117 switch (tx_type) {
118 case DCT_DCT:
119 case ADST_DCT:
120 case DCT_ADST:
121 case ADST_ADST:
Angie Chiangeae82082018-02-05 16:49:33 -0800122 *ud_flip = 0;
123 *lr_flip = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700124 break;
Sarah Parker3eed4172017-05-15 20:49:22 -0700125 case IDTX:
126 case V_DCT:
127 case H_DCT:
128 case V_ADST:
129 case H_ADST:
Angie Chiangeae82082018-02-05 16:49:33 -0800130 *ud_flip = 0;
131 *lr_flip = 0;
Sarah Parker3eed4172017-05-15 20:49:22 -0700132 break;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700133 case FLIPADST_DCT:
Sarah Parkereec47e62017-05-15 20:49:22 -0700134 case FLIPADST_ADST:
Sarah Parker3eed4172017-05-15 20:49:22 -0700135 case V_FLIPADST:
Angie Chiangeae82082018-02-05 16:49:33 -0800136 *ud_flip = 1;
137 *lr_flip = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700138 break;
139 case DCT_FLIPADST:
Sarah Parkereec47e62017-05-15 20:49:22 -0700140 case ADST_FLIPADST:
Sarah Parker3eed4172017-05-15 20:49:22 -0700141 case H_FLIPADST:
Angie Chiangeae82082018-02-05 16:49:33 -0800142 *ud_flip = 0;
143 *lr_flip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700144 break;
145 case FLIPADST_FLIPADST:
Angie Chiangeae82082018-02-05 16:49:33 -0800146 *ud_flip = 1;
147 *lr_flip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700148 break;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700149 default:
Angie Chiangeae82082018-02-05 16:49:33 -0800150 *ud_flip = 0;
151 *lr_flip = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700152 assert(0);
153 }
154}
155
Angie Chiangeae82082018-02-05 16:49:33 -0800156static INLINE void set_flip_cfg(TX_TYPE tx_type, TXFM_2D_FLIP_CFG *cfg) {
157 get_flip_cfg(tx_type, &cfg->ud_flip, &cfg->lr_flip);
158}
159
Urvang Joshi9752a2e2017-10-02 17:32:27 -0700160static INLINE TX_SIZE av1_rotate_tx_size(TX_SIZE tx_size) {
Angie Chiang155bf9a2017-08-06 19:52:57 -0700161 switch (tx_size) {
Angie Chiang155bf9a2017-08-06 19:52:57 -0700162 case TX_4X4: return TX_4X4;
163 case TX_8X8: return TX_8X8;
164 case TX_16X16: return TX_16X16;
165 case TX_32X32: return TX_32X32;
Angie Chiang155bf9a2017-08-06 19:52:57 -0700166 case TX_64X64: return TX_64X64;
Debargha Mukherjee2b435012017-09-28 08:30:35 -0700167 case TX_32X64: return TX_64X32;
168 case TX_64X32: return TX_32X64;
Angie Chiang155bf9a2017-08-06 19:52:57 -0700169 case TX_4X8: return TX_8X4;
170 case TX_8X4: return TX_4X8;
171 case TX_8X16: return TX_16X8;
172 case TX_16X8: return TX_8X16;
173 case TX_16X32: return TX_32X16;
174 case TX_32X16: return TX_16X32;
175 case TX_4X16: return TX_16X4;
176 case TX_16X4: return TX_4X16;
177 case TX_8X32: return TX_32X8;
178 case TX_32X8: return TX_8X32;
Debargha Mukherjee3f921082017-12-01 21:45:57 -0800179 case TX_16X64: return TX_64X16;
180 case TX_64X16: return TX_16X64;
Angie Chiang155bf9a2017-08-06 19:52:57 -0700181 default: assert(0); return TX_INVALID;
182 }
183}
184
Urvang Joshi2283d372017-10-02 17:16:45 -0700185static INLINE TX_TYPE av1_rotate_tx_type(TX_TYPE tx_type) {
Angie Chiang155bf9a2017-08-06 19:52:57 -0700186 switch (tx_type) {
187 case DCT_DCT: return DCT_DCT;
188 case ADST_DCT: return DCT_ADST;
189 case DCT_ADST: return ADST_DCT;
190 case ADST_ADST: return ADST_ADST;
Angie Chiang155bf9a2017-08-06 19:52:57 -0700191 case FLIPADST_DCT: return DCT_FLIPADST;
192 case DCT_FLIPADST: return FLIPADST_DCT;
193 case FLIPADST_FLIPADST: return FLIPADST_FLIPADST;
194 case ADST_FLIPADST: return FLIPADST_ADST;
195 case FLIPADST_ADST: return ADST_FLIPADST;
196 case IDTX: return IDTX;
197 case V_DCT: return H_DCT;
198 case H_DCT: return V_DCT;
199 case V_ADST: return H_ADST;
200 case H_ADST: return V_ADST;
201 case V_FLIPADST: return H_FLIPADST;
202 case H_FLIPADST: return V_FLIPADST;
Angie Chiang155bf9a2017-08-06 19:52:57 -0700203 default: assert(0); return TX_TYPES;
204 }
205}
Angie Chiang155bf9a2017-08-06 19:52:57 -0700206
Debargha Mukherjee9eabd692017-11-16 12:44:31 -0800207// Utility function that returns the log of the ratio of the col and row
208// sizes.
209static INLINE int get_rect_tx_log_ratio(int col, int row) {
210 if (col == row) return 0;
211 if (col > row) {
212 if (col == row * 2) return 1;
213 if (col == row * 4) return 2;
214 assert(0 && "Unsupported transform size");
215 } else {
216 if (row == col * 2) return -1;
217 if (row == col * 4) return -2;
218 assert(0 && "Unsupported transform size");
219 }
220 return 0; // Invalid
221}
222
Angie Chiangce3ad282017-08-08 09:51:54 -0700223void av1_gen_fwd_stage_range(int8_t *stage_range_col, int8_t *stage_range_row,
224 const TXFM_2D_FLIP_CFG *cfg, int bd);
225
226void av1_gen_inv_stage_range(int8_t *stage_range_col, int8_t *stage_range_row,
Debargha Mukherjee1158bff2018-01-01 18:23:59 -0800227 const TXFM_2D_FLIP_CFG *cfg, TX_SIZE tx_size,
Angie Chiangce3ad282017-08-08 09:51:54 -0700228 int bd);
229
Urvang Joshic5022162017-11-21 15:57:42 -0800230void av1_get_fwd_txfm_cfg(TX_TYPE tx_type, TX_SIZE tx_size,
231 TXFM_2D_FLIP_CFG *cfg);
232void av1_get_inv_txfm_cfg(TX_TYPE tx_type, TX_SIZE tx_size,
233 TXFM_2D_FLIP_CFG *cfg);
Angie Chiang0c7b8d82018-01-23 19:20:44 -0800234extern const TXFM_TYPE av1_txfm_type_ls[5][TX_TYPES_1D];
235extern const int8_t av1_txfm_stage_num_list[TXFM_TYPES];
Angie Chiang29d2f212018-01-24 19:42:57 -0800236static INLINE int get_txw_idx(TX_SIZE tx_size) {
237 return tx_size_wide_log2[tx_size] - tx_size_wide_log2[0];
238}
239static INLINE int get_txh_idx(TX_SIZE tx_size) {
240 return tx_size_high_log2[tx_size] - tx_size_high_log2[0];
241}
242#define MAX_TXWH_IDX 5
Yaowu Xuc27fc142016-08-22 16:08:15 -0700243#ifdef __cplusplus
244}
245#endif // __cplusplus
246
Yaowu Xuf883b422016-08-30 14:01:10 -0700247#endif // AV1_TXFM_H_