2 * Copyright (c) 2012 The WebM project authors. All Rights Reserved.
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.
15 #include "third_party/googletest/src/include/gtest/gtest.h"
17 #include "./vpx_config.h"
18 #include "./vpx_dsp_rtcd.h"
20 #include "test/acm_random.h"
21 #include "test/clear_system_state.h"
22 #include "test/register_state_check.h"
23 #include "test/util.h"
24 #include "vpx_mem/vpx_mem.h"
26 using libvpx_test::ACMRandom
;
29 class AverageTestBase
: public ::testing::Test
{
31 AverageTestBase(int width
, int height
) : width_(width
), height_(height
) {}
33 static void SetUpTestCase() {
34 source_data_
= reinterpret_cast<uint8_t*>(
35 vpx_memalign(kDataAlignment
, kDataBlockSize
));
38 static void TearDownTestCase() {
39 vpx_free(source_data_
);
43 virtual void TearDown() {
44 libvpx_test::ClearSystemState();
48 // Handle blocks up to 4 blocks 64x64 with stride up to 128
49 static const int kDataAlignment
= 16;
50 static const int kDataBlockSize
= 64 * 128;
52 virtual void SetUp() {
53 source_stride_
= (width_
+ 31) & ~31;
54 rnd_
.Reset(ACMRandom::DeterministicSeed());
58 unsigned int ReferenceAverage8x8(const uint8_t* source
, int pitch
) {
59 unsigned int average
= 0;
60 for (int h
= 0; h
< 8; ++h
)
61 for (int w
= 0; w
< 8; ++w
)
62 average
+= source
[h
* pitch
+ w
];
63 return ((average
+ 32) >> 6);
66 unsigned int ReferenceAverage4x4(const uint8_t* source
, int pitch
) {
67 unsigned int average
= 0;
68 for (int h
= 0; h
< 4; ++h
)
69 for (int w
= 0; w
< 4; ++w
)
70 average
+= source
[h
* pitch
+ w
];
71 return ((average
+ 8) >> 4);
74 void FillConstant(uint8_t fill_constant
) {
75 for (int i
= 0; i
< width_
* height_
; ++i
) {
76 source_data_
[i
] = fill_constant
;
81 for (int i
= 0; i
< width_
* height_
; ++i
) {
82 source_data_
[i
] = rnd_
.Rand8();
87 static uint8_t* source_data_
;
92 typedef unsigned int (*AverageFunction
)(const uint8_t* s
, int pitch
);
94 typedef std::tr1::tuple
<int, int, int, int, AverageFunction
> AvgFunc
;
97 : public AverageTestBase
,
98 public ::testing::WithParamInterface
<AvgFunc
>{
100 AverageTest() : AverageTestBase(GET_PARAM(0), GET_PARAM(1)) {}
103 void CheckAverages() {
104 unsigned int expected
= 0;
105 if (GET_PARAM(3) == 8) {
106 expected
= ReferenceAverage8x8(source_data_
+ GET_PARAM(2),
108 } else if (GET_PARAM(3) == 4) {
109 expected
= ReferenceAverage4x4(source_data_
+ GET_PARAM(2),
113 ASM_REGISTER_STATE_CHECK(GET_PARAM(4)(source_data_
+ GET_PARAM(2),
115 unsigned int actual
= GET_PARAM(4)(source_data_
+ GET_PARAM(2),
118 EXPECT_EQ(expected
, actual
);
122 typedef void (*IntProRowFunc
)(int16_t hbuf
[16], uint8_t const *ref
,
123 const int ref_stride
, const int height
);
125 typedef std::tr1::tuple
<int, IntProRowFunc
, IntProRowFunc
> IntProRowParam
;
128 : public AverageTestBase
,
129 public ::testing::WithParamInterface
<IntProRowParam
> {
132 : AverageTestBase(16, GET_PARAM(0)),
135 asm_func_
= GET_PARAM(1);
136 c_func_
= GET_PARAM(2);
140 virtual void SetUp() {
141 hbuf_asm_
= reinterpret_cast<int16_t*>(
142 vpx_memalign(kDataAlignment
, sizeof(*hbuf_asm_
) * 16));
143 hbuf_c_
= reinterpret_cast<int16_t*>(
144 vpx_memalign(kDataAlignment
, sizeof(*hbuf_c_
) * 16));
147 virtual void TearDown() {
154 void RunComparison() {
155 ASM_REGISTER_STATE_CHECK(c_func_(hbuf_c_
, source_data_
, 0, height_
));
156 ASM_REGISTER_STATE_CHECK(asm_func_(hbuf_asm_
, source_data_
, 0, height_
));
157 EXPECT_EQ(0, memcmp(hbuf_c_
, hbuf_asm_
, sizeof(*hbuf_c_
) * 16))
158 << "Output mismatch";
162 IntProRowFunc asm_func_
;
163 IntProRowFunc c_func_
;
168 typedef int16_t (*IntProColFunc
)(uint8_t const *ref
, const int width
);
170 typedef std::tr1::tuple
<int, IntProColFunc
, IntProColFunc
> IntProColParam
;
173 : public AverageTestBase
,
174 public ::testing::WithParamInterface
<IntProColParam
> {
176 IntProColTest() : AverageTestBase(GET_PARAM(0), 1), sum_asm_(0), sum_c_(0) {
177 asm_func_
= GET_PARAM(1);
178 c_func_
= GET_PARAM(2);
182 void RunComparison() {
183 ASM_REGISTER_STATE_CHECK(sum_c_
= c_func_(source_data_
, width_
));
184 ASM_REGISTER_STATE_CHECK(sum_asm_
= asm_func_(source_data_
, width_
));
185 EXPECT_EQ(sum_c_
, sum_asm_
) << "Output mismatch";
189 IntProColFunc asm_func_
;
190 IntProColFunc c_func_
;
195 typedef int (*SatdFunc
)(const int16_t *coeffs
, int length
);
196 typedef std::tr1::tuple
<int, SatdFunc
> SatdTestParam
;
199 : public ::testing::Test
,
200 public ::testing::WithParamInterface
<SatdTestParam
> {
202 virtual void SetUp() {
203 satd_size_
= GET_PARAM(0);
204 satd_func_
= GET_PARAM(1);
205 rnd_
.Reset(ACMRandom::DeterministicSeed());
206 src_
= reinterpret_cast<int16_t*>(
207 vpx_memalign(16, sizeof(*src_
) * satd_size_
));
208 ASSERT_TRUE(src_
!= NULL
);
211 virtual void TearDown() {
212 libvpx_test::ClearSystemState();
216 void FillConstant(const int16_t val
) {
217 for (int i
= 0; i
< satd_size_
; ++i
) src_
[i
] = val
;
221 for (int i
= 0; i
< satd_size_
; ++i
) src_
[i
] = rnd_
.Rand16();
224 void Check(const int expected
) {
226 ASM_REGISTER_STATE_CHECK(total
= satd_func_(src_
, satd_size_
));
227 EXPECT_EQ(expected
, total
);
238 uint8_t* AverageTestBase::source_data_
= NULL
;
240 TEST_P(AverageTest
, MinValue
) {
245 TEST_P(AverageTest
, MaxValue
) {
250 TEST_P(AverageTest
, Random
) {
251 // The reference frame, but not the source frame, may be unaligned for
252 // certain types of searches.
253 for (int i
= 0; i
< 1000; i
++) {
259 TEST_P(IntProRowTest
, MinValue
) {
264 TEST_P(IntProRowTest
, MaxValue
) {
269 TEST_P(IntProRowTest
, Random
) {
274 TEST_P(IntProColTest
, MinValue
) {
279 TEST_P(IntProColTest
, MaxValue
) {
284 TEST_P(IntProColTest
, Random
) {
290 TEST_P(SatdTest
, MinValue
) {
291 const int kMin
= -32640;
292 const int expected
= -kMin
* satd_size_
;
297 TEST_P(SatdTest
, MaxValue
) {
298 const int kMax
= 32640;
299 const int expected
= kMax
* satd_size_
;
304 TEST_P(SatdTest
, Random
) {
306 switch (satd_size_
) {
307 case 16: expected
= 205298; break;
308 case 64: expected
= 1113950; break;
309 case 256: expected
= 4268415; break;
310 case 1024: expected
= 16954082; break;
312 FAIL() << "Invalid satd size (" << satd_size_
313 << ") valid: 16/64/256/1024";
319 using std::tr1::make_tuple
;
321 INSTANTIATE_TEST_CASE_P(
324 make_tuple(16, 16, 1, 8, &vpx_avg_8x8_c
),
325 make_tuple(16, 16, 1, 4, &vpx_avg_4x4_c
)));
327 INSTANTIATE_TEST_CASE_P(
330 make_tuple(16, &vpx_satd_c
),
331 make_tuple(64, &vpx_satd_c
),
332 make_tuple(256, &vpx_satd_c
),
333 make_tuple(1024, &vpx_satd_c
)));
336 INSTANTIATE_TEST_CASE_P(
339 make_tuple(16, 16, 0, 8, &vpx_avg_8x8_sse2
),
340 make_tuple(16, 16, 5, 8, &vpx_avg_8x8_sse2
),
341 make_tuple(32, 32, 15, 8, &vpx_avg_8x8_sse2
),
342 make_tuple(16, 16, 0, 4, &vpx_avg_4x4_sse2
),
343 make_tuple(16, 16, 5, 4, &vpx_avg_4x4_sse2
),
344 make_tuple(32, 32, 15, 4, &vpx_avg_4x4_sse2
)));
346 INSTANTIATE_TEST_CASE_P(
347 SSE2
, IntProRowTest
, ::testing::Values(
348 make_tuple(16, &vpx_int_pro_row_sse2
, &vpx_int_pro_row_c
),
349 make_tuple(32, &vpx_int_pro_row_sse2
, &vpx_int_pro_row_c
),
350 make_tuple(64, &vpx_int_pro_row_sse2
, &vpx_int_pro_row_c
)));
352 INSTANTIATE_TEST_CASE_P(
353 SSE2
, IntProColTest
, ::testing::Values(
354 make_tuple(16, &vpx_int_pro_col_sse2
, &vpx_int_pro_col_c
),
355 make_tuple(32, &vpx_int_pro_col_sse2
, &vpx_int_pro_col_c
),
356 make_tuple(64, &vpx_int_pro_col_sse2
, &vpx_int_pro_col_c
)));
358 INSTANTIATE_TEST_CASE_P(
361 make_tuple(16, &vpx_satd_sse2
),
362 make_tuple(64, &vpx_satd_sse2
),
363 make_tuple(256, &vpx_satd_sse2
),
364 make_tuple(1024, &vpx_satd_sse2
)));
368 INSTANTIATE_TEST_CASE_P(
371 make_tuple(16, 16, 0, 8, &vpx_avg_8x8_neon
),
372 make_tuple(16, 16, 5, 8, &vpx_avg_8x8_neon
),
373 make_tuple(32, 32, 15, 8, &vpx_avg_8x8_neon
),
374 make_tuple(16, 16, 0, 4, &vpx_avg_4x4_neon
),
375 make_tuple(16, 16, 5, 4, &vpx_avg_4x4_neon
),
376 make_tuple(32, 32, 15, 4, &vpx_avg_4x4_neon
)));
378 INSTANTIATE_TEST_CASE_P(
379 NEON
, IntProRowTest
, ::testing::Values(
380 make_tuple(16, &vpx_int_pro_row_neon
, &vpx_int_pro_row_c
),
381 make_tuple(32, &vpx_int_pro_row_neon
, &vpx_int_pro_row_c
),
382 make_tuple(64, &vpx_int_pro_row_neon
, &vpx_int_pro_row_c
)));
384 INSTANTIATE_TEST_CASE_P(
385 NEON
, IntProColTest
, ::testing::Values(
386 make_tuple(16, &vpx_int_pro_col_neon
, &vpx_int_pro_col_c
),
387 make_tuple(32, &vpx_int_pro_col_neon
, &vpx_int_pro_col_c
),
388 make_tuple(64, &vpx_int_pro_col_neon
, &vpx_int_pro_col_c
)));
390 INSTANTIATE_TEST_CASE_P(
393 make_tuple(16, &vpx_satd_neon
),
394 make_tuple(64, &vpx_satd_neon
),
395 make_tuple(256, &vpx_satd_neon
),
396 make_tuple(1024, &vpx_satd_neon
)));
400 INSTANTIATE_TEST_CASE_P(
403 make_tuple(16, 16, 0, 8, &vpx_avg_8x8_msa
),
404 make_tuple(16, 16, 5, 8, &vpx_avg_8x8_msa
),
405 make_tuple(32, 32, 15, 8, &vpx_avg_8x8_msa
),
406 make_tuple(16, 16, 0, 4, &vpx_avg_4x4_msa
),
407 make_tuple(16, 16, 5, 4, &vpx_avg_4x4_msa
),
408 make_tuple(32, 32, 15, 4, &vpx_avg_4x4_msa
)));