Merge "remove mmx variance functions"
[aom.git] / test / avg_test.cc
blob44d8dd7db5c07f3782319d9cb2572ebe186f3ec7
1 /*
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.
9 */
11 #include <limits.h>
12 #include <stdio.h>
13 #include <string.h>
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;
28 namespace {
29 class AverageTestBase : public ::testing::Test {
30 public:
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_);
40 source_data_ = NULL;
43 virtual void TearDown() {
44 libvpx_test::ClearSystemState();
47 protected:
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());
57 // Sum Pixels
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;
80 void FillRandom() {
81 for (int i = 0; i < width_ * height_; ++i) {
82 source_data_[i] = rnd_.Rand8();
86 int width_, height_;
87 static uint8_t* source_data_;
88 int source_stride_;
90 ACMRandom rnd_;
92 typedef unsigned int (*AverageFunction)(const uint8_t* s, int pitch);
94 typedef std::tr1::tuple<int, int, int, int, AverageFunction> AvgFunc;
96 class AverageTest
97 : public AverageTestBase,
98 public ::testing::WithParamInterface<AvgFunc>{
99 public:
100 AverageTest() : AverageTestBase(GET_PARAM(0), GET_PARAM(1)) {}
102 protected:
103 void CheckAverages() {
104 unsigned int expected = 0;
105 if (GET_PARAM(3) == 8) {
106 expected = ReferenceAverage8x8(source_data_+ GET_PARAM(2),
107 source_stride_);
108 } else if (GET_PARAM(3) == 4) {
109 expected = ReferenceAverage4x4(source_data_+ GET_PARAM(2),
110 source_stride_);
113 ASM_REGISTER_STATE_CHECK(GET_PARAM(4)(source_data_+ GET_PARAM(2),
114 source_stride_));
115 unsigned int actual = GET_PARAM(4)(source_data_+ GET_PARAM(2),
116 source_stride_);
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;
127 class IntProRowTest
128 : public AverageTestBase,
129 public ::testing::WithParamInterface<IntProRowParam> {
130 public:
131 IntProRowTest()
132 : AverageTestBase(16, GET_PARAM(0)),
133 hbuf_asm_(NULL),
134 hbuf_c_(NULL) {
135 asm_func_ = GET_PARAM(1);
136 c_func_ = GET_PARAM(2);
139 protected:
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() {
148 vpx_free(hbuf_c_);
149 hbuf_c_ = NULL;
150 vpx_free(hbuf_asm_);
151 hbuf_asm_ = NULL;
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";
161 private:
162 IntProRowFunc asm_func_;
163 IntProRowFunc c_func_;
164 int16_t *hbuf_asm_;
165 int16_t *hbuf_c_;
168 typedef int16_t (*IntProColFunc)(uint8_t const *ref, const int width);
170 typedef std::tr1::tuple<int, IntProColFunc, IntProColFunc> IntProColParam;
172 class IntProColTest
173 : public AverageTestBase,
174 public ::testing::WithParamInterface<IntProColParam> {
175 public:
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);
181 protected:
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";
188 private:
189 IntProColFunc asm_func_;
190 IntProColFunc c_func_;
191 int16_t sum_asm_;
192 int16_t sum_c_;
195 typedef int (*SatdFunc)(const int16_t *coeffs, int length);
196 typedef std::tr1::tuple<int, SatdFunc> SatdTestParam;
198 class SatdTest
199 : public ::testing::Test,
200 public ::testing::WithParamInterface<SatdTestParam> {
201 protected:
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();
213 vpx_free(src_);
216 void FillConstant(const int16_t val) {
217 for (int i = 0; i < satd_size_; ++i) src_[i] = val;
220 void FillRandom() {
221 for (int i = 0; i < satd_size_; ++i) src_[i] = rnd_.Rand16();
224 void Check(const int expected) {
225 int total;
226 ASM_REGISTER_STATE_CHECK(total = satd_func_(src_, satd_size_));
227 EXPECT_EQ(expected, total);
230 int satd_size_;
232 private:
233 int16_t *src_;
234 SatdFunc satd_func_;
235 ACMRandom rnd_;
238 uint8_t* AverageTestBase::source_data_ = NULL;
240 TEST_P(AverageTest, MinValue) {
241 FillConstant(0);
242 CheckAverages();
245 TEST_P(AverageTest, MaxValue) {
246 FillConstant(255);
247 CheckAverages();
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++) {
254 FillRandom();
255 CheckAverages();
259 TEST_P(IntProRowTest, MinValue) {
260 FillConstant(0);
261 RunComparison();
264 TEST_P(IntProRowTest, MaxValue) {
265 FillConstant(255);
266 RunComparison();
269 TEST_P(IntProRowTest, Random) {
270 FillRandom();
271 RunComparison();
274 TEST_P(IntProColTest, MinValue) {
275 FillConstant(0);
276 RunComparison();
279 TEST_P(IntProColTest, MaxValue) {
280 FillConstant(255);
281 RunComparison();
284 TEST_P(IntProColTest, Random) {
285 FillRandom();
286 RunComparison();
290 TEST_P(SatdTest, MinValue) {
291 const int kMin = -32640;
292 const int expected = -kMin * satd_size_;
293 FillConstant(kMin);
294 Check(expected);
297 TEST_P(SatdTest, MaxValue) {
298 const int kMax = 32640;
299 const int expected = kMax * satd_size_;
300 FillConstant(kMax);
301 Check(expected);
304 TEST_P(SatdTest, Random) {
305 int expected;
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;
311 default:
312 FAIL() << "Invalid satd size (" << satd_size_
313 << ") valid: 16/64/256/1024";
315 FillRandom();
316 Check(expected);
319 using std::tr1::make_tuple;
321 INSTANTIATE_TEST_CASE_P(
322 C, AverageTest,
323 ::testing::Values(
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(
328 C, SatdTest,
329 ::testing::Values(
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)));
335 #if HAVE_SSE2
336 INSTANTIATE_TEST_CASE_P(
337 SSE2, AverageTest,
338 ::testing::Values(
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(
359 SSE2, SatdTest,
360 ::testing::Values(
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)));
365 #endif
367 #if HAVE_NEON
368 INSTANTIATE_TEST_CASE_P(
369 NEON, AverageTest,
370 ::testing::Values(
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(
391 NEON, SatdTest,
392 ::testing::Values(
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)));
397 #endif
399 #if HAVE_MSA
400 INSTANTIATE_TEST_CASE_P(
401 MSA, AverageTest,
402 ::testing::Values(
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)));
409 #endif
411 } // namespace