/* * Copyright (c) 2017, Alliance for Open Media. All rights reserved * * This source code is subject to the terms of the BSD 2 Clause License and * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License * was not distributed with this source code in the LICENSE file, you can * obtain it at www.aomedia.org/license/software. If the Alliance for Open * Media Patent License 1.0 was not distributed with this source code in the * PATENTS file, you can obtain it at www.aomedia.org/license/patent. */ #include "./av1_rtcd.h" #include "./aom_config.h" #include "./aom_dsp_rtcd.h" #include "av1/common/daala_tx.h" #include "av1/encoder/daala_fwd_txfm.h" #if CONFIG_DAALA_TX // Complete Daala TX map, sans lossless which is special cased typedef void (*daala_ftx)(od_coeff[], const od_coeff *, int); static daala_ftx tx_map[TX_SIZES][TX_TYPES_1D] = { // 4-point transforms { od_bin_fdct4, od_bin_fdst4, od_bin_fdst4, od_bin_fidtx4 }, // 8-point transforms { od_bin_fdct8, od_bin_fdst8, od_bin_fdst8, od_bin_fidtx8 }, // 16-point transforms { od_bin_fdct16, od_bin_fdst16, od_bin_fdst16, od_bin_fidtx16 }, // 32-point transforms { od_bin_fdct32, od_bin_fdst32, od_bin_fdst32, od_bin_fidtx32 }, #if CONFIG_TX64X64 // 64-point transforms { od_bin_fdct64, NULL, NULL, od_bin_fidtx64 }, #endif }; static int tx_flip(TX_TYPE_1D t) { return t == 2; } // Daala TX toplevel entry point, same interface as av1 low-bidepth // and high-bitdepth TX (av1_fwd_txfm and av1_highbd_fwd_txfm). This // same function is intended for both low and high bitdepth cases with // a tran_low_t of 32 bits (matching od_coeff). void daala_fwd_txfm(const int16_t *input_pixels, tran_low_t *output_coeffs, int input_stride, TxfmParam *txfm_param) { const TX_SIZE tx_size = txfm_param->tx_size; const TX_TYPE tx_type = txfm_param->tx_type; assert(tx_size <= TX_SIZES_ALL); assert(tx_type <= TX_TYPES); if (txfm_param->lossless) { // Transform function special-cased for lossless assert(tx_type == DCT_DCT); assert(tx_size == TX_4X4); av1_fwht4x4(input_pixels, output_coeffs, input_stride); } else { // General TX case const int upshift = TX_COEFF_DEPTH - txfm_param->bd; assert(upshift >= 0); assert(sizeof(tran_low_t) == sizeof(od_coeff)); assert(sizeof(tran_low_t) >= 4); // Hook into existing map translation infrastructure to select // appropriate TX functions const int cols = tx_size_wide[tx_size]; const int rows = tx_size_high[tx_size]; const TX_SIZE col_idx = txsize_vert_map[tx_size]; const TX_SIZE row_idx = txsize_horz_map[tx_size]; assert(col_idx <= TX_SIZES); assert(row_idx <= TX_SIZES); assert(vtx_tab[tx_type] <= (int)TX_TYPES_1D); assert(htx_tab[tx_type] <= (int)TX_TYPES_1D); daala_ftx col_tx = tx_map[col_idx][vtx_tab[tx_type]]; daala_ftx row_tx = tx_map[row_idx][htx_tab[tx_type]]; int col_flip = tx_flip(vtx_tab[tx_type]); int row_flip = tx_flip(htx_tab[tx_type]); od_coeff tmp[MAX_TX_SIZE]; int r; int c; assert(col_tx); assert(row_tx); // Transform columns for (c = 0; c < cols; ++c) { // Cast and shift for (r = 0; r < rows; ++r) tmp[r] = ((od_coeff)(input_pixels[r * input_stride + c])) * (1 << upshift); if (col_flip) col_tx(tmp, tmp + (rows - 1), -1); else col_tx(tmp, tmp, 1); // No ystride in daala_tx lowlevel functions, store output vector // into column the long way for (r = 0; r < rows; ++r) output_coeffs[r * cols + c] = tmp[r]; } // Transform rows for (r = 0; r < rows; ++r) { if (row_flip) row_tx(output_coeffs + r * cols, output_coeffs + r * cols + cols - 1, -1); else row_tx(output_coeffs + r * cols, output_coeffs + r * cols, 1); } } } #endif