• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2017, Alliance for Open Media. All rights reserved
3  *
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.
10  */
11 
12 #include <math.h>
13 #include <stdlib.h>
14 #include <string.h>
15 
16 #include "third_party/googletest/src/googletest/include/gtest/gtest.h"
17 #include "test/register_state_check.h"
18 #include "test/function_equivalence_test.h"
19 
20 #include "config/aom_config.h"
21 #include "config/aom_dsp_rtcd.h"
22 #include "config/av1_rtcd.h"
23 
24 #include "aom/aom_integer.h"
25 #include "av1/common/enums.h"
26 
27 using libaom_test::FunctionEquivalenceTest;
28 
29 namespace {
30 
31 template <typename F, typename T>
32 class UpsampleTest : public FunctionEquivalenceTest<F> {
33  protected:
34   static const int kIterations = 1000000;
35   static const int kMinEdge = 4;
36   static const int kMaxEdge = 24;
37   static const int kBufSize = 2 * 64 + 32;
38   static const int kOffset = 16;
39 
~UpsampleTest()40   virtual ~UpsampleTest() {}
41 
42   virtual void Execute(T *edge_tst) = 0;
43 
Common()44   void Common() {
45     edge_ref_ = &edge_ref_data_[kOffset];
46     edge_tst_ = &edge_tst_data_[kOffset];
47 
48     Execute(edge_tst_);
49 
50     const int max_idx = (size_ - 1) * 2;
51     for (int r = -2; r <= max_idx; ++r) {
52       ASSERT_EQ(edge_ref_[r], edge_tst_[r]);
53     }
54   }
55 
56   T edge_ref_data_[kBufSize];
57   T edge_tst_data_[kBufSize];
58 
59   T *edge_ref_;
60   T *edge_tst_;
61 
62   int size_;
63 };
64 
65 //////////////////////////////////////////////////////////////////////////////
66 // 8 bit version
67 //////////////////////////////////////////////////////////////////////////////
68 
69 typedef void (*UP8B)(uint8_t *p, int size);
70 typedef libaom_test::FuncParam<UP8B> TestFuncs;
71 
72 class UpsampleTest8B : public UpsampleTest<UP8B, uint8_t> {
73  protected:
Execute(uint8_t * edge_tst)74   void Execute(uint8_t *edge_tst) {
75     params_.ref_func(edge_ref_, size_);
76     API_REGISTER_STATE_CHECK(params_.tst_func(edge_tst, size_));
77   }
78 };
79 
TEST_P(UpsampleTest8B,RandomValues)80 TEST_P(UpsampleTest8B, RandomValues) {
81   for (int iter = 0; iter < kIterations && !HasFatalFailure(); ++iter) {
82     size_ = 4 * (this->rng_(4) + 1);
83 
84     int i, pix = 0;
85     for (i = 0; i < kOffset + size_; ++i) {
86       pix = rng_.Rand8();
87       edge_ref_data_[i] = pix;
88       edge_tst_data_[i] = edge_ref_data_[i];
89     }
90 
91     // Extend final sample
92     while (i < kBufSize) {
93       edge_ref_data_[i] = pix;
94       edge_tst_data_[i] = pix;
95       i++;
96     }
97 
98     Common();
99   }
100 }
101 
102 #if HAVE_SSE4_1
103 INSTANTIATE_TEST_SUITE_P(
104     SSE4_1, UpsampleTest8B,
105     ::testing::Values(TestFuncs(av1_upsample_intra_edge_c,
106                                 av1_upsample_intra_edge_sse4_1)));
107 #endif  // HAVE_SSE4_1
108 
109 //////////////////////////////////////////////////////////////////////////////
110 // High bit-depth version
111 //////////////////////////////////////////////////////////////////////////////
112 
113 typedef void (*UPHB)(uint16_t *p, int size, int bd);
114 typedef libaom_test::FuncParam<UPHB> TestFuncsHBD;
115 
116 class UpsampleTestHB : public UpsampleTest<UPHB, uint16_t> {
117  protected:
Execute(uint16_t * edge_tst)118   void Execute(uint16_t *edge_tst) {
119     params_.ref_func(edge_ref_, size_, bit_depth_);
120     API_REGISTER_STATE_CHECK(params_.tst_func(edge_tst, size_, bit_depth_));
121   }
122   int bit_depth_;
123 };
124 
TEST_P(UpsampleTestHB,RandomValues)125 TEST_P(UpsampleTestHB, RandomValues) {
126   for (int iter = 0; iter < kIterations && !HasFatalFailure(); ++iter) {
127     switch (rng_(3)) {
128       case 0: bit_depth_ = 8; break;
129       case 1: bit_depth_ = 10; break;
130       default: bit_depth_ = 12; break;
131     }
132     const int hi = 1 << bit_depth_;
133 
134     size_ = 4 * (this->rng_(4) + 1);
135 
136     int i, pix = 0;
137     for (i = 0; i < kOffset + size_; ++i) {
138       pix = rng_(hi);
139       edge_ref_data_[i] = pix;
140       edge_tst_data_[i] = pix;
141     }
142 
143     // Extend final sample
144     while (i < kBufSize) {
145       edge_ref_data_[i] = pix;
146       edge_tst_data_[i] = pix;
147       i++;
148     }
149 
150     Common();
151   }
152 }
153 
154 #if HAVE_SSE4_1
155 INSTANTIATE_TEST_SUITE_P(
156     SSE4_1, UpsampleTestHB,
157     ::testing::Values(TestFuncsHBD(av1_upsample_intra_edge_high_c,
158                                    av1_upsample_intra_edge_high_sse4_1)));
159 #endif  // HAVE_SSE4_1
160 
161 template <typename F, typename T>
162 class FilterEdgeTest : public FunctionEquivalenceTest<F> {
163  protected:
164   static const int kIterations = 1000000;
165   static const int kMaxEdge = 2 * 64;
166   static const int kBufSize = kMaxEdge + 32;
167   static const int kOffset = 15;
168 
~FilterEdgeTest()169   virtual ~FilterEdgeTest() {}
170 
171   virtual void Execute(T *edge_tst) = 0;
172 
Common()173   void Common() {
174     edge_ref_ = &edge_ref_data_[kOffset];
175     edge_tst_ = &edge_tst_data_[kOffset];
176 
177     Execute(edge_tst_);
178 
179     for (int r = 0; r < size_; ++r) {
180       ASSERT_EQ(edge_ref_[r], edge_tst_[r]);
181     }
182   }
183 
184   T edge_ref_data_[kBufSize];
185   T edge_tst_data_[kBufSize];
186 
187   T *edge_ref_;
188   T *edge_tst_;
189 
190   int size_;
191   int strength_;
192 };
193 
194 //////////////////////////////////////////////////////////////////////////////
195 // 8 bit version
196 //////////////////////////////////////////////////////////////////////////////
197 
198 typedef void (*FE8B)(uint8_t *p, int size, int strength);
199 typedef libaom_test::FuncParam<FE8B> FilterEdgeTestFuncs;
200 
201 class FilterEdgeTest8B : public FilterEdgeTest<FE8B, uint8_t> {
202  protected:
Execute(uint8_t * edge_tst)203   void Execute(uint8_t *edge_tst) {
204     params_.ref_func(edge_ref_, size_, strength_);
205     API_REGISTER_STATE_CHECK(params_.tst_func(edge_tst, size_, strength_));
206   }
207 };
208 
TEST_P(FilterEdgeTest8B,RandomValues)209 TEST_P(FilterEdgeTest8B, RandomValues) {
210   for (int iter = 0; iter < kIterations && !HasFatalFailure(); ++iter) {
211     strength_ = this->rng_(4);
212     size_ = 4 * (this->rng_(128 / 4) + 1) + 1;
213 
214     int i, pix = 0;
215     for (i = 0; i < kOffset + size_; ++i) {
216       pix = rng_.Rand8();
217       edge_ref_data_[i] = pix;
218       edge_tst_data_[i] = pix;
219     }
220 
221     Common();
222   }
223 }
224 
225 #if HAVE_SSE4_1
226 INSTANTIATE_TEST_SUITE_P(
227     SSE4_1, FilterEdgeTest8B,
228     ::testing::Values(FilterEdgeTestFuncs(av1_filter_intra_edge_c,
229                                           av1_filter_intra_edge_sse4_1)));
230 #endif  // HAVE_SSE4_1
231 
232 //////////////////////////////////////////////////////////////////////////////
233 // High bit-depth version
234 //////////////////////////////////////////////////////////////////////////////
235 
236 typedef void (*FEHB)(uint16_t *p, int size, int strength);
237 typedef libaom_test::FuncParam<FEHB> FilterEdgeTestFuncsHBD;
238 
239 class FilterEdgeTestHB : public FilterEdgeTest<FEHB, uint16_t> {
240  protected:
Execute(uint16_t * edge_tst)241   void Execute(uint16_t *edge_tst) {
242     params_.ref_func(edge_ref_, size_, strength_);
243     API_REGISTER_STATE_CHECK(params_.tst_func(edge_tst, size_, strength_));
244   }
245   int bit_depth_;
246 };
247 
TEST_P(FilterEdgeTestHB,RandomValues)248 TEST_P(FilterEdgeTestHB, RandomValues) {
249   for (int iter = 0; iter < kIterations && !HasFatalFailure(); ++iter) {
250     switch (rng_(3)) {
251       case 0: bit_depth_ = 8; break;
252       case 1: bit_depth_ = 10; break;
253       default: bit_depth_ = 12; break;
254     }
255     const int hi = 1 << bit_depth_;
256     strength_ = this->rng_(4);
257     size_ = 4 * (this->rng_(128 / 4) + 1) + 1;
258 
259     int i, pix = 0;
260     for (i = 0; i < kOffset + size_; ++i) {
261       pix = rng_(hi);
262       edge_ref_data_[i] = pix;
263       edge_tst_data_[i] = pix;
264     }
265 
266     Common();
267   }
268 }
269 
270 #if HAVE_SSE4_1
271 INSTANTIATE_TEST_SUITE_P(SSE4_1, FilterEdgeTestHB,
272                          ::testing::Values(FilterEdgeTestFuncsHBD(
273                              av1_filter_intra_edge_high_c,
274                              av1_filter_intra_edge_high_sse4_1)));
275 #endif  // HAVE_SSE4_1
276 
277 // Speed tests
278 
TEST_P(UpsampleTest8B,DISABLED_Speed)279 TEST_P(UpsampleTest8B, DISABLED_Speed) {
280   const int test_count = 10000000;
281   size_ = kMaxEdge;
282   for (int i = 0; i < kOffset + size_; ++i) {
283     edge_tst_data_[i] = rng_.Rand8();
284   }
285   edge_tst_ = &edge_tst_data_[kOffset];
286   for (int iter = 0; iter < test_count; ++iter) {
287     API_REGISTER_STATE_CHECK(params_.tst_func(edge_tst_, size_));
288   }
289 }
290 
TEST_P(UpsampleTestHB,DISABLED_Speed)291 TEST_P(UpsampleTestHB, DISABLED_Speed) {
292   const int test_count = 10000000;
293   size_ = kMaxEdge;
294   bit_depth_ = 12;
295   const int hi = 1 << bit_depth_;
296   for (int i = 0; i < kOffset + size_; ++i) {
297     edge_tst_data_[i] = rng_(hi);
298   }
299   edge_tst_ = &edge_tst_data_[kOffset];
300   for (int iter = 0; iter < test_count; ++iter) {
301     API_REGISTER_STATE_CHECK(params_.tst_func(edge_tst_, size_, bit_depth_));
302   }
303 }
304 
TEST_P(FilterEdgeTest8B,DISABLED_Speed)305 TEST_P(FilterEdgeTest8B, DISABLED_Speed) {
306   const int test_count = 10000000;
307   size_ = kMaxEdge;
308   strength_ = 1;
309   for (int i = 0; i < kOffset + size_; ++i) {
310     edge_tst_data_[i] = rng_.Rand8();
311   }
312   edge_tst_ = &edge_tst_data_[kOffset];
313   for (int iter = 0; iter < test_count; ++iter) {
314     API_REGISTER_STATE_CHECK(params_.tst_func(edge_tst_, size_, strength_));
315     // iterate over filter strengths (1,2,3)
316     strength_ = (strength_ == 3) ? 1 : strength_ + 1;
317   }
318 }
319 
TEST_P(FilterEdgeTestHB,DISABLED_Speed)320 TEST_P(FilterEdgeTestHB, DISABLED_Speed) {
321   const int test_count = 10000000;
322   size_ = kMaxEdge;
323   strength_ = 1;
324   bit_depth_ = 12;
325   const int hi = 1 << bit_depth_;
326   for (int i = 0; i < kOffset + size_; ++i) {
327     edge_tst_data_[i] = rng_(hi);
328   }
329   edge_tst_ = &edge_tst_data_[kOffset];
330   for (int iter = 0; iter < test_count; ++iter) {
331     API_REGISTER_STATE_CHECK(params_.tst_func(edge_tst_, size_, strength_));
332     // iterate over filter strengths (1,2,3)
333     strength_ = (strength_ == 3) ? 1 : strength_ + 1;
334   }
335 }
336 
337 }  // namespace
338