2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
4 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
15 #include "config/av1_rtcd.h"
17 #include "third_party/googletest/src/googletest/include/gtest/gtest.h"
18 #include "test/acm_random.h"
19 #include "test/util.h"
20 #include "test/register_state_check.h"
22 #include "av1/encoder/corner_match.h"
24 namespace test_libaom
{
26 namespace AV1CornerMatch
{
28 using libaom_test::ACMRandom
;
30 typedef double (*ComputeCrossCorrFunc
)(unsigned char *im1
, int stride1
, int x1
,
31 int y1
, unsigned char *im2
, int stride2
,
34 using std::make_tuple
;
36 typedef tuple
<int, ComputeCrossCorrFunc
> CornerMatchParam
;
38 class AV1CornerMatchTest
: public ::testing::TestWithParam
<CornerMatchParam
> {
40 virtual ~AV1CornerMatchTest();
43 virtual void TearDown();
46 void RunCheckOutput(int run_times
);
47 ComputeCrossCorrFunc target_func
;
49 libaom_test::ACMRandom rnd_
;
51 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AV1CornerMatchTest
);
53 AV1CornerMatchTest::~AV1CornerMatchTest() {}
54 void AV1CornerMatchTest::SetUp() {
55 rnd_
.Reset(ACMRandom::DeterministicSeed());
56 target_func
= GET_PARAM(1);
58 void AV1CornerMatchTest::TearDown() {}
60 void AV1CornerMatchTest::RunCheckOutput(int run_times
) {
61 const int w
= 128, h
= 128;
62 const int num_iters
= 10000;
64 aom_usec_timer ref_timer
, test_timer
;
66 std::unique_ptr
<uint8_t[]> input1(new (std::nothrow
) uint8_t[w
* h
]);
67 std::unique_ptr
<uint8_t[]> input2(new (std::nothrow
) uint8_t[w
* h
]);
68 ASSERT_NE(input1
, nullptr);
69 ASSERT_NE(input2
, nullptr);
71 // Test the two extreme cases:
72 // i) Random data, should have correlation close to 0
73 // ii) Linearly related data + noise, should have correlation close to 1
74 int mode
= GET_PARAM(0);
76 for (i
= 0; i
< h
; ++i
)
77 for (j
= 0; j
< w
; ++j
) {
78 input1
[i
* w
+ j
] = rnd_
.Rand8();
79 input2
[i
* w
+ j
] = rnd_
.Rand8();
81 } else if (mode
== 1) {
82 for (i
= 0; i
< h
; ++i
)
83 for (j
= 0; j
< w
; ++j
) {
85 input1
[i
* w
+ j
] = v
;
86 input2
[i
* w
+ j
] = (v
/ 2) + (rnd_
.Rand8() & 15);
90 for (i
= 0; i
< num_iters
; ++i
) {
91 int x1
= MATCH_SZ_BY2
+ rnd_
.PseudoUniform(w
- 2 * MATCH_SZ_BY2
);
92 int y1
= MATCH_SZ_BY2
+ rnd_
.PseudoUniform(h
- 2 * MATCH_SZ_BY2
);
93 int x2
= MATCH_SZ_BY2
+ rnd_
.PseudoUniform(w
- 2 * MATCH_SZ_BY2
);
94 int y2
= MATCH_SZ_BY2
+ rnd_
.PseudoUniform(h
- 2 * MATCH_SZ_BY2
);
96 double res_c
= av1_compute_cross_correlation_c(input1
.get(), w
, x1
, y1
,
97 input2
.get(), w
, x2
, y2
);
99 target_func(input1
.get(), w
, x1
, y1
, input2
.get(), w
, x2
, y2
);
102 aom_usec_timer_start(&ref_timer
);
103 for (j
= 0; j
< run_times
; j
++) {
104 av1_compute_cross_correlation_c(input1
.get(), w
, x1
, y1
, input2
.get(),
107 aom_usec_timer_mark(&ref_timer
);
108 const int elapsed_time_c
=
109 static_cast<int>(aom_usec_timer_elapsed(&ref_timer
));
111 aom_usec_timer_start(&test_timer
);
112 for (j
= 0; j
< run_times
; j
++) {
113 target_func(input1
.get(), w
, x1
, y1
, input2
.get(), w
, x2
, y2
);
115 aom_usec_timer_mark(&test_timer
);
116 const int elapsed_time_simd
=
117 static_cast<int>(aom_usec_timer_elapsed(&test_timer
));
120 "c_time=%d \t simd_time=%d \t "
122 elapsed_time_c
, elapsed_time_simd
,
123 (elapsed_time_c
/ elapsed_time_simd
));
125 ASSERT_EQ(res_simd
, res_c
);
130 TEST_P(AV1CornerMatchTest
, CheckOutput
) { RunCheckOutput(1); }
131 TEST_P(AV1CornerMatchTest
, DISABLED_Speed
) { RunCheckOutput(100000); }
134 INSTANTIATE_TEST_SUITE_P(
135 SSE4_1
, AV1CornerMatchTest
,
136 ::testing::Values(make_tuple(0, &av1_compute_cross_correlation_sse4_1
),
137 make_tuple(1, &av1_compute_cross_correlation_sse4_1
)));
141 INSTANTIATE_TEST_SUITE_P(
142 AVX2
, AV1CornerMatchTest
,
143 ::testing::Values(make_tuple(0, &av1_compute_cross_correlation_avx2
),
144 make_tuple(1, &av1_compute_cross_correlation_avx2
)));
146 } // namespace AV1CornerMatch
148 } // namespace test_libaom