1 /* 2 * Copyright (c) 2016 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 <stdlib.h> 12 #include <string.h> 13 14 #include "third_party/googletest/src/include/gtest/gtest.h" 15 16 #include "./vpx_dsp_rtcd.h" 17 #include "vpx/vpx_integer.h" 18 19 #include "test/acm_random.h" 20 #include "test/register_state_check.h" 21 22 namespace { 23 24 using ::libvpx_test::ACMRandom; 25 26 typedef void (*MinMaxFunc)(const uint8_t *a, int a_stride, const uint8_t *b, 27 int b_stride, int *min, int *max); 28 29 class MinMaxTest : public ::testing::TestWithParam<MinMaxFunc> { 30 public: 31 virtual void SetUp() { 32 mm_func_ = GetParam(); 33 rnd_.Reset(ACMRandom::DeterministicSeed()); 34 } 35 36 protected: 37 MinMaxFunc mm_func_; 38 ACMRandom rnd_; 39 }; 40 41 void reference_minmax(const uint8_t *a, int a_stride, const uint8_t *b, 42 int b_stride, int *min_ret, int *max_ret) { 43 int min = 255; 44 int max = 0; 45 for (int i = 0; i < 8; i++) { 46 for (int j = 0; j < 8; j++) { 47 const int diff = abs(a[i * a_stride + j] - b[i * b_stride + j]); 48 if (min > diff) min = diff; 49 if (max < diff) max = diff; 50 } 51 } 52 53 *min_ret = min; 54 *max_ret = max; 55 } 56 57 TEST_P(MinMaxTest, MinValue) { 58 for (int i = 0; i < 64; i++) { 59 uint8_t a[64], b[64]; 60 memset(a, 0, sizeof(a)); 61 memset(b, 255, sizeof(b)); 62 b[i] = i; // Set a minimum difference of i. 63 64 int min, max; 65 ASM_REGISTER_STATE_CHECK(mm_func_(a, 8, b, 8, &min, &max)); 66 EXPECT_EQ(255, max); 67 EXPECT_EQ(i, min); 68 } 69 } 70 71 TEST_P(MinMaxTest, MaxValue) { 72 for (int i = 0; i < 64; i++) { 73 uint8_t a[64], b[64]; 74 memset(a, 0, sizeof(a)); 75 memset(b, 0, sizeof(b)); 76 b[i] = i; // Set a maximum difference of i. 77 78 int min, max; 79 ASM_REGISTER_STATE_CHECK(mm_func_(a, 8, b, 8, &min, &max)); 80 EXPECT_EQ(i, max); 81 EXPECT_EQ(0, min); 82 } 83 } 84 85 TEST_P(MinMaxTest, CompareReference) { 86 uint8_t a[64], b[64]; 87 for (int j = 0; j < 64; j++) { 88 a[j] = rnd_.Rand8(); 89 b[j] = rnd_.Rand8(); 90 } 91 92 int min_ref, max_ref, min, max; 93 reference_minmax(a, 8, b, 8, &min_ref, &max_ref); 94 ASM_REGISTER_STATE_CHECK(mm_func_(a, 8, b, 8, &min, &max)); 95 EXPECT_EQ(max_ref, max); 96 EXPECT_EQ(min_ref, min); 97 } 98 99 TEST_P(MinMaxTest, CompareReferenceAndVaryStride) { 100 uint8_t a[8 * 64], b[8 * 64]; 101 for (int i = 0; i < 8 * 64; i++) { 102 a[i] = rnd_.Rand8(); 103 b[i] = rnd_.Rand8(); 104 } 105 for (int a_stride = 8; a_stride <= 64; a_stride += 8) { 106 for (int b_stride = 8; b_stride <= 64; b_stride += 8) { 107 int min_ref, max_ref, min, max; 108 reference_minmax(a, a_stride, b, b_stride, &min_ref, &max_ref); 109 ASM_REGISTER_STATE_CHECK(mm_func_(a, a_stride, b, b_stride, &min, &max)); 110 EXPECT_EQ(max_ref, max) 111 << "when a_stride = " << a_stride << " and b_stride = " << b_stride; 112 EXPECT_EQ(min_ref, min) 113 << "when a_stride = " << a_stride << " and b_stride = " << b_stride; 114 } 115 } 116 } 117 118 INSTANTIATE_TEST_CASE_P(C, MinMaxTest, ::testing::Values(&vpx_minmax_8x8_c)); 119 120 #if HAVE_SSE2 121 INSTANTIATE_TEST_CASE_P(SSE2, MinMaxTest, 122 ::testing::Values(&vpx_minmax_8x8_sse2)); 123 #endif 124 125 #if HAVE_NEON 126 INSTANTIATE_TEST_CASE_P(NEON, MinMaxTest, 127 ::testing::Values(&vpx_minmax_8x8_neon)); 128 #endif 129 130 #if HAVE_MSA 131 INSTANTIATE_TEST_CASE_P(MSA, MinMaxTest, 132 ::testing::Values(&vpx_minmax_8x8_msa)); 133 #endif 134 135 } // namespace 136