intra_edge_test.cc (9644B)
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 "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 40 ~UpsampleTest() override = default; 41 42 virtual void Execute(T *edge_tst) = 0; 43 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 using UP8B = void (*)(uint8_t *p, int size); 66 using TestFuncs = libaom_test::FuncParam<UP8B>; 67 68 class UpsampleTest8B : public UpsampleTest<UP8B, uint8_t> { 69 protected: 70 void Execute(uint8_t *edge_tst) override { 71 params_.ref_func(edge_ref_, size_); 72 API_REGISTER_STATE_CHECK(params_.tst_func(edge_tst, size_)); 73 } 74 }; 75 76 TEST_P(UpsampleTest8B, RandomValues) { 77 for (int iter = 0; iter < kIterations && !HasFatalFailure(); ++iter) { 78 size_ = 4 * (this->rng_(4) + 1); 79 80 int i, pix = 0; 81 for (i = 0; i < kOffset + size_; ++i) { 82 pix = rng_.Rand8(); 83 edge_ref_data_[i] = pix; 84 edge_tst_data_[i] = edge_ref_data_[i]; 85 } 86 87 // Extend final sample 88 while (i < kBufSize) { 89 edge_ref_data_[i] = pix; 90 edge_tst_data_[i] = pix; 91 i++; 92 } 93 94 Common(); 95 } 96 } 97 98 TEST_P(UpsampleTest8B, DISABLED_Speed) { 99 const int test_count = 10000000; 100 size_ = kMaxEdge; 101 for (int i = 0; i < kOffset + size_; ++i) { 102 edge_tst_data_[i] = rng_.Rand8(); 103 } 104 edge_tst_ = &edge_tst_data_[kOffset]; 105 for (int iter = 0; iter < test_count; ++iter) { 106 API_REGISTER_STATE_CHECK(params_.tst_func(edge_tst_, size_)); 107 } 108 } 109 110 #if HAVE_SSE4_1 111 INSTANTIATE_TEST_SUITE_P( 112 SSE4_1, UpsampleTest8B, 113 ::testing::Values(TestFuncs(av1_upsample_intra_edge_c, 114 av1_upsample_intra_edge_sse4_1))); 115 #endif // HAVE_SSE4_1 116 117 #if HAVE_NEON 118 INSTANTIATE_TEST_SUITE_P( 119 NEON, UpsampleTest8B, 120 ::testing::Values(TestFuncs(av1_upsample_intra_edge_c, 121 av1_upsample_intra_edge_neon))); 122 #endif // HAVE_NEON 123 124 template <typename F, typename T> 125 class FilterEdgeTest : public FunctionEquivalenceTest<F> { 126 protected: 127 static const int kIterations = 1000000; 128 static const int kMaxEdge = 2 * 64; 129 static const int kBufSize = kMaxEdge + 32; 130 static const int kOffset = 15; 131 132 ~FilterEdgeTest() override = default; 133 134 virtual void Execute(T *edge_tst) = 0; 135 136 void Common() { 137 edge_ref_ = &edge_ref_data_[kOffset]; 138 edge_tst_ = &edge_tst_data_[kOffset]; 139 140 Execute(edge_tst_); 141 142 for (int r = 0; r < size_; ++r) { 143 ASSERT_EQ(edge_ref_[r], edge_tst_[r]); 144 } 145 } 146 147 T edge_ref_data_[kBufSize]; 148 T edge_tst_data_[kBufSize]; 149 150 T *edge_ref_; 151 T *edge_tst_; 152 153 int size_; 154 int strength_; 155 }; 156 157 using FE8B = void (*)(uint8_t *p, int size, int strength); 158 using FilterEdgeTestFuncs = libaom_test::FuncParam<FE8B>; 159 160 class FilterEdgeTest8B : public FilterEdgeTest<FE8B, uint8_t> { 161 protected: 162 void Execute(uint8_t *edge_tst) override { 163 params_.ref_func(edge_ref_, size_, strength_); 164 API_REGISTER_STATE_CHECK(params_.tst_func(edge_tst, size_, strength_)); 165 } 166 }; 167 168 TEST_P(FilterEdgeTest8B, RandomValues) { 169 for (int iter = 0; iter < kIterations && !HasFatalFailure(); ++iter) { 170 strength_ = this->rng_(4); 171 size_ = 4 * (this->rng_(128 / 4) + 1) + 1; 172 173 int i, pix = 0; 174 for (i = 0; i < kOffset + size_; ++i) { 175 pix = rng_.Rand8(); 176 edge_ref_data_[i] = pix; 177 edge_tst_data_[i] = pix; 178 } 179 180 Common(); 181 } 182 } 183 184 TEST_P(FilterEdgeTest8B, DISABLED_Speed) { 185 const int test_count = 10000000; 186 size_ = kMaxEdge; 187 strength_ = 1; 188 for (int i = 0; i < kOffset + size_; ++i) { 189 edge_tst_data_[i] = rng_.Rand8(); 190 } 191 edge_tst_ = &edge_tst_data_[kOffset]; 192 for (int iter = 0; iter < test_count; ++iter) { 193 API_REGISTER_STATE_CHECK(params_.tst_func(edge_tst_, size_, strength_)); 194 // iterate over filter strengths (1,2,3) 195 strength_ = strength_ == 3 ? 1 : strength_ + 1; 196 } 197 } 198 199 #if HAVE_SSE4_1 200 INSTANTIATE_TEST_SUITE_P( 201 SSE4_1, FilterEdgeTest8B, 202 ::testing::Values(FilterEdgeTestFuncs(av1_filter_intra_edge_c, 203 av1_filter_intra_edge_sse4_1))); 204 #endif // HAVE_SSE4_1 205 206 #if HAVE_NEON 207 INSTANTIATE_TEST_SUITE_P( 208 NEON, FilterEdgeTest8B, 209 ::testing::Values(FilterEdgeTestFuncs(av1_filter_intra_edge_c, 210 av1_filter_intra_edge_neon))); 211 #endif // HAVE_NEON 212 213 #if CONFIG_AV1_HIGHBITDEPTH 214 215 using UPHB = void (*)(uint16_t *p, int size, int bd); 216 using TestFuncsHBD = libaom_test::FuncParam<UPHB>; 217 218 class UpsampleTestHB : public UpsampleTest<UPHB, uint16_t> { 219 protected: 220 void Execute(uint16_t *edge_tst) override { 221 params_.ref_func(edge_ref_, size_, bit_depth_); 222 API_REGISTER_STATE_CHECK(params_.tst_func(edge_tst, size_, bit_depth_)); 223 } 224 int bit_depth_; 225 }; 226 227 TEST_P(UpsampleTestHB, RandomValues) { 228 for (int iter = 0; iter < kIterations && !HasFatalFailure(); ++iter) { 229 switch (rng_(3)) { 230 case 0: bit_depth_ = 8; break; 231 case 1: bit_depth_ = 10; break; 232 default: bit_depth_ = 12; break; 233 } 234 const int hi = 1 << bit_depth_; 235 236 size_ = 4 * (this->rng_(4) + 1); 237 238 int i, pix = 0; 239 for (i = 0; i < kOffset + size_; ++i) { 240 pix = rng_(hi); 241 edge_ref_data_[i] = pix; 242 edge_tst_data_[i] = pix; 243 } 244 245 // Extend final sample 246 while (i < kBufSize) { 247 edge_ref_data_[i] = pix; 248 edge_tst_data_[i] = pix; 249 i++; 250 } 251 252 Common(); 253 } 254 } 255 256 TEST_P(UpsampleTestHB, DISABLED_Speed) { 257 const int test_count = 10000000; 258 size_ = kMaxEdge; 259 bit_depth_ = 12; 260 const int hi = 1 << bit_depth_; 261 for (int i = 0; i < kOffset + size_; ++i) { 262 edge_tst_data_[i] = rng_(hi); 263 } 264 edge_tst_ = &edge_tst_data_[kOffset]; 265 for (int iter = 0; iter < test_count; ++iter) { 266 API_REGISTER_STATE_CHECK(params_.tst_func(edge_tst_, size_, bit_depth_)); 267 } 268 } 269 270 #if HAVE_SSE4_1 271 INSTANTIATE_TEST_SUITE_P( 272 SSE4_1, UpsampleTestHB, 273 ::testing::Values(TestFuncsHBD(av1_highbd_upsample_intra_edge_c, 274 av1_highbd_upsample_intra_edge_sse4_1))); 275 #endif // HAVE_SSE4_1 276 277 #if HAVE_NEON 278 INSTANTIATE_TEST_SUITE_P( 279 NEON, UpsampleTestHB, 280 ::testing::Values(TestFuncsHBD(av1_highbd_upsample_intra_edge_c, 281 av1_highbd_upsample_intra_edge_neon))); 282 #endif // HAVE_NEON 283 284 using FEHB = void (*)(uint16_t *p, int size, int strength); 285 using FilterEdgeTestFuncsHBD = libaom_test::FuncParam<FEHB>; 286 287 class FilterEdgeTestHB : public FilterEdgeTest<FEHB, uint16_t> { 288 protected: 289 void Execute(uint16_t *edge_tst) override { 290 params_.ref_func(edge_ref_, size_, strength_); 291 API_REGISTER_STATE_CHECK(params_.tst_func(edge_tst, size_, strength_)); 292 } 293 int bit_depth_; 294 }; 295 296 TEST_P(FilterEdgeTestHB, RandomValues) { 297 for (int iter = 0; iter < kIterations && !HasFatalFailure(); ++iter) { 298 switch (rng_(3)) { 299 case 0: bit_depth_ = 8; break; 300 case 1: bit_depth_ = 10; break; 301 default: bit_depth_ = 12; break; 302 } 303 const int hi = 1 << bit_depth_; 304 strength_ = this->rng_(4); 305 size_ = 4 * (this->rng_(128 / 4) + 1) + 1; 306 307 int i, pix = 0; 308 for (i = 0; i < kOffset + size_; ++i) { 309 pix = rng_(hi); 310 edge_ref_data_[i] = pix; 311 edge_tst_data_[i] = pix; 312 } 313 314 Common(); 315 } 316 } 317 318 TEST_P(FilterEdgeTestHB, DISABLED_Speed) { 319 const int test_count = 10000000; 320 size_ = kMaxEdge; 321 strength_ = 1; 322 bit_depth_ = 12; 323 const int hi = 1 << bit_depth_; 324 for (int i = 0; i < kOffset + size_; ++i) { 325 edge_tst_data_[i] = rng_(hi); 326 } 327 edge_tst_ = &edge_tst_data_[kOffset]; 328 for (int iter = 0; iter < test_count; ++iter) { 329 API_REGISTER_STATE_CHECK(params_.tst_func(edge_tst_, size_, strength_)); 330 // iterate over filter strengths (1,2,3) 331 strength_ = strength_ == 3 ? 1 : strength_ + 1; 332 } 333 } 334 335 #if HAVE_SSE4_1 336 INSTANTIATE_TEST_SUITE_P(SSE4_1, FilterEdgeTestHB, 337 ::testing::Values(FilterEdgeTestFuncsHBD( 338 av1_highbd_filter_intra_edge_c, 339 av1_highbd_filter_intra_edge_sse4_1))); 340 #endif // HAVE_SSE4_1 341 342 #if HAVE_NEON 343 INSTANTIATE_TEST_SUITE_P(NEON, FilterEdgeTestHB, 344 ::testing::Values(FilterEdgeTestFuncsHBD( 345 av1_highbd_filter_intra_edge_c, 346 av1_highbd_filter_intra_edge_neon))); 347 #endif // HAVE_NEON 348 349 #endif // CONFIG_AV1_HIGHBITDEPTH 350 351 } // namespace