From: Angie Chiang Date: Wed, 11 May 2016 00:53:06 +0000 (-0700) Subject: Add flip option for vp10_fwd_txfm2d_#x#_c X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1954fa390f6f322c6e490aa6b908a53f994db23b;p=libvpx Add flip option for vp10_fwd_txfm2d_#x#_c Will add unit test to test/vp10_fwd_txfm2d_test.cc later Change-Id: I626900c67fca4eee2ad0ae1828188527a04a5362 --- diff --git a/test/vp10_fwd_txfm2d_test.cc b/test/vp10_fwd_txfm2d_test.cc index 8e90dc2ca..da8560fe8 100644 --- a/test/vp10_fwd_txfm2d_test.cc +++ b/test/vp10_fwd_txfm2d_test.cc @@ -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; diff --git a/test/vp10_inv_txfm2d_test.cc b/test/vp10_inv_txfm2d_test.cc index 80ac78b80..1f6e2a6df 100644 --- a/test/vp10_inv_txfm2d_test.cc +++ b/test/vp10_inv_txfm2d_test.cc @@ -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; diff --git a/test/vp10_txfm_test.h b/test/vp10_txfm_test.h index c4d03cea6..4d417adea 100644 --- a/test/vp10_txfm_test.h +++ b/test/vp10_txfm_test.h @@ -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_ diff --git a/vp10/common/vp10_fwd_txfm2d.c b/vp10/common/vp10_fwd_txfm2d.c index cd5ce71c1..371b4dfd6 100644 --- a/vp10/common/vp10_fwd_txfm2d.c +++ b/vp10/common/vp10_fwd_txfm2d.c @@ -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: diff --git a/vp10/common/vp10_fwd_txfm2d_cfg.h b/vp10/common/vp10_fwd_txfm2d_cfg.h index ed976df5a..e15e4baf9 100644 --- a/vp10/common/vp10_fwd_txfm2d_cfg.h +++ b/vp10/common/vp10_fwd_txfm2d_cfg.h @@ -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_ diff --git a/vp10/common/vp10_txfm.h b/vp10/common/vp10_txfm.h index 9944bdda4..1538df3d1 100644 --- a/vp10/common/vp10_txfm.h +++ b/vp10/common/vp10_txfm.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_ diff --git a/vp10/common/x86/vp10_fwd_txfm2d_sse4.c b/vp10/common/x86/vp10_fwd_txfm2d_sse4.c index 499e58d94..1d70f1447 100644 --- a/vp10/common/x86/vp10_fwd_txfm2d_sse4.c +++ b/vp10/common/x86/vp10_fwd_txfm2d_sse4.c @@ -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); } diff --git a/vp10/encoder/hybrid_fwd_txfm.c b/vp10/encoder/hybrid_fwd_txfm.c index 491f2ac48..a20eb14f9 100644 --- a/vp10/encoder/hybrid_fwd_txfm.c +++ b/vp10/encoder/hybrid_fwd_txfm.c @@ -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,