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