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