Commit 4fd0ba8f authored by Angie Chiang's avatar Angie Chiang
Browse files

Add vp10_inv_txfm2d

Change-Id: Ib63062a52c688e65bae5eb0052ce69d73d96c9c5
parent 4d3cf459
...@@ -174,6 +174,7 @@ LIBVPX_TEST_SRCS-$(CONFIG_VP10) += vp10_txfm_test.h ...@@ -174,6 +174,7 @@ LIBVPX_TEST_SRCS-$(CONFIG_VP10) += vp10_txfm_test.h
LIBVPX_TEST_SRCS-$(CONFIG_VP10) += vp10_fwd_txfm1d_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP10) += vp10_fwd_txfm1d_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP10) += vp10_inv_txfm1d_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP10) += vp10_inv_txfm1d_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP10) += vp10_fwd_txfm2d_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP10) += vp10_fwd_txfm2d_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP10) += vp10_inv_txfm2d_test.cc
endif # CONFIG_SHARED endif # CONFIG_SHARED
......
/*
* Copyright (c) 2015 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "test/acm_random.h"
#include "test/vp10_txfm_test.h"
#include "vp10/common/vp10_fwd_txfm2d.h"
#include "vp10/common/vp10_fwd_txfm2d_cfg.h"
#include "vp10/common/vp10_inv_txfm2d.h"
#include "vp10/common/vp10_inv_txfm2d_cfg.h"
using libvpx_test::ACMRandom;
namespace {
const int txfm_size_num = 4;
const int txfm_size_ls[4] = {4, 8, 16, 32};
const TXFM_2D_CFG fwd_txfm_cfg_ls[4][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}};
const TXFM_2D_CFG inv_txfm_cfg_ls[4][4] = {
{inv_txfm_2d_cfg_dct_dct_4, inv_txfm_2d_cfg_dct_adst_4,
inv_txfm_2d_cfg_adst_adst_4, inv_txfm_2d_cfg_adst_dct_4},
{inv_txfm_2d_cfg_dct_dct_8, inv_txfm_2d_cfg_dct_adst_8,
inv_txfm_2d_cfg_adst_adst_8, inv_txfm_2d_cfg_adst_dct_8},
{inv_txfm_2d_cfg_dct_dct_16, inv_txfm_2d_cfg_dct_adst_16,
inv_txfm_2d_cfg_adst_adst_16, inv_txfm_2d_cfg_adst_dct_16},
{inv_txfm_2d_cfg_dct_dct_32, inv_txfm_2d_cfg_dct_adst_32,
inv_txfm_2d_cfg_adst_adst_32, inv_txfm_2d_cfg_adst_dct_32}};
const Fwd_Txfm2d_Func fwd_txfm_func_ls[4] = {
vp10_fwd_txfm2d_4x4, vp10_fwd_txfm2d_8x8, vp10_fwd_txfm2d_16x16,
vp10_fwd_txfm2d_32x32};
const Inv_Txfm2d_Func inv_txfm_func_ls[4] = {
vp10_inv_txfm2d_add_4x4, vp10_inv_txfm2d_add_8x8, vp10_inv_txfm2d_add_16x16,
vp10_inv_txfm2d_add_32x32};
const int txfm_type_num = 4;
TEST(vp10_inv_txfm2d, round_trip) {
for (int txfm_size_idx = 0; txfm_size_idx < txfm_size_num; ++txfm_size_idx) {
const int txfm_size = txfm_size_ls[txfm_size_idx];
const int sqr_txfm_size = txfm_size * txfm_size;
int16_t* input = new int16_t[sqr_txfm_size];
uint16_t* ref_input = new uint16_t[sqr_txfm_size];
int32_t* output = new int32_t[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];
const TXFM_2D_CFG inv_txfm_cfg =
inv_txfm_cfg_ls[txfm_size_idx][txfm_type_idx];
const Fwd_Txfm2d_Func fwd_txfm_func = fwd_txfm_func_ls[txfm_size_idx];
const Inv_Txfm2d_Func inv_txfm_func = inv_txfm_func_ls[txfm_size_idx];
const int count = 5000;
double avg_abs_error = 0;
ACMRandom rnd(ACMRandom::DeterministicSeed());
for (int ci = 0; ci < count; ci++) {
for (int ni = 0; ni < sqr_txfm_size; ++ni) {
if (ci == 0) {
int extreme_input = base - 1;
input[ni] = extreme_input; // extreme case
ref_input[ni] = 0;
} else {
input[ni] = rnd.Rand16() % base;
ref_input[ni] = 0;
}
}
fwd_txfm_func(input, output, txfm_size, &fwd_txfm_cfg, bd);
inv_txfm_func(output, ref_input, txfm_size, &inv_txfm_cfg, bd);
for (int ni = 0; ni < sqr_txfm_size; ++ni) {
EXPECT_LE(abs(input[ni] - ref_input[ni]), 2);
}
avg_abs_error += compute_avg_abs_error<int16_t, uint16_t>(
input, ref_input, sqr_txfm_size);
}
avg_abs_error /= count;
// max_abs_avg_error comes from upper bound of
// printf("txfm_size: %d accuracy_avg_abs_error: %f\n", txfm_size,
// avg_abs_error);
// TODO(angiebird): this upper bound is from adst_adst_8
const double max_abs_avg_error = 0.024;
EXPECT_LE(avg_abs_error, max_abs_avg_error);
}
delete[] input;
delete[] ref_input;
delete[] output;
}
}
} // anonymous namespace
/*
* Copyright (c) 2015 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "vp10/common/vp10_txfm.h"
static INLINE void inv_txfm2d_add_c(const int32_t *input, int16_t *output,
int stride, const TXFM_2D_CFG *cfg,
int32_t *txfm_buf) {
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 = cfg->txfm_func_col;
const TxfmFunc txfm_func_row = cfg->txfm_func_row;
// txfm_buf's length is txfm_size * txfm_size + 2 * txfm_size
// it is used for intermediate data buffering
int32_t *temp_in = txfm_buf;
int32_t *temp_out = temp_in + txfm_size;
int32_t *buf = temp_out + txfm_size;
int32_t *buf_ptr = buf;
int i, j;
// Rows
for (i = 0; i < txfm_size; ++i) {
txfm_func_row(input, buf_ptr, cos_bit_row, stage_range_row);
round_shift_array(buf_ptr, txfm_size, -shift[0]);
input += txfm_size;
buf_ptr += txfm_size;
}
// Columns
for (i = 0; i < txfm_size; ++i) {
for (j = 0; j < txfm_size; ++j)
temp_in[j] = buf[j * txfm_size + i];
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)
output[j * stride + i] += temp_out[j];
}
}
void vp10_inv_txfm2d_add_4x4(const int32_t *input, uint16_t *output,
const int stride, const TXFM_2D_CFG *cfg,
const int bd) {
int txfm_buf[4 * 4 + 4 + 4];
// output contains the prediction signal which is always positive and smaller
// than (1 << bd) - 1
// since bd < 16-1, therefore we can treat the uint16_t* output buffer as an
// int16_t*
inv_txfm2d_add_c(input, (int16_t *)output, stride, cfg, txfm_buf);
clamp_block((int16_t *)output, 4, stride, 0, (1 << bd) - 1);
}
void vp10_inv_txfm2d_add_8x8(const int32_t *input, uint16_t *output,
const int stride, const TXFM_2D_CFG *cfg,
const int bd) {
int txfm_buf[8 * 8 + 8 + 8];
// output contains the prediction signal which is always positive and smaller
// than (1 << bd) - 1
// since bd < 16-1, therefore we can treat the uint16_t* output buffer as an
// int16_t*
inv_txfm2d_add_c(input, (int16_t *)output, stride, cfg, txfm_buf);
clamp_block((int16_t *)output, 8, stride, 0, (1 << bd) - 1);
}
void vp10_inv_txfm2d_add_16x16(const int32_t *input, uint16_t *output,
const int stride, const TXFM_2D_CFG *cfg,
const int bd) {
int txfm_buf[16 * 16 + 16 + 16];
// output contains the prediction signal which is always positive and smaller
// than (1 << bd) - 1
// since bd < 16-1, therefore we can treat the uint16_t* output buffer as an
// int16_t*
inv_txfm2d_add_c(input, (int16_t *)output, stride, cfg, txfm_buf);
clamp_block((int16_t *)output, 16, stride, 0, (1 << bd) - 1);
}
void vp10_inv_txfm2d_add_32x32(const int32_t *input, uint16_t *output,
const int stride, const TXFM_2D_CFG *cfg,
const int bd) {
int txfm_buf[32 * 32 + 32 + 32];
// output contains the prediction signal which is always positive and smaller
// than (1 << bd) - 1
// since bd < 16-1, therefore we can treat the uint16_t* output buffer as an
// int16_t*
inv_txfm2d_add_c(input, (int16_t *)output, stride, cfg, txfm_buf);
clamp_block((int16_t *)output, 32, stride, 0, (1 << bd) - 1);
}
/*
* Copyright (c) 2015 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef VP10_INV_TXFM2D_C_H_
#define VP10_INV_TXFM2D_C_H_
#include "vp10/common/vp10_inv_txfm2d_cfg.h"
#ifdef __cplusplus
extern "C" {
#endif
void vp10_inv_txfm2d_add_4x4(const int32_t *input, uint16_t *output,
const int stride, const TXFM_2D_CFG *cfg,
const int bd);
void vp10_inv_txfm2d_add_8x8(const int32_t *input, uint16_t *output,
const int stride, const TXFM_2D_CFG *cfg,
const int bd);
void vp10_inv_txfm2d_add_16x16(const int32_t *input, uint16_t *output,
const int stride, const TXFM_2D_CFG *cfg,
const int bd);
void vp10_inv_txfm2d_add_32x32(const int32_t *input, uint16_t *output,
const int stride, const TXFM_2D_CFG *cfg,
const int bd);
#ifdef __cplusplus
}
#endif
#endif // VP10_INV_TXFM2D_C_H_
...@@ -151,17 +151,17 @@ typedef void (*TxfmFunc)(const int32_t *input, int32_t *output, ...@@ -151,17 +151,17 @@ typedef void (*TxfmFunc)(const int32_t *input, int32_t *output,
const int8_t *cos_bit, const int8_t *stage_range); const int8_t *cos_bit, const int8_t *stage_range);
typedef struct TXFM_2D_CFG { typedef struct TXFM_2D_CFG {
int txfm_size; const int txfm_size;
int stage_num_col; const int stage_num_col;
int stage_num_row; const int stage_num_row;
int8_t *shift; const int8_t *shift;
int8_t *stage_range_col; const int8_t *stage_range_col;
int8_t *stage_range_row; const int8_t *stage_range_row;
int8_t *cos_bit_col; const int8_t *cos_bit_col;
int8_t *cos_bit_row; const int8_t *cos_bit_row;
TxfmFunc txfm_func_col; const TxfmFunc txfm_func_col;
TxfmFunc txfm_func_row; const TxfmFunc txfm_func_row;
} TXFM_2D_CFG; } TXFM_2D_CFG;
#endif // VP10_TXFM_H_ #endif // VP10_TXFM_H_
...@@ -71,6 +71,8 @@ VP10_COMMON_SRCS-yes += common/vp10_inv_txfm1d.c ...@@ -71,6 +71,8 @@ VP10_COMMON_SRCS-yes += common/vp10_inv_txfm1d.c
VP10_COMMON_SRCS-yes += common/vp10_fwd_txfm2d.h VP10_COMMON_SRCS-yes += common/vp10_fwd_txfm2d.h
VP10_COMMON_SRCS-yes += common/vp10_fwd_txfm2d.c VP10_COMMON_SRCS-yes += common/vp10_fwd_txfm2d.c
VP10_COMMON_SRCS-yes += common/vp10_fwd_txfm2d_cfg.h VP10_COMMON_SRCS-yes += common/vp10_fwd_txfm2d_cfg.h
VP10_COMMON_SRCS-yes += common/vp10_inv_txfm2d.h
VP10_COMMON_SRCS-yes += common/vp10_inv_txfm2d.c
VP10_COMMON_SRCS-yes += common/vp10_inv_txfm2d_cfg.h VP10_COMMON_SRCS-yes += common/vp10_inv_txfm2d_cfg.h
VP10_COMMON_SRCS-$(CONFIG_VP9_POSTPROC) += common/postproc.h VP10_COMMON_SRCS-$(CONFIG_VP9_POSTPROC) += common/postproc.h
......
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