1*09537850SAkhilesh Sanikop // Copyright 2021 The libgav1 Authors
2*09537850SAkhilesh Sanikop //
3*09537850SAkhilesh Sanikop // Licensed under the Apache License, Version 2.0 (the "License");
4*09537850SAkhilesh Sanikop // you may not use this file except in compliance with the License.
5*09537850SAkhilesh Sanikop // You may obtain a copy of the License at
6*09537850SAkhilesh Sanikop //
7*09537850SAkhilesh Sanikop // http://www.apache.org/licenses/LICENSE-2.0
8*09537850SAkhilesh Sanikop //
9*09537850SAkhilesh Sanikop // Unless required by applicable law or agreed to in writing, software
10*09537850SAkhilesh Sanikop // distributed under the License is distributed on an "AS IS" BASIS,
11*09537850SAkhilesh Sanikop // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*09537850SAkhilesh Sanikop // See the License for the specific language governing permissions and
13*09537850SAkhilesh Sanikop // limitations under the License.
14*09537850SAkhilesh Sanikop
15*09537850SAkhilesh Sanikop #include "src/dsp/intrapred_directional.h"
16*09537850SAkhilesh Sanikop
17*09537850SAkhilesh Sanikop #include <cmath>
18*09537850SAkhilesh Sanikop #include <cstddef>
19*09537850SAkhilesh Sanikop #include <cstdint>
20*09537850SAkhilesh Sanikop #include <cstring>
21*09537850SAkhilesh Sanikop #include <memory>
22*09537850SAkhilesh Sanikop #include <ostream>
23*09537850SAkhilesh Sanikop
24*09537850SAkhilesh Sanikop #include "absl/strings/match.h"
25*09537850SAkhilesh Sanikop #include "absl/time/clock.h"
26*09537850SAkhilesh Sanikop #include "absl/time/time.h"
27*09537850SAkhilesh Sanikop #include "gtest/gtest.h"
28*09537850SAkhilesh Sanikop #include "src/dsp/constants.h"
29*09537850SAkhilesh Sanikop #include "src/dsp/dsp.h"
30*09537850SAkhilesh Sanikop #include "src/utils/common.h"
31*09537850SAkhilesh Sanikop #include "src/utils/compiler_attributes.h"
32*09537850SAkhilesh Sanikop #include "src/utils/constants.h"
33*09537850SAkhilesh Sanikop #include "src/utils/cpu.h"
34*09537850SAkhilesh Sanikop #include "src/utils/memory.h"
35*09537850SAkhilesh Sanikop #include "tests/block_utils.h"
36*09537850SAkhilesh Sanikop #include "tests/third_party/libvpx/acm_random.h"
37*09537850SAkhilesh Sanikop #include "tests/utils.h"
38*09537850SAkhilesh Sanikop
39*09537850SAkhilesh Sanikop namespace libgav1 {
40*09537850SAkhilesh Sanikop namespace dsp {
41*09537850SAkhilesh Sanikop namespace {
42*09537850SAkhilesh Sanikop
43*09537850SAkhilesh Sanikop constexpr int kMaxBlockSize = 64;
44*09537850SAkhilesh Sanikop constexpr int kTotalPixels = kMaxBlockSize * kMaxBlockSize;
45*09537850SAkhilesh Sanikop constexpr int kNumDirectionalIntraPredictors = 3;
46*09537850SAkhilesh Sanikop
47*09537850SAkhilesh Sanikop constexpr int kBaseAngles[] = {45, 67, 90, 113, 135, 157, 180, 203};
48*09537850SAkhilesh Sanikop
49*09537850SAkhilesh Sanikop const char* const kDirectionalPredNames[kNumDirectionalIntraPredictors] = {
50*09537850SAkhilesh Sanikop "kDirectionalIntraPredictorZone1", "kDirectionalIntraPredictorZone2",
51*09537850SAkhilesh Sanikop "kDirectionalIntraPredictorZone3"};
52*09537850SAkhilesh Sanikop
GetDirectionalIntraPredictorDerivative(const int angle)53*09537850SAkhilesh Sanikop int16_t GetDirectionalIntraPredictorDerivative(const int angle) {
54*09537850SAkhilesh Sanikop EXPECT_GE(angle, 3);
55*09537850SAkhilesh Sanikop EXPECT_LE(angle, 87);
56*09537850SAkhilesh Sanikop return kDirectionalIntraPredictorDerivative[DivideBy2(angle) - 1];
57*09537850SAkhilesh Sanikop }
58*09537850SAkhilesh Sanikop
59*09537850SAkhilesh Sanikop template <int bitdepth, typename Pixel>
60*09537850SAkhilesh Sanikop class IntraPredTestBase : public testing::TestWithParam<TransformSize>,
61*09537850SAkhilesh Sanikop public test_utils::MaxAlignedAllocable {
62*09537850SAkhilesh Sanikop public:
63*09537850SAkhilesh Sanikop static_assert(bitdepth >= kBitdepth8 && bitdepth <= LIBGAV1_MAX_BITDEPTH, "");
IntraPredTestBase()64*09537850SAkhilesh Sanikop IntraPredTestBase() {
65*09537850SAkhilesh Sanikop switch (tx_size_) {
66*09537850SAkhilesh Sanikop case kNumTransformSizes:
67*09537850SAkhilesh Sanikop EXPECT_NE(tx_size_, kNumTransformSizes);
68*09537850SAkhilesh Sanikop break;
69*09537850SAkhilesh Sanikop default:
70*09537850SAkhilesh Sanikop block_width_ = kTransformWidth[tx_size_];
71*09537850SAkhilesh Sanikop block_height_ = kTransformHeight[tx_size_];
72*09537850SAkhilesh Sanikop break;
73*09537850SAkhilesh Sanikop }
74*09537850SAkhilesh Sanikop }
75*09537850SAkhilesh Sanikop
76*09537850SAkhilesh Sanikop IntraPredTestBase(const IntraPredTestBase&) = delete;
77*09537850SAkhilesh Sanikop IntraPredTestBase& operator=(const IntraPredTestBase&) = delete;
78*09537850SAkhilesh Sanikop ~IntraPredTestBase() override = default;
79*09537850SAkhilesh Sanikop
80*09537850SAkhilesh Sanikop protected:
81*09537850SAkhilesh Sanikop struct IntraPredMem {
Resetlibgav1::dsp::__anonab1825120111::IntraPredTestBase::IntraPredMem82*09537850SAkhilesh Sanikop void Reset(libvpx_test::ACMRandom* rnd) {
83*09537850SAkhilesh Sanikop ASSERT_NE(rnd, nullptr);
84*09537850SAkhilesh Sanikop #if LIBGAV1_MSAN
85*09537850SAkhilesh Sanikop // Match the behavior of Tile::IntraPrediction to prevent warnings due to
86*09537850SAkhilesh Sanikop // assembly code (safely) overreading to fill a register.
87*09537850SAkhilesh Sanikop memset(left_mem, 0, sizeof(left_mem));
88*09537850SAkhilesh Sanikop memset(top_mem, 0, sizeof(top_mem));
89*09537850SAkhilesh Sanikop #endif // LIBGAV1_MSAN
90*09537850SAkhilesh Sanikop Pixel* const left = left_mem + 16;
91*09537850SAkhilesh Sanikop Pixel* const top = top_mem + 16;
92*09537850SAkhilesh Sanikop const int mask = (1 << bitdepth) - 1;
93*09537850SAkhilesh Sanikop for (auto& r : ref_src) r = rnd->Rand16() & mask;
94*09537850SAkhilesh Sanikop for (int i = 0; i < kMaxBlockSize; ++i) left[i] = rnd->Rand16() & mask;
95*09537850SAkhilesh Sanikop for (int i = -1; i < kMaxBlockSize; ++i) top[i] = rnd->Rand16() & mask;
96*09537850SAkhilesh Sanikop
97*09537850SAkhilesh Sanikop // Some directional predictors require top-right, bottom-left.
98*09537850SAkhilesh Sanikop for (int i = kMaxBlockSize; i < 2 * kMaxBlockSize; ++i) {
99*09537850SAkhilesh Sanikop left[i] = rnd->Rand16() & mask;
100*09537850SAkhilesh Sanikop top[i] = rnd->Rand16() & mask;
101*09537850SAkhilesh Sanikop }
102*09537850SAkhilesh Sanikop // TODO(jzern): reorder this and regenerate the digests after switching
103*09537850SAkhilesh Sanikop // random number generators.
104*09537850SAkhilesh Sanikop // Upsampling in the directional predictors extends left/top[-1] to [-2].
105*09537850SAkhilesh Sanikop left[-1] = rnd->Rand16() & mask;
106*09537850SAkhilesh Sanikop left[-2] = rnd->Rand16() & mask;
107*09537850SAkhilesh Sanikop top[-2] = rnd->Rand16() & mask;
108*09537850SAkhilesh Sanikop memset(left_mem, 0, sizeof(left_mem[0]) * 14);
109*09537850SAkhilesh Sanikop memset(top_mem, 0, sizeof(top_mem[0]) * 14);
110*09537850SAkhilesh Sanikop memset(top_mem + kMaxBlockSize * 2 + 16, 0,
111*09537850SAkhilesh Sanikop sizeof(top_mem[0]) * kTopMemPadding);
112*09537850SAkhilesh Sanikop }
113*09537850SAkhilesh Sanikop
114*09537850SAkhilesh Sanikop // Set ref_src, top-left, top and left to |pixel|.
Setlibgav1::dsp::__anonab1825120111::IntraPredTestBase::IntraPredMem115*09537850SAkhilesh Sanikop void Set(const Pixel pixel) {
116*09537850SAkhilesh Sanikop #if LIBGAV1_MSAN
117*09537850SAkhilesh Sanikop // Match the behavior of Tile::IntraPrediction to prevent warnings due to
118*09537850SAkhilesh Sanikop // assembly code (safely) overreading to fill a register.
119*09537850SAkhilesh Sanikop memset(left_mem, 0, sizeof(left_mem));
120*09537850SAkhilesh Sanikop memset(top_mem, 0, sizeof(top_mem));
121*09537850SAkhilesh Sanikop #endif // LIBGAV1_MSAN
122*09537850SAkhilesh Sanikop Pixel* const left = left_mem + 16;
123*09537850SAkhilesh Sanikop Pixel* const top = top_mem + 16;
124*09537850SAkhilesh Sanikop for (auto& r : ref_src) r = pixel;
125*09537850SAkhilesh Sanikop // Upsampling in the directional predictors extends left/top[-1] to [-2].
126*09537850SAkhilesh Sanikop for (int i = -2; i < 2 * kMaxBlockSize; ++i) {
127*09537850SAkhilesh Sanikop left[i] = top[i] = pixel;
128*09537850SAkhilesh Sanikop }
129*09537850SAkhilesh Sanikop }
130*09537850SAkhilesh Sanikop
131*09537850SAkhilesh Sanikop // DirectionalZone1_Large() overreads up to 7 pixels in |top_mem|.
132*09537850SAkhilesh Sanikop static constexpr int kTopMemPadding = 7;
133*09537850SAkhilesh Sanikop alignas(kMaxAlignment) Pixel dst[kTotalPixels];
134*09537850SAkhilesh Sanikop alignas(kMaxAlignment) Pixel ref_src[kTotalPixels];
135*09537850SAkhilesh Sanikop alignas(kMaxAlignment) Pixel left_mem[kMaxBlockSize * 2 + 16];
136*09537850SAkhilesh Sanikop alignas(
137*09537850SAkhilesh Sanikop kMaxAlignment) Pixel top_mem[kMaxBlockSize * 2 + 16 + kTopMemPadding];
138*09537850SAkhilesh Sanikop };
139*09537850SAkhilesh Sanikop
SetUp()140*09537850SAkhilesh Sanikop void SetUp() override { test_utils::ResetDspTable(bitdepth); }
141*09537850SAkhilesh Sanikop
142*09537850SAkhilesh Sanikop const TransformSize tx_size_ = GetParam();
143*09537850SAkhilesh Sanikop int block_width_;
144*09537850SAkhilesh Sanikop int block_height_;
145*09537850SAkhilesh Sanikop IntraPredMem intra_pred_mem_;
146*09537850SAkhilesh Sanikop };
147*09537850SAkhilesh Sanikop
148*09537850SAkhilesh Sanikop //------------------------------------------------------------------------------
149*09537850SAkhilesh Sanikop // DirectionalIntraPredTest
150*09537850SAkhilesh Sanikop
151*09537850SAkhilesh Sanikop template <int bitdepth, typename Pixel>
152*09537850SAkhilesh Sanikop class DirectionalIntraPredTest : public IntraPredTestBase<bitdepth, Pixel> {
153*09537850SAkhilesh Sanikop public:
154*09537850SAkhilesh Sanikop static_assert(bitdepth >= kBitdepth8 && bitdepth <= LIBGAV1_MAX_BITDEPTH, "");
155*09537850SAkhilesh Sanikop DirectionalIntraPredTest() = default;
156*09537850SAkhilesh Sanikop DirectionalIntraPredTest(const DirectionalIntraPredTest&) = delete;
157*09537850SAkhilesh Sanikop DirectionalIntraPredTest& operator=(const DirectionalIntraPredTest&) = delete;
158*09537850SAkhilesh Sanikop ~DirectionalIntraPredTest() override = default;
159*09537850SAkhilesh Sanikop
160*09537850SAkhilesh Sanikop protected:
161*09537850SAkhilesh Sanikop using IntraPredTestBase<bitdepth, Pixel>::tx_size_;
162*09537850SAkhilesh Sanikop using IntraPredTestBase<bitdepth, Pixel>::block_width_;
163*09537850SAkhilesh Sanikop using IntraPredTestBase<bitdepth, Pixel>::block_height_;
164*09537850SAkhilesh Sanikop using IntraPredTestBase<bitdepth, Pixel>::intra_pred_mem_;
165*09537850SAkhilesh Sanikop
166*09537850SAkhilesh Sanikop enum Zone { kZone1, kZone2, kZone3, kNumZones };
167*09537850SAkhilesh Sanikop
168*09537850SAkhilesh Sanikop enum { kAngleDeltaStart = -9, kAngleDeltaStop = 9, kAngleDeltaStep = 3 };
169*09537850SAkhilesh Sanikop
SetUp()170*09537850SAkhilesh Sanikop void SetUp() override {
171*09537850SAkhilesh Sanikop IntraPredTestBase<bitdepth, Pixel>::SetUp();
172*09537850SAkhilesh Sanikop IntraPredDirectionalInit_C();
173*09537850SAkhilesh Sanikop
174*09537850SAkhilesh Sanikop const Dsp* const dsp = GetDspTable(bitdepth);
175*09537850SAkhilesh Sanikop ASSERT_NE(dsp, nullptr);
176*09537850SAkhilesh Sanikop base_directional_intra_pred_zone1_ = dsp->directional_intra_predictor_zone1;
177*09537850SAkhilesh Sanikop base_directional_intra_pred_zone2_ = dsp->directional_intra_predictor_zone2;
178*09537850SAkhilesh Sanikop base_directional_intra_pred_zone3_ = dsp->directional_intra_predictor_zone3;
179*09537850SAkhilesh Sanikop
180*09537850SAkhilesh Sanikop const testing::TestInfo* const test_info =
181*09537850SAkhilesh Sanikop testing::UnitTest::GetInstance()->current_test_info();
182*09537850SAkhilesh Sanikop const char* const test_case = test_info->test_suite_name();
183*09537850SAkhilesh Sanikop if (absl::StartsWith(test_case, "C/")) {
184*09537850SAkhilesh Sanikop base_directional_intra_pred_zone1_ = nullptr;
185*09537850SAkhilesh Sanikop base_directional_intra_pred_zone2_ = nullptr;
186*09537850SAkhilesh Sanikop base_directional_intra_pred_zone3_ = nullptr;
187*09537850SAkhilesh Sanikop } else if (absl::StartsWith(test_case, "NEON/")) {
188*09537850SAkhilesh Sanikop IntraPredDirectionalInit_NEON();
189*09537850SAkhilesh Sanikop } else if (absl::StartsWith(test_case, "SSE41/")) {
190*09537850SAkhilesh Sanikop if ((GetCpuInfo() & kSSE4_1) == 0) GTEST_SKIP() << "No SSE4.1 support!";
191*09537850SAkhilesh Sanikop IntraPredDirectionalInit_SSE4_1();
192*09537850SAkhilesh Sanikop } else {
193*09537850SAkhilesh Sanikop FAIL() << "Unrecognized architecture prefix in test case name: "
194*09537850SAkhilesh Sanikop << test_case;
195*09537850SAkhilesh Sanikop }
196*09537850SAkhilesh Sanikop
197*09537850SAkhilesh Sanikop cur_directional_intra_pred_zone1_ = dsp->directional_intra_predictor_zone1;
198*09537850SAkhilesh Sanikop cur_directional_intra_pred_zone2_ = dsp->directional_intra_predictor_zone2;
199*09537850SAkhilesh Sanikop cur_directional_intra_pred_zone3_ = dsp->directional_intra_predictor_zone3;
200*09537850SAkhilesh Sanikop
201*09537850SAkhilesh Sanikop // Skip functions that haven't been specialized for this particular
202*09537850SAkhilesh Sanikop // architecture.
203*09537850SAkhilesh Sanikop if (cur_directional_intra_pred_zone1_ ==
204*09537850SAkhilesh Sanikop base_directional_intra_pred_zone1_) {
205*09537850SAkhilesh Sanikop cur_directional_intra_pred_zone1_ = nullptr;
206*09537850SAkhilesh Sanikop }
207*09537850SAkhilesh Sanikop if (cur_directional_intra_pred_zone2_ ==
208*09537850SAkhilesh Sanikop base_directional_intra_pred_zone2_) {
209*09537850SAkhilesh Sanikop cur_directional_intra_pred_zone2_ = nullptr;
210*09537850SAkhilesh Sanikop }
211*09537850SAkhilesh Sanikop if (cur_directional_intra_pred_zone3_ ==
212*09537850SAkhilesh Sanikop base_directional_intra_pred_zone3_) {
213*09537850SAkhilesh Sanikop cur_directional_intra_pred_zone3_ = nullptr;
214*09537850SAkhilesh Sanikop }
215*09537850SAkhilesh Sanikop }
216*09537850SAkhilesh Sanikop
IsEdgeUpsampled(int delta,const int filter_type) const217*09537850SAkhilesh Sanikop bool IsEdgeUpsampled(int delta, const int filter_type) const {
218*09537850SAkhilesh Sanikop delta = std::abs(delta);
219*09537850SAkhilesh Sanikop if (delta == 0 || delta >= 40) return false;
220*09537850SAkhilesh Sanikop const int block_wh = block_width_ + block_height_;
221*09537850SAkhilesh Sanikop return (filter_type == 1) ? block_wh <= 8 : block_wh <= 16;
222*09537850SAkhilesh Sanikop }
223*09537850SAkhilesh Sanikop
224*09537850SAkhilesh Sanikop // Returns the minimum and maximum (exclusive) range of angles that the
225*09537850SAkhilesh Sanikop // predictor should be applied to.
GetZoneAngleRange(const Zone zone,int * const min_angle,int * const max_angle) const226*09537850SAkhilesh Sanikop void GetZoneAngleRange(const Zone zone, int* const min_angle,
227*09537850SAkhilesh Sanikop int* const max_angle) const {
228*09537850SAkhilesh Sanikop ASSERT_NE(min_angle, nullptr);
229*09537850SAkhilesh Sanikop ASSERT_NE(max_angle, nullptr);
230*09537850SAkhilesh Sanikop switch (zone) {
231*09537850SAkhilesh Sanikop // The overall minimum angle comes from mode D45_PRED, yielding:
232*09537850SAkhilesh Sanikop // min_angle = 45-(MAX_ANGLE_DELTA*ANGLE_STEP) = 36
233*09537850SAkhilesh Sanikop // The overall maximum angle comes from mode D203_PRED, yielding:
234*09537850SAkhilesh Sanikop // max_angle = 203+(MAX_ANGLE_DELTA*ANGLE_STEP) = 212
235*09537850SAkhilesh Sanikop // The angles 180 and 90 are not permitted because they correspond to
236*09537850SAkhilesh Sanikop // V_PRED and H_PRED, which are handled in distinct functions.
237*09537850SAkhilesh Sanikop case kZone1:
238*09537850SAkhilesh Sanikop *min_angle = 36;
239*09537850SAkhilesh Sanikop *max_angle = 87;
240*09537850SAkhilesh Sanikop break;
241*09537850SAkhilesh Sanikop case kZone2:
242*09537850SAkhilesh Sanikop *min_angle = 93;
243*09537850SAkhilesh Sanikop *max_angle = 177;
244*09537850SAkhilesh Sanikop break;
245*09537850SAkhilesh Sanikop case kZone3:
246*09537850SAkhilesh Sanikop *min_angle = 183;
247*09537850SAkhilesh Sanikop *max_angle = 212;
248*09537850SAkhilesh Sanikop break;
249*09537850SAkhilesh Sanikop case kNumZones:
250*09537850SAkhilesh Sanikop FAIL() << "Invalid zone value: " << zone;
251*09537850SAkhilesh Sanikop break;
252*09537850SAkhilesh Sanikop }
253*09537850SAkhilesh Sanikop }
254*09537850SAkhilesh Sanikop
255*09537850SAkhilesh Sanikop // These tests modify intra_pred_mem_.
256*09537850SAkhilesh Sanikop void TestSpeed(const char* const digests[kNumDirectionalIntraPredictors],
257*09537850SAkhilesh Sanikop Zone zone, int num_runs);
258*09537850SAkhilesh Sanikop void TestSaturatedValues();
259*09537850SAkhilesh Sanikop void TestRandomValues();
260*09537850SAkhilesh Sanikop
261*09537850SAkhilesh Sanikop DirectionalIntraPredictorZone1Func base_directional_intra_pred_zone1_;
262*09537850SAkhilesh Sanikop DirectionalIntraPredictorZone2Func base_directional_intra_pred_zone2_;
263*09537850SAkhilesh Sanikop DirectionalIntraPredictorZone3Func base_directional_intra_pred_zone3_;
264*09537850SAkhilesh Sanikop DirectionalIntraPredictorZone1Func cur_directional_intra_pred_zone1_;
265*09537850SAkhilesh Sanikop DirectionalIntraPredictorZone2Func cur_directional_intra_pred_zone2_;
266*09537850SAkhilesh Sanikop DirectionalIntraPredictorZone3Func cur_directional_intra_pred_zone3_;
267*09537850SAkhilesh Sanikop };
268*09537850SAkhilesh Sanikop
269*09537850SAkhilesh Sanikop template <int bitdepth, typename Pixel>
TestSpeed(const char * const digests[kNumDirectionalIntraPredictors],const Zone zone,const int num_runs)270*09537850SAkhilesh Sanikop void DirectionalIntraPredTest<bitdepth, Pixel>::TestSpeed(
271*09537850SAkhilesh Sanikop const char* const digests[kNumDirectionalIntraPredictors], const Zone zone,
272*09537850SAkhilesh Sanikop const int num_runs) {
273*09537850SAkhilesh Sanikop switch (zone) {
274*09537850SAkhilesh Sanikop case kZone1:
275*09537850SAkhilesh Sanikop if (cur_directional_intra_pred_zone1_ == nullptr) return;
276*09537850SAkhilesh Sanikop break;
277*09537850SAkhilesh Sanikop case kZone2:
278*09537850SAkhilesh Sanikop if (cur_directional_intra_pred_zone2_ == nullptr) return;
279*09537850SAkhilesh Sanikop break;
280*09537850SAkhilesh Sanikop case kZone3:
281*09537850SAkhilesh Sanikop if (cur_directional_intra_pred_zone3_ == nullptr) return;
282*09537850SAkhilesh Sanikop break;
283*09537850SAkhilesh Sanikop case kNumZones:
284*09537850SAkhilesh Sanikop FAIL() << "Invalid zone value: " << zone;
285*09537850SAkhilesh Sanikop break;
286*09537850SAkhilesh Sanikop }
287*09537850SAkhilesh Sanikop ASSERT_NE(digests, nullptr);
288*09537850SAkhilesh Sanikop const Pixel* const left = intra_pred_mem_.left_mem + 16;
289*09537850SAkhilesh Sanikop const Pixel* const top = intra_pred_mem_.top_mem + 16;
290*09537850SAkhilesh Sanikop
291*09537850SAkhilesh Sanikop libvpx_test::ACMRandom rnd(libvpx_test::ACMRandom::DeterministicSeed());
292*09537850SAkhilesh Sanikop intra_pred_mem_.Reset(&rnd);
293*09537850SAkhilesh Sanikop
294*09537850SAkhilesh Sanikop // Allocate separate blocks for each angle + filter + upsampled combination.
295*09537850SAkhilesh Sanikop // Add a 1 pixel right border to test for overwrites.
296*09537850SAkhilesh Sanikop static constexpr int kMaxZoneAngles = 27; // zone 2
297*09537850SAkhilesh Sanikop static constexpr int kMaxFilterTypes = 2;
298*09537850SAkhilesh Sanikop static constexpr int kBlockBorder = 1;
299*09537850SAkhilesh Sanikop static constexpr int kBorderSize =
300*09537850SAkhilesh Sanikop kBlockBorder * kMaxZoneAngles * kMaxFilterTypes;
301*09537850SAkhilesh Sanikop const int ref_stride =
302*09537850SAkhilesh Sanikop kMaxZoneAngles * kMaxFilterTypes * block_width_ + kBorderSize;
303*09537850SAkhilesh Sanikop const size_t ref_alloc_size = sizeof(Pixel) * ref_stride * block_height_;
304*09537850SAkhilesh Sanikop
305*09537850SAkhilesh Sanikop using AlignedPtr = std::unique_ptr<Pixel[], decltype(&AlignedFree)>;
306*09537850SAkhilesh Sanikop AlignedPtr ref_src(static_cast<Pixel*>(AlignedAlloc(16, ref_alloc_size)),
307*09537850SAkhilesh Sanikop &AlignedFree);
308*09537850SAkhilesh Sanikop AlignedPtr dest(static_cast<Pixel*>(AlignedAlloc(16, ref_alloc_size)),
309*09537850SAkhilesh Sanikop &AlignedFree);
310*09537850SAkhilesh Sanikop ASSERT_NE(ref_src, nullptr);
311*09537850SAkhilesh Sanikop ASSERT_NE(dest, nullptr);
312*09537850SAkhilesh Sanikop
313*09537850SAkhilesh Sanikop const int mask = (1 << bitdepth) - 1;
314*09537850SAkhilesh Sanikop for (size_t i = 0; i < ref_alloc_size / sizeof(ref_src[0]); ++i) {
315*09537850SAkhilesh Sanikop ref_src[i] = rnd.Rand16() & mask;
316*09537850SAkhilesh Sanikop }
317*09537850SAkhilesh Sanikop
318*09537850SAkhilesh Sanikop int min_angle = 0, max_angle = 0;
319*09537850SAkhilesh Sanikop ASSERT_NO_FATAL_FAILURE(GetZoneAngleRange(zone, &min_angle, &max_angle));
320*09537850SAkhilesh Sanikop
321*09537850SAkhilesh Sanikop absl::Duration elapsed_time;
322*09537850SAkhilesh Sanikop for (int run = 0; run < num_runs; ++run) {
323*09537850SAkhilesh Sanikop Pixel* dst = dest.get();
324*09537850SAkhilesh Sanikop memcpy(dst, ref_src.get(), ref_alloc_size);
325*09537850SAkhilesh Sanikop for (const auto& base_angle : kBaseAngles) {
326*09537850SAkhilesh Sanikop for (int filter_type = 0; filter_type <= 1; ++filter_type) {
327*09537850SAkhilesh Sanikop for (int angle_delta = kAngleDeltaStart; angle_delta <= kAngleDeltaStop;
328*09537850SAkhilesh Sanikop angle_delta += kAngleDeltaStep) {
329*09537850SAkhilesh Sanikop const int predictor_angle = base_angle + angle_delta;
330*09537850SAkhilesh Sanikop if (predictor_angle < min_angle || predictor_angle > max_angle) {
331*09537850SAkhilesh Sanikop continue;
332*09537850SAkhilesh Sanikop }
333*09537850SAkhilesh Sanikop
334*09537850SAkhilesh Sanikop ASSERT_GT(predictor_angle, 0) << "base_angle: " << base_angle
335*09537850SAkhilesh Sanikop << " angle_delta: " << angle_delta;
336*09537850SAkhilesh Sanikop const bool upsampled_left =
337*09537850SAkhilesh Sanikop IsEdgeUpsampled(predictor_angle - 180, filter_type);
338*09537850SAkhilesh Sanikop const bool upsampled_top =
339*09537850SAkhilesh Sanikop IsEdgeUpsampled(predictor_angle - 90, filter_type);
340*09537850SAkhilesh Sanikop const ptrdiff_t stride = ref_stride * sizeof(ref_src[0]);
341*09537850SAkhilesh Sanikop if (predictor_angle < 90) {
342*09537850SAkhilesh Sanikop ASSERT_EQ(zone, kZone1);
343*09537850SAkhilesh Sanikop const int xstep =
344*09537850SAkhilesh Sanikop GetDirectionalIntraPredictorDerivative(predictor_angle);
345*09537850SAkhilesh Sanikop const absl::Time start = absl::Now();
346*09537850SAkhilesh Sanikop cur_directional_intra_pred_zone1_(dst, stride, top, block_width_,
347*09537850SAkhilesh Sanikop block_height_, xstep,
348*09537850SAkhilesh Sanikop upsampled_top);
349*09537850SAkhilesh Sanikop elapsed_time += absl::Now() - start;
350*09537850SAkhilesh Sanikop } else if (predictor_angle < 180) {
351*09537850SAkhilesh Sanikop ASSERT_EQ(zone, kZone2);
352*09537850SAkhilesh Sanikop const int xstep =
353*09537850SAkhilesh Sanikop GetDirectionalIntraPredictorDerivative(180 - predictor_angle);
354*09537850SAkhilesh Sanikop const int ystep =
355*09537850SAkhilesh Sanikop GetDirectionalIntraPredictorDerivative(predictor_angle - 90);
356*09537850SAkhilesh Sanikop const absl::Time start = absl::Now();
357*09537850SAkhilesh Sanikop cur_directional_intra_pred_zone2_(
358*09537850SAkhilesh Sanikop dst, stride, top, left, block_width_, block_height_, xstep,
359*09537850SAkhilesh Sanikop ystep, upsampled_top, upsampled_left);
360*09537850SAkhilesh Sanikop elapsed_time += absl::Now() - start;
361*09537850SAkhilesh Sanikop } else {
362*09537850SAkhilesh Sanikop ASSERT_EQ(zone, kZone3);
363*09537850SAkhilesh Sanikop ASSERT_LT(predictor_angle, 270);
364*09537850SAkhilesh Sanikop const int ystep =
365*09537850SAkhilesh Sanikop GetDirectionalIntraPredictorDerivative(270 - predictor_angle);
366*09537850SAkhilesh Sanikop const absl::Time start = absl::Now();
367*09537850SAkhilesh Sanikop cur_directional_intra_pred_zone3_(dst, stride, left, block_width_,
368*09537850SAkhilesh Sanikop block_height_, ystep,
369*09537850SAkhilesh Sanikop upsampled_left);
370*09537850SAkhilesh Sanikop elapsed_time += absl::Now() - start;
371*09537850SAkhilesh Sanikop }
372*09537850SAkhilesh Sanikop dst += block_width_ + kBlockBorder;
373*09537850SAkhilesh Sanikop }
374*09537850SAkhilesh Sanikop }
375*09537850SAkhilesh Sanikop }
376*09537850SAkhilesh Sanikop }
377*09537850SAkhilesh Sanikop
378*09537850SAkhilesh Sanikop test_utils::CheckMd5Digest(ToString(tx_size_), kDirectionalPredNames[zone],
379*09537850SAkhilesh Sanikop digests[zone], dest.get(), ref_alloc_size,
380*09537850SAkhilesh Sanikop elapsed_time);
381*09537850SAkhilesh Sanikop }
382*09537850SAkhilesh Sanikop
383*09537850SAkhilesh Sanikop template <int bitdepth, typename Pixel>
TestSaturatedValues()384*09537850SAkhilesh Sanikop void DirectionalIntraPredTest<bitdepth, Pixel>::TestSaturatedValues() {
385*09537850SAkhilesh Sanikop const Pixel* const left = intra_pred_mem_.left_mem + 16;
386*09537850SAkhilesh Sanikop const Pixel* const top = intra_pred_mem_.top_mem + 16;
387*09537850SAkhilesh Sanikop const auto kMaxPixel = static_cast<Pixel>((1 << bitdepth) - 1);
388*09537850SAkhilesh Sanikop intra_pred_mem_.Set(kMaxPixel);
389*09537850SAkhilesh Sanikop
390*09537850SAkhilesh Sanikop for (int i = kZone1; i < kNumZones; ++i) {
391*09537850SAkhilesh Sanikop switch (i) {
392*09537850SAkhilesh Sanikop case kZone1:
393*09537850SAkhilesh Sanikop if (cur_directional_intra_pred_zone1_ == nullptr) continue;
394*09537850SAkhilesh Sanikop break;
395*09537850SAkhilesh Sanikop case kZone2:
396*09537850SAkhilesh Sanikop if (cur_directional_intra_pred_zone2_ == nullptr) continue;
397*09537850SAkhilesh Sanikop break;
398*09537850SAkhilesh Sanikop case kZone3:
399*09537850SAkhilesh Sanikop if (cur_directional_intra_pred_zone3_ == nullptr) continue;
400*09537850SAkhilesh Sanikop break;
401*09537850SAkhilesh Sanikop case kNumZones:
402*09537850SAkhilesh Sanikop FAIL() << "Invalid zone value: " << i;
403*09537850SAkhilesh Sanikop break;
404*09537850SAkhilesh Sanikop }
405*09537850SAkhilesh Sanikop int min_angle = 0, max_angle = 0;
406*09537850SAkhilesh Sanikop ASSERT_NO_FATAL_FAILURE(
407*09537850SAkhilesh Sanikop GetZoneAngleRange(static_cast<Zone>(i), &min_angle, &max_angle));
408*09537850SAkhilesh Sanikop
409*09537850SAkhilesh Sanikop for (const auto& base_angle : kBaseAngles) {
410*09537850SAkhilesh Sanikop for (int filter_type = 0; filter_type <= 1; ++filter_type) {
411*09537850SAkhilesh Sanikop for (int angle_delta = kAngleDeltaStart; angle_delta <= kAngleDeltaStop;
412*09537850SAkhilesh Sanikop angle_delta += kAngleDeltaStep) {
413*09537850SAkhilesh Sanikop const int predictor_angle = base_angle + angle_delta;
414*09537850SAkhilesh Sanikop if (predictor_angle <= min_angle || predictor_angle >= max_angle) {
415*09537850SAkhilesh Sanikop continue;
416*09537850SAkhilesh Sanikop }
417*09537850SAkhilesh Sanikop ASSERT_GT(predictor_angle, 0) << "base_angle: " << base_angle
418*09537850SAkhilesh Sanikop << " angle_delta: " << angle_delta;
419*09537850SAkhilesh Sanikop
420*09537850SAkhilesh Sanikop memcpy(intra_pred_mem_.dst, intra_pred_mem_.ref_src,
421*09537850SAkhilesh Sanikop sizeof(intra_pred_mem_.dst));
422*09537850SAkhilesh Sanikop
423*09537850SAkhilesh Sanikop const bool upsampled_left =
424*09537850SAkhilesh Sanikop IsEdgeUpsampled(predictor_angle - 180, filter_type);
425*09537850SAkhilesh Sanikop const bool upsampled_top =
426*09537850SAkhilesh Sanikop IsEdgeUpsampled(predictor_angle - 90, filter_type);
427*09537850SAkhilesh Sanikop const ptrdiff_t stride = kMaxBlockSize * sizeof(Pixel);
428*09537850SAkhilesh Sanikop if (predictor_angle < 90) {
429*09537850SAkhilesh Sanikop const int xstep =
430*09537850SAkhilesh Sanikop GetDirectionalIntraPredictorDerivative(predictor_angle);
431*09537850SAkhilesh Sanikop cur_directional_intra_pred_zone1_(intra_pred_mem_.dst, stride, top,
432*09537850SAkhilesh Sanikop block_width_, block_height_,
433*09537850SAkhilesh Sanikop xstep, upsampled_top);
434*09537850SAkhilesh Sanikop } else if (predictor_angle < 180) {
435*09537850SAkhilesh Sanikop const int xstep =
436*09537850SAkhilesh Sanikop GetDirectionalIntraPredictorDerivative(180 - predictor_angle);
437*09537850SAkhilesh Sanikop const int ystep =
438*09537850SAkhilesh Sanikop GetDirectionalIntraPredictorDerivative(predictor_angle - 90);
439*09537850SAkhilesh Sanikop cur_directional_intra_pred_zone2_(
440*09537850SAkhilesh Sanikop intra_pred_mem_.dst, stride, top, left, block_width_,
441*09537850SAkhilesh Sanikop block_height_, xstep, ystep, upsampled_top, upsampled_left);
442*09537850SAkhilesh Sanikop } else {
443*09537850SAkhilesh Sanikop ASSERT_LT(predictor_angle, 270);
444*09537850SAkhilesh Sanikop const int ystep =
445*09537850SAkhilesh Sanikop GetDirectionalIntraPredictorDerivative(270 - predictor_angle);
446*09537850SAkhilesh Sanikop cur_directional_intra_pred_zone3_(intra_pred_mem_.dst, stride, left,
447*09537850SAkhilesh Sanikop block_width_, block_height_,
448*09537850SAkhilesh Sanikop ystep, upsampled_left);
449*09537850SAkhilesh Sanikop }
450*09537850SAkhilesh Sanikop
451*09537850SAkhilesh Sanikop if (!test_utils::CompareBlocks(
452*09537850SAkhilesh Sanikop intra_pred_mem_.dst, intra_pred_mem_.ref_src, block_width_,
453*09537850SAkhilesh Sanikop block_height_, kMaxBlockSize, kMaxBlockSize, true)) {
454*09537850SAkhilesh Sanikop ADD_FAILURE() << "Expected " << kDirectionalPredNames[i]
455*09537850SAkhilesh Sanikop << " (angle: " << predictor_angle
456*09537850SAkhilesh Sanikop << " filter type: " << filter_type
457*09537850SAkhilesh Sanikop << ") to produce a block containing '"
458*09537850SAkhilesh Sanikop << static_cast<int>(kMaxPixel) << "'";
459*09537850SAkhilesh Sanikop return;
460*09537850SAkhilesh Sanikop }
461*09537850SAkhilesh Sanikop }
462*09537850SAkhilesh Sanikop }
463*09537850SAkhilesh Sanikop }
464*09537850SAkhilesh Sanikop }
465*09537850SAkhilesh Sanikop }
466*09537850SAkhilesh Sanikop
467*09537850SAkhilesh Sanikop template <int bitdepth, typename Pixel>
TestRandomValues()468*09537850SAkhilesh Sanikop void DirectionalIntraPredTest<bitdepth, Pixel>::TestRandomValues() {
469*09537850SAkhilesh Sanikop const Pixel* const left = intra_pred_mem_.left_mem + 16;
470*09537850SAkhilesh Sanikop const Pixel* const top = intra_pred_mem_.top_mem + 16;
471*09537850SAkhilesh Sanikop // Use an alternate seed to differentiate this test from TestSpeed().
472*09537850SAkhilesh Sanikop libvpx_test::ACMRandom rnd(test_utils::kAlternateDeterministicSeed);
473*09537850SAkhilesh Sanikop
474*09537850SAkhilesh Sanikop for (int i = kZone1; i < kNumZones; ++i) {
475*09537850SAkhilesh Sanikop // Only run when there is a reference version (base) and a different
476*09537850SAkhilesh Sanikop // optimized version (cur).
477*09537850SAkhilesh Sanikop switch (i) {
478*09537850SAkhilesh Sanikop case kZone1:
479*09537850SAkhilesh Sanikop if (base_directional_intra_pred_zone1_ == nullptr ||
480*09537850SAkhilesh Sanikop cur_directional_intra_pred_zone1_ == nullptr) {
481*09537850SAkhilesh Sanikop continue;
482*09537850SAkhilesh Sanikop }
483*09537850SAkhilesh Sanikop break;
484*09537850SAkhilesh Sanikop case kZone2:
485*09537850SAkhilesh Sanikop if (base_directional_intra_pred_zone2_ == nullptr ||
486*09537850SAkhilesh Sanikop cur_directional_intra_pred_zone2_ == nullptr) {
487*09537850SAkhilesh Sanikop continue;
488*09537850SAkhilesh Sanikop }
489*09537850SAkhilesh Sanikop break;
490*09537850SAkhilesh Sanikop case kZone3:
491*09537850SAkhilesh Sanikop if (base_directional_intra_pred_zone3_ == nullptr ||
492*09537850SAkhilesh Sanikop cur_directional_intra_pred_zone3_ == nullptr) {
493*09537850SAkhilesh Sanikop continue;
494*09537850SAkhilesh Sanikop }
495*09537850SAkhilesh Sanikop break;
496*09537850SAkhilesh Sanikop case kNumZones:
497*09537850SAkhilesh Sanikop FAIL() << "Invalid zone value: " << i;
498*09537850SAkhilesh Sanikop break;
499*09537850SAkhilesh Sanikop }
500*09537850SAkhilesh Sanikop int min_angle = 0, max_angle = 0;
501*09537850SAkhilesh Sanikop ASSERT_NO_FATAL_FAILURE(
502*09537850SAkhilesh Sanikop GetZoneAngleRange(static_cast<Zone>(i), &min_angle, &max_angle));
503*09537850SAkhilesh Sanikop
504*09537850SAkhilesh Sanikop for (const auto& base_angle : kBaseAngles) {
505*09537850SAkhilesh Sanikop for (int n = 0; n < 1000; ++n) {
506*09537850SAkhilesh Sanikop for (int filter_type = 0; filter_type <= 1; ++filter_type) {
507*09537850SAkhilesh Sanikop for (int angle_delta = kAngleDeltaStart;
508*09537850SAkhilesh Sanikop angle_delta <= kAngleDeltaStop; angle_delta += kAngleDeltaStep) {
509*09537850SAkhilesh Sanikop const int predictor_angle = base_angle + angle_delta;
510*09537850SAkhilesh Sanikop if (predictor_angle <= min_angle || predictor_angle >= max_angle) {
511*09537850SAkhilesh Sanikop continue;
512*09537850SAkhilesh Sanikop }
513*09537850SAkhilesh Sanikop ASSERT_GT(predictor_angle, 0) << "base_angle: " << base_angle
514*09537850SAkhilesh Sanikop << " angle_delta: " << angle_delta;
515*09537850SAkhilesh Sanikop
516*09537850SAkhilesh Sanikop intra_pred_mem_.Reset(&rnd);
517*09537850SAkhilesh Sanikop memcpy(intra_pred_mem_.dst, intra_pred_mem_.ref_src,
518*09537850SAkhilesh Sanikop sizeof(intra_pred_mem_.dst));
519*09537850SAkhilesh Sanikop
520*09537850SAkhilesh Sanikop const bool upsampled_left =
521*09537850SAkhilesh Sanikop IsEdgeUpsampled(predictor_angle - 180, filter_type);
522*09537850SAkhilesh Sanikop const bool upsampled_top =
523*09537850SAkhilesh Sanikop IsEdgeUpsampled(predictor_angle - 90, filter_type);
524*09537850SAkhilesh Sanikop const ptrdiff_t stride = kMaxBlockSize * sizeof(Pixel);
525*09537850SAkhilesh Sanikop if (predictor_angle < 90) {
526*09537850SAkhilesh Sanikop const int xstep =
527*09537850SAkhilesh Sanikop GetDirectionalIntraPredictorDerivative(predictor_angle);
528*09537850SAkhilesh Sanikop base_directional_intra_pred_zone1_(
529*09537850SAkhilesh Sanikop intra_pred_mem_.ref_src, stride, top, block_width_,
530*09537850SAkhilesh Sanikop block_height_, xstep, upsampled_top);
531*09537850SAkhilesh Sanikop cur_directional_intra_pred_zone1_(
532*09537850SAkhilesh Sanikop intra_pred_mem_.dst, stride, top, block_width_, block_height_,
533*09537850SAkhilesh Sanikop xstep, upsampled_top);
534*09537850SAkhilesh Sanikop } else if (predictor_angle < 180) {
535*09537850SAkhilesh Sanikop const int xstep =
536*09537850SAkhilesh Sanikop GetDirectionalIntraPredictorDerivative(180 - predictor_angle);
537*09537850SAkhilesh Sanikop const int ystep =
538*09537850SAkhilesh Sanikop GetDirectionalIntraPredictorDerivative(predictor_angle - 90);
539*09537850SAkhilesh Sanikop base_directional_intra_pred_zone2_(
540*09537850SAkhilesh Sanikop intra_pred_mem_.ref_src, stride, top, left, block_width_,
541*09537850SAkhilesh Sanikop block_height_, xstep, ystep, upsampled_top, upsampled_left);
542*09537850SAkhilesh Sanikop cur_directional_intra_pred_zone2_(
543*09537850SAkhilesh Sanikop intra_pred_mem_.dst, stride, top, left, block_width_,
544*09537850SAkhilesh Sanikop block_height_, xstep, ystep, upsampled_top, upsampled_left);
545*09537850SAkhilesh Sanikop } else {
546*09537850SAkhilesh Sanikop ASSERT_LT(predictor_angle, 270);
547*09537850SAkhilesh Sanikop const int ystep =
548*09537850SAkhilesh Sanikop GetDirectionalIntraPredictorDerivative(270 - predictor_angle);
549*09537850SAkhilesh Sanikop base_directional_intra_pred_zone3_(
550*09537850SAkhilesh Sanikop intra_pred_mem_.ref_src, stride, left, block_width_,
551*09537850SAkhilesh Sanikop block_height_, ystep, upsampled_left);
552*09537850SAkhilesh Sanikop cur_directional_intra_pred_zone3_(
553*09537850SAkhilesh Sanikop intra_pred_mem_.dst, stride, left, block_width_,
554*09537850SAkhilesh Sanikop block_height_, ystep, upsampled_left);
555*09537850SAkhilesh Sanikop }
556*09537850SAkhilesh Sanikop
557*09537850SAkhilesh Sanikop if (!test_utils::CompareBlocks(
558*09537850SAkhilesh Sanikop intra_pred_mem_.dst, intra_pred_mem_.ref_src, block_width_,
559*09537850SAkhilesh Sanikop block_height_, kMaxBlockSize, kMaxBlockSize, true)) {
560*09537850SAkhilesh Sanikop ADD_FAILURE() << "Result from optimized version of "
561*09537850SAkhilesh Sanikop << kDirectionalPredNames[i]
562*09537850SAkhilesh Sanikop << " differs from reference at angle "
563*09537850SAkhilesh Sanikop << predictor_angle << " with filter type "
564*09537850SAkhilesh Sanikop << filter_type << " in iteration #" << n;
565*09537850SAkhilesh Sanikop return;
566*09537850SAkhilesh Sanikop }
567*09537850SAkhilesh Sanikop }
568*09537850SAkhilesh Sanikop }
569*09537850SAkhilesh Sanikop }
570*09537850SAkhilesh Sanikop }
571*09537850SAkhilesh Sanikop }
572*09537850SAkhilesh Sanikop }
573*09537850SAkhilesh Sanikop
574*09537850SAkhilesh Sanikop using DirectionalIntraPredTest8bpp = DirectionalIntraPredTest<8, uint8_t>;
575*09537850SAkhilesh Sanikop
GetDirectionalIntraPredDigests8bpp(TransformSize tx_size)576*09537850SAkhilesh Sanikop const char* const* GetDirectionalIntraPredDigests8bpp(TransformSize tx_size) {
577*09537850SAkhilesh Sanikop static const char* const kDigests4x4[kNumDirectionalIntraPredictors] = {
578*09537850SAkhilesh Sanikop "9cfc1da729ad08682e165826c29b280b",
579*09537850SAkhilesh Sanikop "bb73539c7afbda7bddd2184723b932d6",
580*09537850SAkhilesh Sanikop "9d2882800ffe948196e984a26a2da72c",
581*09537850SAkhilesh Sanikop };
582*09537850SAkhilesh Sanikop static const char* const kDigests4x8[kNumDirectionalIntraPredictors] = {
583*09537850SAkhilesh Sanikop "090efe6f83cc6fa301f65d3bbd5c38d2",
584*09537850SAkhilesh Sanikop "d0fba4cdfb90f8bd293a94cae9db1a15",
585*09537850SAkhilesh Sanikop "f7ad0eeab4389d0baa485d30fec87617",
586*09537850SAkhilesh Sanikop };
587*09537850SAkhilesh Sanikop static const char* const kDigests4x16[kNumDirectionalIntraPredictors] = {
588*09537850SAkhilesh Sanikop "1d32b33c75fe85248c48cdc8caa78d84",
589*09537850SAkhilesh Sanikop "7000e18159443d366129a6cc6ef8fcee",
590*09537850SAkhilesh Sanikop "06c02fac5f8575f687abb3f634eb0b4c",
591*09537850SAkhilesh Sanikop };
592*09537850SAkhilesh Sanikop static const char* const kDigests8x4[kNumDirectionalIntraPredictors] = {
593*09537850SAkhilesh Sanikop "1b591799685bc135982114b731293f78",
594*09537850SAkhilesh Sanikop "5cd9099acb9f7b2618dafa6712666580",
595*09537850SAkhilesh Sanikop "d023883efede88f99c19d006044d9fa1",
596*09537850SAkhilesh Sanikop };
597*09537850SAkhilesh Sanikop static const char* const kDigests8x8[kNumDirectionalIntraPredictors] = {
598*09537850SAkhilesh Sanikop "f1e46ecf62a2516852f30c5025adb7ea",
599*09537850SAkhilesh Sanikop "864442a209c16998065af28d8cdd839a",
600*09537850SAkhilesh Sanikop "411a6e554868982af577de69e53f12e8",
601*09537850SAkhilesh Sanikop };
602*09537850SAkhilesh Sanikop static const char* const kDigests8x16[kNumDirectionalIntraPredictors] = {
603*09537850SAkhilesh Sanikop "89278302be913a85cfb06feaea339459",
604*09537850SAkhilesh Sanikop "6c42f1a9493490cd4529fd40729cec3c",
605*09537850SAkhilesh Sanikop "2516b5e1c681e5dcb1acedd5f3d41106",
606*09537850SAkhilesh Sanikop };
607*09537850SAkhilesh Sanikop static const char* const kDigests8x32[kNumDirectionalIntraPredictors] = {
608*09537850SAkhilesh Sanikop "aea7078f3eeaa8afbfe6c959c9e676f1",
609*09537850SAkhilesh Sanikop "cad30babf12729dda5010362223ba65c",
610*09537850SAkhilesh Sanikop "ff384ebdc832007775af418a2aae1463",
611*09537850SAkhilesh Sanikop };
612*09537850SAkhilesh Sanikop static const char* const kDigests16x4[kNumDirectionalIntraPredictors] = {
613*09537850SAkhilesh Sanikop "964a821c313c831e12f4d32e616c0b55",
614*09537850SAkhilesh Sanikop "adf6dad3a84ab4d16c16eea218bec57a",
615*09537850SAkhilesh Sanikop "a54fa008d43895e523474686c48a81c2",
616*09537850SAkhilesh Sanikop };
617*09537850SAkhilesh Sanikop static const char* const kDigests16x8[kNumDirectionalIntraPredictors] = {
618*09537850SAkhilesh Sanikop "fe2851b4e4f9fcf924cf17d50415a4c0",
619*09537850SAkhilesh Sanikop "50a0e279c481437ff315d08eb904c733",
620*09537850SAkhilesh Sanikop "0682065c8fb6cbf9be4949316c87c9e5",
621*09537850SAkhilesh Sanikop };
622*09537850SAkhilesh Sanikop static const char* const kDigests16x16[kNumDirectionalIntraPredictors] = {
623*09537850SAkhilesh Sanikop "ef15503b1943642e7a0bace1616c0e11",
624*09537850SAkhilesh Sanikop "bf1a4d3f855f1072a902a88ec6ce0350",
625*09537850SAkhilesh Sanikop "7e87a03e29cd7fd843fd71b729a18f3f",
626*09537850SAkhilesh Sanikop };
627*09537850SAkhilesh Sanikop static const char* const kDigests16x32[kNumDirectionalIntraPredictors] = {
628*09537850SAkhilesh Sanikop "f7b636615d2e5bf289b5db452a6f188d",
629*09537850SAkhilesh Sanikop "e95858c532c10d00b0ce7a02a02121dd",
630*09537850SAkhilesh Sanikop "34a18ccf58ef490f32268e85ce8c7de4",
631*09537850SAkhilesh Sanikop };
632*09537850SAkhilesh Sanikop static const char* const kDigests16x64[kNumDirectionalIntraPredictors] = {
633*09537850SAkhilesh Sanikop "b250099986c2fab9670748598058846b",
634*09537850SAkhilesh Sanikop "f25d80af4da862a9b6b72979f1e17cb4",
635*09537850SAkhilesh Sanikop "5347dc7bc346733b4887f6c8ad5e0898",
636*09537850SAkhilesh Sanikop };
637*09537850SAkhilesh Sanikop static const char* const kDigests32x8[kNumDirectionalIntraPredictors] = {
638*09537850SAkhilesh Sanikop "72e4c9f8af043b1cb1263490351818ab",
639*09537850SAkhilesh Sanikop "1fc010d2df011b9e4e3d0957107c78df",
640*09537850SAkhilesh Sanikop "f4cbfa3ca941ef08b972a68d7e7bafc4",
641*09537850SAkhilesh Sanikop };
642*09537850SAkhilesh Sanikop static const char* const kDigests32x16[kNumDirectionalIntraPredictors] = {
643*09537850SAkhilesh Sanikop "37e5a1aaf7549d2bce08eece9d20f0f6",
644*09537850SAkhilesh Sanikop "6a2794025d0aca414ab17baa3cf8251a",
645*09537850SAkhilesh Sanikop "63dd37a6efdc91eeefef166c99ce2db1",
646*09537850SAkhilesh Sanikop };
647*09537850SAkhilesh Sanikop static const char* const kDigests32x32[kNumDirectionalIntraPredictors] = {
648*09537850SAkhilesh Sanikop "198aabc958992eb49cceab97d1acb43e",
649*09537850SAkhilesh Sanikop "aee88b6c8bacfcf38799fe338e6c66e7",
650*09537850SAkhilesh Sanikop "01e8f8f96696636f6d79d33951907a16",
651*09537850SAkhilesh Sanikop };
652*09537850SAkhilesh Sanikop static const char* const kDigests32x64[kNumDirectionalIntraPredictors] = {
653*09537850SAkhilesh Sanikop "0611390202c4f90f7add7aec763ded58",
654*09537850SAkhilesh Sanikop "960240c7ceda2ccfac7c90b71460578a",
655*09537850SAkhilesh Sanikop "7e7d97594aab8ad56e8c01c340335607",
656*09537850SAkhilesh Sanikop };
657*09537850SAkhilesh Sanikop static const char* const kDigests64x16[kNumDirectionalIntraPredictors] = {
658*09537850SAkhilesh Sanikop "7e1f567e7fc510757f2d89d638bc826f",
659*09537850SAkhilesh Sanikop "c929d687352ce40a58670be2ce3c8c90",
660*09537850SAkhilesh Sanikop "f6881e6a9ba3c3d3d730b425732656b1",
661*09537850SAkhilesh Sanikop };
662*09537850SAkhilesh Sanikop static const char* const kDigests64x32[kNumDirectionalIntraPredictors] = {
663*09537850SAkhilesh Sanikop "27b4c2a7081d4139f22003ba8b6dfdf2",
664*09537850SAkhilesh Sanikop "301e82740866b9274108a04c872fa848",
665*09537850SAkhilesh Sanikop "98d3aa4fef838f4abf00dac33806659f",
666*09537850SAkhilesh Sanikop };
667*09537850SAkhilesh Sanikop static const char* const kDigests64x64[kNumDirectionalIntraPredictors] = {
668*09537850SAkhilesh Sanikop "b31816db8fade3accfd975b21aa264c7",
669*09537850SAkhilesh Sanikop "2adce01a03b9452633d5830e1a9b4e23",
670*09537850SAkhilesh Sanikop "7b988fadba8b07c36e88d7be6b270494",
671*09537850SAkhilesh Sanikop };
672*09537850SAkhilesh Sanikop
673*09537850SAkhilesh Sanikop switch (tx_size) {
674*09537850SAkhilesh Sanikop case kTransformSize4x4:
675*09537850SAkhilesh Sanikop return kDigests4x4;
676*09537850SAkhilesh Sanikop case kTransformSize4x8:
677*09537850SAkhilesh Sanikop return kDigests4x8;
678*09537850SAkhilesh Sanikop case kTransformSize4x16:
679*09537850SAkhilesh Sanikop return kDigests4x16;
680*09537850SAkhilesh Sanikop case kTransformSize8x4:
681*09537850SAkhilesh Sanikop return kDigests8x4;
682*09537850SAkhilesh Sanikop case kTransformSize8x8:
683*09537850SAkhilesh Sanikop return kDigests8x8;
684*09537850SAkhilesh Sanikop case kTransformSize8x16:
685*09537850SAkhilesh Sanikop return kDigests8x16;
686*09537850SAkhilesh Sanikop case kTransformSize8x32:
687*09537850SAkhilesh Sanikop return kDigests8x32;
688*09537850SAkhilesh Sanikop case kTransformSize16x4:
689*09537850SAkhilesh Sanikop return kDigests16x4;
690*09537850SAkhilesh Sanikop case kTransformSize16x8:
691*09537850SAkhilesh Sanikop return kDigests16x8;
692*09537850SAkhilesh Sanikop case kTransformSize16x16:
693*09537850SAkhilesh Sanikop return kDigests16x16;
694*09537850SAkhilesh Sanikop case kTransformSize16x32:
695*09537850SAkhilesh Sanikop return kDigests16x32;
696*09537850SAkhilesh Sanikop case kTransformSize16x64:
697*09537850SAkhilesh Sanikop return kDigests16x64;
698*09537850SAkhilesh Sanikop case kTransformSize32x8:
699*09537850SAkhilesh Sanikop return kDigests32x8;
700*09537850SAkhilesh Sanikop case kTransformSize32x16:
701*09537850SAkhilesh Sanikop return kDigests32x16;
702*09537850SAkhilesh Sanikop case kTransformSize32x32:
703*09537850SAkhilesh Sanikop return kDigests32x32;
704*09537850SAkhilesh Sanikop case kTransformSize32x64:
705*09537850SAkhilesh Sanikop return kDigests32x64;
706*09537850SAkhilesh Sanikop case kTransformSize64x16:
707*09537850SAkhilesh Sanikop return kDigests64x16;
708*09537850SAkhilesh Sanikop case kTransformSize64x32:
709*09537850SAkhilesh Sanikop return kDigests64x32;
710*09537850SAkhilesh Sanikop case kTransformSize64x64:
711*09537850SAkhilesh Sanikop return kDigests64x64;
712*09537850SAkhilesh Sanikop default:
713*09537850SAkhilesh Sanikop ADD_FAILURE() << "Unknown transform size: " << tx_size;
714*09537850SAkhilesh Sanikop return nullptr;
715*09537850SAkhilesh Sanikop }
716*09537850SAkhilesh Sanikop }
717*09537850SAkhilesh Sanikop
TEST_P(DirectionalIntraPredTest8bpp,DISABLED_Speed)718*09537850SAkhilesh Sanikop TEST_P(DirectionalIntraPredTest8bpp, DISABLED_Speed) {
719*09537850SAkhilesh Sanikop #if LIBGAV1_ENABLE_NEON
720*09537850SAkhilesh Sanikop const auto num_runs = static_cast<int>(2e5 / (block_width_ * block_height_));
721*09537850SAkhilesh Sanikop #else
722*09537850SAkhilesh Sanikop const int num_runs = static_cast<int>(4e7 / (block_width_ * block_height_));
723*09537850SAkhilesh Sanikop #endif
724*09537850SAkhilesh Sanikop for (int i = kZone1; i < kNumZones; ++i) {
725*09537850SAkhilesh Sanikop TestSpeed(GetDirectionalIntraPredDigests8bpp(tx_size_),
726*09537850SAkhilesh Sanikop static_cast<Zone>(i), num_runs);
727*09537850SAkhilesh Sanikop }
728*09537850SAkhilesh Sanikop }
729*09537850SAkhilesh Sanikop
TEST_P(DirectionalIntraPredTest8bpp,FixedInput)730*09537850SAkhilesh Sanikop TEST_P(DirectionalIntraPredTest8bpp, FixedInput) {
731*09537850SAkhilesh Sanikop for (int i = kZone1; i < kNumZones; ++i) {
732*09537850SAkhilesh Sanikop TestSpeed(GetDirectionalIntraPredDigests8bpp(tx_size_),
733*09537850SAkhilesh Sanikop static_cast<Zone>(i), 1);
734*09537850SAkhilesh Sanikop }
735*09537850SAkhilesh Sanikop }
736*09537850SAkhilesh Sanikop
TEST_P(DirectionalIntraPredTest8bpp,Overflow)737*09537850SAkhilesh Sanikop TEST_P(DirectionalIntraPredTest8bpp, Overflow) { TestSaturatedValues(); }
TEST_P(DirectionalIntraPredTest8bpp,Random)738*09537850SAkhilesh Sanikop TEST_P(DirectionalIntraPredTest8bpp, Random) { TestRandomValues(); }
739*09537850SAkhilesh Sanikop
740*09537850SAkhilesh Sanikop //------------------------------------------------------------------------------
741*09537850SAkhilesh Sanikop
742*09537850SAkhilesh Sanikop #if LIBGAV1_MAX_BITDEPTH >= 10
743*09537850SAkhilesh Sanikop using DirectionalIntraPredTest10bpp = DirectionalIntraPredTest<10, uint16_t>;
744*09537850SAkhilesh Sanikop
GetDirectionalIntraPredDigests10bpp(TransformSize tx_size)745*09537850SAkhilesh Sanikop const char* const* GetDirectionalIntraPredDigests10bpp(TransformSize tx_size) {
746*09537850SAkhilesh Sanikop static const char* const kDigests4x4[kNumDirectionalIntraPredictors] = {
747*09537850SAkhilesh Sanikop "a683f4d7ccd978737615f61ecb4d638d",
748*09537850SAkhilesh Sanikop "90c94374eaf7e9501f197863937b8639",
749*09537850SAkhilesh Sanikop "0d3969cd081523ac6a906eecc7980c43",
750*09537850SAkhilesh Sanikop };
751*09537850SAkhilesh Sanikop static const char* const kDigests4x8[kNumDirectionalIntraPredictors] = {
752*09537850SAkhilesh Sanikop "c3ffa2979b325644e4a56c882fe27347",
753*09537850SAkhilesh Sanikop "1f61f5ee413a9a3b8d1d93869ec2aee0",
754*09537850SAkhilesh Sanikop "4795ea944779ec4a783408769394d874",
755*09537850SAkhilesh Sanikop };
756*09537850SAkhilesh Sanikop static const char* const kDigests4x16[kNumDirectionalIntraPredictors] = {
757*09537850SAkhilesh Sanikop "45c3282c9aa51024c1d64a40f230aa45",
758*09537850SAkhilesh Sanikop "5cd47dd69f8bd0b15365a0c5cfc0a49a",
759*09537850SAkhilesh Sanikop "06336c507b05f98c1d6a21abc43e6182",
760*09537850SAkhilesh Sanikop };
761*09537850SAkhilesh Sanikop static const char* const kDigests8x4[kNumDirectionalIntraPredictors] = {
762*09537850SAkhilesh Sanikop "7370476ff0abbdc5e92f811b8879c861",
763*09537850SAkhilesh Sanikop "a239a50adb28a4791b52a0dfff3bee06",
764*09537850SAkhilesh Sanikop "4779a17f958a9ca04e8ec08c5aba1d36",
765*09537850SAkhilesh Sanikop };
766*09537850SAkhilesh Sanikop static const char* const kDigests8x8[kNumDirectionalIntraPredictors] = {
767*09537850SAkhilesh Sanikop "305463f346c376594f82aad8304e0362",
768*09537850SAkhilesh Sanikop "0cd481e5bda286c87a645417569fd948",
769*09537850SAkhilesh Sanikop "48c7899dc9b7163b0b1f61b3a2b4b73e",
770*09537850SAkhilesh Sanikop };
771*09537850SAkhilesh Sanikop static const char* const kDigests8x16[kNumDirectionalIntraPredictors] = {
772*09537850SAkhilesh Sanikop "5c18fd5339be90628c82b1fb6af50d5e",
773*09537850SAkhilesh Sanikop "35eaa566ebd3bb7c903cfead5dc9ac78",
774*09537850SAkhilesh Sanikop "9fdb0e790e5965810d02c02713c84071",
775*09537850SAkhilesh Sanikop };
776*09537850SAkhilesh Sanikop static const char* const kDigests8x32[kNumDirectionalIntraPredictors] = {
777*09537850SAkhilesh Sanikop "2168d6cc858c704748b7b343ced2ac3a",
778*09537850SAkhilesh Sanikop "1d3ce273107447faafd2e55877e48ffb",
779*09537850SAkhilesh Sanikop "d344164049d1fe9b65a3ae8764bbbd37",
780*09537850SAkhilesh Sanikop };
781*09537850SAkhilesh Sanikop static const char* const kDigests16x4[kNumDirectionalIntraPredictors] = {
782*09537850SAkhilesh Sanikop "dcef2cf51abe3fe150f388a14c762d30",
783*09537850SAkhilesh Sanikop "6a810b289b1c14f8eab8ca1274e91ecd",
784*09537850SAkhilesh Sanikop "c94da7c11f3fb11963d85c8804fce2d9",
785*09537850SAkhilesh Sanikop };
786*09537850SAkhilesh Sanikop static const char* const kDigests16x8[kNumDirectionalIntraPredictors] = {
787*09537850SAkhilesh Sanikop "50a0d08b0d99b7a574bad2cfb36efc39",
788*09537850SAkhilesh Sanikop "2dcb55874db39da70c8ca1318559f9fe",
789*09537850SAkhilesh Sanikop "6390bcd30ff3bc389ecc0a0952bea531",
790*09537850SAkhilesh Sanikop };
791*09537850SAkhilesh Sanikop static const char* const kDigests16x16[kNumDirectionalIntraPredictors] = {
792*09537850SAkhilesh Sanikop "7146c83c2620935606d49f3cb5876f41",
793*09537850SAkhilesh Sanikop "2318ddf30c070a53c9b9cf199cd1b2c5",
794*09537850SAkhilesh Sanikop "e9042e2124925aa7c1b6110617cb10e8",
795*09537850SAkhilesh Sanikop };
796*09537850SAkhilesh Sanikop static const char* const kDigests16x32[kNumDirectionalIntraPredictors] = {
797*09537850SAkhilesh Sanikop "c970f401de7b7c5bb4e3ad447fcbef8f",
798*09537850SAkhilesh Sanikop "a18cc70730eecdaa31dbcf4306ff490f",
799*09537850SAkhilesh Sanikop "32c1528ad4a576a2210399d6b4ccd46e",
800*09537850SAkhilesh Sanikop };
801*09537850SAkhilesh Sanikop static const char* const kDigests16x64[kNumDirectionalIntraPredictors] = {
802*09537850SAkhilesh Sanikop "00b3f0007da2e5d01380594a3d7162d5",
803*09537850SAkhilesh Sanikop "1971af519e4a18967b7311f93efdd1b8",
804*09537850SAkhilesh Sanikop "e6139769ce5a9c4982cfab9363004516",
805*09537850SAkhilesh Sanikop };
806*09537850SAkhilesh Sanikop static const char* const kDigests32x8[kNumDirectionalIntraPredictors] = {
807*09537850SAkhilesh Sanikop "08107ad971179cc9f465ae5966bd4901",
808*09537850SAkhilesh Sanikop "b215212a3c0dfe9182c4f2e903d731f7",
809*09537850SAkhilesh Sanikop "791274416a0da87c674e1ae318b3ce09",
810*09537850SAkhilesh Sanikop };
811*09537850SAkhilesh Sanikop static const char* const kDigests32x16[kNumDirectionalIntraPredictors] = {
812*09537850SAkhilesh Sanikop "94ea6cccae35b5d08799aa003ac08ccf",
813*09537850SAkhilesh Sanikop "ae105e20e63fb55d4fd9d9e59dc62dde",
814*09537850SAkhilesh Sanikop "973d0b2358ea585e4f486e7e645c5310",
815*09537850SAkhilesh Sanikop };
816*09537850SAkhilesh Sanikop static const char* const kDigests32x32[kNumDirectionalIntraPredictors] = {
817*09537850SAkhilesh Sanikop "d14c695c4853ddf5e5d8256bc1d1ed60",
818*09537850SAkhilesh Sanikop "6bd0ebeb53adecc11442b1218b870cb7",
819*09537850SAkhilesh Sanikop "e03bc402a9999aba8272275dce93e89f",
820*09537850SAkhilesh Sanikop };
821*09537850SAkhilesh Sanikop static const char* const kDigests32x64[kNumDirectionalIntraPredictors] = {
822*09537850SAkhilesh Sanikop "b21a8a8723758392ee659eeeae518a1e",
823*09537850SAkhilesh Sanikop "e50285454896210ce44d6f04dfde05a7",
824*09537850SAkhilesh Sanikop "f0f8ea0c6c2acc8d7d390927c3a90370",
825*09537850SAkhilesh Sanikop };
826*09537850SAkhilesh Sanikop static const char* const kDigests64x16[kNumDirectionalIntraPredictors] = {
827*09537850SAkhilesh Sanikop "ce51db16fd4fa56e601631397b098c89",
828*09537850SAkhilesh Sanikop "aa87a8635e02c1e91d13158c61e443f6",
829*09537850SAkhilesh Sanikop "4c1ee3afd46ef34bd711a34d0bf86f13",
830*09537850SAkhilesh Sanikop };
831*09537850SAkhilesh Sanikop static const char* const kDigests64x32[kNumDirectionalIntraPredictors] = {
832*09537850SAkhilesh Sanikop "25aaf5971e24e543e3e69a47254af777",
833*09537850SAkhilesh Sanikop "eb6f444b3df127d69460778ab5bf8fc1",
834*09537850SAkhilesh Sanikop "2f846cc0d506f90c0a58438600819817",
835*09537850SAkhilesh Sanikop };
836*09537850SAkhilesh Sanikop static const char* const kDigests64x64[kNumDirectionalIntraPredictors] = {
837*09537850SAkhilesh Sanikop "b26ce5b5f4b5d4a438b52e5987877fb8",
838*09537850SAkhilesh Sanikop "35721a00a70938111939cf69988d928e",
839*09537850SAkhilesh Sanikop "0af7ec35939483fac82c246a13845806",
840*09537850SAkhilesh Sanikop };
841*09537850SAkhilesh Sanikop
842*09537850SAkhilesh Sanikop switch (tx_size) {
843*09537850SAkhilesh Sanikop case kTransformSize4x4:
844*09537850SAkhilesh Sanikop return kDigests4x4;
845*09537850SAkhilesh Sanikop case kTransformSize4x8:
846*09537850SAkhilesh Sanikop return kDigests4x8;
847*09537850SAkhilesh Sanikop case kTransformSize4x16:
848*09537850SAkhilesh Sanikop return kDigests4x16;
849*09537850SAkhilesh Sanikop case kTransformSize8x4:
850*09537850SAkhilesh Sanikop return kDigests8x4;
851*09537850SAkhilesh Sanikop case kTransformSize8x8:
852*09537850SAkhilesh Sanikop return kDigests8x8;
853*09537850SAkhilesh Sanikop case kTransformSize8x16:
854*09537850SAkhilesh Sanikop return kDigests8x16;
855*09537850SAkhilesh Sanikop case kTransformSize8x32:
856*09537850SAkhilesh Sanikop return kDigests8x32;
857*09537850SAkhilesh Sanikop case kTransformSize16x4:
858*09537850SAkhilesh Sanikop return kDigests16x4;
859*09537850SAkhilesh Sanikop case kTransformSize16x8:
860*09537850SAkhilesh Sanikop return kDigests16x8;
861*09537850SAkhilesh Sanikop case kTransformSize16x16:
862*09537850SAkhilesh Sanikop return kDigests16x16;
863*09537850SAkhilesh Sanikop case kTransformSize16x32:
864*09537850SAkhilesh Sanikop return kDigests16x32;
865*09537850SAkhilesh Sanikop case kTransformSize16x64:
866*09537850SAkhilesh Sanikop return kDigests16x64;
867*09537850SAkhilesh Sanikop case kTransformSize32x8:
868*09537850SAkhilesh Sanikop return kDigests32x8;
869*09537850SAkhilesh Sanikop case kTransformSize32x16:
870*09537850SAkhilesh Sanikop return kDigests32x16;
871*09537850SAkhilesh Sanikop case kTransformSize32x32:
872*09537850SAkhilesh Sanikop return kDigests32x32;
873*09537850SAkhilesh Sanikop case kTransformSize32x64:
874*09537850SAkhilesh Sanikop return kDigests32x64;
875*09537850SAkhilesh Sanikop case kTransformSize64x16:
876*09537850SAkhilesh Sanikop return kDigests64x16;
877*09537850SAkhilesh Sanikop case kTransformSize64x32:
878*09537850SAkhilesh Sanikop return kDigests64x32;
879*09537850SAkhilesh Sanikop case kTransformSize64x64:
880*09537850SAkhilesh Sanikop return kDigests64x64;
881*09537850SAkhilesh Sanikop default:
882*09537850SAkhilesh Sanikop ADD_FAILURE() << "Unknown transform size: " << tx_size;
883*09537850SAkhilesh Sanikop return nullptr;
884*09537850SAkhilesh Sanikop }
885*09537850SAkhilesh Sanikop }
886*09537850SAkhilesh Sanikop
TEST_P(DirectionalIntraPredTest10bpp,DISABLED_Speed)887*09537850SAkhilesh Sanikop TEST_P(DirectionalIntraPredTest10bpp, DISABLED_Speed) {
888*09537850SAkhilesh Sanikop #if LIBGAV1_ENABLE_NEON
889*09537850SAkhilesh Sanikop const int num_runs = static_cast<int>(2e5 / (block_width_ * block_height_));
890*09537850SAkhilesh Sanikop #else
891*09537850SAkhilesh Sanikop const int num_runs = static_cast<int>(4e7 / (block_width_ * block_height_));
892*09537850SAkhilesh Sanikop #endif
893*09537850SAkhilesh Sanikop for (int i = kZone1; i < kNumZones; ++i) {
894*09537850SAkhilesh Sanikop TestSpeed(GetDirectionalIntraPredDigests10bpp(tx_size_),
895*09537850SAkhilesh Sanikop static_cast<Zone>(i), num_runs);
896*09537850SAkhilesh Sanikop }
897*09537850SAkhilesh Sanikop }
898*09537850SAkhilesh Sanikop
TEST_P(DirectionalIntraPredTest10bpp,FixedInput)899*09537850SAkhilesh Sanikop TEST_P(DirectionalIntraPredTest10bpp, FixedInput) {
900*09537850SAkhilesh Sanikop for (int i = kZone1; i < kNumZones; ++i) {
901*09537850SAkhilesh Sanikop TestSpeed(GetDirectionalIntraPredDigests10bpp(tx_size_),
902*09537850SAkhilesh Sanikop static_cast<Zone>(i), 1);
903*09537850SAkhilesh Sanikop }
904*09537850SAkhilesh Sanikop }
905*09537850SAkhilesh Sanikop
TEST_P(DirectionalIntraPredTest10bpp,Overflow)906*09537850SAkhilesh Sanikop TEST_P(DirectionalIntraPredTest10bpp, Overflow) { TestSaturatedValues(); }
TEST_P(DirectionalIntraPredTest10bpp,Random)907*09537850SAkhilesh Sanikop TEST_P(DirectionalIntraPredTest10bpp, Random) { TestRandomValues(); }
908*09537850SAkhilesh Sanikop #endif // LIBGAV1_MAX_BITDEPTH >= 10
909*09537850SAkhilesh Sanikop
910*09537850SAkhilesh Sanikop //------------------------------------------------------------------------------
911*09537850SAkhilesh Sanikop
912*09537850SAkhilesh Sanikop #if LIBGAV1_MAX_BITDEPTH == 12
913*09537850SAkhilesh Sanikop using DirectionalIntraPredTest12bpp = DirectionalIntraPredTest<12, uint16_t>;
914*09537850SAkhilesh Sanikop
GetDirectionalIntraPredDigests12bpp(TransformSize tx_size)915*09537850SAkhilesh Sanikop const char* const* GetDirectionalIntraPredDigests12bpp(TransformSize tx_size) {
916*09537850SAkhilesh Sanikop static const char* const kDigests4x4[kNumDirectionalIntraPredictors] = {
917*09537850SAkhilesh Sanikop "78f3297743f75e928e755b6ffa2d3050",
918*09537850SAkhilesh Sanikop "7315da39861c6e3ef2e47c913e3be349",
919*09537850SAkhilesh Sanikop "5609cb40b575f24d05880df202a60bd3",
920*09537850SAkhilesh Sanikop };
921*09537850SAkhilesh Sanikop static const char* const kDigests4x8[kNumDirectionalIntraPredictors] = {
922*09537850SAkhilesh Sanikop "efb2363d3c25427abe198806c8ba4d6b",
923*09537850SAkhilesh Sanikop "b5aaa41665a10e7e7944fb7fc90fd59a",
924*09537850SAkhilesh Sanikop "5a85610342339ca3109d775fa18dc25c",
925*09537850SAkhilesh Sanikop };
926*09537850SAkhilesh Sanikop static const char* const kDigests4x16[kNumDirectionalIntraPredictors] = {
927*09537850SAkhilesh Sanikop "9045679914980ea1f579d84509397b6e",
928*09537850SAkhilesh Sanikop "f9f50bdc9f81a93095fd9d6998174aa7",
929*09537850SAkhilesh Sanikop "46c1f82e85b8ba5b03bab41a2f561483",
930*09537850SAkhilesh Sanikop };
931*09537850SAkhilesh Sanikop static const char* const kDigests8x4[kNumDirectionalIntraPredictors] = {
932*09537850SAkhilesh Sanikop "a0ae0956b2b667c528b7803d733d49da",
933*09537850SAkhilesh Sanikop "5d9f60ef8904c4faedb6cfc19e54418a",
934*09537850SAkhilesh Sanikop "4ffdcbbbcb23bca8286f1c286b9cb3e8",
935*09537850SAkhilesh Sanikop };
936*09537850SAkhilesh Sanikop static const char* const kDigests8x8[kNumDirectionalIntraPredictors] = {
937*09537850SAkhilesh Sanikop "086116c6b116613b8b47a086726566ea",
938*09537850SAkhilesh Sanikop "141dca7fcae0e4d4b88887a618271ea1",
939*09537850SAkhilesh Sanikop "3575a34278aa0fb1eed934290982f4a7",
940*09537850SAkhilesh Sanikop };
941*09537850SAkhilesh Sanikop static const char* const kDigests8x16[kNumDirectionalIntraPredictors] = {
942*09537850SAkhilesh Sanikop "7922f40216c78a40abaf675667e79493",
943*09537850SAkhilesh Sanikop "55d20588240171df2e24d105ee1563ad",
944*09537850SAkhilesh Sanikop "674b4d8f4dbf514d22e21cc4baeda1d3",
945*09537850SAkhilesh Sanikop };
946*09537850SAkhilesh Sanikop static const char* const kDigests8x32[kNumDirectionalIntraPredictors] = {
947*09537850SAkhilesh Sanikop "32d4d7e256d3b304026ddb5430cf6a09",
948*09537850SAkhilesh Sanikop "72f4be2569f4e067c252d51ff4030de3",
949*09537850SAkhilesh Sanikop "6779a132e1bac0ac43c2373f56553ed8",
950*09537850SAkhilesh Sanikop };
951*09537850SAkhilesh Sanikop static const char* const kDigests16x4[kNumDirectionalIntraPredictors] = {
952*09537850SAkhilesh Sanikop "1be2e0efc1403f9e22cfb8aeb28763d9",
953*09537850SAkhilesh Sanikop "558c8a5418ac91d21a5839c454a9391f",
954*09537850SAkhilesh Sanikop "7693ebef9b86416ebd6e78e98fcafba7",
955*09537850SAkhilesh Sanikop };
956*09537850SAkhilesh Sanikop static const char* const kDigests16x8[kNumDirectionalIntraPredictors] = {
957*09537850SAkhilesh Sanikop "e6217ed1c673ae42e84f8757316b580d",
958*09537850SAkhilesh Sanikop "028aa582c11a9733f0cd693211a067c5",
959*09537850SAkhilesh Sanikop "082de9fc7c4bc80a8ec8522b5a5cb52c",
960*09537850SAkhilesh Sanikop };
961*09537850SAkhilesh Sanikop static const char* const kDigests16x16[kNumDirectionalIntraPredictors] = {
962*09537850SAkhilesh Sanikop "e3b293c09bdc9c5c543ad046a3f0d64f",
963*09537850SAkhilesh Sanikop "2de5803a6ed497c1039c8e6d675c1dd3",
964*09537850SAkhilesh Sanikop "05742f807560f5d5206e54b70097dc4a",
965*09537850SAkhilesh Sanikop };
966*09537850SAkhilesh Sanikop static const char* const kDigests16x32[kNumDirectionalIntraPredictors] = {
967*09537850SAkhilesh Sanikop "57f2ca4ba56be253eff7e6b73df5003d",
968*09537850SAkhilesh Sanikop "ef8bea00437e01fb798a22cda59f0191",
969*09537850SAkhilesh Sanikop "989ff38c96600c2f108d6e6fa381fd13",
970*09537850SAkhilesh Sanikop };
971*09537850SAkhilesh Sanikop static const char* const kDigests16x64[kNumDirectionalIntraPredictors] = {
972*09537850SAkhilesh Sanikop "f5540f4874c02aa2222a3ba75106f841",
973*09537850SAkhilesh Sanikop "17e5d20f798a96c39abc8a81e7aa7bc6",
974*09537850SAkhilesh Sanikop "0fe9ea14c9dcae466b4a36f1c7db6978",
975*09537850SAkhilesh Sanikop };
976*09537850SAkhilesh Sanikop static const char* const kDigests32x8[kNumDirectionalIntraPredictors] = {
977*09537850SAkhilesh Sanikop "aff9429951ab1885c0d9ed29aa1b6a9f",
978*09537850SAkhilesh Sanikop "4b686e2a879bf0b4aadd06b412e0eb48",
979*09537850SAkhilesh Sanikop "39325d71cddc272bfa1dd2dc80d09ffe",
980*09537850SAkhilesh Sanikop };
981*09537850SAkhilesh Sanikop static const char* const kDigests32x16[kNumDirectionalIntraPredictors] = {
982*09537850SAkhilesh Sanikop "b83dffdf8bad2b7c3808925b6138ca1e",
983*09537850SAkhilesh Sanikop "3656b58c7aaf2025979b4a3ed8a2841e",
984*09537850SAkhilesh Sanikop "cfcc0c6ae3fa5e7d45dec581479459f6",
985*09537850SAkhilesh Sanikop };
986*09537850SAkhilesh Sanikop static const char* const kDigests32x32[kNumDirectionalIntraPredictors] = {
987*09537850SAkhilesh Sanikop "3c91b3b9e2df73ffb718e0bf53c5a5c2",
988*09537850SAkhilesh Sanikop "0dbe27603e111158e70d99e181befb83",
989*09537850SAkhilesh Sanikop "edecbffb32ae1e49b66b6e55ad0af6c6",
990*09537850SAkhilesh Sanikop };
991*09537850SAkhilesh Sanikop static const char* const kDigests32x64[kNumDirectionalIntraPredictors] = {
992*09537850SAkhilesh Sanikop "a3290917f755c7ccdc7b77eb3c6c89a7",
993*09537850SAkhilesh Sanikop "42f89db41fbb366ddb78ef79a043f3e3",
994*09537850SAkhilesh Sanikop "7f7bcbe33aa003b166677c68d12490e9",
995*09537850SAkhilesh Sanikop };
996*09537850SAkhilesh Sanikop static const char* const kDigests64x16[kNumDirectionalIntraPredictors] = {
997*09537850SAkhilesh Sanikop "d4f4c6b70a82695f843e9227bd7d9cc8",
998*09537850SAkhilesh Sanikop "550a0bd87936801651d552e229b683e9",
999*09537850SAkhilesh Sanikop "a4c730ad71f566a930c5672e1b2f48f1",
1000*09537850SAkhilesh Sanikop };
1001*09537850SAkhilesh Sanikop static const char* const kDigests64x32[kNumDirectionalIntraPredictors] = {
1002*09537850SAkhilesh Sanikop "2087c9264c4c5fea9a6fe20dcedbe2b9",
1003*09537850SAkhilesh Sanikop "d4dd51d9578a3fc2eb75086fba867c22",
1004*09537850SAkhilesh Sanikop "6121a67d63e40107e780d0938aeb3d21",
1005*09537850SAkhilesh Sanikop };
1006*09537850SAkhilesh Sanikop static const char* const kDigests64x64[kNumDirectionalIntraPredictors] = {
1007*09537850SAkhilesh Sanikop "09c3818a07bc54467634c2bfce66f58f",
1008*09537850SAkhilesh Sanikop "8da453b8d72d73d71ba15a14ddd59db4",
1009*09537850SAkhilesh Sanikop "9bc939aa54445722469b120b8a505cb3",
1010*09537850SAkhilesh Sanikop };
1011*09537850SAkhilesh Sanikop
1012*09537850SAkhilesh Sanikop switch (tx_size) {
1013*09537850SAkhilesh Sanikop case kTransformSize4x4:
1014*09537850SAkhilesh Sanikop return kDigests4x4;
1015*09537850SAkhilesh Sanikop case kTransformSize4x8:
1016*09537850SAkhilesh Sanikop return kDigests4x8;
1017*09537850SAkhilesh Sanikop case kTransformSize4x16:
1018*09537850SAkhilesh Sanikop return kDigests4x16;
1019*09537850SAkhilesh Sanikop case kTransformSize8x4:
1020*09537850SAkhilesh Sanikop return kDigests8x4;
1021*09537850SAkhilesh Sanikop case kTransformSize8x8:
1022*09537850SAkhilesh Sanikop return kDigests8x8;
1023*09537850SAkhilesh Sanikop case kTransformSize8x16:
1024*09537850SAkhilesh Sanikop return kDigests8x16;
1025*09537850SAkhilesh Sanikop case kTransformSize8x32:
1026*09537850SAkhilesh Sanikop return kDigests8x32;
1027*09537850SAkhilesh Sanikop case kTransformSize16x4:
1028*09537850SAkhilesh Sanikop return kDigests16x4;
1029*09537850SAkhilesh Sanikop case kTransformSize16x8:
1030*09537850SAkhilesh Sanikop return kDigests16x8;
1031*09537850SAkhilesh Sanikop case kTransformSize16x16:
1032*09537850SAkhilesh Sanikop return kDigests16x16;
1033*09537850SAkhilesh Sanikop case kTransformSize16x32:
1034*09537850SAkhilesh Sanikop return kDigests16x32;
1035*09537850SAkhilesh Sanikop case kTransformSize16x64:
1036*09537850SAkhilesh Sanikop return kDigests16x64;
1037*09537850SAkhilesh Sanikop case kTransformSize32x8:
1038*09537850SAkhilesh Sanikop return kDigests32x8;
1039*09537850SAkhilesh Sanikop case kTransformSize32x16:
1040*09537850SAkhilesh Sanikop return kDigests32x16;
1041*09537850SAkhilesh Sanikop case kTransformSize32x32:
1042*09537850SAkhilesh Sanikop return kDigests32x32;
1043*09537850SAkhilesh Sanikop case kTransformSize32x64:
1044*09537850SAkhilesh Sanikop return kDigests32x64;
1045*09537850SAkhilesh Sanikop case kTransformSize64x16:
1046*09537850SAkhilesh Sanikop return kDigests64x16;
1047*09537850SAkhilesh Sanikop case kTransformSize64x32:
1048*09537850SAkhilesh Sanikop return kDigests64x32;
1049*09537850SAkhilesh Sanikop case kTransformSize64x64:
1050*09537850SAkhilesh Sanikop return kDigests64x64;
1051*09537850SAkhilesh Sanikop default:
1052*09537850SAkhilesh Sanikop ADD_FAILURE() << "Unknown transform size: " << tx_size;
1053*09537850SAkhilesh Sanikop return nullptr;
1054*09537850SAkhilesh Sanikop }
1055*09537850SAkhilesh Sanikop }
1056*09537850SAkhilesh Sanikop
TEST_P(DirectionalIntraPredTest12bpp,DISABLED_Speed)1057*09537850SAkhilesh Sanikop TEST_P(DirectionalIntraPredTest12bpp, DISABLED_Speed) {
1058*09537850SAkhilesh Sanikop #if LIBGAV1_ENABLE_NEON
1059*09537850SAkhilesh Sanikop const int num_runs = static_cast<int>(2e7 / (block_width_ * block_height_));
1060*09537850SAkhilesh Sanikop #else
1061*09537850SAkhilesh Sanikop const int num_runs = static_cast<int>(4e7 / (block_width_ * block_height_));
1062*09537850SAkhilesh Sanikop #endif
1063*09537850SAkhilesh Sanikop for (int i = kZone1; i < kNumZones; ++i) {
1064*09537850SAkhilesh Sanikop TestSpeed(GetDirectionalIntraPredDigests12bpp(tx_size_),
1065*09537850SAkhilesh Sanikop static_cast<Zone>(i), num_runs);
1066*09537850SAkhilesh Sanikop }
1067*09537850SAkhilesh Sanikop }
1068*09537850SAkhilesh Sanikop
TEST_P(DirectionalIntraPredTest12bpp,FixedInput)1069*09537850SAkhilesh Sanikop TEST_P(DirectionalIntraPredTest12bpp, FixedInput) {
1070*09537850SAkhilesh Sanikop for (int i = kZone1; i < kNumZones; ++i) {
1071*09537850SAkhilesh Sanikop TestSpeed(GetDirectionalIntraPredDigests12bpp(tx_size_),
1072*09537850SAkhilesh Sanikop static_cast<Zone>(i), 1);
1073*09537850SAkhilesh Sanikop }
1074*09537850SAkhilesh Sanikop }
1075*09537850SAkhilesh Sanikop
TEST_P(DirectionalIntraPredTest12bpp,Overflow)1076*09537850SAkhilesh Sanikop TEST_P(DirectionalIntraPredTest12bpp, Overflow) { TestSaturatedValues(); }
TEST_P(DirectionalIntraPredTest12bpp,Random)1077*09537850SAkhilesh Sanikop TEST_P(DirectionalIntraPredTest12bpp, Random) { TestRandomValues(); }
1078*09537850SAkhilesh Sanikop #endif // LIBGAV1_MAX_BITDEPTH == 12
1079*09537850SAkhilesh Sanikop
1080*09537850SAkhilesh Sanikop constexpr TransformSize kTransformSizes[] = {
1081*09537850SAkhilesh Sanikop kTransformSize4x4, kTransformSize4x8, kTransformSize4x16,
1082*09537850SAkhilesh Sanikop kTransformSize8x4, kTransformSize8x8, kTransformSize8x16,
1083*09537850SAkhilesh Sanikop kTransformSize8x32, kTransformSize16x4, kTransformSize16x8,
1084*09537850SAkhilesh Sanikop kTransformSize16x16, kTransformSize16x32, kTransformSize16x64,
1085*09537850SAkhilesh Sanikop kTransformSize32x8, kTransformSize32x16, kTransformSize32x32,
1086*09537850SAkhilesh Sanikop kTransformSize32x64, kTransformSize64x16, kTransformSize64x32,
1087*09537850SAkhilesh Sanikop kTransformSize64x64};
1088*09537850SAkhilesh Sanikop
1089*09537850SAkhilesh Sanikop INSTANTIATE_TEST_SUITE_P(C, DirectionalIntraPredTest8bpp,
1090*09537850SAkhilesh Sanikop testing::ValuesIn(kTransformSizes));
1091*09537850SAkhilesh Sanikop #if LIBGAV1_ENABLE_SSE4_1
1092*09537850SAkhilesh Sanikop INSTANTIATE_TEST_SUITE_P(SSE41, DirectionalIntraPredTest8bpp,
1093*09537850SAkhilesh Sanikop testing::ValuesIn(kTransformSizes));
1094*09537850SAkhilesh Sanikop #endif // LIBGAV1_ENABLE_SSE4_1
1095*09537850SAkhilesh Sanikop #if LIBGAV1_ENABLE_NEON
1096*09537850SAkhilesh Sanikop INSTANTIATE_TEST_SUITE_P(NEON, DirectionalIntraPredTest8bpp,
1097*09537850SAkhilesh Sanikop testing::ValuesIn(kTransformSizes));
1098*09537850SAkhilesh Sanikop #endif // LIBGAV1_ENABLE_NEON
1099*09537850SAkhilesh Sanikop
1100*09537850SAkhilesh Sanikop #if LIBGAV1_MAX_BITDEPTH >= 10
1101*09537850SAkhilesh Sanikop INSTANTIATE_TEST_SUITE_P(C, DirectionalIntraPredTest10bpp,
1102*09537850SAkhilesh Sanikop testing::ValuesIn(kTransformSizes));
1103*09537850SAkhilesh Sanikop #if LIBGAV1_ENABLE_SSE4_1
1104*09537850SAkhilesh Sanikop INSTANTIATE_TEST_SUITE_P(SSE41, DirectionalIntraPredTest10bpp,
1105*09537850SAkhilesh Sanikop testing::ValuesIn(kTransformSizes));
1106*09537850SAkhilesh Sanikop #endif // LIBGAV1_ENABLE_SSE4_1
1107*09537850SAkhilesh Sanikop #if LIBGAV1_ENABLE_NEON
1108*09537850SAkhilesh Sanikop INSTANTIATE_TEST_SUITE_P(NEON, DirectionalIntraPredTest10bpp,
1109*09537850SAkhilesh Sanikop testing::ValuesIn(kTransformSizes));
1110*09537850SAkhilesh Sanikop #endif // LIBGAV1_ENABLE_NEON
1111*09537850SAkhilesh Sanikop #endif // LIBGAV1_MAX_BITDEPTH >= 10
1112*09537850SAkhilesh Sanikop
1113*09537850SAkhilesh Sanikop #if LIBGAV1_MAX_BITDEPTH == 12
1114*09537850SAkhilesh Sanikop INSTANTIATE_TEST_SUITE_P(C, DirectionalIntraPredTest12bpp,
1115*09537850SAkhilesh Sanikop testing::ValuesIn(kTransformSizes));
1116*09537850SAkhilesh Sanikop #endif // LIBGAV1_MAX_BITDEPTH == 12
1117*09537850SAkhilesh Sanikop
1118*09537850SAkhilesh Sanikop } // namespace
1119*09537850SAkhilesh Sanikop } // namespace dsp
1120*09537850SAkhilesh Sanikop
operator <<(std::ostream & os,const TransformSize tx_size)1121*09537850SAkhilesh Sanikop static std::ostream& operator<<(std::ostream& os, const TransformSize tx_size) {
1122*09537850SAkhilesh Sanikop return os << ToString(tx_size);
1123*09537850SAkhilesh Sanikop }
1124*09537850SAkhilesh Sanikop
1125*09537850SAkhilesh Sanikop } // namespace libgav1
1126