blob: f6c83003a602625ee5276f03dd4d57848cd91eb8 [file] [log] [blame]
Yaowu Xued7e3d22013-12-13 10:05:40 -08001/*
2 * Copyright (c) 2013 The WebM project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include <math.h>
12#include <stdlib.h>
13#include <string.h>
14
15#include "third_party/googletest/src/include/gtest/gtest.h"
Jingning Han097d59c2015-07-29 14:51:36 -070016
Yaowu Xuf883b422016-08-30 14:01:10 -070017#include "./av1_rtcd.h"
18#include "./aom_dsp_rtcd.h"
Yaowu Xued7e3d22013-12-13 10:05:40 -080019#include "test/acm_random.h"
20#include "test/clear_system_state.h"
21#include "test/register_state_check.h"
22#include "test/util.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070023#include "av1/common/blockd.h"
24#include "av1/common/scan.h"
Yaowu Xuf883b422016-08-30 14:01:10 -070025#include "aom/aom_integer.h"
Yaowu Xued7e3d22013-12-13 10:05:40 -080026
Yaowu Xuc27fc142016-08-22 16:08:15 -070027using libaom_test::ACMRandom;
Yaowu Xued7e3d22013-12-13 10:05:40 -080028
29namespace {
Deb Mukherjee10783d42014-09-02 16:34:09 -070030typedef void (*FwdTxfmFunc)(const int16_t *in, tran_low_t *out, int stride);
31typedef void (*InvTxfmFunc)(const tran_low_t *in, uint8_t *out, int stride);
clang-format3a826f12016-08-11 17:46:05 -070032typedef std::tr1::tuple<FwdTxfmFunc, InvTxfmFunc, InvTxfmFunc, TX_SIZE, int>
33 PartialInvTxfmParam;
Yaowu Xued7e3d22013-12-13 10:05:40 -080034const int kMaxNumCoeffs = 1024;
James Zern49135d32014-07-16 18:58:16 -070035class PartialIDctTest : public ::testing::TestWithParam<PartialInvTxfmParam> {
Yaowu Xued7e3d22013-12-13 10:05:40 -080036 public:
37 virtual ~PartialIDctTest() {}
38 virtual void SetUp() {
Jingning Han7eaad702014-05-28 11:18:33 -070039 ftxfm_ = GET_PARAM(0);
40 full_itxfm_ = GET_PARAM(1);
41 partial_itxfm_ = GET_PARAM(2);
clang-format3a826f12016-08-11 17:46:05 -070042 tx_size_ = GET_PARAM(3);
Jingning Han7eaad702014-05-28 11:18:33 -070043 last_nonzero_ = GET_PARAM(4);
Yaowu Xued7e3d22013-12-13 10:05:40 -080044 }
45
Yaowu Xuc27fc142016-08-22 16:08:15 -070046 virtual void TearDown() { libaom_test::ClearSystemState(); }
Yaowu Xued7e3d22013-12-13 10:05:40 -080047
48 protected:
49 int last_nonzero_;
50 TX_SIZE tx_size_;
James Zern49135d32014-07-16 18:58:16 -070051 FwdTxfmFunc ftxfm_;
52 InvTxfmFunc full_itxfm_;
53 InvTxfmFunc partial_itxfm_;
Yaowu Xued7e3d22013-12-13 10:05:40 -080054};
55
Jingning Han7eaad702014-05-28 11:18:33 -070056TEST_P(PartialIDctTest, RunQuantCheck) {
57 ACMRandom rnd(ACMRandom::DeterministicSeed());
58 int size;
59 switch (tx_size_) {
clang-format3a826f12016-08-11 17:46:05 -070060 case TX_4X4: size = 4; break;
61 case TX_8X8: size = 8; break;
62 case TX_16X16: size = 16; break;
63 case TX_32X32: size = 32; break;
64 default: FAIL() << "Wrong Size!"; break;
Jingning Han7eaad702014-05-28 11:18:33 -070065 }
James Zernfd3658b2015-05-02 13:24:16 -070066 DECLARE_ALIGNED(16, tran_low_t, test_coef_block1[kMaxNumCoeffs]);
67 DECLARE_ALIGNED(16, tran_low_t, test_coef_block2[kMaxNumCoeffs]);
68 DECLARE_ALIGNED(16, uint8_t, dst1[kMaxNumCoeffs]);
69 DECLARE_ALIGNED(16, uint8_t, dst2[kMaxNumCoeffs]);
Jingning Han7eaad702014-05-28 11:18:33 -070070
71 const int count_test_block = 1000;
72 const int block_size = size * size;
73
James Zernfd3658b2015-05-02 13:24:16 -070074 DECLARE_ALIGNED(16, int16_t, input_extreme_block[kMaxNumCoeffs]);
75 DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kMaxNumCoeffs]);
Jingning Han7eaad702014-05-28 11:18:33 -070076
77 int max_error = 0;
78 for (int i = 0; i < count_test_block; ++i) {
79 // clear out destination buffer
80 memset(dst1, 0, sizeof(*dst1) * block_size);
81 memset(dst2, 0, sizeof(*dst2) * block_size);
82 memset(test_coef_block1, 0, sizeof(*test_coef_block1) * block_size);
83 memset(test_coef_block2, 0, sizeof(*test_coef_block2) * block_size);
84
85 ACMRandom rnd(ACMRandom::DeterministicSeed());
86
87 for (int i = 0; i < count_test_block; ++i) {
88 // Initialize a test block with input range [-255, 255].
89 if (i == 0) {
clang-format3a826f12016-08-11 17:46:05 -070090 for (int j = 0; j < block_size; ++j) input_extreme_block[j] = 255;
Jingning Han7eaad702014-05-28 11:18:33 -070091 } else if (i == 1) {
clang-format3a826f12016-08-11 17:46:05 -070092 for (int j = 0; j < block_size; ++j) input_extreme_block[j] = -255;
Jingning Han7eaad702014-05-28 11:18:33 -070093 } else {
94 for (int j = 0; j < block_size; ++j) {
95 input_extreme_block[j] = rnd.Rand8() % 2 ? 255 : -255;
96 }
97 }
98
99 ftxfm_(input_extreme_block, output_ref_block, size);
100
101 // quantization with maximum allowed step sizes
102 test_coef_block1[0] = (output_ref_block[0] / 1336) * 1336;
103 for (int j = 1; j < last_nonzero_; ++j)
Yaowu Xuf883b422016-08-30 14:01:10 -0700104 test_coef_block1[av1_default_scan_orders[tx_size_].scan[j]] =
clang-format3a826f12016-08-11 17:46:05 -0700105 (output_ref_block[j] / 1828) * 1828;
Jingning Han7eaad702014-05-28 11:18:33 -0700106 }
107
James Zern29e1b1a2014-07-09 21:02:02 -0700108 ASM_REGISTER_STATE_CHECK(full_itxfm_(test_coef_block1, dst1, size));
109 ASM_REGISTER_STATE_CHECK(partial_itxfm_(test_coef_block1, dst2, size));
Jingning Han7eaad702014-05-28 11:18:33 -0700110
111 for (int j = 0; j < block_size; ++j) {
112 const int diff = dst1[j] - dst2[j];
113 const int error = diff * diff;
clang-format3a826f12016-08-11 17:46:05 -0700114 if (max_error < error) max_error = error;
Jingning Han7eaad702014-05-28 11:18:33 -0700115 }
116 }
117
118 EXPECT_EQ(0, max_error)
119 << "Error: partial inverse transform produces different results";
120}
121
Yaowu Xued7e3d22013-12-13 10:05:40 -0800122TEST_P(PartialIDctTest, ResultsMatch) {
123 ACMRandom rnd(ACMRandom::DeterministicSeed());
124 int size;
125 switch (tx_size_) {
clang-format3a826f12016-08-11 17:46:05 -0700126 case TX_4X4: size = 4; break;
127 case TX_8X8: size = 8; break;
128 case TX_16X16: size = 16; break;
129 case TX_32X32: size = 32; break;
130 default: FAIL() << "Wrong Size!"; break;
Yaowu Xued7e3d22013-12-13 10:05:40 -0800131 }
James Zernfd3658b2015-05-02 13:24:16 -0700132 DECLARE_ALIGNED(16, tran_low_t, test_coef_block1[kMaxNumCoeffs]);
133 DECLARE_ALIGNED(16, tran_low_t, test_coef_block2[kMaxNumCoeffs]);
134 DECLARE_ALIGNED(16, uint8_t, dst1[kMaxNumCoeffs]);
135 DECLARE_ALIGNED(16, uint8_t, dst2[kMaxNumCoeffs]);
Yaowu Xued7e3d22013-12-13 10:05:40 -0800136 const int count_test_block = 1000;
137 const int max_coeff = 32766 / 4;
138 const int block_size = size * size;
139 int max_error = 0;
140 for (int i = 0; i < count_test_block; ++i) {
141 // clear out destination buffer
142 memset(dst1, 0, sizeof(*dst1) * block_size);
143 memset(dst2, 0, sizeof(*dst2) * block_size);
144 memset(test_coef_block1, 0, sizeof(*test_coef_block1) * block_size);
145 memset(test_coef_block2, 0, sizeof(*test_coef_block2) * block_size);
146 int max_energy_leftover = max_coeff * max_coeff;
147 for (int j = 0; j < last_nonzero_; ++j) {
James Zerna5768f62013-12-18 16:38:41 -0800148 int16_t coef = static_cast<int16_t>(sqrt(1.0 * max_energy_leftover) *
Yaowu Xued7e3d22013-12-13 10:05:40 -0800149 (rnd.Rand16() - 32768) / 65536);
150 max_energy_leftover -= coef * coef;
151 if (max_energy_leftover < 0) {
152 max_energy_leftover = 0;
153 coef = 0;
154 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700155 test_coef_block1[av1_default_scan_orders[tx_size_].scan[j]] = coef;
Yaowu Xued7e3d22013-12-13 10:05:40 -0800156 }
157
158 memcpy(test_coef_block2, test_coef_block1,
159 sizeof(*test_coef_block2) * block_size);
160
James Zern29e1b1a2014-07-09 21:02:02 -0700161 ASM_REGISTER_STATE_CHECK(full_itxfm_(test_coef_block1, dst1, size));
162 ASM_REGISTER_STATE_CHECK(partial_itxfm_(test_coef_block2, dst2, size));
Yaowu Xued7e3d22013-12-13 10:05:40 -0800163
164 for (int j = 0; j < block_size; ++j) {
165 const int diff = dst1[j] - dst2[j];
166 const int error = diff * diff;
clang-format3a826f12016-08-11 17:46:05 -0700167 if (max_error < error) max_error = error;
Yaowu Xued7e3d22013-12-13 10:05:40 -0800168 }
169 }
170
171 EXPECT_EQ(0, max_error)
172 << "Error: partial inverse transform produces different results";
173}
174using std::tr1::make_tuple;
175
176INSTANTIATE_TEST_CASE_P(
177 C, PartialIDctTest,
Yaowu Xuf883b422016-08-30 14:01:10 -0700178 ::testing::Values(make_tuple(&aom_fdct32x32_c, &aom_idct32x32_1024_add_c,
179 &aom_idct32x32_34_add_c, TX_32X32, 34),
180 make_tuple(&aom_fdct32x32_c, &aom_idct32x32_1024_add_c,
181 &aom_idct32x32_1_add_c, TX_32X32, 1),
182 make_tuple(&aom_fdct16x16_c, &aom_idct16x16_256_add_c,
183 &aom_idct16x16_10_add_c, TX_16X16, 10),
184 make_tuple(&aom_fdct16x16_c, &aom_idct16x16_256_add_c,
185 &aom_idct16x16_1_add_c, TX_16X16, 1),
186 make_tuple(&aom_fdct8x8_c, &aom_idct8x8_64_add_c,
187 &aom_idct8x8_12_add_c, TX_8X8, 12),
188 make_tuple(&aom_fdct8x8_c, &aom_idct8x8_64_add_c,
189 &aom_idct8x8_1_add_c, TX_8X8, 1),
190 make_tuple(&aom_fdct4x4_c, &aom_idct4x4_16_add_c,
191 &aom_idct4x4_1_add_c, TX_4X4, 1)));
Deb Mukherjee10783d42014-09-02 16:34:09 -0700192
Yaowu Xuf883b422016-08-30 14:01:10 -0700193#if HAVE_NEON && !CONFIG_AOM_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
James Zern2a66e9f2014-02-25 23:11:49 -0800194INSTANTIATE_TEST_CASE_P(
195 NEON, PartialIDctTest,
Yaowu Xuf883b422016-08-30 14:01:10 -0700196 ::testing::Values(make_tuple(&aom_fdct32x32_c, &aom_idct32x32_1024_add_c,
197 &aom_idct32x32_1_add_neon, TX_32X32, 1),
198 make_tuple(&aom_fdct16x16_c, &aom_idct16x16_256_add_c,
199 &aom_idct16x16_10_add_neon, TX_16X16, 10),
200 make_tuple(&aom_fdct16x16_c, &aom_idct16x16_256_add_c,
201 &aom_idct16x16_1_add_neon, TX_16X16, 1),
202 make_tuple(&aom_fdct8x8_c, &aom_idct8x8_64_add_c,
203 &aom_idct8x8_12_add_neon, TX_8X8, 12),
204 make_tuple(&aom_fdct8x8_c, &aom_idct8x8_64_add_c,
205 &aom_idct8x8_1_add_neon, TX_8X8, 1),
206 make_tuple(&aom_fdct4x4_c, &aom_idct4x4_16_add_c,
207 &aom_idct4x4_1_add_neon, TX_4X4, 1)));
208#endif // HAVE_NEON && !CONFIG_AOM_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
James Zern2a66e9f2014-02-25 23:11:49 -0800209
Yaowu Xuf883b422016-08-30 14:01:10 -0700210#if HAVE_SSE2 && !CONFIG_AOM_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
Yaowu Xued7e3d22013-12-13 10:05:40 -0800211INSTANTIATE_TEST_CASE_P(
212 SSE2, PartialIDctTest,
Yaowu Xuf883b422016-08-30 14:01:10 -0700213 ::testing::Values(make_tuple(&aom_fdct32x32_c, &aom_idct32x32_1024_add_c,
214 &aom_idct32x32_34_add_sse2, TX_32X32, 34),
215 make_tuple(&aom_fdct32x32_c, &aom_idct32x32_1024_add_c,
216 &aom_idct32x32_1_add_sse2, TX_32X32, 1),
217 make_tuple(&aom_fdct16x16_c, &aom_idct16x16_256_add_c,
218 &aom_idct16x16_10_add_sse2, TX_16X16, 10),
219 make_tuple(&aom_fdct16x16_c, &aom_idct16x16_256_add_c,
220 &aom_idct16x16_1_add_sse2, TX_16X16, 1),
221 make_tuple(&aom_fdct8x8_c, &aom_idct8x8_64_add_c,
222 &aom_idct8x8_12_add_sse2, TX_8X8, 12),
223 make_tuple(&aom_fdct8x8_c, &aom_idct8x8_64_add_c,
224 &aom_idct8x8_1_add_sse2, TX_8X8, 1),
225 make_tuple(&aom_fdct4x4_c, &aom_idct4x4_16_add_c,
226 &aom_idct4x4_1_add_sse2, TX_4X4, 1)));
Yaowu Xued7e3d22013-12-13 10:05:40 -0800227#endif
Jingning Hanb466ad52014-05-08 09:56:38 -0700228
Yaowu Xuf883b422016-08-30 14:01:10 -0700229#if HAVE_SSSE3 && ARCH_X86_64 && !CONFIG_AOM_HIGHBITDEPTH && \
clang-format3a826f12016-08-11 17:46:05 -0700230 !CONFIG_EMULATE_HARDWARE
James Zern8da50882014-11-13 10:59:54 -0800231INSTANTIATE_TEST_CASE_P(
232 SSSE3_64, PartialIDctTest,
Yaowu Xuf883b422016-08-30 14:01:10 -0700233 ::testing::Values(make_tuple(&aom_fdct8x8_c, &aom_idct8x8_64_add_c,
234 &aom_idct8x8_12_add_ssse3, TX_8X8, 12)));
James Zern8da50882014-11-13 10:59:54 -0800235#endif
236
Yaowu Xuf883b422016-08-30 14:01:10 -0700237#if HAVE_MSA && !CONFIG_AOM_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
Parag Salasakar60052b62015-05-04 13:45:55 +0530238INSTANTIATE_TEST_CASE_P(
239 MSA, PartialIDctTest,
Yaowu Xuf883b422016-08-30 14:01:10 -0700240 ::testing::Values(make_tuple(&aom_fdct32x32_c, &aom_idct32x32_1024_add_c,
241 &aom_idct32x32_34_add_msa, TX_32X32, 34),
242 make_tuple(&aom_fdct32x32_c, &aom_idct32x32_1024_add_c,
243 &aom_idct32x32_1_add_msa, TX_32X32, 1),
244 make_tuple(&aom_fdct16x16_c, &aom_idct16x16_256_add_c,
245 &aom_idct16x16_10_add_msa, TX_16X16, 10),
246 make_tuple(&aom_fdct16x16_c, &aom_idct16x16_256_add_c,
247 &aom_idct16x16_1_add_msa, TX_16X16, 1),
248 make_tuple(&aom_fdct8x8_c, &aom_idct8x8_64_add_c,
249 &aom_idct8x8_12_add_msa, TX_8X8, 10),
250 make_tuple(&aom_fdct8x8_c, &aom_idct8x8_64_add_c,
251 &aom_idct8x8_1_add_msa, TX_8X8, 1),
252 make_tuple(&aom_fdct4x4_c, &aom_idct4x4_16_add_c,
253 &aom_idct4x4_1_add_msa, TX_4X4, 1)));
254#endif // HAVE_MSA && !CONFIG_AOM_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
Parag Salasakar60052b62015-05-04 13:45:55 +0530255
Yaowu Xued7e3d22013-12-13 10:05:40 -0800256} // namespace