1*09537850SAkhilesh Sanikop // Copyright 2020 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/obmc.h"
16*09537850SAkhilesh Sanikop
17*09537850SAkhilesh Sanikop #include <algorithm>
18*09537850SAkhilesh Sanikop #include <cassert>
19*09537850SAkhilesh Sanikop #include <cstddef>
20*09537850SAkhilesh Sanikop #include <cstdint>
21*09537850SAkhilesh Sanikop #include <cstring>
22*09537850SAkhilesh Sanikop #include <ostream>
23*09537850SAkhilesh Sanikop #include <string>
24*09537850SAkhilesh Sanikop
25*09537850SAkhilesh Sanikop #include "absl/strings/match.h"
26*09537850SAkhilesh Sanikop #include "absl/strings/str_format.h"
27*09537850SAkhilesh Sanikop #include "absl/strings/string_view.h"
28*09537850SAkhilesh Sanikop #include "absl/time/clock.h"
29*09537850SAkhilesh Sanikop #include "absl/time/time.h"
30*09537850SAkhilesh Sanikop #include "gtest/gtest.h"
31*09537850SAkhilesh Sanikop #include "src/dsp/dsp.h"
32*09537850SAkhilesh Sanikop #include "src/utils/common.h"
33*09537850SAkhilesh Sanikop #include "src/utils/constants.h"
34*09537850SAkhilesh Sanikop #include "src/utils/cpu.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 #include "src/dsp/obmc.inc"
44*09537850SAkhilesh Sanikop
45*09537850SAkhilesh Sanikop constexpr int kMaxBlendingBlockSize = 64;
46*09537850SAkhilesh Sanikop constexpr int kNumSpeedTests = 2e8;
47*09537850SAkhilesh Sanikop
GetDigest8bpp(int id)48*09537850SAkhilesh Sanikop const char* GetDigest8bpp(int id) {
49*09537850SAkhilesh Sanikop static const char* const kDigest[] = {
50*09537850SAkhilesh Sanikop "c8659acd1e8ecdab06be73f0954fa1ae", "e785f31f2723a193fefd534bd6f6c18f",
51*09537850SAkhilesh Sanikop "751fcd8a345fef1c38a25293c9b528c0", "69af412dfa5e96ad43b79c178cb1c58b",
52*09537850SAkhilesh Sanikop "2766a64622e183bb4614f2018f14fa85", "8d98589a5cef6e68ee8fadf19d420e3c",
53*09537850SAkhilesh Sanikop "19eccf31dd8cf1abcee9414128fe4141", "35019f98e30bcbc6ab624682a0628519",
54*09537850SAkhilesh Sanikop "199c551164e73c100045d7ab033ffdcc", "ad5a5eb2906265690c22741b0715f37b",
55*09537850SAkhilesh Sanikop "e2152dea159249149ff4151111b73ed6", "1edd570bec7e63780d83588f6aacda25",
56*09537850SAkhilesh Sanikop "b24ad192e151b1e0f74d1493004cb1b6", "6c1ce7ed3463cc60870e336f990d4f14",
57*09537850SAkhilesh Sanikop "2e6b7a06da21512dfdd9a517d2988655", "971ba1c41ab13bb341c04f936760f546",
58*09537850SAkhilesh Sanikop "55b803239d9f12888c666c5320450937", "3d0838963f8c95dafbfb8e5e25c865d2",
59*09537850SAkhilesh Sanikop "98a9be6245720d4e0da18115c1a1dbd7", "7e7afe3136ad681b5ea05664fe916548",
60*09537850SAkhilesh Sanikop "33971753243f09106173199b7bae1ef5", "65413f33c19a42c112d395121aa4b3b4",
61*09537850SAkhilesh Sanikop };
62*09537850SAkhilesh Sanikop assert(id >= 0);
63*09537850SAkhilesh Sanikop assert(id < sizeof(kDigest) / sizeof(kDigest[0]));
64*09537850SAkhilesh Sanikop return kDigest[id];
65*09537850SAkhilesh Sanikop }
66*09537850SAkhilesh Sanikop
GetDigestSpeed8bpp(int id)67*09537850SAkhilesh Sanikop const char* GetDigestSpeed8bpp(int id) {
68*09537850SAkhilesh Sanikop static const char* const kDigest[] = {
69*09537850SAkhilesh Sanikop "5ea519b616cd2998fbb9b25b4c2660cb", "f23d18197a96de48901738d130a147d9",
70*09537850SAkhilesh Sanikop "07b4140c693947a63865f835089766c4", "62547d29bc4dfb2e201e9d907c09e345",
71*09537850SAkhilesh Sanikop "c3988da521be50aeb9944564001b282b", "d5a8ff9ca1bd49f4260bb497c489b06c",
72*09537850SAkhilesh Sanikop "b3e94f1e33c316759ebf47620327168c", "c5e64a34ca7e55f4daed19cbe4c27049",
73*09537850SAkhilesh Sanikop "3b234eb729e8e79db8692c4cbe1b6667", "f9f3060a44c3a575470f9700b3c3a75b",
74*09537850SAkhilesh Sanikop "e3a1960b0a7238db1184a3f9d8e9a4b2", "ba9938553703d520bc0ade427c397140",
75*09537850SAkhilesh Sanikop "31bf64a6ed1e8002d488c0b9dcffb80a", "9ab1f3ae2e7f70cd27452f30cecfd18e",
76*09537850SAkhilesh Sanikop "eaf25ac79ad70fc17ca96d8fcdf0f939", "9aaa88cb5e6b8757e37c3430bd664e70",
77*09537850SAkhilesh Sanikop "8293874b2794df8fd22f5a35c3de7bee", "e9d6ee9106227c2c67ea9e6a4652e4ad",
78*09537850SAkhilesh Sanikop "29f8a6fc2a650f3945a4ea6d3b975b6d", "8f300a257e913a42666b4921b2b0b5c5",
79*09537850SAkhilesh Sanikop "a526265c4b3c8593736a82ddc1fd1603", "76e248f6756ac96343204b0e48d72a9e",
80*09537850SAkhilesh Sanikop };
81*09537850SAkhilesh Sanikop assert(id >= 0);
82*09537850SAkhilesh Sanikop assert(id < sizeof(kDigest) / sizeof(kDigest[0]));
83*09537850SAkhilesh Sanikop return kDigest[id];
84*09537850SAkhilesh Sanikop }
85*09537850SAkhilesh Sanikop
86*09537850SAkhilesh Sanikop #if LIBGAV1_MAX_BITDEPTH >= 10
GetDigest10bpp(int id)87*09537850SAkhilesh Sanikop const char* GetDigest10bpp(int id) {
88*09537850SAkhilesh Sanikop static const char* const kDigest[] = {
89*09537850SAkhilesh Sanikop "6f922e4142b644ca3f1eb0f363a1c34e", "84e7c098a9335b36082fec0bc7203075",
90*09537850SAkhilesh Sanikop "40f00ea6884fea23a3b7fae59e3b02c3", "70cb92d08b4fdb6dd9c7d418cb1455d3",
91*09537850SAkhilesh Sanikop "ed550798b56e70439a93cb48c359e873", "55e0d927b984e78cd51a1961e58a431d",
92*09537850SAkhilesh Sanikop "482a6856b87265a82e4ea3fdadb2d95b", "0be46226ff87d74ff2ce68a83eaf9cca",
93*09537850SAkhilesh Sanikop "bb4461f0131a1693a0a76f21d92a480b", "ea24f78d74c7864fb247c9a98c9b97b6",
94*09537850SAkhilesh Sanikop "d2e70b81882aeb3d9fccef89e7552a9d", "f5d882ee6d9ae6f7dfa467ca99301424",
95*09537850SAkhilesh Sanikop "824ddb98eb4129b3d254c0bc7a64cd73", "5eaaafa8ef9b7ba5e2856a947e5b33df",
96*09537850SAkhilesh Sanikop "071de1494e0f1b2f99266b90bdc43ddd", "c33227a96dad506adc32dacfb371ab78",
97*09537850SAkhilesh Sanikop "e8a632f9fff240c439d4ae6e86795046", "26b90d74f18f9df4427b6180d48db1fc",
98*09537850SAkhilesh Sanikop "e4a01e492ddc0398b5c5b60c81468242", "f1b4f7ab5c8b949e51db104f2e33565a",
99*09537850SAkhilesh Sanikop "b1fb9ecc6a552e2b23ee92e2f3e4122a", "a683d20129a91bb20b904aa20c0499b1",
100*09537850SAkhilesh Sanikop };
101*09537850SAkhilesh Sanikop assert(id >= 0);
102*09537850SAkhilesh Sanikop assert(id < sizeof(kDigest) / sizeof(kDigest[0]));
103*09537850SAkhilesh Sanikop return kDigest[id];
104*09537850SAkhilesh Sanikop }
105*09537850SAkhilesh Sanikop
GetDigestSpeed10bpp(int id)106*09537850SAkhilesh Sanikop const char* GetDigestSpeed10bpp(int id) {
107*09537850SAkhilesh Sanikop static const char* const kDigest[] = {
108*09537850SAkhilesh Sanikop "80557576299708005111029cef04da53", "24f84f07f53f61cd46bdcfe1e05ff9b5",
109*09537850SAkhilesh Sanikop "4dd6bc62145baa5357a4cbf6d7a6ef15", "0b7aa27cee43b8ae0c02d07887eaa225",
110*09537850SAkhilesh Sanikop "9e28cdae73ca97433499c31ca79e1d07", "1cacd6466a143f88e736fffaf21e2246",
111*09537850SAkhilesh Sanikop "9c7699626660d8965e06a54282a408f3", "eef893efef62b2eb4aaad06fc462819c",
112*09537850SAkhilesh Sanikop "4965d0a3ff750813df85c0082b21bd4b", "ec10fd79fbf552abc595def392e9a863",
113*09537850SAkhilesh Sanikop "a148bbafdc4466fbb700b31acccca8ac", "5da9d960988549f53b817003b93e4d01",
114*09537850SAkhilesh Sanikop "b4c4f88d1fb54869ce7ff452ca7786a6", "d607f785fce62bad85102054539e7089",
115*09537850SAkhilesh Sanikop "b441761ea2817e4618c594aaa11d670a", "1cc5e08e6d5f9315dbc0369b97af941d",
116*09537850SAkhilesh Sanikop "568cc1a3a67ba4e6e77f54602d0ed3e3", "522f14c068f788bc284a7d1e47d623ed",
117*09537850SAkhilesh Sanikop "b543855cbe384b88861c881853c28192", "5faaafc124e94eedc69dc0f5d33dacac",
118*09537850SAkhilesh Sanikop "13ca4d01bd20085459e6126555e1f7b5", "46d46fae3c8a7d9e4725154d8d2b76d8",
119*09537850SAkhilesh Sanikop };
120*09537850SAkhilesh Sanikop assert(id >= 0);
121*09537850SAkhilesh Sanikop assert(id < sizeof(kDigest) / sizeof(kDigest[0]));
122*09537850SAkhilesh Sanikop return kDigest[id];
123*09537850SAkhilesh Sanikop }
124*09537850SAkhilesh Sanikop #endif // LIBGAV1_MAX_BITDEPTH >= 10
125*09537850SAkhilesh Sanikop
126*09537850SAkhilesh Sanikop #if LIBGAV1_MAX_BITDEPTH == 12
GetDigest12bpp(int id)127*09537850SAkhilesh Sanikop const char* GetDigest12bpp(int id) {
128*09537850SAkhilesh Sanikop static const char* const kDigest[] = {
129*09537850SAkhilesh Sanikop "eb18c776d7b56280f01cca40b04a9c44", "058d4a6ed025eac5dcf7aec3203c0882",
130*09537850SAkhilesh Sanikop "8355884d7470e9c6af9309ab23bee859", "2ba330551ac58d1d034b947d7ab9b59f",
131*09537850SAkhilesh Sanikop "0d25cd773c81e4c57f82513e3b031f01", "b9075f7c3b9a240dbb015a24454eeb71",
132*09537850SAkhilesh Sanikop "563ed8683723d1e4f2746280bca3db0a", "d7125306bd8c952d0f85fe1515ca16a7",
133*09537850SAkhilesh Sanikop "5bf99c7e4a918c9b6a7e251484ea6527", "38ac9c685e8d2bd2771b6f2b38268301",
134*09537850SAkhilesh Sanikop "abc39dbde7470e08b15417ee97c704b2", "37e12753d23b7a8df92b1d32f3170d9f",
135*09537850SAkhilesh Sanikop "9a609776cfa31f64826225d0a6b7afdd", "ccdd89e70e94f751fd891b124c1c3210",
136*09537850SAkhilesh Sanikop "2bbf7b095e26ed4f27e7d05e20117084", "9a1b403c3a7c00da5686bcb87f1270e8",
137*09537850SAkhilesh Sanikop "701d651e391043ab8ebbd0023a430980", "0047f10bdd8321494e8e82597fe2f969",
138*09537850SAkhilesh Sanikop "f97e662d139b2811e3d3227de95135a2", "852933b90d4a70f9254157381ed641e0",
139*09537850SAkhilesh Sanikop "cfcda707ec8e4361ef741dc716888348", "95e34eab83b3159f61685db248c6a881",
140*09537850SAkhilesh Sanikop };
141*09537850SAkhilesh Sanikop assert(id >= 0);
142*09537850SAkhilesh Sanikop assert(id < sizeof(kDigest) / sizeof(kDigest[0]));
143*09537850SAkhilesh Sanikop return kDigest[id];
144*09537850SAkhilesh Sanikop }
145*09537850SAkhilesh Sanikop
GetDigestSpeed12bpp(int id)146*09537850SAkhilesh Sanikop const char* GetDigestSpeed12bpp(int id) {
147*09537850SAkhilesh Sanikop static const char* const kDigest[] = {
148*09537850SAkhilesh Sanikop "6c0f37c41d72ce40d95545ac0f08d88a", "8a8efeb7d8b2f852d76d0176b6c6878f",
149*09537850SAkhilesh Sanikop "5757c88d1cdc0cd29c47c346474161f0", "fef8cf06d16ba7357bfc061e43080cd3",
150*09537850SAkhilesh Sanikop "6bd11582448532bce8b91cc8807ab6a0", "1e6dd42eada2d636e210f4e20a771102",
151*09537850SAkhilesh Sanikop "377a0472f45fcb42f1712243ea845530", "e3760f2b6e69c1b40e71ecde711d227c",
152*09537850SAkhilesh Sanikop "6721638d1a5dadb96ddd0ca067c737ca", "3d3a23210a8496a76991bcec5045808b",
153*09537850SAkhilesh Sanikop "2cbd26ecf7d4e927ab569083d3ddb4ca", "7d61af2d7841d1a39a2e930bac166804",
154*09537850SAkhilesh Sanikop "dd929506442fb1f2e67130fe8cdf487b", "c0e57f8d2546d5bcb646a24d09d83d7c",
155*09537850SAkhilesh Sanikop "2989c6487456c92eb003c8e17e904f45", "5cfb60a3be6ee5c41e0f655a3020f687",
156*09537850SAkhilesh Sanikop "28f37d47cb07aa382659ff556a55a4c6", "b6478ab317b11f592deb60d02ce62f2f",
157*09537850SAkhilesh Sanikop "bc78e7250c101f82e794d4fa0ee55025", "24304ed23d336a46f205206d3c5d48ef",
158*09537850SAkhilesh Sanikop "dc1e71d95d06c1086bb7f9e05e38bf39", "32606ef72985e7de608df2e8760784b7",
159*09537850SAkhilesh Sanikop };
160*09537850SAkhilesh Sanikop assert(id >= 0);
161*09537850SAkhilesh Sanikop assert(id < sizeof(kDigest) / sizeof(kDigest[0]));
162*09537850SAkhilesh Sanikop return kDigest[id];
163*09537850SAkhilesh Sanikop }
164*09537850SAkhilesh Sanikop #endif // LIBGAV1_MAX_BITDEPTH == 12
165*09537850SAkhilesh Sanikop
166*09537850SAkhilesh Sanikop struct ObmcTestParam {
ObmcTestParamlibgav1::dsp::__anon353de85d0111::ObmcTestParam167*09537850SAkhilesh Sanikop ObmcTestParam(int width, int height, ObmcDirection blending_direction)
168*09537850SAkhilesh Sanikop : width(width), height(height), blending_direction(blending_direction) {}
169*09537850SAkhilesh Sanikop int width;
170*09537850SAkhilesh Sanikop int height;
171*09537850SAkhilesh Sanikop ObmcDirection blending_direction;
172*09537850SAkhilesh Sanikop };
173*09537850SAkhilesh Sanikop
operator <<(std::ostream & os,const ObmcTestParam & param)174*09537850SAkhilesh Sanikop std::ostream& operator<<(std::ostream& os, const ObmcTestParam& param) {
175*09537850SAkhilesh Sanikop return os << "BlockSize" << param.width << "x" << param.height
176*09537850SAkhilesh Sanikop << ", blending_direction: " << ToString(param.blending_direction);
177*09537850SAkhilesh Sanikop }
178*09537850SAkhilesh Sanikop
179*09537850SAkhilesh Sanikop template <int bitdepth, typename Pixel>
180*09537850SAkhilesh Sanikop class ObmcBlendTest : public testing::TestWithParam<ObmcTestParam> {
181*09537850SAkhilesh Sanikop public:
182*09537850SAkhilesh Sanikop static_assert(bitdepth >= kBitdepth8 && bitdepth <= LIBGAV1_MAX_BITDEPTH, "");
183*09537850SAkhilesh Sanikop ObmcBlendTest() = default;
184*09537850SAkhilesh Sanikop ~ObmcBlendTest() override = default;
185*09537850SAkhilesh Sanikop
SetUp()186*09537850SAkhilesh Sanikop void SetUp() override {
187*09537850SAkhilesh Sanikop test_utils::ResetDspTable(bitdepth);
188*09537850SAkhilesh Sanikop ObmcInit_C();
189*09537850SAkhilesh Sanikop const dsp::Dsp* const dsp = dsp::GetDspTable(bitdepth);
190*09537850SAkhilesh Sanikop ASSERT_NE(dsp, nullptr);
191*09537850SAkhilesh Sanikop const testing::TestInfo* const test_info =
192*09537850SAkhilesh Sanikop testing::UnitTest::GetInstance()->current_test_info();
193*09537850SAkhilesh Sanikop const absl::string_view test_case = test_info->test_suite_name();
194*09537850SAkhilesh Sanikop if (absl::StartsWith(test_case, "C/")) {
195*09537850SAkhilesh Sanikop } else if (absl::StartsWith(test_case, "SSE41/")) {
196*09537850SAkhilesh Sanikop if ((GetCpuInfo() & kSSE4_1) == 0) GTEST_SKIP() << "No SSE4.1 support!";
197*09537850SAkhilesh Sanikop ObmcInit_SSE4_1();
198*09537850SAkhilesh Sanikop } else if (absl::StartsWith(test_case, "NEON/")) {
199*09537850SAkhilesh Sanikop ObmcInit_NEON();
200*09537850SAkhilesh Sanikop } else {
201*09537850SAkhilesh Sanikop FAIL() << "Unrecognized architecture prefix in test case name: "
202*09537850SAkhilesh Sanikop << test_case;
203*09537850SAkhilesh Sanikop }
204*09537850SAkhilesh Sanikop func_ = dsp->obmc_blend[blending_direction_];
205*09537850SAkhilesh Sanikop }
206*09537850SAkhilesh Sanikop
207*09537850SAkhilesh Sanikop protected:
GetDigestId() const208*09537850SAkhilesh Sanikop int GetDigestId() const {
209*09537850SAkhilesh Sanikop // blending_direction_ == kObmcDirectionVertical:
210*09537850SAkhilesh Sanikop // (width, height):
211*09537850SAkhilesh Sanikop // (4, 2), id = 0. (4, 4), id = 1. (4, 8), id = 2. (8, 4), id = 3.
212*09537850SAkhilesh Sanikop // ...
213*09537850SAkhilesh Sanikop // blending_direction_ == kObmcDirectionHorizontal: id starts from 11.
214*09537850SAkhilesh Sanikop // Vertical skips (2, 4) while horizontal skips (4, 2) creating a gap after
215*09537850SAkhilesh Sanikop // (2, 4).
216*09537850SAkhilesh Sanikop const int id = (blending_direction_ == kObmcDirectionVertical) ? 0
217*09537850SAkhilesh Sanikop : (width_ == 2) ? 12
218*09537850SAkhilesh Sanikop : 11;
219*09537850SAkhilesh Sanikop if (width_ == height_) return id + 3 * (FloorLog2(width_) - 1) - 2;
220*09537850SAkhilesh Sanikop if (width_ < height_) return id + 3 * (FloorLog2(width_) - 1) - 1;
221*09537850SAkhilesh Sanikop return id + 3 * (FloorLog2(height_) - 1);
222*09537850SAkhilesh Sanikop }
223*09537850SAkhilesh Sanikop
224*09537850SAkhilesh Sanikop // Note |digest| is only used when |use_fixed_values| is false.
225*09537850SAkhilesh Sanikop void Test(const char* digest, bool use_fixed_values, int value);
226*09537850SAkhilesh Sanikop void TestSpeed(const char* digest, int num_runs);
227*09537850SAkhilesh Sanikop
228*09537850SAkhilesh Sanikop private:
229*09537850SAkhilesh Sanikop const int width_ = GetParam().width;
230*09537850SAkhilesh Sanikop const int height_ = GetParam().height;
231*09537850SAkhilesh Sanikop const ObmcDirection blending_direction_ = GetParam().blending_direction;
232*09537850SAkhilesh Sanikop Pixel source1_[kMaxBlendingBlockSize * kMaxBlendingBlockSize] = {};
233*09537850SAkhilesh Sanikop Pixel source2_[kMaxBlendingBlockSize * kMaxBlendingBlockSize] = {};
234*09537850SAkhilesh Sanikop dsp::ObmcBlendFunc func_;
235*09537850SAkhilesh Sanikop };
236*09537850SAkhilesh Sanikop
237*09537850SAkhilesh Sanikop template <int bitdepth, typename Pixel>
Test(const char * const digest,const bool use_fixed_values,const int value)238*09537850SAkhilesh Sanikop void ObmcBlendTest<bitdepth, Pixel>::Test(const char* const digest,
239*09537850SAkhilesh Sanikop const bool use_fixed_values,
240*09537850SAkhilesh Sanikop const int value) {
241*09537850SAkhilesh Sanikop if (func_ == nullptr) return;
242*09537850SAkhilesh Sanikop if (use_fixed_values) {
243*09537850SAkhilesh Sanikop std::fill(source1_,
244*09537850SAkhilesh Sanikop source1_ + kMaxBlendingBlockSize * kMaxBlendingBlockSize, value);
245*09537850SAkhilesh Sanikop std::fill(source2_,
246*09537850SAkhilesh Sanikop source2_ + kMaxBlendingBlockSize * kMaxBlendingBlockSize, value);
247*09537850SAkhilesh Sanikop } else {
248*09537850SAkhilesh Sanikop libvpx_test::ACMRandom rnd(libvpx_test::ACMRandom::DeterministicSeed());
249*09537850SAkhilesh Sanikop Pixel* src_1 = source1_;
250*09537850SAkhilesh Sanikop Pixel* src_2 = source2_;
251*09537850SAkhilesh Sanikop const int mask = (1 << bitdepth) - 1;
252*09537850SAkhilesh Sanikop for (int y = 0; y < height_; ++y) {
253*09537850SAkhilesh Sanikop for (int x = 0; x < width_; ++x) {
254*09537850SAkhilesh Sanikop src_1[x] = rnd.Rand16() & mask;
255*09537850SAkhilesh Sanikop src_2[x] = rnd.Rand16() & mask;
256*09537850SAkhilesh Sanikop }
257*09537850SAkhilesh Sanikop src_1 += kMaxBlendingBlockSize;
258*09537850SAkhilesh Sanikop src_2 += width_;
259*09537850SAkhilesh Sanikop }
260*09537850SAkhilesh Sanikop }
261*09537850SAkhilesh Sanikop const ptrdiff_t stride = kMaxBlendingBlockSize * sizeof(Pixel);
262*09537850SAkhilesh Sanikop func_(source1_, stride, width_, height_, source2_,
263*09537850SAkhilesh Sanikop width_ * sizeof(source2_[0]));
264*09537850SAkhilesh Sanikop if (use_fixed_values) {
265*09537850SAkhilesh Sanikop const bool success = test_utils::CompareBlocks(
266*09537850SAkhilesh Sanikop source1_, source2_, width_, height_, kMaxBlendingBlockSize,
267*09537850SAkhilesh Sanikop kMaxBlendingBlockSize, false);
268*09537850SAkhilesh Sanikop EXPECT_TRUE(success);
269*09537850SAkhilesh Sanikop } else {
270*09537850SAkhilesh Sanikop test_utils::CheckMd5Digest(
271*09537850SAkhilesh Sanikop ToString(blending_direction_),
272*09537850SAkhilesh Sanikop absl::StrFormat("%dx%d", width_, height_).c_str(), digest, source1_,
273*09537850SAkhilesh Sanikop sizeof(source1_), absl::Duration());
274*09537850SAkhilesh Sanikop }
275*09537850SAkhilesh Sanikop }
276*09537850SAkhilesh Sanikop
277*09537850SAkhilesh Sanikop template <int bitdepth, typename Pixel>
TestSpeed(const char * const digest,const int num_runs)278*09537850SAkhilesh Sanikop void ObmcBlendTest<bitdepth, Pixel>::TestSpeed(const char* const digest,
279*09537850SAkhilesh Sanikop const int num_runs) {
280*09537850SAkhilesh Sanikop if (func_ == nullptr) return;
281*09537850SAkhilesh Sanikop libvpx_test::ACMRandom rnd(libvpx_test::ACMRandom::DeterministicSeed());
282*09537850SAkhilesh Sanikop Pixel* src_1 = source1_;
283*09537850SAkhilesh Sanikop Pixel* src_2 = source2_;
284*09537850SAkhilesh Sanikop const int mask = (1 << bitdepth) - 1;
285*09537850SAkhilesh Sanikop for (int y = 0; y < height_; ++y) {
286*09537850SAkhilesh Sanikop for (int x = 0; x < width_; ++x) {
287*09537850SAkhilesh Sanikop src_1[x] = rnd.Rand16() & mask;
288*09537850SAkhilesh Sanikop src_2[x] = rnd.Rand16() & mask;
289*09537850SAkhilesh Sanikop }
290*09537850SAkhilesh Sanikop src_1 += kMaxBlendingBlockSize;
291*09537850SAkhilesh Sanikop src_2 += width_;
292*09537850SAkhilesh Sanikop }
293*09537850SAkhilesh Sanikop const ptrdiff_t stride = kMaxBlendingBlockSize * sizeof(Pixel);
294*09537850SAkhilesh Sanikop uint8_t dest[sizeof(Pixel) * kMaxBlendingBlockSize * kMaxBlendingBlockSize];
295*09537850SAkhilesh Sanikop absl::Duration elapsed_time;
296*09537850SAkhilesh Sanikop for (int i = 0; i < num_runs; ++i) {
297*09537850SAkhilesh Sanikop memcpy(dest, source1_,
298*09537850SAkhilesh Sanikop sizeof(Pixel) * kMaxBlendingBlockSize * kMaxBlendingBlockSize);
299*09537850SAkhilesh Sanikop const absl::Time start = absl::Now();
300*09537850SAkhilesh Sanikop func_(dest, stride, width_, height_, source2_,
301*09537850SAkhilesh Sanikop width_ * sizeof(source2_[0]));
302*09537850SAkhilesh Sanikop elapsed_time += absl::Now() - start;
303*09537850SAkhilesh Sanikop }
304*09537850SAkhilesh Sanikop memcpy(source1_, dest,
305*09537850SAkhilesh Sanikop sizeof(Pixel) * kMaxBlendingBlockSize * kMaxBlendingBlockSize);
306*09537850SAkhilesh Sanikop test_utils::CheckMd5Digest(ToString(blending_direction_),
307*09537850SAkhilesh Sanikop absl::StrFormat("%dx%d", width_, height_).c_str(),
308*09537850SAkhilesh Sanikop digest, source1_, sizeof(source1_), elapsed_time);
309*09537850SAkhilesh Sanikop }
310*09537850SAkhilesh Sanikop
311*09537850SAkhilesh Sanikop const ObmcTestParam kObmcTestParam[] = {
312*09537850SAkhilesh Sanikop ObmcTestParam(4, 2, kObmcDirectionVertical),
313*09537850SAkhilesh Sanikop ObmcTestParam(4, 4, kObmcDirectionVertical),
314*09537850SAkhilesh Sanikop ObmcTestParam(4, 8, kObmcDirectionVertical),
315*09537850SAkhilesh Sanikop ObmcTestParam(8, 4, kObmcDirectionVertical),
316*09537850SAkhilesh Sanikop ObmcTestParam(8, 8, kObmcDirectionVertical),
317*09537850SAkhilesh Sanikop ObmcTestParam(8, 16, kObmcDirectionVertical),
318*09537850SAkhilesh Sanikop ObmcTestParam(16, 8, kObmcDirectionVertical),
319*09537850SAkhilesh Sanikop ObmcTestParam(16, 16, kObmcDirectionVertical),
320*09537850SAkhilesh Sanikop ObmcTestParam(16, 32, kObmcDirectionVertical),
321*09537850SAkhilesh Sanikop ObmcTestParam(32, 16, kObmcDirectionVertical),
322*09537850SAkhilesh Sanikop ObmcTestParam(32, 32, kObmcDirectionVertical),
323*09537850SAkhilesh Sanikop ObmcTestParam(2, 4, kObmcDirectionHorizontal),
324*09537850SAkhilesh Sanikop ObmcTestParam(4, 4, kObmcDirectionHorizontal),
325*09537850SAkhilesh Sanikop ObmcTestParam(4, 8, kObmcDirectionHorizontal),
326*09537850SAkhilesh Sanikop ObmcTestParam(8, 4, kObmcDirectionHorizontal),
327*09537850SAkhilesh Sanikop ObmcTestParam(8, 8, kObmcDirectionHorizontal),
328*09537850SAkhilesh Sanikop ObmcTestParam(8, 16, kObmcDirectionHorizontal),
329*09537850SAkhilesh Sanikop ObmcTestParam(16, 8, kObmcDirectionHorizontal),
330*09537850SAkhilesh Sanikop ObmcTestParam(16, 16, kObmcDirectionHorizontal),
331*09537850SAkhilesh Sanikop ObmcTestParam(16, 32, kObmcDirectionHorizontal),
332*09537850SAkhilesh Sanikop ObmcTestParam(32, 16, kObmcDirectionHorizontal),
333*09537850SAkhilesh Sanikop ObmcTestParam(32, 32, kObmcDirectionHorizontal),
334*09537850SAkhilesh Sanikop };
335*09537850SAkhilesh Sanikop
336*09537850SAkhilesh Sanikop using ObmcBlendTest8bpp = ObmcBlendTest<8, uint8_t>;
337*09537850SAkhilesh Sanikop
TEST_P(ObmcBlendTest8bpp,Blending)338*09537850SAkhilesh Sanikop TEST_P(ObmcBlendTest8bpp, Blending) {
339*09537850SAkhilesh Sanikop Test(/*digest=*/nullptr, /*use_fixed_values=*/true, 0);
340*09537850SAkhilesh Sanikop Test(/*digest=*/nullptr, /*use_fixed_values=*/true, 1);
341*09537850SAkhilesh Sanikop Test(/*digest=*/nullptr, /*use_fixed_values=*/true, 128);
342*09537850SAkhilesh Sanikop Test(/*digest=*/nullptr, /*use_fixed_values=*/true, 255);
343*09537850SAkhilesh Sanikop Test(GetDigest8bpp(GetDigestId()), /*use_fixed_values=*/false, -1);
344*09537850SAkhilesh Sanikop }
345*09537850SAkhilesh Sanikop
TEST_P(ObmcBlendTest8bpp,DISABLED_Speed)346*09537850SAkhilesh Sanikop TEST_P(ObmcBlendTest8bpp, DISABLED_Speed) {
347*09537850SAkhilesh Sanikop TestSpeed(GetDigestSpeed8bpp(GetDigestId()),
348*09537850SAkhilesh Sanikop kNumSpeedTests / (GetParam().height * GetParam().width));
349*09537850SAkhilesh Sanikop }
350*09537850SAkhilesh Sanikop
351*09537850SAkhilesh Sanikop INSTANTIATE_TEST_SUITE_P(C, ObmcBlendTest8bpp,
352*09537850SAkhilesh Sanikop testing::ValuesIn(kObmcTestParam));
353*09537850SAkhilesh Sanikop
354*09537850SAkhilesh Sanikop #if LIBGAV1_ENABLE_SSE4_1
355*09537850SAkhilesh Sanikop INSTANTIATE_TEST_SUITE_P(SSE41, ObmcBlendTest8bpp,
356*09537850SAkhilesh Sanikop testing::ValuesIn(kObmcTestParam));
357*09537850SAkhilesh Sanikop #endif
358*09537850SAkhilesh Sanikop
359*09537850SAkhilesh Sanikop #if LIBGAV1_ENABLE_NEON
360*09537850SAkhilesh Sanikop INSTANTIATE_TEST_SUITE_P(NEON, ObmcBlendTest8bpp,
361*09537850SAkhilesh Sanikop testing::ValuesIn(kObmcTestParam));
362*09537850SAkhilesh Sanikop #endif
363*09537850SAkhilesh Sanikop
364*09537850SAkhilesh Sanikop #if LIBGAV1_MAX_BITDEPTH >= 10
365*09537850SAkhilesh Sanikop using ObmcBlendTest10bpp = ObmcBlendTest<10, uint16_t>;
366*09537850SAkhilesh Sanikop
TEST_P(ObmcBlendTest10bpp,Blending)367*09537850SAkhilesh Sanikop TEST_P(ObmcBlendTest10bpp, Blending) {
368*09537850SAkhilesh Sanikop Test(/*digest=*/nullptr, /*use_fixed_values=*/true, 0);
369*09537850SAkhilesh Sanikop Test(/*digest=*/nullptr, /*use_fixed_values=*/true, 1);
370*09537850SAkhilesh Sanikop Test(/*digest=*/nullptr, /*use_fixed_values=*/true, 128);
371*09537850SAkhilesh Sanikop Test(/*digest=*/nullptr, /*use_fixed_values=*/true, (1 << 10) - 1);
372*09537850SAkhilesh Sanikop Test(GetDigest10bpp(GetDigestId()), /*use_fixed_values=*/false, -1);
373*09537850SAkhilesh Sanikop }
374*09537850SAkhilesh Sanikop
TEST_P(ObmcBlendTest10bpp,DISABLED_Speed)375*09537850SAkhilesh Sanikop TEST_P(ObmcBlendTest10bpp, DISABLED_Speed) {
376*09537850SAkhilesh Sanikop TestSpeed(GetDigestSpeed10bpp(GetDigestId()),
377*09537850SAkhilesh Sanikop kNumSpeedTests / (GetParam().height * GetParam().width));
378*09537850SAkhilesh Sanikop }
379*09537850SAkhilesh Sanikop
380*09537850SAkhilesh Sanikop INSTANTIATE_TEST_SUITE_P(C, ObmcBlendTest10bpp,
381*09537850SAkhilesh Sanikop testing::ValuesIn(kObmcTestParam));
382*09537850SAkhilesh Sanikop #if LIBGAV1_ENABLE_SSE4_1
383*09537850SAkhilesh Sanikop INSTANTIATE_TEST_SUITE_P(SSE41, ObmcBlendTest10bpp,
384*09537850SAkhilesh Sanikop testing::ValuesIn(kObmcTestParam));
385*09537850SAkhilesh Sanikop #endif
386*09537850SAkhilesh Sanikop #if LIBGAV1_ENABLE_NEON
387*09537850SAkhilesh Sanikop INSTANTIATE_TEST_SUITE_P(NEON, ObmcBlendTest10bpp,
388*09537850SAkhilesh Sanikop testing::ValuesIn(kObmcTestParam));
389*09537850SAkhilesh Sanikop #endif
390*09537850SAkhilesh Sanikop #endif // LIBGAV1_MAX_BITDEPTH >= 10
391*09537850SAkhilesh Sanikop
392*09537850SAkhilesh Sanikop #if LIBGAV1_MAX_BITDEPTH == 12
393*09537850SAkhilesh Sanikop using ObmcBlendTest12bpp = ObmcBlendTest<12, uint16_t>;
394*09537850SAkhilesh Sanikop
TEST_P(ObmcBlendTest12bpp,Blending)395*09537850SAkhilesh Sanikop TEST_P(ObmcBlendTest12bpp, Blending) {
396*09537850SAkhilesh Sanikop Test(/*digest=*/nullptr, /*use_fixed_values=*/true, 0);
397*09537850SAkhilesh Sanikop Test(/*digest=*/nullptr, /*use_fixed_values=*/true, 1);
398*09537850SAkhilesh Sanikop Test(/*digest=*/nullptr, /*use_fixed_values=*/true, 128);
399*09537850SAkhilesh Sanikop Test(/*digest=*/nullptr, /*use_fixed_values=*/true, (1 << 12) - 1);
400*09537850SAkhilesh Sanikop Test(GetDigest12bpp(GetDigestId()), /*use_fixed_values=*/false, -1);
401*09537850SAkhilesh Sanikop }
402*09537850SAkhilesh Sanikop
TEST_P(ObmcBlendTest12bpp,DISABLED_Speed)403*09537850SAkhilesh Sanikop TEST_P(ObmcBlendTest12bpp, DISABLED_Speed) {
404*09537850SAkhilesh Sanikop TestSpeed(GetDigestSpeed12bpp(GetDigestId()),
405*09537850SAkhilesh Sanikop kNumSpeedTests / (GetParam().height * GetParam().width));
406*09537850SAkhilesh Sanikop }
407*09537850SAkhilesh Sanikop
408*09537850SAkhilesh Sanikop INSTANTIATE_TEST_SUITE_P(C, ObmcBlendTest12bpp,
409*09537850SAkhilesh Sanikop testing::ValuesIn(kObmcTestParam));
410*09537850SAkhilesh Sanikop #endif // LIBGAV1_MAX_BITDEPTH == 12
411*09537850SAkhilesh Sanikop
412*09537850SAkhilesh Sanikop } // namespace
413*09537850SAkhilesh Sanikop } // namespace dsp
414*09537850SAkhilesh Sanikop } // namespace libgav1
415