• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "vpx_mem/vpx_mem.h"
19 
20 #include "test/acm_random.h"
21 #include "test/register_state_check.h"
22 
23 namespace {
24 
25 using ::libvpx_test::ACMRandom;
26 
27 typedef void (*MinMaxFunc)(const uint8_t *a, int a_stride, const uint8_t *b,
28                            int b_stride, int *min, int *max);
29 
30 class MinMaxTest : public ::testing::TestWithParam<MinMaxFunc> {
31  public:
SetUp()32   void SetUp() override {
33     mm_func_ = GetParam();
34     rnd_.Reset(ACMRandom::DeterministicSeed());
35   }
36 
37  protected:
38   MinMaxFunc mm_func_;
39   ACMRandom rnd_;
40 };
41 
reference_minmax(const uint8_t * a,int a_stride,const uint8_t * b,int b_stride,int * min_ret,int * max_ret)42 void reference_minmax(const uint8_t *a, int a_stride, const uint8_t *b,
43                       int b_stride, int *min_ret, int *max_ret) {
44   int min = 255;
45   int max = 0;
46   for (int i = 0; i < 8; i++) {
47     for (int j = 0; j < 8; j++) {
48       const int diff = abs(a[i * a_stride + j] - b[i * b_stride + j]);
49       if (min > diff) min = diff;
50       if (max < diff) max = diff;
51     }
52   }
53 
54   *min_ret = min;
55   *max_ret = max;
56 }
57 
TEST_P(MinMaxTest,MinValue)58 TEST_P(MinMaxTest, MinValue) {
59   for (int i = 0; i < 64; i++) {
60     uint8_t a[64], b[64];
61     memset(a, 0, sizeof(a));
62     memset(b, 255, sizeof(b));
63     b[i] = i;  // Set a minimum difference of i.
64 
65     int min, max;
66     ASM_REGISTER_STATE_CHECK(mm_func_(a, 8, b, 8, &min, &max));
67     EXPECT_EQ(255, max);
68     EXPECT_EQ(i, min);
69   }
70 }
71 
TEST_P(MinMaxTest,MaxValue)72 TEST_P(MinMaxTest, MaxValue) {
73   for (int i = 0; i < 64; i++) {
74     uint8_t a[64], b[64];
75     memset(a, 0, sizeof(a));
76     memset(b, 0, sizeof(b));
77     b[i] = i;  // Set a maximum difference of i.
78 
79     int min, max;
80     ASM_REGISTER_STATE_CHECK(mm_func_(a, 8, b, 8, &min, &max));
81     EXPECT_EQ(i, max);
82     EXPECT_EQ(0, min);
83   }
84 }
85 
TEST_P(MinMaxTest,CompareReference)86 TEST_P(MinMaxTest, CompareReference) {
87   uint8_t a[64], b[64];
88   for (int j = 0; j < 64; j++) {
89     a[j] = rnd_.Rand8();
90     b[j] = rnd_.Rand8();
91   }
92 
93   int min_ref, max_ref, min, max;
94   reference_minmax(a, 8, b, 8, &min_ref, &max_ref);
95   ASM_REGISTER_STATE_CHECK(mm_func_(a, 8, b, 8, &min, &max));
96   EXPECT_EQ(max_ref, max);
97   EXPECT_EQ(min_ref, min);
98 }
99 
TEST_P(MinMaxTest,CompareReferenceAndVaryStride)100 TEST_P(MinMaxTest, CompareReferenceAndVaryStride) {
101   uint8_t a[8 * 64], b[8 * 64];
102   for (int i = 0; i < 8 * 64; i++) {
103     a[i] = rnd_.Rand8();
104     b[i] = rnd_.Rand8();
105   }
106   for (int a_stride = 8; a_stride <= 64; a_stride += 8) {
107     for (int b_stride = 8; b_stride <= 64; b_stride += 8) {
108       int min_ref, max_ref, min, max;
109       reference_minmax(a, a_stride, b, b_stride, &min_ref, &max_ref);
110       ASM_REGISTER_STATE_CHECK(mm_func_(a, a_stride, b, b_stride, &min, &max));
111       EXPECT_EQ(max_ref, max)
112           << "when a_stride = " << a_stride << " and b_stride = " << b_stride;
113       EXPECT_EQ(min_ref, min)
114           << "when a_stride = " << a_stride << " and b_stride = " << b_stride;
115     }
116   }
117 }
118 
119 #if CONFIG_VP9_HIGHBITDEPTH
120 
121 using HBDMinMaxTest = MinMaxTest;
122 
highbd_reference_minmax(const uint8_t * a,int a_stride,const uint8_t * b,int b_stride,int * min_ret,int * max_ret)123 void highbd_reference_minmax(const uint8_t *a, int a_stride, const uint8_t *b,
124                              int b_stride, int *min_ret, int *max_ret) {
125   int min = 65535;
126   int max = 0;
127   const uint16_t *a_ptr = CONVERT_TO_SHORTPTR(a);
128   const uint16_t *b_ptr = CONVERT_TO_SHORTPTR(b);
129   for (int i = 0; i < 8; i++) {
130     for (int j = 0; j < 8; j++) {
131       const int diff = abs(a_ptr[i * a_stride + j] - b_ptr[i * b_stride + j]);
132       if (min > diff) min = diff;
133       if (max < diff) max = diff;
134     }
135   }
136 
137   *min_ret = min;
138   *max_ret = max;
139 }
140 
TEST_P(HBDMinMaxTest,MinValue)141 TEST_P(HBDMinMaxTest, MinValue) {
142   uint8_t *a = CONVERT_TO_BYTEPTR(
143       reinterpret_cast<uint16_t *>(vpx_malloc(64 * sizeof(uint16_t))));
144   uint8_t *b = CONVERT_TO_BYTEPTR(
145       reinterpret_cast<uint16_t *>(vpx_malloc(64 * sizeof(uint16_t))));
146   for (int i = 0; i < 64; i++) {
147     vpx_memset16(CONVERT_TO_SHORTPTR(a), 0, 64);
148     vpx_memset16(CONVERT_TO_SHORTPTR(b), 65535, 64);
149     CONVERT_TO_SHORTPTR(b)[i] = i;  // Set a minimum difference of i.
150 
151     int min, max;
152     ASM_REGISTER_STATE_CHECK(mm_func_(a, 8, b, 8, &min, &max));
153     EXPECT_EQ(65535, max);
154     EXPECT_EQ(i, min);
155   }
156   vpx_free(CONVERT_TO_SHORTPTR(a));
157   vpx_free(CONVERT_TO_SHORTPTR(b));
158 }
159 
TEST_P(HBDMinMaxTest,MaxValue)160 TEST_P(HBDMinMaxTest, MaxValue) {
161   uint8_t *a = CONVERT_TO_BYTEPTR(
162       reinterpret_cast<uint16_t *>(vpx_malloc(64 * sizeof(uint16_t))));
163   uint8_t *b = CONVERT_TO_BYTEPTR(
164       reinterpret_cast<uint16_t *>(vpx_malloc(64 * sizeof(uint16_t))));
165   for (int i = 0; i < 64; i++) {
166     vpx_memset16(CONVERT_TO_SHORTPTR(a), 0, 64);
167     vpx_memset16(CONVERT_TO_SHORTPTR(b), 0, 64);
168     CONVERT_TO_SHORTPTR(b)[i] = i;  // Set a minimum difference of i.
169 
170     int min, max;
171     ASM_REGISTER_STATE_CHECK(mm_func_(a, 8, b, 8, &min, &max));
172     EXPECT_EQ(i, max);
173     EXPECT_EQ(0, min);
174   }
175   vpx_free(CONVERT_TO_SHORTPTR(a));
176   vpx_free(CONVERT_TO_SHORTPTR(b));
177 }
178 
TEST_P(HBDMinMaxTest,CompareReference)179 TEST_P(HBDMinMaxTest, CompareReference) {
180   uint8_t *a = CONVERT_TO_BYTEPTR(
181       reinterpret_cast<uint16_t *>(vpx_malloc(64 * sizeof(uint16_t))));
182   uint8_t *b = CONVERT_TO_BYTEPTR(
183       reinterpret_cast<uint16_t *>(vpx_malloc(64 * sizeof(uint16_t))));
184   for (int j = 0; j < 64; j++) {
185     CONVERT_TO_SHORTPTR(a)[j] = rnd_.Rand16();
186     CONVERT_TO_SHORTPTR(b)[j] = rnd_.Rand16();
187   }
188 
189   int min_ref, max_ref, min, max;
190   highbd_reference_minmax(a, 8, b, 8, &min_ref, &max_ref);
191   ASM_REGISTER_STATE_CHECK(mm_func_(a, 8, b, 8, &min, &max));
192   vpx_free(CONVERT_TO_SHORTPTR(a));
193   vpx_free(CONVERT_TO_SHORTPTR(b));
194   EXPECT_EQ(max_ref, max);
195   EXPECT_EQ(min_ref, min);
196 }
197 
TEST_P(HBDMinMaxTest,CompareReferenceAndVaryStride)198 TEST_P(HBDMinMaxTest, CompareReferenceAndVaryStride) {
199   uint8_t *a = CONVERT_TO_BYTEPTR(
200       reinterpret_cast<uint16_t *>(vpx_malloc((8 * 64) * sizeof(uint16_t))));
201   uint8_t *b = CONVERT_TO_BYTEPTR(
202       reinterpret_cast<uint16_t *>(vpx_malloc((8 * 64) * sizeof(uint16_t))));
203   for (int i = 0; i < 8 * 64; i++) {
204     CONVERT_TO_SHORTPTR(a)[i] = rnd_.Rand16();
205     CONVERT_TO_SHORTPTR(b)[i] = rnd_.Rand16();
206   }
207   for (int a_stride = 8; a_stride <= 64; a_stride += 8) {
208     for (int b_stride = 8; b_stride <= 64; b_stride += 8) {
209       int min_ref, max_ref, min, max;
210       highbd_reference_minmax(a, a_stride, b, b_stride, &min_ref, &max_ref);
211       ASM_REGISTER_STATE_CHECK(mm_func_(a, a_stride, b, b_stride, &min, &max));
212       EXPECT_EQ(max_ref, max)
213           << "when a_stride = " << a_stride << " and b_stride = " << b_stride;
214       EXPECT_EQ(min_ref, min)
215           << "when a_stride = " << a_stride << " and b_stride = " << b_stride;
216     }
217   }
218   vpx_free(CONVERT_TO_SHORTPTR(a));
219   vpx_free(CONVERT_TO_SHORTPTR(b));
220 }
221 #endif
222 
223 INSTANTIATE_TEST_SUITE_P(C, MinMaxTest, ::testing::Values(&vpx_minmax_8x8_c));
224 #if CONFIG_VP9_HIGHBITDEPTH
225 INSTANTIATE_TEST_SUITE_P(C, HBDMinMaxTest,
226                          ::testing::Values(&vpx_highbd_minmax_8x8_c));
227 #endif
228 
229 #if HAVE_SSE2
230 INSTANTIATE_TEST_SUITE_P(SSE2, MinMaxTest,
231                          ::testing::Values(&vpx_minmax_8x8_sse2));
232 #endif
233 
234 #if HAVE_NEON
235 INSTANTIATE_TEST_SUITE_P(NEON, MinMaxTest,
236                          ::testing::Values(&vpx_minmax_8x8_neon));
237 #if CONFIG_VP9_HIGHBITDEPTH
238 INSTANTIATE_TEST_SUITE_P(NEON, HBDMinMaxTest,
239                          ::testing::Values(&vpx_highbd_minmax_8x8_neon));
240 #endif
241 #endif
242 
243 #if HAVE_MSA
244 INSTANTIATE_TEST_SUITE_P(MSA, MinMaxTest,
245                          ::testing::Values(&vpx_minmax_8x8_msa));
246 #endif
247 
248 }  // namespace
249