#include "test/acm_random.h"
#include "test/vp10_txfm_test.h"
-#include "vp10/common/vp10_fwd_txfm2d_cfg.h"
+#include "vp10/common/vp10_txfm.h"
#include "./vp10_rtcd.h"
using libvpx_test::ACMRandom;
namespace {
#if CONFIG_VP9_HIGHBITDEPTH
-const int txfm_size_num = 5;
-const int txfm_size_ls[5] = {4, 8, 16, 32, 64};
-const TXFM_2D_CFG* fwd_txfm_cfg_ls[5][4] = {
- {&fwd_txfm_2d_cfg_dct_dct_4, &fwd_txfm_2d_cfg_dct_adst_4,
- &fwd_txfm_2d_cfg_adst_adst_4, &fwd_txfm_2d_cfg_adst_dct_4},
- {&fwd_txfm_2d_cfg_dct_dct_8, &fwd_txfm_2d_cfg_dct_adst_8,
- &fwd_txfm_2d_cfg_adst_adst_8, &fwd_txfm_2d_cfg_adst_dct_8},
- {&fwd_txfm_2d_cfg_dct_dct_16, &fwd_txfm_2d_cfg_dct_adst_16,
- &fwd_txfm_2d_cfg_adst_adst_16, &fwd_txfm_2d_cfg_adst_dct_16},
- {&fwd_txfm_2d_cfg_dct_dct_32, &fwd_txfm_2d_cfg_dct_adst_32,
- &fwd_txfm_2d_cfg_adst_adst_32, &fwd_txfm_2d_cfg_adst_dct_32},
- {&fwd_txfm_2d_cfg_dct_dct_64, NULL, NULL, NULL}};
-
-const Fwd_Txfm2d_Func fwd_txfm_func_ls[5] = {
+const Fwd_Txfm2d_Func fwd_txfm_func_ls[TX_SIZES] = {
vp10_fwd_txfm2d_4x4_c, vp10_fwd_txfm2d_8x8_c, vp10_fwd_txfm2d_16x16_c,
- vp10_fwd_txfm2d_32x32_c, vp10_fwd_txfm2d_64x64_c};
+ vp10_fwd_txfm2d_32x32_c};
-const int txfm_type_num = 4;
-const TYPE_TXFM type_ls_0[4] = {TYPE_DCT, TYPE_DCT, TYPE_ADST, TYPE_ADST};
-const TYPE_TXFM type_ls_1[4] = {TYPE_DCT, TYPE_ADST, TYPE_ADST, TYPE_DCT};
+const TYPE_TXFM type_ls_0[4] = {TYPE_DCT, TYPE_ADST, TYPE_DCT, TYPE_ADST};
+const TYPE_TXFM type_ls_1[4] = {TYPE_DCT, TYPE_DCT, TYPE_ADST, TYPE_ADST};
TEST(vp10_fwd_txfm2d, accuracy) {
- for (int txfm_size_idx = 0; txfm_size_idx < txfm_size_num; ++txfm_size_idx) {
- int txfm_size = txfm_size_ls[txfm_size_idx];
+ for (int tx_size = 0; tx_size < TX_SIZES; ++tx_size) {
+ int txfm_size = 1 << (tx_size + 2);
int sqr_txfm_size = txfm_size * txfm_size;
int16_t* input = new int16_t[sqr_txfm_size];
int32_t* output = new int32_t[sqr_txfm_size];
double* ref_input = new double[sqr_txfm_size];
double* ref_output = new double[sqr_txfm_size];
- for (int txfm_type_idx = 0; txfm_type_idx < txfm_type_num;
- ++txfm_type_idx) {
- const TXFM_2D_CFG* fwd_txfm_cfg =
- fwd_txfm_cfg_ls[txfm_size_idx][txfm_type_idx];
+ for (int tx_type = 0; tx_type < 4; ++tx_type) {
+ TXFM_2D_FLIP_CFG fwd_txfm_flip_cfg =
+ vp10_get_fwd_txfm_cfg(tx_type, tx_size);
+ const TXFM_2D_CFG *fwd_txfm_cfg = fwd_txfm_flip_cfg.cfg;
if (fwd_txfm_cfg != NULL) {
- Fwd_Txfm2d_Func fwd_txfm_func = fwd_txfm_func_ls[txfm_size_idx];
- TYPE_TXFM type0 = type_ls_0[txfm_type_idx];
- TYPE_TXFM type1 = type_ls_1[txfm_type_idx];
+ Fwd_Txfm2d_Func fwd_txfm_func = fwd_txfm_func_ls[tx_size];
+ TYPE_TXFM type0 = type_ls_0[tx_type];
+ TYPE_TXFM type1 = type_ls_1[tx_type];
int amplify_bit = fwd_txfm_cfg->shift[0] + fwd_txfm_cfg->shift[1] +
fwd_txfm_cfg->shift[2];
double amplify_factor =
amplify_bit >= 0 ? (1 << amplify_bit) : (1.0 / (1 << -amplify_bit));
- int tx_type = libvpx_test::get_tx_type(fwd_txfm_cfg);
ACMRandom rnd(ACMRandom::DeterministicSeed());
int count = 500;
switch (txfm_type) {
case TXFM_TYPE_DCT4:
return vp10_fdct4_new;
- break;
case TXFM_TYPE_DCT8:
return vp10_fdct8_new;
- break;
case TXFM_TYPE_DCT16:
return vp10_fdct16_new;
- break;
case TXFM_TYPE_DCT32:
return vp10_fdct32_new;
- break;
case TXFM_TYPE_DCT64:
return vp10_fdct64_new;
- break;
case TXFM_TYPE_ADST4:
return vp10_fadst4_new;
- break;
case TXFM_TYPE_ADST8:
return vp10_fadst8_new;
- break;
case TXFM_TYPE_ADST16:
return vp10_fadst16_new;
- break;
case TXFM_TYPE_ADST32:
return vp10_fadst32_new;
- break;
default:
assert(0);
return NULL;
}
static INLINE void fwd_txfm2d_c(const int16_t *input, int32_t *output,
- const int stride, const TXFM_2D_CFG *cfg,
+ const int stride, const TXFM_2D_FLIP_CFG *cfg,
int32_t *buf) {
- int i, j;
- const int txfm_size = cfg->txfm_size;
- const int8_t *shift = cfg->shift;
- const int8_t *stage_range_col = cfg->stage_range_col;
- const int8_t *stage_range_row = cfg->stage_range_row;
- const int8_t *cos_bit_col = cfg->cos_bit_col;
- const int8_t *cos_bit_row = cfg->cos_bit_row;
- const TxfmFunc txfm_func_col = fwd_txfm_type_to_func(cfg->txfm_type_col);
- const TxfmFunc txfm_func_row = fwd_txfm_type_to_func(cfg->txfm_type_row);
+ int c, r;
+ const int txfm_size = cfg->cfg->txfm_size;
+ const int8_t *shift = cfg->cfg->shift;
+ const int8_t *stage_range_col = cfg->cfg->stage_range_col;
+ const int8_t *stage_range_row = cfg->cfg->stage_range_row;
+ const int8_t *cos_bit_col = cfg->cfg->cos_bit_col;
+ const int8_t *cos_bit_row = cfg->cfg->cos_bit_row;
+ const TxfmFunc txfm_func_col = fwd_txfm_type_to_func(cfg->cfg->txfm_type_col);
+ const TxfmFunc txfm_func_row = fwd_txfm_type_to_func(cfg->cfg->txfm_type_row);
// use output buffer as temp buffer
int32_t* temp_in = output;
int32_t* temp_out = output + txfm_size;
// Columns
- for (i = 0; i < txfm_size; ++i) {
- for (j = 0; j < txfm_size; ++j)
- temp_in[j] = input[j * stride + i];
+ for (c = 0; c < txfm_size; ++c) {
+ if (cfg->ud_flip == 0) {
+ for (r = 0; r < txfm_size; ++r)
+ temp_in[r] = input[r * stride + c];
+ } else {
+ for (r = 0; r < txfm_size; ++r)
+ // flip upside down
+ temp_in[r] = input[(txfm_size - r - 1) * stride + c];
+ }
round_shift_array(temp_in, txfm_size, -shift[0]);
txfm_func_col(temp_in, temp_out, cos_bit_col, stage_range_col);
round_shift_array(temp_out, txfm_size, -shift[1]);
- for (j = 0; j < txfm_size; ++j)
- buf[j * txfm_size + i] = temp_out[j];
+ if (cfg->lr_flip == 0) {
+ for (r = 0; r < txfm_size; ++r)
+ buf[r * txfm_size + c] = temp_out[r];
+ } else {
+ for (r = 0; r < txfm_size; ++r)
+ // flip from left to right
+ buf[r * txfm_size + (txfm_size - c - 1)] = temp_out[r];
+ }
}
// Rows
- for (i = 0; i < txfm_size; ++i) {
- txfm_func_row(buf + i * txfm_size, output + i * txfm_size, cos_bit_row,
+ for (r = 0; r < txfm_size; ++r) {
+ txfm_func_row(buf + r * txfm_size, output + r * txfm_size, cos_bit_row,
stage_range_row);
- round_shift_array(output + i * txfm_size, txfm_size, -shift[2]);
+ round_shift_array(output + r * txfm_size, txfm_size, -shift[2]);
}
}
const int stride, int tx_type,
const int bd) {
int32_t txfm_buf[4 * 4];
- const TXFM_2D_CFG* cfg = vp10_get_txfm_4x4_cfg(tx_type);
+ TXFM_2D_FLIP_CFG cfg = vp10_get_fwd_txfm_cfg(tx_type, TX_4X4);
(void)bd;
- fwd_txfm2d_c(input, output, stride, cfg, txfm_buf);
+ fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf);
}
void vp10_fwd_txfm2d_8x8_c(const int16_t *input, int32_t *output,
const int stride, int tx_type,
const int bd) {
int32_t txfm_buf[8 * 8];
- const TXFM_2D_CFG* cfg = vp10_get_txfm_8x8_cfg(tx_type);
+ TXFM_2D_FLIP_CFG cfg = vp10_get_fwd_txfm_cfg(tx_type, TX_8X8);
(void)bd;
- fwd_txfm2d_c(input, output, stride, cfg, txfm_buf);
+ fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf);
}
void vp10_fwd_txfm2d_16x16_c(const int16_t *input, int32_t *output,
const int stride, int tx_type,
const int bd) {
int32_t txfm_buf[16 * 16];
- const TXFM_2D_CFG* cfg = vp10_get_txfm_16x16_cfg(tx_type);
+ TXFM_2D_FLIP_CFG cfg = vp10_get_fwd_txfm_cfg(tx_type, TX_16X16);
(void)bd;
- fwd_txfm2d_c(input, output, stride, cfg, txfm_buf);
+ fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf);
}
void vp10_fwd_txfm2d_32x32_c(const int16_t *input, int32_t *output,
const int stride, int tx_type,
const int bd) {
int32_t txfm_buf[32 * 32];
- const TXFM_2D_CFG* cfg = vp10_get_txfm_32x32_cfg(tx_type);
+ TXFM_2D_FLIP_CFG cfg = vp10_get_fwd_txfm_cfg(tx_type, TX_32X32);
(void)bd;
- fwd_txfm2d_c(input, output, stride, cfg, txfm_buf);
+ fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf);
}
void vp10_fwd_txfm2d_64x64_c(const int16_t *input, int32_t *output,
const int stride, int tx_type,
const int bd) {
int32_t txfm_buf[64 * 64];
- const TXFM_2D_CFG* cfg = vp10_get_txfm_64x64_cfg(tx_type);
+ TXFM_2D_FLIP_CFG cfg = vp10_get_fwd_txfm_64x64_cfg(tx_type);
(void)bd;
- fwd_txfm2d_c(input, output, stride, cfg, txfm_buf);
-}
-
-const TXFM_2D_CFG* vp10_get_txfm_4x4_cfg(int tx_type) {
- const TXFM_2D_CFG* cfg = NULL;
- switch (tx_type) {
- case DCT_DCT:
- cfg = &fwd_txfm_2d_cfg_dct_dct_4;
- break;
- case ADST_DCT:
- cfg = &fwd_txfm_2d_cfg_adst_dct_4;
- break;
- case DCT_ADST:
- cfg = &fwd_txfm_2d_cfg_dct_adst_4;
- break;
- case ADST_ADST:
- cfg = &fwd_txfm_2d_cfg_adst_adst_4;
- break;
- default:
- assert(0);
- }
- return cfg;
+ fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf);
}
-const TXFM_2D_CFG* vp10_get_txfm_8x8_cfg(int tx_type) {
- const TXFM_2D_CFG* cfg = NULL;
+static const TXFM_2D_CFG* fwd_txfm_cfg_ls[4][TX_SIZES] = {
+ {&fwd_txfm_2d_cfg_dct_dct_4 , &fwd_txfm_2d_cfg_dct_dct_8,
+ &fwd_txfm_2d_cfg_dct_dct_16 , &fwd_txfm_2d_cfg_dct_dct_32},
+ {&fwd_txfm_2d_cfg_adst_dct_4 , &fwd_txfm_2d_cfg_adst_dct_8,
+ &fwd_txfm_2d_cfg_adst_dct_16 , &fwd_txfm_2d_cfg_adst_dct_32},
+ {&fwd_txfm_2d_cfg_dct_adst_4 , &fwd_txfm_2d_cfg_dct_adst_8,
+ &fwd_txfm_2d_cfg_dct_adst_16 , &fwd_txfm_2d_cfg_dct_adst_32},
+ {&fwd_txfm_2d_cfg_adst_adst_4, &fwd_txfm_2d_cfg_adst_adst_8,
+ &fwd_txfm_2d_cfg_adst_adst_16, &fwd_txfm_2d_cfg_adst_adst_32},
+};
+
+void set_flip_cfg(int tx_type, TXFM_2D_FLIP_CFG* cfg) {
switch (tx_type) {
case DCT_DCT:
- cfg = &fwd_txfm_2d_cfg_dct_dct_8;
- break;
case ADST_DCT:
- cfg = &fwd_txfm_2d_cfg_adst_dct_8;
- break;
case DCT_ADST:
- cfg = &fwd_txfm_2d_cfg_dct_adst_8;
- break;
case ADST_ADST:
- cfg = &fwd_txfm_2d_cfg_adst_adst_8;
+ cfg->ud_flip = 0;
+ cfg->lr_flip = 0;
break;
default:
assert(0);
}
- return cfg;
}
-const TXFM_2D_CFG* vp10_get_txfm_16x16_cfg(int tx_type) {
- const TXFM_2D_CFG* cfg = NULL;
- switch (tx_type) {
- case DCT_DCT:
- cfg = &fwd_txfm_2d_cfg_dct_dct_16;
- break;
- case ADST_DCT:
- cfg = &fwd_txfm_2d_cfg_adst_dct_16;
- break;
- case DCT_ADST:
- cfg = &fwd_txfm_2d_cfg_dct_adst_16;
- break;
- case ADST_ADST:
- cfg = &fwd_txfm_2d_cfg_adst_adst_16;
- break;
- default:
- assert(0);
- }
- return cfg;
-}
-
-const TXFM_2D_CFG* vp10_get_txfm_32x32_cfg(int tx_type) {
- const TXFM_2D_CFG* cfg = NULL;
- switch (tx_type) {
- case DCT_DCT:
- cfg = &fwd_txfm_2d_cfg_dct_dct_32;
- break;
- case ADST_DCT:
- cfg = &fwd_txfm_2d_cfg_adst_dct_32;
- break;
- case DCT_ADST:
- cfg = &fwd_txfm_2d_cfg_dct_adst_32;
- break;
- case ADST_ADST:
- cfg = &fwd_txfm_2d_cfg_adst_adst_32;
- break;
- default:
- assert(0);
- }
+TXFM_2D_FLIP_CFG vp10_get_fwd_txfm_cfg(int tx_type, int tx_size) {
+ TXFM_2D_FLIP_CFG cfg;
+ set_flip_cfg(tx_type, &cfg);
+ cfg.cfg = fwd_txfm_cfg_ls[tx_type][tx_size];
return cfg;
}
-const TXFM_2D_CFG* vp10_get_txfm_64x64_cfg(int tx_type) {
- const TXFM_2D_CFG* cfg = NULL;
+TXFM_2D_FLIP_CFG vp10_get_fwd_txfm_64x64_cfg(int tx_type) {
+ TXFM_2D_FLIP_CFG cfg;
switch (tx_type) {
case DCT_DCT:
- cfg = &fwd_txfm_2d_cfg_dct_dct_64;
+ cfg.cfg = &fwd_txfm_2d_cfg_dct_dct_64;
+ cfg.ud_flip = 0;
+ cfg.lr_flip = 0;
break;
case ADST_DCT:
case DCT_ADST: