1*fb1b10abSAndroid Build Coastguard Worker /*
2*fb1b10abSAndroid Build Coastguard Worker * Copyright (c) 2017 The WebM project authors. All Rights Reserved.
3*fb1b10abSAndroid Build Coastguard Worker *
4*fb1b10abSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license
5*fb1b10abSAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source
6*fb1b10abSAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found
7*fb1b10abSAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may
8*fb1b10abSAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree.
9*fb1b10abSAndroid Build Coastguard Worker */
10*fb1b10abSAndroid Build Coastguard Worker
11*fb1b10abSAndroid Build Coastguard Worker #include <math.h>
12*fb1b10abSAndroid Build Coastguard Worker #include <stdlib.h>
13*fb1b10abSAndroid Build Coastguard Worker #include <string.h>
14*fb1b10abSAndroid Build Coastguard Worker #include <limits>
15*fb1b10abSAndroid Build Coastguard Worker #include <tuple>
16*fb1b10abSAndroid Build Coastguard Worker
17*fb1b10abSAndroid Build Coastguard Worker #include "gtest/gtest.h"
18*fb1b10abSAndroid Build Coastguard Worker
19*fb1b10abSAndroid Build Coastguard Worker #include "./vpx_dsp_rtcd.h"
20*fb1b10abSAndroid Build Coastguard Worker #include "test/acm_random.h"
21*fb1b10abSAndroid Build Coastguard Worker #include "test/buffer.h"
22*fb1b10abSAndroid Build Coastguard Worker #include "test/clear_system_state.h"
23*fb1b10abSAndroid Build Coastguard Worker #include "test/register_state_check.h"
24*fb1b10abSAndroid Build Coastguard Worker #include "test/util.h"
25*fb1b10abSAndroid Build Coastguard Worker #include "vpx_config.h"
26*fb1b10abSAndroid Build Coastguard Worker #include "vpx/vpx_codec.h"
27*fb1b10abSAndroid Build Coastguard Worker #include "vpx/vpx_integer.h"
28*fb1b10abSAndroid Build Coastguard Worker #include "vpx_dsp/vpx_dsp_common.h"
29*fb1b10abSAndroid Build Coastguard Worker
30*fb1b10abSAndroid Build Coastguard Worker using libvpx_test::ACMRandom;
31*fb1b10abSAndroid Build Coastguard Worker using libvpx_test::Buffer;
32*fb1b10abSAndroid Build Coastguard Worker using std::make_tuple;
33*fb1b10abSAndroid Build Coastguard Worker using std::tuple;
34*fb1b10abSAndroid Build Coastguard Worker
35*fb1b10abSAndroid Build Coastguard Worker namespace {
36*fb1b10abSAndroid Build Coastguard Worker typedef void (*PartialFdctFunc)(const int16_t *in, tran_low_t *out, int stride);
37*fb1b10abSAndroid Build Coastguard Worker
38*fb1b10abSAndroid Build Coastguard Worker typedef tuple<PartialFdctFunc, int /* size */, vpx_bit_depth_t>
39*fb1b10abSAndroid Build Coastguard Worker PartialFdctParam;
40*fb1b10abSAndroid Build Coastguard Worker
partial_fdct_ref(const Buffer<int16_t> & in,int size)41*fb1b10abSAndroid Build Coastguard Worker tran_low_t partial_fdct_ref(const Buffer<int16_t> &in, int size) {
42*fb1b10abSAndroid Build Coastguard Worker int64_t sum = 0;
43*fb1b10abSAndroid Build Coastguard Worker if (in.TopLeftPixel() != nullptr) {
44*fb1b10abSAndroid Build Coastguard Worker for (int y = 0; y < size; ++y) {
45*fb1b10abSAndroid Build Coastguard Worker for (int x = 0; x < size; ++x) {
46*fb1b10abSAndroid Build Coastguard Worker sum += in.TopLeftPixel()[y * in.stride() + x];
47*fb1b10abSAndroid Build Coastguard Worker }
48*fb1b10abSAndroid Build Coastguard Worker }
49*fb1b10abSAndroid Build Coastguard Worker } else {
50*fb1b10abSAndroid Build Coastguard Worker assert(0);
51*fb1b10abSAndroid Build Coastguard Worker }
52*fb1b10abSAndroid Build Coastguard Worker
53*fb1b10abSAndroid Build Coastguard Worker switch (size) {
54*fb1b10abSAndroid Build Coastguard Worker case 4: sum *= 2; break;
55*fb1b10abSAndroid Build Coastguard Worker case 8: /*sum = sum;*/ break;
56*fb1b10abSAndroid Build Coastguard Worker case 16: sum >>= 1; break;
57*fb1b10abSAndroid Build Coastguard Worker case 32: sum >>= 3; break;
58*fb1b10abSAndroid Build Coastguard Worker }
59*fb1b10abSAndroid Build Coastguard Worker
60*fb1b10abSAndroid Build Coastguard Worker return static_cast<tran_low_t>(sum);
61*fb1b10abSAndroid Build Coastguard Worker }
62*fb1b10abSAndroid Build Coastguard Worker
63*fb1b10abSAndroid Build Coastguard Worker class PartialFdctTest : public ::testing::TestWithParam<PartialFdctParam> {
64*fb1b10abSAndroid Build Coastguard Worker public:
PartialFdctTest()65*fb1b10abSAndroid Build Coastguard Worker PartialFdctTest() {
66*fb1b10abSAndroid Build Coastguard Worker fwd_txfm_ = GET_PARAM(0);
67*fb1b10abSAndroid Build Coastguard Worker size_ = GET_PARAM(1);
68*fb1b10abSAndroid Build Coastguard Worker bit_depth_ = GET_PARAM(2);
69*fb1b10abSAndroid Build Coastguard Worker }
70*fb1b10abSAndroid Build Coastguard Worker
TearDown()71*fb1b10abSAndroid Build Coastguard Worker void TearDown() override { libvpx_test::ClearSystemState(); }
72*fb1b10abSAndroid Build Coastguard Worker
73*fb1b10abSAndroid Build Coastguard Worker protected:
RunTest()74*fb1b10abSAndroid Build Coastguard Worker void RunTest() {
75*fb1b10abSAndroid Build Coastguard Worker ACMRandom rnd(ACMRandom::DeterministicSeed());
76*fb1b10abSAndroid Build Coastguard Worker const int16_t maxvalue =
77*fb1b10abSAndroid Build Coastguard Worker clip_pixel_highbd(std::numeric_limits<int16_t>::max(), bit_depth_);
78*fb1b10abSAndroid Build Coastguard Worker const int16_t minvalue = -maxvalue;
79*fb1b10abSAndroid Build Coastguard Worker Buffer<int16_t> input_block =
80*fb1b10abSAndroid Build Coastguard Worker Buffer<int16_t>(size_, size_, 8, size_ == 4 ? 0 : 16);
81*fb1b10abSAndroid Build Coastguard Worker ASSERT_TRUE(input_block.Init());
82*fb1b10abSAndroid Build Coastguard Worker Buffer<tran_low_t> output_block = Buffer<tran_low_t>(size_, size_, 0, 16);
83*fb1b10abSAndroid Build Coastguard Worker ASSERT_TRUE(output_block.Init());
84*fb1b10abSAndroid Build Coastguard Worker
85*fb1b10abSAndroid Build Coastguard Worker if (output_block.TopLeftPixel() != nullptr) {
86*fb1b10abSAndroid Build Coastguard Worker for (int i = 0; i < 100; ++i) {
87*fb1b10abSAndroid Build Coastguard Worker if (i == 0) {
88*fb1b10abSAndroid Build Coastguard Worker input_block.Set(maxvalue);
89*fb1b10abSAndroid Build Coastguard Worker } else if (i == 1) {
90*fb1b10abSAndroid Build Coastguard Worker input_block.Set(minvalue);
91*fb1b10abSAndroid Build Coastguard Worker } else {
92*fb1b10abSAndroid Build Coastguard Worker input_block.Set(&rnd, minvalue, maxvalue);
93*fb1b10abSAndroid Build Coastguard Worker }
94*fb1b10abSAndroid Build Coastguard Worker
95*fb1b10abSAndroid Build Coastguard Worker ASM_REGISTER_STATE_CHECK(fwd_txfm_(input_block.TopLeftPixel(),
96*fb1b10abSAndroid Build Coastguard Worker output_block.TopLeftPixel(),
97*fb1b10abSAndroid Build Coastguard Worker input_block.stride()));
98*fb1b10abSAndroid Build Coastguard Worker
99*fb1b10abSAndroid Build Coastguard Worker EXPECT_EQ(partial_fdct_ref(input_block, size_),
100*fb1b10abSAndroid Build Coastguard Worker output_block.TopLeftPixel()[0]);
101*fb1b10abSAndroid Build Coastguard Worker }
102*fb1b10abSAndroid Build Coastguard Worker } else {
103*fb1b10abSAndroid Build Coastguard Worker assert(0);
104*fb1b10abSAndroid Build Coastguard Worker }
105*fb1b10abSAndroid Build Coastguard Worker }
106*fb1b10abSAndroid Build Coastguard Worker
107*fb1b10abSAndroid Build Coastguard Worker PartialFdctFunc fwd_txfm_;
108*fb1b10abSAndroid Build Coastguard Worker vpx_bit_depth_t bit_depth_;
109*fb1b10abSAndroid Build Coastguard Worker int size_;
110*fb1b10abSAndroid Build Coastguard Worker };
111*fb1b10abSAndroid Build Coastguard Worker
TEST_P(PartialFdctTest,PartialFdctTest)112*fb1b10abSAndroid Build Coastguard Worker TEST_P(PartialFdctTest, PartialFdctTest) { RunTest(); }
113*fb1b10abSAndroid Build Coastguard Worker
114*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
115*fb1b10abSAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(
116*fb1b10abSAndroid Build Coastguard Worker C, PartialFdctTest,
117*fb1b10abSAndroid Build Coastguard Worker ::testing::Values(make_tuple(&vpx_highbd_fdct32x32_1_c, 32, VPX_BITS_12),
118*fb1b10abSAndroid Build Coastguard Worker make_tuple(&vpx_highbd_fdct32x32_1_c, 32, VPX_BITS_10),
119*fb1b10abSAndroid Build Coastguard Worker make_tuple(&vpx_fdct32x32_1_c, 32, VPX_BITS_8),
120*fb1b10abSAndroid Build Coastguard Worker make_tuple(&vpx_highbd_fdct16x16_1_c, 16, VPX_BITS_12),
121*fb1b10abSAndroid Build Coastguard Worker make_tuple(&vpx_highbd_fdct16x16_1_c, 16, VPX_BITS_10),
122*fb1b10abSAndroid Build Coastguard Worker make_tuple(&vpx_fdct16x16_1_c, 16, VPX_BITS_8),
123*fb1b10abSAndroid Build Coastguard Worker make_tuple(&vpx_highbd_fdct8x8_1_c, 8, VPX_BITS_12),
124*fb1b10abSAndroid Build Coastguard Worker make_tuple(&vpx_highbd_fdct8x8_1_c, 8, VPX_BITS_10),
125*fb1b10abSAndroid Build Coastguard Worker make_tuple(&vpx_fdct8x8_1_c, 8, VPX_BITS_8),
126*fb1b10abSAndroid Build Coastguard Worker make_tuple(&vpx_fdct4x4_1_c, 4, VPX_BITS_8)));
127*fb1b10abSAndroid Build Coastguard Worker #else
128*fb1b10abSAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(
129*fb1b10abSAndroid Build Coastguard Worker C, PartialFdctTest,
130*fb1b10abSAndroid Build Coastguard Worker ::testing::Values(make_tuple(&vpx_fdct32x32_1_c, 32, VPX_BITS_8),
131*fb1b10abSAndroid Build Coastguard Worker make_tuple(&vpx_fdct16x16_1_c, 16, VPX_BITS_8),
132*fb1b10abSAndroid Build Coastguard Worker make_tuple(&vpx_fdct8x8_1_c, 8, VPX_BITS_8),
133*fb1b10abSAndroid Build Coastguard Worker make_tuple(&vpx_fdct4x4_1_c, 4, VPX_BITS_8)));
134*fb1b10abSAndroid Build Coastguard Worker #endif // CONFIG_VP9_HIGHBITDEPTH
135*fb1b10abSAndroid Build Coastguard Worker
136*fb1b10abSAndroid Build Coastguard Worker #if HAVE_SSE2
137*fb1b10abSAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(
138*fb1b10abSAndroid Build Coastguard Worker SSE2, PartialFdctTest,
139*fb1b10abSAndroid Build Coastguard Worker ::testing::Values(make_tuple(&vpx_fdct32x32_1_sse2, 32, VPX_BITS_8),
140*fb1b10abSAndroid Build Coastguard Worker make_tuple(&vpx_fdct16x16_1_sse2, 16, VPX_BITS_8),
141*fb1b10abSAndroid Build Coastguard Worker make_tuple(&vpx_fdct8x8_1_sse2, 8, VPX_BITS_8),
142*fb1b10abSAndroid Build Coastguard Worker make_tuple(&vpx_fdct4x4_1_sse2, 4, VPX_BITS_8)));
143*fb1b10abSAndroid Build Coastguard Worker #endif // HAVE_SSE2
144*fb1b10abSAndroid Build Coastguard Worker
145*fb1b10abSAndroid Build Coastguard Worker #if HAVE_NEON
146*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
147*fb1b10abSAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(
148*fb1b10abSAndroid Build Coastguard Worker NEON, PartialFdctTest,
149*fb1b10abSAndroid Build Coastguard Worker ::testing::Values(make_tuple(&vpx_highbd_fdct32x32_1_neon, 32, VPX_BITS_12),
150*fb1b10abSAndroid Build Coastguard Worker make_tuple(&vpx_highbd_fdct32x32_1_neon, 32, VPX_BITS_10),
151*fb1b10abSAndroid Build Coastguard Worker make_tuple(&vpx_highbd_fdct32x32_1_neon, 32, VPX_BITS_8),
152*fb1b10abSAndroid Build Coastguard Worker make_tuple(&vpx_highbd_fdct16x16_1_neon, 16, VPX_BITS_12),
153*fb1b10abSAndroid Build Coastguard Worker make_tuple(&vpx_highbd_fdct16x16_1_neon, 16, VPX_BITS_10),
154*fb1b10abSAndroid Build Coastguard Worker make_tuple(&vpx_highbd_fdct16x16_1_neon, 16, VPX_BITS_8),
155*fb1b10abSAndroid Build Coastguard Worker make_tuple(&vpx_fdct8x8_1_neon, 8, VPX_BITS_12),
156*fb1b10abSAndroid Build Coastguard Worker make_tuple(&vpx_fdct8x8_1_neon, 8, VPX_BITS_10),
157*fb1b10abSAndroid Build Coastguard Worker make_tuple(&vpx_fdct8x8_1_neon, 8, VPX_BITS_8),
158*fb1b10abSAndroid Build Coastguard Worker make_tuple(&vpx_fdct4x4_1_neon, 4, VPX_BITS_12),
159*fb1b10abSAndroid Build Coastguard Worker make_tuple(&vpx_fdct4x4_1_neon, 4, VPX_BITS_10),
160*fb1b10abSAndroid Build Coastguard Worker make_tuple(&vpx_fdct4x4_1_neon, 4, VPX_BITS_8)));
161*fb1b10abSAndroid Build Coastguard Worker #else
162*fb1b10abSAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(
163*fb1b10abSAndroid Build Coastguard Worker NEON, PartialFdctTest,
164*fb1b10abSAndroid Build Coastguard Worker ::testing::Values(make_tuple(&vpx_fdct32x32_1_neon, 32, VPX_BITS_8),
165*fb1b10abSAndroid Build Coastguard Worker make_tuple(&vpx_fdct16x16_1_neon, 16, VPX_BITS_8),
166*fb1b10abSAndroid Build Coastguard Worker make_tuple(&vpx_fdct8x8_1_neon, 8, VPX_BITS_8),
167*fb1b10abSAndroid Build Coastguard Worker make_tuple(&vpx_fdct4x4_1_neon, 4, VPX_BITS_8)));
168*fb1b10abSAndroid Build Coastguard Worker #endif // CONFIG_VP9_HIGHBITDEPTH
169*fb1b10abSAndroid Build Coastguard Worker #endif // HAVE_NEON
170*fb1b10abSAndroid Build Coastguard Worker
171*fb1b10abSAndroid Build Coastguard Worker #if HAVE_MSA
172*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
173*fb1b10abSAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(MSA, PartialFdctTest,
174*fb1b10abSAndroid Build Coastguard Worker ::testing::Values(make_tuple(&vpx_fdct8x8_1_msa, 8,
175*fb1b10abSAndroid Build Coastguard Worker VPX_BITS_8)));
176*fb1b10abSAndroid Build Coastguard Worker #else // !CONFIG_VP9_HIGHBITDEPTH
177*fb1b10abSAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(
178*fb1b10abSAndroid Build Coastguard Worker MSA, PartialFdctTest,
179*fb1b10abSAndroid Build Coastguard Worker ::testing::Values(make_tuple(&vpx_fdct32x32_1_msa, 32, VPX_BITS_8),
180*fb1b10abSAndroid Build Coastguard Worker make_tuple(&vpx_fdct16x16_1_msa, 16, VPX_BITS_8),
181*fb1b10abSAndroid Build Coastguard Worker make_tuple(&vpx_fdct8x8_1_msa, 8, VPX_BITS_8)));
182*fb1b10abSAndroid Build Coastguard Worker #endif // CONFIG_VP9_HIGHBITDEPTH
183*fb1b10abSAndroid Build Coastguard Worker #endif // HAVE_MSA
184*fb1b10abSAndroid Build Coastguard Worker } // namespace
185