Commit 1954fa39 authored by Angie Chiang's avatar Angie Chiang

Add flip option for vp10_fwd_txfm2d_#x#_c

Will add unit test to test/vp10_fwd_txfm2d_test.cc later

Change-Id: I626900c67fca4eee2ad0ae1828188527a04a5362
parent b5331459
......@@ -14,7 +14,7 @@
#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;
......@@ -29,49 +29,34 @@ using libvpx_test::TYPE_ADST;
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;
......
......@@ -15,7 +15,6 @@
#include "./vp10_rtcd.h"
#include "test/acm_random.h"
#include "test/vp10_txfm_test.h"
#include "vp10/common/vp10_fwd_txfm2d_cfg.h"
#include "vp10/common/vp10_inv_txfm2d_cfg.h"
using libvpx_test::ACMRandom;
......
......@@ -109,23 +109,5 @@ typedef void (*Inv_Txfm2d_Func)(const int32_t*, uint16_t*, int, int, int);
static const int bd = 10;
static const int input_base = (1 << bd);
static INLINE int get_tx_type(const TXFM_2D_CFG *cfg) {
int tx_type;
if (cfg->txfm_type_col <= TXFM_TYPE_DCT64) {
if (cfg->txfm_type_row <= TXFM_TYPE_DCT64) {
tx_type = DCT_DCT;
} else {
tx_type = DCT_ADST;
}
} else {
if (cfg->txfm_type_row <= TXFM_TYPE_DCT64) {
tx_type = ADST_DCT;
} else {
tx_type = ADST_ADST;
}
}
return tx_type;
}
} // namespace libvpx_test
#endif // VP10_TXFM_TEST_H_
......@@ -19,31 +19,22 @@ static INLINE TxfmFunc fwd_txfm_type_to_func(TXFM_TYPE txfm_type) {
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;
......@@ -51,38 +42,50 @@ static INLINE TxfmFunc fwd_txfm_type_to_func(TXFM_TYPE txfm_type) {
}
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]);
}
}
......@@ -90,136 +93,86 @@ void vp10_fwd_txfm2d_4x4_c(const int16_t *input, int32_t *output,
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:
......
......@@ -399,11 +399,4 @@ static const TXFM_2D_CFG fwd_txfm_2d_cfg_adst_dct_32 = {
fwd_cos_bit_row_adst_dct_32, // .cos_bit_row
TXFM_TYPE_ADST32, // .txfm_type_col
TXFM_TYPE_DCT32}; // .txfm_type_row
const TXFM_2D_CFG* vp10_get_txfm_4x4_cfg(int tx_type);
const TXFM_2D_CFG* vp10_get_txfm_8x8_cfg(int tx_type);
const TXFM_2D_CFG* vp10_get_txfm_16x16_cfg(int tx_type);
const TXFM_2D_CFG* vp10_get_txfm_32x32_cfg(int tx_type);
const TXFM_2D_CFG* vp10_get_txfm_64x64_cfg(int tx_type);
#endif // VP10_FWD_TXFM2D_CFG_H_
......@@ -7,7 +7,6 @@
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef VP10_TXFM_H_
#define VP10_TXFM_H_
......@@ -166,4 +165,19 @@ typedef struct TXFM_2D_CFG {
const TXFM_TYPE txfm_type_row;
} TXFM_2D_CFG;
typedef struct TXFM_2D_FLIP_CFG {
int ud_flip; // flip upside down
int lr_flip; // flip left to right
const TXFM_2D_CFG* cfg;
} TXFM_2D_FLIP_CFG;
#ifdef __cplusplus
extern "C" {
#endif
TXFM_2D_FLIP_CFG vp10_get_fwd_txfm_cfg(int tx_type, int tx_size);
TXFM_2D_FLIP_CFG vp10_get_fwd_txfm_64x64_cfg(int tx_type);
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // VP10_TXFM_H_
......@@ -8,7 +8,8 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#include "vp10/common/vp10_fwd_txfm2d_cfg.h"
#include "vp10/common/enums.h"
#include "vp10/common/vp10_txfm.h"
#include "vp10/common/x86/vp10_txfm1d_sse4.h"
static INLINE void int16_array_with_stride_to_int32_array_without_stride(
......@@ -91,16 +92,16 @@ void vp10_fwd_txfm2d_32x32_sse4_1(const int16_t *input, int32_t *output,
const int stride, int tx_type,
const int bd) {
int32_t txfm_buf[1024];
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_sse4_1(input, output, stride, cfg, txfm_buf);
fwd_txfm2d_sse4_1(input, output, stride, cfg.cfg, txfm_buf);
}
void vp10_fwd_txfm2d_64x64_sse4_1(const int16_t *input, int32_t *output,
const int stride, int tx_type,
const int bd) {
int32_t txfm_buf[4096];
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_sse4_1(input, output, stride, cfg, txfm_buf);
fwd_txfm2d_sse4_1(input, output, stride, cfg.cfg, txfm_buf);
}
......@@ -13,7 +13,6 @@
#include "./vpx_dsp_rtcd.h"
#include "vp10/common/idct.h"
#include "vp10/common/vp10_fwd_txfm2d_cfg.h"
#include "vp10/encoder/hybrid_fwd_txfm.h"
static INLINE void fdct32x32(int rd_transform, const int16_t *src,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment