From: Angie Chiang Date: Wed, 28 Oct 2015 21:01:38 +0000 (-0700) Subject: Add vp10_fwd_txfm2d_test X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=af38f6fca4aaaa0a620228b3e1d34d6db8c96d07;p=libvpx Add vp10_fwd_txfm2d_test Change-Id: Icbc17403430751d3a841f822a190f0c30450d603 --- diff --git a/test/test.mk b/test/test.mk index 0ac9a8a5a..face2ad67 100644 --- a/test/test.mk +++ b/test/test.mk @@ -173,6 +173,7 @@ LIBVPX_TEST_SRCS-$(CONFIG_VP10) += vp10_inv_txfm_test.cc 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_inv_txfm1d_test.cc +LIBVPX_TEST_SRCS-$(CONFIG_VP10) += vp10_fwd_txfm2d_test.cc endif # CONFIG_SHARED diff --git a/test/vp10_fwd_txfm2d_test.cc b/test/vp10_fwd_txfm2d_test.cc new file mode 100644 index 000000000..e6416ccf4 --- /dev/null +++ b/test/vp10_fwd_txfm2d_test.cc @@ -0,0 +1,104 @@ +/* + * 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 +#include +#include + +#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" + +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 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 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}; + +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]; + 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) { + TXFM_2D_CFG fwd_txfm_cfg = fwd_txfm_cfg_ls[txfm_size_idx][txfm_type_idx]; + 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]; + 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)); + + ACMRandom rnd(ACMRandom::DeterministicSeed()); + int count = 5000; + double avg_abs_error = 0; + for (int ci = 0; ci < count; ci++) { + for (int ni = 0; ni < sqr_txfm_size; ++ni) { + input[ni] = rnd.Rand16() % base; + ref_input[ni] = static_cast(input[ni]); + output[ni] = 0; + ref_output[ni] = 0; + } + + fwd_txfm_func(input, output, txfm_size, &fwd_txfm_cfg, bd); + reference_hybrid_2d(ref_input, ref_output, txfm_size, type0, type1); + + for (int ni = 0; ni < sqr_txfm_size; ++ni) { + ref_output[ni] = round(ref_output[ni] * amplify_factor); + EXPECT_LE(fabs(output[ni] - ref_output[ni]) / amplify_factor, 30); + } + avg_abs_error += compute_avg_abs_error( + output, ref_output, sqr_txfm_size); + } + + avg_abs_error /= amplify_factor; + avg_abs_error /= count; + // max_abs_avg_error comes from upper bound of avg_abs_error + // printf("type0: %d type1: %d txfm_size: %d accuracy_avg_abs_error: + // %f\n", type0, type1, txfm_size, avg_abs_error); + double max_abs_avg_error = 1.5; + EXPECT_LE(avg_abs_error, max_abs_avg_error); + } + + delete[] input; + delete[] output; + delete[] ref_input; + delete[] ref_output; + } +} + +} // anonymous namespace