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. */ 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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