1 // Copyright 2021 The libgav1 Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "src/dsp/intrapred_cfl.h"
16
17 #include <cmath>
18 #include <cstddef>
19 #include <cstdint>
20 #include <cstring>
21 #include <memory>
22 #include <ostream>
23
24 #include "absl/strings/match.h"
25 #include "absl/time/clock.h"
26 #include "absl/time/time.h"
27 #include "gtest/gtest.h"
28 #include "src/dsp/constants.h"
29 #include "src/dsp/dsp.h"
30 #include "src/utils/common.h"
31 #include "src/utils/compiler_attributes.h"
32 #include "src/utils/constants.h"
33 #include "src/utils/cpu.h"
34 #include "src/utils/memory.h"
35 #include "tests/block_utils.h"
36 #include "tests/third_party/libvpx/acm_random.h"
37 #include "tests/utils.h"
38
39 namespace libgav1 {
40 namespace dsp {
41 namespace {
42
43 constexpr int kMaxBlockSize = 64;
44 constexpr int kTotalPixels = kMaxBlockSize * kMaxBlockSize;
45
46 const char* const kCflIntraPredName = "kCflIntraPredictor";
47
48 template <int bitdepth, typename Pixel>
49 class IntraPredTestBase : public testing::TestWithParam<TransformSize>,
50 public test_utils::MaxAlignedAllocable {
51 public:
52 static_assert(bitdepth >= kBitdepth8 && bitdepth <= LIBGAV1_MAX_BITDEPTH, "");
IntraPredTestBase()53 IntraPredTestBase() {
54 switch (tx_size_) {
55 case kNumTransformSizes:
56 EXPECT_NE(tx_size_, kNumTransformSizes);
57 break;
58 default:
59 block_width_ = kTransformWidth[tx_size_];
60 block_height_ = kTransformHeight[tx_size_];
61 break;
62 }
63 }
64
65 IntraPredTestBase(const IntraPredTestBase&) = delete;
66 IntraPredTestBase& operator=(const IntraPredTestBase&) = delete;
67 ~IntraPredTestBase() override = default;
68
69 protected:
70 struct IntraPredMem {
Resetlibgav1::dsp::__anon0712f7390111::IntraPredTestBase::IntraPredMem71 void Reset(libvpx_test::ACMRandom* rnd) {
72 ASSERT_NE(rnd, nullptr);
73 Pixel* const left = left_mem + 16;
74 Pixel* const top = top_mem + 16;
75 const int mask = (1 << bitdepth) - 1;
76 for (auto& r : ref_src) r = rnd->Rand16() & mask;
77 for (int i = 0; i < kMaxBlockSize; ++i) left[i] = rnd->Rand16() & mask;
78 for (int i = -1; i < kMaxBlockSize; ++i) top[i] = rnd->Rand16() & mask;
79
80 // Some directional predictors require top-right, bottom-left.
81 for (int i = kMaxBlockSize; i < 2 * kMaxBlockSize; ++i) {
82 left[i] = rnd->Rand16() & mask;
83 top[i] = rnd->Rand16() & mask;
84 }
85 // TODO(jzern): reorder this and regenerate the digests after switching
86 // random number generators.
87 // Upsampling in the directional predictors extends left/top[-1] to [-2].
88 left[-1] = rnd->Rand16() & mask;
89 left[-2] = rnd->Rand16() & mask;
90 top[-2] = rnd->Rand16() & mask;
91 memset(left_mem, 0, sizeof(left_mem[0]) * 14);
92 memset(top_mem, 0, sizeof(top_mem[0]) * 14);
93 memset(top_mem + kMaxBlockSize * 2 + 16, 0,
94 sizeof(top_mem[0]) * kTopMemPadding);
95 }
96
97 // Set ref_src, top-left, top and left to |pixel|.
Setlibgav1::dsp::__anon0712f7390111::IntraPredTestBase::IntraPredMem98 void Set(const Pixel pixel) {
99 Pixel* const left = left_mem + 16;
100 Pixel* const top = top_mem + 16;
101 for (auto& r : ref_src) r = pixel;
102 // Upsampling in the directional predictors extends left/top[-1] to [-2].
103 for (int i = -2; i < 2 * kMaxBlockSize; ++i) {
104 left[i] = top[i] = pixel;
105 }
106 }
107
108 // DirectionalZone1_Large() overreads up to 7 pixels in |top_mem|.
109 static constexpr int kTopMemPadding = 7;
110 alignas(kMaxAlignment) Pixel dst[kTotalPixels];
111 alignas(kMaxAlignment) Pixel ref_src[kTotalPixels];
112 alignas(kMaxAlignment) Pixel left_mem[kMaxBlockSize * 2 + 16];
113 alignas(
114 kMaxAlignment) Pixel top_mem[kMaxBlockSize * 2 + 16 + kTopMemPadding];
115 };
116
SetUp()117 void SetUp() override { test_utils::ResetDspTable(bitdepth); }
118
119 const TransformSize tx_size_ = GetParam();
120 int block_width_;
121 int block_height_;
122 IntraPredMem intra_pred_mem_;
123 };
124
125 //------------------------------------------------------------------------------
126 // CflIntraPredTest
127
128 template <int bitdepth, typename Pixel>
129 class CflIntraPredTest : public IntraPredTestBase<bitdepth, Pixel> {
130 public:
131 static_assert(bitdepth >= kBitdepth8 && bitdepth <= LIBGAV1_MAX_BITDEPTH, "");
132 CflIntraPredTest() = default;
133 CflIntraPredTest(const CflIntraPredTest&) = delete;
134 CflIntraPredTest& operator=(const CflIntraPredTest&) = delete;
135 ~CflIntraPredTest() override = default;
136
137 protected:
138 using IntraPredTestBase<bitdepth, Pixel>::tx_size_;
139 using IntraPredTestBase<bitdepth, Pixel>::block_width_;
140 using IntraPredTestBase<bitdepth, Pixel>::block_height_;
141 using IntraPredTestBase<bitdepth, Pixel>::intra_pred_mem_;
142
SetUp()143 void SetUp() override {
144 IntraPredTestBase<bitdepth, Pixel>::SetUp();
145 IntraPredCflInit_C();
146
147 const Dsp* const dsp = GetDspTable(bitdepth);
148 ASSERT_NE(dsp, nullptr);
149 base_cfl_intra_pred_ = dsp->cfl_intra_predictors[tx_size_];
150
151 const testing::TestInfo* const test_info =
152 testing::UnitTest::GetInstance()->current_test_info();
153 const char* const test_case = test_info->test_suite_name();
154 if (absl::StartsWith(test_case, "C/")) {
155 base_cfl_intra_pred_ = nullptr;
156 } else if (absl::StartsWith(test_case, "NEON/")) {
157 IntraPredCflInit_NEON();
158 } else if (absl::StartsWith(test_case, "SSE41/")) {
159 if ((GetCpuInfo() & kSSE4_1) == 0) GTEST_SKIP() << "No SSE4.1 support!";
160 IntraPredCflInit_SSE4_1();
161 } else {
162 FAIL() << "Unrecognized architecture prefix in test case name: "
163 << test_case;
164 }
165
166 cur_cfl_intra_pred_ = dsp->cfl_intra_predictors[tx_size_];
167
168 if (cur_cfl_intra_pred_ == base_cfl_intra_pred_) {
169 cur_cfl_intra_pred_ = nullptr;
170 }
171 }
172
173 // This test modifies intra_pred_mem_.
174 void TestSpeed(const char* digest, int num_runs);
175 void TestSaturatedValues();
176 void TestRandomValues();
177
178 CflIntraPredictorFunc base_cfl_intra_pred_;
179 CflIntraPredictorFunc cur_cfl_intra_pred_;
180 };
181
182 template <int bitdepth, typename Pixel>
TestSpeed(const char * const digest,const int num_runs)183 void CflIntraPredTest<bitdepth, Pixel>::TestSpeed(const char* const digest,
184 const int num_runs) {
185 if (cur_cfl_intra_pred_ == nullptr) return;
186 libvpx_test::ACMRandom rnd(libvpx_test::ACMRandom::DeterministicSeed());
187 int16_t luma[kCflLumaBufferStride][kCflLumaBufferStride] = {};
188 const int alpha = rnd(33) - 16;
189 const int dc = rnd(1 << bitdepth);
190 const int max_luma = ((1 << bitdepth) - 1) << 3;
191 for (int i = 0; i < block_height_; ++i) {
192 for (int j = 0; j < block_width_; ++j) {
193 if (i < kCflLumaBufferStride && j < kCflLumaBufferStride) {
194 luma[i][j] = max_luma - rnd(max_luma << 1);
195 }
196 }
197 }
198 for (auto& r : intra_pred_mem_.ref_src) r = dc;
199
200 absl::Duration elapsed_time;
201 for (int run = 0; run < num_runs; ++run) {
202 const ptrdiff_t stride = kMaxBlockSize * sizeof(Pixel);
203 memcpy(intra_pred_mem_.dst, intra_pred_mem_.ref_src,
204 sizeof(intra_pred_mem_.dst));
205 const absl::Time start = absl::Now();
206 cur_cfl_intra_pred_(intra_pred_mem_.dst, stride, luma, alpha);
207 elapsed_time += absl::Now() - start;
208 }
209 test_utils::CheckMd5Digest(ToString(tx_size_), kCflIntraPredName, digest,
210 intra_pred_mem_.dst, sizeof(intra_pred_mem_.dst),
211 elapsed_time);
212 }
213
214 template <int bitdepth, typename Pixel>
TestSaturatedValues()215 void CflIntraPredTest<bitdepth, Pixel>::TestSaturatedValues() {
216 // Skip the 'C' test case as this is used as the reference.
217 if (base_cfl_intra_pred_ == nullptr) return;
218
219 int16_t luma_buffer[kCflLumaBufferStride][kCflLumaBufferStride];
220 for (auto& line : luma_buffer) {
221 for (auto& luma : line) luma = ((1 << bitdepth) - 1) << 3;
222 }
223
224 libvpx_test::ACMRandom rnd(libvpx_test::ACMRandom::DeterministicSeed());
225 static constexpr int kSaturatedAlpha[] = {-16, 16};
226 for (const int alpha : kSaturatedAlpha) {
227 for (auto& r : intra_pred_mem_.ref_src) r = (1 << bitdepth) - 1;
228 memcpy(intra_pred_mem_.dst, intra_pred_mem_.ref_src,
229 sizeof(intra_pred_mem_.dst));
230 const ptrdiff_t stride = kMaxBlockSize * sizeof(Pixel);
231 base_cfl_intra_pred_(intra_pred_mem_.ref_src, stride, luma_buffer, alpha);
232 cur_cfl_intra_pred_(intra_pred_mem_.dst, stride, luma_buffer, alpha);
233 if (!test_utils::CompareBlocks(intra_pred_mem_.dst, intra_pred_mem_.ref_src,
234 block_width_, block_height_, kMaxBlockSize,
235 kMaxBlockSize, true)) {
236 ADD_FAILURE() << "Result from optimized version of CFL with alpha "
237 << alpha << " differs from reference.";
238 break;
239 }
240 }
241 }
242
243 template <int bitdepth, typename Pixel>
TestRandomValues()244 void CflIntraPredTest<bitdepth, Pixel>::TestRandomValues() {
245 // Skip the 'C' test case as this is used as the reference.
246 if (base_cfl_intra_pred_ == nullptr) return;
247 int16_t luma_buffer[kCflLumaBufferStride][kCflLumaBufferStride];
248
249 const int max_luma = ((1 << bitdepth) - 1) << 3;
250 // Use an alternate seed to differentiate this test from TestSpeed().
251 libvpx_test::ACMRandom rnd(test_utils::kAlternateDeterministicSeed);
252 for (auto& line : luma_buffer) {
253 for (auto& luma : line) luma = max_luma - rnd(max_luma << 1);
254 }
255 const int dc = rnd(1 << bitdepth);
256 for (auto& r : intra_pred_mem_.ref_src) r = dc;
257 static constexpr int kSaturatedAlpha[] = {-16, 16};
258 for (const int alpha : kSaturatedAlpha) {
259 intra_pred_mem_.Reset(&rnd);
260 memcpy(intra_pred_mem_.dst, intra_pred_mem_.ref_src,
261 sizeof(intra_pred_mem_.dst));
262 const ptrdiff_t stride = kMaxBlockSize * sizeof(Pixel);
263 base_cfl_intra_pred_(intra_pred_mem_.ref_src, stride, luma_buffer, alpha);
264 cur_cfl_intra_pred_(intra_pred_mem_.dst, stride, luma_buffer, alpha);
265 if (!test_utils::CompareBlocks(intra_pred_mem_.dst, intra_pred_mem_.ref_src,
266 block_width_, block_height_, kMaxBlockSize,
267 kMaxBlockSize, true)) {
268 ADD_FAILURE() << "Result from optimized version of CFL with alpha "
269 << alpha << " differs from reference.";
270 break;
271 }
272 }
273 }
274
275 template <int bitdepth, typename Pixel, SubsamplingType subsampling_type>
276 class CflSubsamplerTest : public IntraPredTestBase<bitdepth, Pixel> {
277 public:
278 static_assert(bitdepth >= kBitdepth8 && bitdepth <= LIBGAV1_MAX_BITDEPTH, "");
279 CflSubsamplerTest() = default;
280 CflSubsamplerTest(const CflSubsamplerTest&) = delete;
281 CflSubsamplerTest& operator=(const CflSubsamplerTest&) = delete;
282 ~CflSubsamplerTest() override = default;
283
284 protected:
285 using IntraPredTestBase<bitdepth, Pixel>::tx_size_;
286 using IntraPredTestBase<bitdepth, Pixel>::block_width_;
287 using IntraPredTestBase<bitdepth, Pixel>::block_height_;
288 using IntraPredTestBase<bitdepth, Pixel>::intra_pred_mem_;
289
SetUp()290 void SetUp() override {
291 IntraPredTestBase<bitdepth, Pixel>::SetUp();
292 IntraPredCflInit_C();
293
294 const Dsp* const dsp = GetDspTable(bitdepth);
295 ASSERT_NE(dsp, nullptr);
296 base_cfl_subsampler_ = dsp->cfl_subsamplers[tx_size_][subsampling_type];
297
298 const testing::TestInfo* const test_info =
299 testing::UnitTest::GetInstance()->current_test_info();
300 const char* const test_case = test_info->test_suite_name();
301 if (absl::StartsWith(test_case, "C/")) {
302 base_cfl_subsampler_ = nullptr;
303 } else if (absl::StartsWith(test_case, "NEON/")) {
304 IntraPredCflInit_NEON();
305 } else if (absl::StartsWith(test_case, "SSE41/")) {
306 if ((GetCpuInfo() & kSSE4_1) == 0) GTEST_SKIP() << "No SSE4.1 support!";
307 IntraPredCflInit_SSE4_1();
308 } else {
309 FAIL() << "Unrecognized architecture prefix in test case name: "
310 << test_case;
311 }
312 cur_cfl_subsampler_ = dsp->cfl_subsamplers[tx_size_][subsampling_type];
313 }
314
315 // This test modifies intra_pred_mem_.
316 void TestSpeed(const char* digest, int num_runs);
317 void TestSaturatedValues();
318 void TestRandomValues();
319
SubsamplingType() const320 enum SubsamplingType SubsamplingType() const { return subsampling_type; }
321
322 CflSubsamplerFunc base_cfl_subsampler_;
323 CflSubsamplerFunc cur_cfl_subsampler_;
324 };
325
326 // There is no case where both source and output have lowest height or width
327 // when that dimension is subsampled.
GetLumaWidth(int block_width,SubsamplingType subsampling_type)328 int GetLumaWidth(int block_width, SubsamplingType subsampling_type) {
329 if (block_width == 4) {
330 const int width_shift =
331 static_cast<int>(subsampling_type != kSubsamplingType444);
332 return block_width << width_shift;
333 }
334 return block_width;
335 }
336
GetLumaHeight(int block_height,SubsamplingType subsampling_type)337 int GetLumaHeight(int block_height, SubsamplingType subsampling_type) {
338 if (block_height == 4) {
339 const int height_shift =
340 static_cast<int>(subsampling_type == kSubsamplingType420);
341 return block_height << height_shift;
342 }
343 return block_height;
344 }
345
346 template <int bitdepth, typename Pixel, SubsamplingType subsampling_type>
TestSpeed(const char * const digest,const int num_runs)347 void CflSubsamplerTest<bitdepth, Pixel, subsampling_type>::TestSpeed(
348 const char* const digest, const int num_runs) {
349 // C declines initializing the table in normal circumstances because there are
350 // assembly implementations.
351 if (cur_cfl_subsampler_ == nullptr) return;
352 libvpx_test::ACMRandom rnd(libvpx_test::ACMRandom::DeterministicSeed());
353
354 const int width = GetLumaWidth(block_width_, subsampling_type);
355 const int height = GetLumaHeight(block_height_, subsampling_type);
356 Pixel* src = intra_pred_mem_.ref_src;
357 #if LIBGAV1_MSAN
358 // Quiet 10bpp CflSubsampler420_NEON() msan warning.
359 memset(src, 0, sizeof(intra_pred_mem_.ref_src));
360 #endif
361 for (int i = 0; i < height; ++i) {
362 for (int j = 0; j < width; ++j) {
363 src[j] = rnd.RandRange(1 << bitdepth);
364 }
365 src += kMaxBlockSize;
366 }
367 const absl::Time start = absl::Now();
368 int16_t luma[kCflLumaBufferStride][kCflLumaBufferStride] = {};
369 const ptrdiff_t stride = kMaxBlockSize * sizeof(Pixel);
370 for (int run = 0; run < num_runs; ++run) {
371 cur_cfl_subsampler_(luma, width, height, intra_pred_mem_.ref_src, stride);
372 }
373 const absl::Duration elapsed_time = absl::Now() - start;
374 test_utils::CheckMd5Digest(ToString(tx_size_), kCflIntraPredName, digest,
375 luma, sizeof(luma), elapsed_time);
376 }
377
378 template <int bitdepth, typename Pixel, SubsamplingType subsampling_type>
379 void CflSubsamplerTest<bitdepth, Pixel,
TestSaturatedValues()380 subsampling_type>::TestSaturatedValues() {
381 if (base_cfl_subsampler_ == nullptr) return;
382 const ptrdiff_t stride = kMaxBlockSize * sizeof(Pixel);
383 for (int width = GetLumaWidth(block_width_, subsampling_type); width > 0;
384 width -= 8) {
385 for (int height = GetLumaHeight(block_height_, subsampling_type);
386 height > 0; height -= 8) {
387 Pixel* src = intra_pred_mem_.ref_src;
388 for (int y = 0; y < height; ++y) {
389 Memset(src, (1 << bitdepth) - 1, width);
390 Memset(src + width, 0, kMaxBlockSize - width);
391 src += kMaxBlockSize;
392 }
393 Memset(intra_pred_mem_.ref_src + kMaxBlockSize * height, 0,
394 kMaxBlockSize * (kMaxBlockSize - height));
395
396 int16_t luma_base[kCflLumaBufferStride][kCflLumaBufferStride] = {};
397 int16_t luma_cur[kCflLumaBufferStride][kCflLumaBufferStride] = {};
398 base_cfl_subsampler_(luma_base, width, height, intra_pred_mem_.ref_src,
399 stride);
400 cur_cfl_subsampler_(luma_cur, width, height, intra_pred_mem_.ref_src,
401 stride);
402 if (!test_utils::CompareBlocks(reinterpret_cast<uint16_t*>(luma_cur[0]),
403 reinterpret_cast<uint16_t*>(luma_base[0]),
404 block_width_, block_height_,
405 kCflLumaBufferStride, kCflLumaBufferStride,
406 true)) {
407 FAIL() << "Result from optimized version of CFL subsampler"
408 << " differs from reference. max_luma_width: " << width
409 << " max_luma_height: " << height;
410 }
411 }
412 }
413 }
414
415 template <int bitdepth, typename Pixel, SubsamplingType subsampling_type>
TestRandomValues()416 void CflSubsamplerTest<bitdepth, Pixel, subsampling_type>::TestRandomValues() {
417 if (base_cfl_subsampler_ == nullptr) return;
418 const ptrdiff_t stride = kMaxBlockSize * sizeof(Pixel);
419 // Use an alternate seed to differentiate this test from TestSpeed().
420 libvpx_test::ACMRandom rnd(test_utils::kAlternateDeterministicSeed);
421 for (int width = GetLumaWidth(block_width_, subsampling_type); width > 0;
422 width -= 8) {
423 for (int height = GetLumaHeight(block_height_, subsampling_type);
424 height > 0; height -= 8) {
425 Pixel* src = intra_pred_mem_.ref_src;
426 for (int i = 0; i < height; ++i) {
427 for (int j = 0; j < width; ++j) {
428 src[j] = rnd.RandRange(1 << bitdepth);
429 }
430 Memset(src + width, 0, kMaxBlockSize - width);
431 src += kMaxBlockSize;
432 }
433 Memset(intra_pred_mem_.ref_src + kMaxBlockSize * height, 0,
434 kMaxBlockSize * (kMaxBlockSize - height));
435
436 int16_t luma_base[kCflLumaBufferStride][kCflLumaBufferStride] = {};
437 int16_t luma_cur[kCflLumaBufferStride][kCflLumaBufferStride] = {};
438 base_cfl_subsampler_(luma_base, width, height, intra_pred_mem_.ref_src,
439 stride);
440 cur_cfl_subsampler_(luma_cur, width, height, intra_pred_mem_.ref_src,
441 stride);
442 if (!test_utils::CompareBlocks(reinterpret_cast<uint16_t*>(luma_cur[0]),
443 reinterpret_cast<uint16_t*>(luma_base[0]),
444 block_width_, block_height_,
445 kCflLumaBufferStride, kCflLumaBufferStride,
446 true)) {
447 FAIL() << "Result from optimized version of CFL subsampler"
448 << " differs from reference. max_luma_width: " << width
449 << " max_luma_height: " << height;
450 }
451 }
452 }
453 }
454
455 //------------------------------------------------------------------------------
456
457 using CflIntraPredTest8bpp = CflIntraPredTest<8, uint8_t>;
458
GetCflIntraPredDigest8bpp(TransformSize tx_size)459 const char* GetCflIntraPredDigest8bpp(TransformSize tx_size) {
460 static const char* const kDigest4x4 = "9ea7088e082867fd5ae394ca549fe1ed";
461 static const char* const kDigest4x8 = "323b0b4784b6658da781398e61f2da3d";
462 static const char* const kDigest4x16 = "99eb9c65f227ca7f71dcac24645a4fec";
463 static const char* const kDigest8x4 = "e8e782e31c94f3974b87b93d455262d8";
464 static const char* const kDigest8x8 = "23ab9fb65e7bbbdb985709e115115eb5";
465 static const char* const kDigest8x16 = "52f5add2fc4bbb2ff893148645e95b9c";
466 static const char* const kDigest8x32 = "283fdee9af8afdb76f72dd7339c92c3c";
467 static const char* const kDigest16x4 = "eead35f515b1aa8b5175b283192b86e6";
468 static const char* const kDigest16x8 = "5778e934254eaab04230bc370f64f778";
469 static const char* const kDigest16x16 = "4e8ed38ccba0d62f1213171da2212ed3";
470 static const char* const kDigest16x32 = "61a29bd7699e18ca6ea5641d1d023bfd";
471 static const char* const kDigest32x8 = "7f31607bd4f9ec879aa47f4daf9c7bb0";
472 static const char* const kDigest32x16 = "eb84dfab900fa6a90e132b186b4c6c36";
473 static const char* const kDigest32x32 = "e0ff35d407cb214578d61ef419c94237";
474
475 switch (tx_size) {
476 case kTransformSize4x4:
477 return kDigest4x4;
478 case kTransformSize4x8:
479 return kDigest4x8;
480 case kTransformSize4x16:
481 return kDigest4x16;
482 case kTransformSize8x4:
483 return kDigest8x4;
484 case kTransformSize8x8:
485 return kDigest8x8;
486 case kTransformSize8x16:
487 return kDigest8x16;
488 case kTransformSize8x32:
489 return kDigest8x32;
490 case kTransformSize16x4:
491 return kDigest16x4;
492 case kTransformSize16x8:
493 return kDigest16x8;
494 case kTransformSize16x16:
495 return kDigest16x16;
496 case kTransformSize16x32:
497 return kDigest16x32;
498 case kTransformSize32x8:
499 return kDigest32x8;
500 case kTransformSize32x16:
501 return kDigest32x16;
502 case kTransformSize32x32:
503 return kDigest32x32;
504 default:
505 ADD_FAILURE() << "Unknown transform size: " << tx_size;
506 return nullptr;
507 }
508 }
509
TEST_P(CflIntraPredTest8bpp,DISABLED_Speed)510 TEST_P(CflIntraPredTest8bpp, DISABLED_Speed) {
511 const auto num_runs =
512 static_cast<int>(2.0e9 / (block_width_ * block_height_));
513 TestSpeed(GetCflIntraPredDigest8bpp(tx_size_), num_runs);
514 }
515
TEST_P(CflIntraPredTest8bpp,FixedInput)516 TEST_P(CflIntraPredTest8bpp, FixedInput) {
517 TestSpeed(GetCflIntraPredDigest8bpp(tx_size_), 1);
518 }
519
TEST_P(CflIntraPredTest8bpp,Overflow)520 TEST_P(CflIntraPredTest8bpp, Overflow) { TestSaturatedValues(); }
521
TEST_P(CflIntraPredTest8bpp,Random)522 TEST_P(CflIntraPredTest8bpp, Random) { TestRandomValues(); }
523
524 //------------------------------------------------------------------------------
525
526 using CflSubsamplerTest8bpp444 =
527 CflSubsamplerTest<8, uint8_t, kSubsamplingType444>;
528 using CflSubsamplerTest8bpp422 =
529 CflSubsamplerTest<8, uint8_t, kSubsamplingType422>;
530 using CflSubsamplerTest8bpp420 =
531 CflSubsamplerTest<8, uint8_t, kSubsamplingType420>;
532
GetCflSubsamplerDigest8bpp(TransformSize tx_size,SubsamplingType subsampling_type)533 const char* GetCflSubsamplerDigest8bpp(TransformSize tx_size,
534 SubsamplingType subsampling_type) {
535 static const char* const kDigests4x4[3] = {
536 "a8fa98d76cc3ccffcffc0d02dfae052c", "929cf2c23d926b500616797f8b1baf5b",
537 "1d03f091956838e7f2b113aabd8b9da9"};
538 static const char* const kDigests4x8[3] = {
539 "717b84f867f413c87c90a7c5d0125c8c", "6ccd9f48842b1a802e128b46b8f4885d",
540 "68a334f5d2abecbc78562b3280b5fb0c"};
541 static const char* const kDigests4x16[3] = {
542 "ecd1340b7e065dd8807fd9861abb7d99", "042c3fee17df7ef8fb8cef616f212a91",
543 "b0600f0bc3fbfc374bb3628360dcae5c"};
544 static const char* const kDigests8x4[3] = {
545 "4ea5617f4ed8e9edc2fff88d0ab8e53f", "b02288905f218c9f54ce4a472ec7b22e",
546 "3522d3a4dd3839d1a86fb39b31a86d52"};
547 static const char* const kDigests8x8[3] = {
548 "a0488493e6bcdb868713a95f9b4a0091", "ff6c1ac1d94fce63c282ba49186529bf",
549 "082e34ba04d04d7cd6fe408823987602"};
550 static const char* const kDigests8x16[3] = {
551 "e01dd4bb21daaa6e991cd5b1e6f30300", "2a1b13f932e39cc5f561afea9956f47a",
552 "d8d266282cb7123f780bd7266e8f5913"};
553 static const char* const kDigests8x32[3] = {
554 "0fc95e4ab798b95ccd2966ff75028b03", "6bc6e45ef2f664134449342fe76006ff",
555 "d294fb6399edaa267aa167407c0ebccb"};
556 static const char* const kDigests16x4[3] = {
557 "4798c2cf649b786bd153ad88353d52aa", "43a4bfa3b8caf4b72f58c6a1d1054f64",
558 "a928ebbec2db1508c8831a440d82eb98"};
559 static const char* const kDigests16x8[3] = {
560 "736b7f5b603cb34abcbe1b7e69b6ce93", "90422000ab20ecb519e4d277a9b3ea2b",
561 "c8e71c2fddbb850c5a50592ee5975368"};
562 static const char* const kDigests16x16[3] = {
563 "4f15a694966ee50a9e987e9a0aa2423b", "9e31e2f5a7ce7bef738b135755e25dcd",
564 "2ffeed4d592a0455f6d888913969827f"};
565 static const char* const kDigests16x32[3] = {
566 "3a10438bfe17ea39efad20608a0520eb", "79e8e8732a6ffc29dfbb0b3fc29c2883",
567 "185ca976ccbef7fb5f3f8c6aa22d5a79"};
568 static const char* const kDigests32x8[3] = {
569 "683704f08839a15e42603e4977a3e815", "13d311635372aee8998fca1758e75e20",
570 "9847d88eaaa57c086a2e6aed583048d3"};
571 static const char* const kDigests32x16[3] = {
572 "14b6761bf9f1156cf2496f532512aa99", "ee57bb7f0aa2302d29cdc1bfce72d5fc",
573 "a4189655fe714b82eb88cb5092c0ad76"};
574 static const char* const kDigests32x32[3] = {
575 "dcfbe71b70a37418ccb90dbf27f04226", "c578556a584019c1bdc2d0c3b9fd0c88",
576 "db200bc8ccbeacd6a42d6b8e5ad1d931"};
577
578 switch (tx_size) {
579 case kTransformSize4x4:
580 return kDigests4x4[subsampling_type];
581 case kTransformSize4x8:
582 return kDigests4x8[subsampling_type];
583 case kTransformSize4x16:
584 return kDigests4x16[subsampling_type];
585 case kTransformSize8x4:
586 return kDigests8x4[subsampling_type];
587 case kTransformSize8x8:
588 return kDigests8x8[subsampling_type];
589 case kTransformSize8x16:
590 return kDigests8x16[subsampling_type];
591 case kTransformSize8x32:
592 return kDigests8x32[subsampling_type];
593 case kTransformSize16x4:
594 return kDigests16x4[subsampling_type];
595 case kTransformSize16x8:
596 return kDigests16x8[subsampling_type];
597 case kTransformSize16x16:
598 return kDigests16x16[subsampling_type];
599 case kTransformSize16x32:
600 return kDigests16x32[subsampling_type];
601 case kTransformSize32x8:
602 return kDigests32x8[subsampling_type];
603 case kTransformSize32x16:
604 return kDigests32x16[subsampling_type];
605 case kTransformSize32x32:
606 return kDigests32x32[subsampling_type];
607 default:
608 ADD_FAILURE() << "Unknown transform size: " << tx_size;
609 return nullptr;
610 }
611 }
612
TEST_P(CflSubsamplerTest8bpp444,DISABLED_Speed)613 TEST_P(CflSubsamplerTest8bpp444, DISABLED_Speed) {
614 const auto num_runs =
615 static_cast<int>(2.0e9 / (block_width_ * block_height_));
616 TestSpeed(GetCflSubsamplerDigest8bpp(tx_size_, SubsamplingType()), num_runs);
617 }
618
TEST_P(CflSubsamplerTest8bpp444,FixedInput)619 TEST_P(CflSubsamplerTest8bpp444, FixedInput) {
620 TestSpeed(GetCflSubsamplerDigest8bpp(tx_size_, SubsamplingType()), 1);
621 }
622
TEST_P(CflSubsamplerTest8bpp444,Overflow)623 TEST_P(CflSubsamplerTest8bpp444, Overflow) { TestSaturatedValues(); }
624
TEST_P(CflSubsamplerTest8bpp444,Random)625 TEST_P(CflSubsamplerTest8bpp444, Random) { TestRandomValues(); }
626
TEST_P(CflSubsamplerTest8bpp422,DISABLED_Speed)627 TEST_P(CflSubsamplerTest8bpp422, DISABLED_Speed) {
628 const auto num_runs =
629 static_cast<int>(2.0e9 / (block_width_ * block_height_));
630 TestSpeed(GetCflSubsamplerDigest8bpp(tx_size_, SubsamplingType()), num_runs);
631 }
632
TEST_P(CflSubsamplerTest8bpp422,FixedInput)633 TEST_P(CflSubsamplerTest8bpp422, FixedInput) {
634 TestSpeed(GetCflSubsamplerDigest8bpp(tx_size_, SubsamplingType()), 1);
635 }
636
TEST_P(CflSubsamplerTest8bpp422,Overflow)637 TEST_P(CflSubsamplerTest8bpp422, Overflow) { TestSaturatedValues(); }
638
TEST_P(CflSubsamplerTest8bpp422,Random)639 TEST_P(CflSubsamplerTest8bpp422, Random) { TestRandomValues(); }
640
TEST_P(CflSubsamplerTest8bpp420,DISABLED_Speed)641 TEST_P(CflSubsamplerTest8bpp420, DISABLED_Speed) {
642 const auto num_runs =
643 static_cast<int>(2.0e9 / (block_width_ * block_height_));
644 TestSpeed(GetCflSubsamplerDigest8bpp(tx_size_, SubsamplingType()), num_runs);
645 }
646
TEST_P(CflSubsamplerTest8bpp420,FixedInput)647 TEST_P(CflSubsamplerTest8bpp420, FixedInput) {
648 TestSpeed(GetCflSubsamplerDigest8bpp(tx_size_, SubsamplingType()), 1);
649 }
650
TEST_P(CflSubsamplerTest8bpp420,Overflow)651 TEST_P(CflSubsamplerTest8bpp420, Overflow) { TestSaturatedValues(); }
652
TEST_P(CflSubsamplerTest8bpp420,Random)653 TEST_P(CflSubsamplerTest8bpp420, Random) { TestRandomValues(); }
654
655 //------------------------------------------------------------------------------
656
657 #if LIBGAV1_MAX_BITDEPTH >= 10
658 using CflIntraPredTest10bpp = CflIntraPredTest<10, uint16_t>;
659
GetCflIntraPredDigest10bpp(TransformSize tx_size)660 const char* GetCflIntraPredDigest10bpp(TransformSize tx_size) {
661 static const char* const kDigest4x4 = "b4ca5f6fbb643a94eb05d59976d44c5d";
662 static const char* const kDigest4x8 = "040139b76ee22af05c56baf887d3d43b";
663 static const char* const kDigest4x16 = "4a1d59ace84ff07e68a0d30e9b1cebdd";
664 static const char* const kDigest8x4 = "c2c149cea5fdcd18bfe5c19ec2a8aa90";
665 static const char* const kDigest8x8 = "68ad90bd6f409548fa5551496b7cb0d0";
666 static const char* const kDigest8x16 = "bdc54eff4de8c5d597b03afaa705d3fe";
667 static const char* const kDigest8x32 = "362aebc6d68ff0d312d55dcd6a8a927d";
668 static const char* const kDigest16x4 = "349e813aedd211581c5e64ba1938eaa7";
669 static const char* const kDigest16x8 = "35c64f6da17f836618b5804185cf3eef";
670 static const char* const kDigest16x16 = "95be0c78dbd8dda793c62c6635b4bfb7";
671 static const char* const kDigest16x32 = "4752b9eda069854d3f5c56d3f2057e79";
672 static const char* const kDigest32x8 = "dafc5e973e4b6a55861f4586a11b7dd1";
673 static const char* const kDigest32x16 = "1e177ed3914a165183916aca1d01bb74";
674 static const char* const kDigest32x32 = "4c9ab3cf9baa27bb34e29729dabc1ea6";
675
676 switch (tx_size) {
677 case kTransformSize4x4:
678 return kDigest4x4;
679 case kTransformSize4x8:
680 return kDigest4x8;
681 case kTransformSize4x16:
682 return kDigest4x16;
683 case kTransformSize8x4:
684 return kDigest8x4;
685 case kTransformSize8x8:
686 return kDigest8x8;
687 case kTransformSize8x16:
688 return kDigest8x16;
689 case kTransformSize8x32:
690 return kDigest8x32;
691 case kTransformSize16x4:
692 return kDigest16x4;
693 case kTransformSize16x8:
694 return kDigest16x8;
695 case kTransformSize16x16:
696 return kDigest16x16;
697 case kTransformSize16x32:
698 return kDigest16x32;
699 case kTransformSize32x8:
700 return kDigest32x8;
701 case kTransformSize32x16:
702 return kDigest32x16;
703 case kTransformSize32x32:
704 return kDigest32x32;
705 default:
706 ADD_FAILURE() << "Unknown transform size: " << tx_size;
707 return nullptr;
708 }
709 }
710
TEST_P(CflIntraPredTest10bpp,DISABLED_Speed)711 TEST_P(CflIntraPredTest10bpp, DISABLED_Speed) {
712 const auto num_runs =
713 static_cast<int>(2.0e9 / (block_width_ * block_height_));
714 TestSpeed(GetCflIntraPredDigest10bpp(tx_size_), num_runs);
715 }
716
TEST_P(CflIntraPredTest10bpp,FixedInput)717 TEST_P(CflIntraPredTest10bpp, FixedInput) {
718 TestSpeed(GetCflIntraPredDigest10bpp(tx_size_), 1);
719 }
720
TEST_P(CflIntraPredTest10bpp,Overflow)721 TEST_P(CflIntraPredTest10bpp, Overflow) { TestSaturatedValues(); }
722
TEST_P(CflIntraPredTest10bpp,Random)723 TEST_P(CflIntraPredTest10bpp, Random) { TestRandomValues(); }
724
725 //------------------------------------------------------------------------------
726
727 using CflSubsamplerTest10bpp444 =
728 CflSubsamplerTest<10, uint16_t, kSubsamplingType444>;
729 using CflSubsamplerTest10bpp422 =
730 CflSubsamplerTest<10, uint16_t, kSubsamplingType422>;
731 using CflSubsamplerTest10bpp420 =
732 CflSubsamplerTest<10, uint16_t, kSubsamplingType420>;
733
GetCflSubsamplerDigest10bpp(TransformSize tx_size,SubsamplingType subsampling_type)734 const char* GetCflSubsamplerDigest10bpp(TransformSize tx_size,
735 SubsamplingType subsampling_type) {
736 static const char* const kDigests4x4[3] = {
737 "a8abcad9a6c9b046a100689135a108cb", "01081c2a0d0c15dabdbc725be5660451",
738 "93d1d9df2861240d88f5618e42178654"};
739 static const char* const kDigests4x8[3] = {
740 "d1fd8cd0709ca6634ad85f3e331672e1", "0d603fcc910aca3db41fc7f64e826c27",
741 "cf88b6d1b7b025cfa0082361775aeb75"};
742 static const char* const kDigests4x16[3] = {
743 "ce2e036a950388a564d8637b1416a6c6", "6c36c46cd72057a6b36bc12188b6d22c",
744 "0884a0e53384cd5173035ad8966d8f2f"};
745 static const char* const kDigests8x4[3] = {
746 "174e961983ed71fb105ed71aa3f9daf5", "330946cc369a534618a1014b4e3f6f18",
747 "8070668aa389c1d09f8aaf43c1223e8c"};
748 static const char* const kDigests8x8[3] = {
749 "86884feb35217010f73ccdbadecb635e", "b8cbc646e1bf1352e5b4b599eaef1193",
750 "4a1110382e56b42d3b7a4132bccc01ee"};
751 static const char* const kDigests8x16[3] = {
752 "a694c4e1f89648ffb49efd6a1d35b300", "864b9da67d23a2f8284b28b2a1e5aa30",
753 "bd012ca1cea256dd02c231339a4cf200"};
754 static const char* const kDigests8x32[3] = {
755 "60c42201bc24e518c1a3b3b6306d8125", "4d530e47c2b7555d5f311ee910d61842",
756 "71888b17b832ef55c0cd9449c0e6b077"};
757 static const char* const kDigests16x4[3] = {
758 "6b6d5ae4cc294c070ce65ab31c5a7d4f", "0fbecee20d294939e7a0183c2b4a0b96",
759 "917cd884923139d5c05a11000722e3b6"};
760 static const char* const kDigests16x8[3] = {
761 "688c41726d9ac35fb5b18c57bca76b9c", "d439a2e0a60d672b644cd1189e2858b9",
762 "edded6d166a77a6c3ff46fddc13f372f"};
763 static const char* const kDigests16x16[3] = {
764 "feb2bad9f6bb3f60eaeaf6c1bfd89ca5", "d65cabce5fcd9a29d1dfc530e4764f3a",
765 "2f1a91898812d2c9320c7506b3a72eb4"};
766 static const char* const kDigests16x32[3] = {
767 "6f23b1851444d29633e62ce77bf09559", "4a449fd078bd0c9657cdc24b709c0796",
768 "e44e18cb8bda2d34b52c96d5b6b510be"};
769 static const char* const kDigests32x8[3] = {
770 "77bf9ba56f7e1d2f04068a8a00b139da", "a85a1dea82963dedab9a2f7ad4169b5f",
771 "d12746071bee96ddc075c6368bc9fbaf"};
772 static const char* const kDigests32x16[3] = {
773 "cce3422f7f8cf57145f979359ac92f98", "1c18738d40bfa91296e5fdb7230bf9a7",
774 "02513142d109aee10f081cacfb33d1c5"};
775 static const char* const kDigests32x32[3] = {
776 "789008e49d0276de186af968196dd4a7", "b8848b00968a7ba4787765b7214da05f",
777 "12d13828db57605b00ce99469489651d"};
778
779 switch (tx_size) {
780 case kTransformSize4x4:
781 return kDigests4x4[subsampling_type];
782 case kTransformSize4x8:
783 return kDigests4x8[subsampling_type];
784 case kTransformSize4x16:
785 return kDigests4x16[subsampling_type];
786 case kTransformSize8x4:
787 return kDigests8x4[subsampling_type];
788 case kTransformSize8x8:
789 return kDigests8x8[subsampling_type];
790 case kTransformSize8x16:
791 return kDigests8x16[subsampling_type];
792 case kTransformSize8x32:
793 return kDigests8x32[subsampling_type];
794 case kTransformSize16x4:
795 return kDigests16x4[subsampling_type];
796 case kTransformSize16x8:
797 return kDigests16x8[subsampling_type];
798 case kTransformSize16x16:
799 return kDigests16x16[subsampling_type];
800 case kTransformSize16x32:
801 return kDigests16x32[subsampling_type];
802 case kTransformSize32x8:
803 return kDigests32x8[subsampling_type];
804 case kTransformSize32x16:
805 return kDigests32x16[subsampling_type];
806 case kTransformSize32x32:
807 return kDigests32x32[subsampling_type];
808 default:
809 ADD_FAILURE() << "Unknown transform size: " << tx_size;
810 return nullptr;
811 }
812 }
813
TEST_P(CflSubsamplerTest10bpp444,DISABLED_Speed)814 TEST_P(CflSubsamplerTest10bpp444, DISABLED_Speed) {
815 const auto num_runs =
816 static_cast<int>(2.0e9 / (block_width_ * block_height_));
817 TestSpeed(GetCflSubsamplerDigest10bpp(tx_size_, SubsamplingType()), num_runs);
818 }
819
TEST_P(CflSubsamplerTest10bpp444,FixedInput)820 TEST_P(CflSubsamplerTest10bpp444, FixedInput) {
821 TestSpeed(GetCflSubsamplerDigest10bpp(tx_size_, SubsamplingType()), 1);
822 }
823
TEST_P(CflSubsamplerTest10bpp444,Overflow)824 TEST_P(CflSubsamplerTest10bpp444, Overflow) { TestSaturatedValues(); }
825
TEST_P(CflSubsamplerTest10bpp444,Random)826 TEST_P(CflSubsamplerTest10bpp444, Random) { TestRandomValues(); }
827
TEST_P(CflSubsamplerTest10bpp422,DISABLED_Speed)828 TEST_P(CflSubsamplerTest10bpp422, DISABLED_Speed) {
829 const auto num_runs =
830 static_cast<int>(2.0e9 / (block_width_ * block_height_));
831 TestSpeed(GetCflSubsamplerDigest10bpp(tx_size_, SubsamplingType()), num_runs);
832 }
833
TEST_P(CflSubsamplerTest10bpp422,FixedInput)834 TEST_P(CflSubsamplerTest10bpp422, FixedInput) {
835 TestSpeed(GetCflSubsamplerDigest10bpp(tx_size_, SubsamplingType()), 1);
836 }
837
TEST_P(CflSubsamplerTest10bpp422,Overflow)838 TEST_P(CflSubsamplerTest10bpp422, Overflow) { TestSaturatedValues(); }
839
TEST_P(CflSubsamplerTest10bpp422,Random)840 TEST_P(CflSubsamplerTest10bpp422, Random) { TestRandomValues(); }
841
TEST_P(CflSubsamplerTest10bpp420,DISABLED_Speed)842 TEST_P(CflSubsamplerTest10bpp420, DISABLED_Speed) {
843 const auto num_runs =
844 static_cast<int>(2.0e9 / (block_width_ * block_height_));
845 TestSpeed(GetCflSubsamplerDigest10bpp(tx_size_, SubsamplingType()), num_runs);
846 }
847
TEST_P(CflSubsamplerTest10bpp420,FixedInput)848 TEST_P(CflSubsamplerTest10bpp420, FixedInput) {
849 TestSpeed(GetCflSubsamplerDigest10bpp(tx_size_, SubsamplingType()), 1);
850 }
851
TEST_P(CflSubsamplerTest10bpp420,Overflow)852 TEST_P(CflSubsamplerTest10bpp420, Overflow) { TestSaturatedValues(); }
853
TEST_P(CflSubsamplerTest10bpp420,Random)854 TEST_P(CflSubsamplerTest10bpp420, Random) { TestRandomValues(); }
855 #endif // LIBGAV1_MAX_BITDEPTH >= 10
856
857 //------------------------------------------------------------------------------
858
859 #if LIBGAV1_MAX_BITDEPTH == 12
860 using CflIntraPredTest12bpp = CflIntraPredTest<12, uint16_t>;
861
GetCflIntraPredDigest12bpp(TransformSize tx_size)862 const char* GetCflIntraPredDigest12bpp(TransformSize tx_size) {
863 static const char* const kDigest4x4 = "1d92a681a58f99396f22acd8b3154e2b";
864 static const char* const kDigest4x8 = "cf6833ebc64c9ae45f192ee384ef4aa3";
865 static const char* const kDigest4x16 = "06a4fbb8590aca98a045c902ed15c777";
866 static const char* const kDigest8x4 = "ad5944c7455f731ae8dd28b2b25a1b9f";
867 static const char* const kDigest8x8 = "c19621e42ca2bc184d5065131d27be2c";
868 static const char* const kDigest8x16 = "8faa7c95e8c3c18621168ed6759c1ac1";
869 static const char* const kDigest8x32 = "502699ef7a8c7aebc8c3bc653e733703";
870 static const char* const kDigest16x4 = "7f30bb038217967336fb8548a6f7df45";
871 static const char* const kDigest16x8 = "b70943098d0fb256c2943e2ebdbe6d34";
872 static const char* const kDigest16x16 = "4c34f5669880ab78d648b16b68ea0c24";
873 static const char* const kDigest16x32 = "5d85daf690020ed235617870a1a179b1";
874 static const char* const kDigest32x8 = "f8eec12e58c469ffb698fc60b13b927c";
875 static const char* const kDigest32x16 = "f272bb7e5d2df333aa63d806c95e6748";
876 static const char* const kDigest32x32 = "c737987c0a5414b03e6014f145dd999c";
877
878 switch (tx_size) {
879 case kTransformSize4x4:
880 return kDigest4x4;
881 case kTransformSize4x8:
882 return kDigest4x8;
883 case kTransformSize4x16:
884 return kDigest4x16;
885 case kTransformSize8x4:
886 return kDigest8x4;
887 case kTransformSize8x8:
888 return kDigest8x8;
889 case kTransformSize8x16:
890 return kDigest8x16;
891 case kTransformSize8x32:
892 return kDigest8x32;
893 case kTransformSize16x4:
894 return kDigest16x4;
895 case kTransformSize16x8:
896 return kDigest16x8;
897 case kTransformSize16x16:
898 return kDigest16x16;
899 case kTransformSize16x32:
900 return kDigest16x32;
901 case kTransformSize32x8:
902 return kDigest32x8;
903 case kTransformSize32x16:
904 return kDigest32x16;
905 case kTransformSize32x32:
906 return kDigest32x32;
907 default:
908 ADD_FAILURE() << "Unknown transform size: " << tx_size;
909 return nullptr;
910 }
911 }
912
TEST_P(CflIntraPredTest12bpp,DISABLED_Speed)913 TEST_P(CflIntraPredTest12bpp, DISABLED_Speed) {
914 const auto num_runs =
915 static_cast<int>(2.0e9 / (block_width_ * block_height_));
916 TestSpeed(GetCflIntraPredDigest12bpp(tx_size_), num_runs);
917 }
918
TEST_P(CflIntraPredTest12bpp,FixedInput)919 TEST_P(CflIntraPredTest12bpp, FixedInput) {
920 TestSpeed(GetCflIntraPredDigest12bpp(tx_size_), 1);
921 }
922
TEST_P(CflIntraPredTest12bpp,Overflow)923 TEST_P(CflIntraPredTest12bpp, Overflow) { TestSaturatedValues(); }
924
TEST_P(CflIntraPredTest12bpp,Random)925 TEST_P(CflIntraPredTest12bpp, Random) { TestRandomValues(); }
926
927 //------------------------------------------------------------------------------
928
929 using CflSubsamplerTest12bpp444 =
930 CflSubsamplerTest<12, uint16_t, kSubsamplingType444>;
931 using CflSubsamplerTest12bpp422 =
932 CflSubsamplerTest<12, uint16_t, kSubsamplingType422>;
933 using CflSubsamplerTest12bpp420 =
934 CflSubsamplerTest<12, uint16_t, kSubsamplingType420>;
935
GetCflSubsamplerDigest12bpp(TransformSize tx_size,SubsamplingType subsampling_type)936 const char* GetCflSubsamplerDigest12bpp(TransformSize tx_size,
937 SubsamplingType subsampling_type) {
938 static const char* const kDigests4x4[3] = {
939 "44af37c60e9ccaacea004b57d5dea4cf",
940 "e29dd1d93f23b23778ed8cd85910d987",
941 "81e5dac2fd4c90f872ab814ed0f76ae5",
942 };
943 static const char* const kDigests4x8[3] = {
944 "bfc04aed9fe41ec07b0462a219652d16",
945 "693dd064636a0aa3be7aa098e867c512",
946 "0636c25d88aacd85d63e56011e7c5d15",
947 };
948 static const char* const kDigests4x16[3] = {
949 "6479ab30377288e75a78068d47c7e194",
950 "7d6f9b8b3eb85e73626118fc9210e622",
951 "1f3d474cd7c86899da90e515b8b7a906",
952 };
953 static const char* const kDigests8x4[3] = {
954 "7da5a2029bcdab159225c475fdff02da",
955 "096bfef24caa0670d2cd7b0bb63a7ba6",
956 "f749310dfc8a6129ed438dbc845470c0",
957 };
958 static const char* const kDigests8x8[3] = {
959 "08494051a7ff50718313a79ec7c51f92",
960 "637efad0630e253f7cce11af1a0af456",
961 "b220faf7dfedef860d59079dcf201757",
962 };
963 static const char* const kDigests8x16[3] = {
964 "19f027af516e88d3b9e613e578deb126",
965 "4f3bb155d70f9ea76d05b2f41b297a0c",
966 "b7504347eeda1e59ba8e36385c219e40",
967 };
968 static const char* const kDigests8x32[3] = {
969 "b8f1ef01c5672c87ee1004bb3cd7b8bc",
970 "b3e3318b050eb1c165d1e320ef622fa7",
971 "67754f7c5ae84dc23bb76ffaa2fa848e",
972 };
973 static const char* const kDigests16x4[3] = {
974 "f687fb4e22d8a1446eeb4915036874f4",
975 "7b5ef3d393a98dfe0ba49a0db2083465",
976 "840bbb6edaa50e9f7d391033a3dda2d9",
977 };
978 static const char* const kDigests16x8[3] = {
979 "dd9aed11d115a028035f0cee5b90d433",
980 "340d5d0784356ea199d3d751f4d6ed5e",
981 "e55f6fb5f34d829727e9dc2068098933",
982 };
983 static const char* const kDigests16x16[3] = {
984 "1df36a20d76a405c6273b88b38693cf9",
985 "2a7590d01df60b4bc6f10bfdb07b7a65",
986 "510ee31a5bd609e8f4542bb817539668",
987 };
988 static const char* const kDigests16x32[3] = {
989 "bdbc13b9fb7c3c50d25fda57f86f5ad9",
990 "7c138c568794b3d0c8aabff2edc07efd",
991 "581bef267c2a66e4c2fb079968440dbe",
992 };
993 static const char* const kDigests32x8[3] = {
994 "26f62743793811475e2afe1414c5fee1",
995 "6e6bf1678a04f2f727f0679564fb3630",
996 "a4c15562c26dbcfa43fe03a2b6e728b5",
997 };
998 static const char* const kDigests32x16[3] = {
999 "791f0713bbf032081da8ec08e58b9cd3",
1000 "5dc7a673e92767186ae86996f4a30691",
1001 "651f09d1244c817d92d1baa094c86f56",
1002 };
1003 static const char* const kDigests32x32[3] = {
1004 "543a9d76e7238d88ba86218ec47c1f49",
1005 "b0f2b29aae4858c1f09c27fc4344fd15",
1006 "1d45083875fed14c4e5f149384a3cd2d",
1007 };
1008
1009 switch (tx_size) {
1010 case kTransformSize4x4:
1011 return kDigests4x4[subsampling_type];
1012 case kTransformSize4x8:
1013 return kDigests4x8[subsampling_type];
1014 case kTransformSize4x16:
1015 return kDigests4x16[subsampling_type];
1016 case kTransformSize8x4:
1017 return kDigests8x4[subsampling_type];
1018 case kTransformSize8x8:
1019 return kDigests8x8[subsampling_type];
1020 case kTransformSize8x16:
1021 return kDigests8x16[subsampling_type];
1022 case kTransformSize8x32:
1023 return kDigests8x32[subsampling_type];
1024 case kTransformSize16x4:
1025 return kDigests16x4[subsampling_type];
1026 case kTransformSize16x8:
1027 return kDigests16x8[subsampling_type];
1028 case kTransformSize16x16:
1029 return kDigests16x16[subsampling_type];
1030 case kTransformSize16x32:
1031 return kDigests16x32[subsampling_type];
1032 case kTransformSize32x8:
1033 return kDigests32x8[subsampling_type];
1034 case kTransformSize32x16:
1035 return kDigests32x16[subsampling_type];
1036 case kTransformSize32x32:
1037 return kDigests32x32[subsampling_type];
1038 default:
1039 ADD_FAILURE() << "Unknown transform size: " << tx_size;
1040 return nullptr;
1041 }
1042 }
1043
TEST_P(CflSubsamplerTest12bpp444,DISABLED_Speed)1044 TEST_P(CflSubsamplerTest12bpp444, DISABLED_Speed) {
1045 const auto num_runs =
1046 static_cast<int>(2.0e9 / (block_width_ * block_height_));
1047 TestSpeed(GetCflSubsamplerDigest12bpp(tx_size_, SubsamplingType()), num_runs);
1048 }
1049
TEST_P(CflSubsamplerTest12bpp444,FixedInput)1050 TEST_P(CflSubsamplerTest12bpp444, FixedInput) {
1051 TestSpeed(GetCflSubsamplerDigest12bpp(tx_size_, SubsamplingType()), 1);
1052 }
1053
TEST_P(CflSubsamplerTest12bpp444,Overflow)1054 TEST_P(CflSubsamplerTest12bpp444, Overflow) { TestSaturatedValues(); }
1055
TEST_P(CflSubsamplerTest12bpp444,Random)1056 TEST_P(CflSubsamplerTest12bpp444, Random) { TestRandomValues(); }
1057
TEST_P(CflSubsamplerTest12bpp422,DISABLED_Speed)1058 TEST_P(CflSubsamplerTest12bpp422, DISABLED_Speed) {
1059 const auto num_runs =
1060 static_cast<int>(2.0e9 / (block_width_ * block_height_));
1061 TestSpeed(GetCflSubsamplerDigest12bpp(tx_size_, SubsamplingType()), num_runs);
1062 }
1063
TEST_P(CflSubsamplerTest12bpp422,FixedInput)1064 TEST_P(CflSubsamplerTest12bpp422, FixedInput) {
1065 TestSpeed(GetCflSubsamplerDigest12bpp(tx_size_, SubsamplingType()), 1);
1066 }
1067
TEST_P(CflSubsamplerTest12bpp422,Overflow)1068 TEST_P(CflSubsamplerTest12bpp422, Overflow) { TestSaturatedValues(); }
1069
TEST_P(CflSubsamplerTest12bpp422,Random)1070 TEST_P(CflSubsamplerTest12bpp422, Random) { TestRandomValues(); }
1071
TEST_P(CflSubsamplerTest12bpp420,DISABLED_Speed)1072 TEST_P(CflSubsamplerTest12bpp420, DISABLED_Speed) {
1073 const auto num_runs =
1074 static_cast<int>(2.0e9 / (block_width_ * block_height_));
1075 TestSpeed(GetCflSubsamplerDigest12bpp(tx_size_, SubsamplingType()), num_runs);
1076 }
1077
TEST_P(CflSubsamplerTest12bpp420,FixedInput)1078 TEST_P(CflSubsamplerTest12bpp420, FixedInput) {
1079 TestSpeed(GetCflSubsamplerDigest12bpp(tx_size_, SubsamplingType()), 1);
1080 }
1081
TEST_P(CflSubsamplerTest12bpp420,Overflow)1082 TEST_P(CflSubsamplerTest12bpp420, Overflow) { TestSaturatedValues(); }
1083
TEST_P(CflSubsamplerTest12bpp420,Random)1084 TEST_P(CflSubsamplerTest12bpp420, Random) { TestRandomValues(); }
1085 #endif // LIBGAV1_MAX_BITDEPTH == 12
1086
1087 // Cfl predictors are available only for transform sizes with
1088 // max(width, height) <= 32.
1089 constexpr TransformSize kTransformSizesSmallerThan32x32[] = {
1090 kTransformSize4x4, kTransformSize4x8, kTransformSize4x16,
1091 kTransformSize8x4, kTransformSize8x8, kTransformSize8x16,
1092 kTransformSize8x32, kTransformSize16x4, kTransformSize16x8,
1093 kTransformSize16x16, kTransformSize16x32, kTransformSize32x8,
1094 kTransformSize32x16, kTransformSize32x32};
1095
1096 INSTANTIATE_TEST_SUITE_P(C, CflIntraPredTest8bpp,
1097 testing::ValuesIn(kTransformSizesSmallerThan32x32));
1098 INSTANTIATE_TEST_SUITE_P(C, CflSubsamplerTest8bpp444,
1099 testing::ValuesIn(kTransformSizesSmallerThan32x32));
1100 INSTANTIATE_TEST_SUITE_P(C, CflSubsamplerTest8bpp422,
1101 testing::ValuesIn(kTransformSizesSmallerThan32x32));
1102 INSTANTIATE_TEST_SUITE_P(C, CflSubsamplerTest8bpp420,
1103 testing::ValuesIn(kTransformSizesSmallerThan32x32));
1104 #if LIBGAV1_ENABLE_SSE4_1
1105 INSTANTIATE_TEST_SUITE_P(SSE41, CflIntraPredTest8bpp,
1106 testing::ValuesIn(kTransformSizesSmallerThan32x32));
1107 INSTANTIATE_TEST_SUITE_P(SSE41, CflSubsamplerTest8bpp444,
1108 testing::ValuesIn(kTransformSizesSmallerThan32x32));
1109 INSTANTIATE_TEST_SUITE_P(SSE41, CflSubsamplerTest8bpp420,
1110 testing::ValuesIn(kTransformSizesSmallerThan32x32));
1111 #endif // LIBGAV1_ENABLE_SSE4_1
1112 #if LIBGAV1_ENABLE_NEON
1113 INSTANTIATE_TEST_SUITE_P(NEON, CflIntraPredTest8bpp,
1114 testing::ValuesIn(kTransformSizesSmallerThan32x32));
1115 INSTANTIATE_TEST_SUITE_P(NEON, CflSubsamplerTest8bpp444,
1116 testing::ValuesIn(kTransformSizesSmallerThan32x32));
1117 INSTANTIATE_TEST_SUITE_P(NEON, CflSubsamplerTest8bpp420,
1118 testing::ValuesIn(kTransformSizesSmallerThan32x32));
1119 #endif // LIBGAV1_ENABLE_NEON
1120
1121 #if LIBGAV1_MAX_BITDEPTH >= 10
1122 INSTANTIATE_TEST_SUITE_P(C, CflIntraPredTest10bpp,
1123 testing::ValuesIn(kTransformSizesSmallerThan32x32));
1124 INSTANTIATE_TEST_SUITE_P(C, CflSubsamplerTest10bpp444,
1125 testing::ValuesIn(kTransformSizesSmallerThan32x32));
1126 INSTANTIATE_TEST_SUITE_P(C, CflSubsamplerTest10bpp422,
1127 testing::ValuesIn(kTransformSizesSmallerThan32x32));
1128 INSTANTIATE_TEST_SUITE_P(C, CflSubsamplerTest10bpp420,
1129 testing::ValuesIn(kTransformSizesSmallerThan32x32));
1130 #if LIBGAV1_ENABLE_SSE4_1
1131 INSTANTIATE_TEST_SUITE_P(SSE41, CflIntraPredTest10bpp,
1132 testing::ValuesIn(kTransformSizesSmallerThan32x32));
1133 INSTANTIATE_TEST_SUITE_P(SSE41, CflSubsamplerTest10bpp444,
1134 testing::ValuesIn(kTransformSizesSmallerThan32x32));
1135 INSTANTIATE_TEST_SUITE_P(SSE41, CflSubsamplerTest10bpp420,
1136 testing::ValuesIn(kTransformSizesSmallerThan32x32));
1137 #endif // LIBGAV1_ENABLE_SSE4_1
1138 #if LIBGAV1_ENABLE_NEON
1139 INSTANTIATE_TEST_SUITE_P(NEON, CflIntraPredTest10bpp,
1140 testing::ValuesIn(kTransformSizesSmallerThan32x32));
1141 INSTANTIATE_TEST_SUITE_P(NEON, CflSubsamplerTest10bpp444,
1142 testing::ValuesIn(kTransformSizesSmallerThan32x32));
1143 INSTANTIATE_TEST_SUITE_P(NEON, CflSubsamplerTest10bpp420,
1144 testing::ValuesIn(kTransformSizesSmallerThan32x32));
1145 #endif // LIBGAV1_ENABLE_NEON
1146
1147 #endif // LIBGAV1_MAX_BITDEPTH >= 10
1148
1149 #if LIBGAV1_MAX_BITDEPTH == 12
1150 INSTANTIATE_TEST_SUITE_P(C, CflIntraPredTest12bpp,
1151 testing::ValuesIn(kTransformSizesSmallerThan32x32));
1152 INSTANTIATE_TEST_SUITE_P(C, CflSubsamplerTest12bpp444,
1153 testing::ValuesIn(kTransformSizesSmallerThan32x32));
1154 INSTANTIATE_TEST_SUITE_P(C, CflSubsamplerTest12bpp422,
1155 testing::ValuesIn(kTransformSizesSmallerThan32x32));
1156 INSTANTIATE_TEST_SUITE_P(C, CflSubsamplerTest12bpp420,
1157 testing::ValuesIn(kTransformSizesSmallerThan32x32));
1158 #endif // LIBGAV1_MAX_BITDEPTH == 12
1159
1160 } // namespace
1161 } // namespace dsp
1162
operator <<(std::ostream & os,const TransformSize tx_size)1163 static std::ostream& operator<<(std::ostream& os, const TransformSize tx_size) {
1164 return os << ToString(tx_size);
1165 }
1166
1167 } // namespace libgav1
1168