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/utils/common.h"
16*09537850SAkhilesh Sanikop
17*09537850SAkhilesh Sanikop #include <cstddef>
18*09537850SAkhilesh Sanikop #include <cstdint>
19*09537850SAkhilesh Sanikop #include <memory>
20*09537850SAkhilesh Sanikop #include <string>
21*09537850SAkhilesh Sanikop
22*09537850SAkhilesh Sanikop #include "absl/base/macros.h"
23*09537850SAkhilesh Sanikop #include "gtest/gtest.h"
24*09537850SAkhilesh Sanikop #include "src/utils/constants.h"
25*09537850SAkhilesh Sanikop #include "src/utils/memory.h"
26*09537850SAkhilesh Sanikop #include "src/utils/types.h"
27*09537850SAkhilesh Sanikop
28*09537850SAkhilesh Sanikop namespace libgav1 {
29*09537850SAkhilesh Sanikop namespace {
30*09537850SAkhilesh Sanikop
BitLength(int64_t n)31*09537850SAkhilesh Sanikop int BitLength(int64_t n) {
32*09537850SAkhilesh Sanikop int count = 0;
33*09537850SAkhilesh Sanikop while (n != 0) {
34*09537850SAkhilesh Sanikop ++count;
35*09537850SAkhilesh Sanikop n >>= 1;
36*09537850SAkhilesh Sanikop }
37*09537850SAkhilesh Sanikop return count;
38*09537850SAkhilesh Sanikop }
39*09537850SAkhilesh Sanikop
TEST(CommonUtilsTest,Align)40*09537850SAkhilesh Sanikop TEST(CommonUtilsTest, Align) {
41*09537850SAkhilesh Sanikop for (int i = 0; i <= 8; ++i) {
42*09537850SAkhilesh Sanikop const int alignment = 1 << i;
43*09537850SAkhilesh Sanikop SCOPED_TRACE("alignment: " + std::to_string(alignment));
44*09537850SAkhilesh Sanikop EXPECT_EQ(Align(0, alignment), 0);
45*09537850SAkhilesh Sanikop EXPECT_EQ(Align(1, alignment), alignment);
46*09537850SAkhilesh Sanikop EXPECT_EQ(Align(alignment + 1, alignment), 2 * alignment);
47*09537850SAkhilesh Sanikop if (i > 1) {
48*09537850SAkhilesh Sanikop EXPECT_EQ(Align(alignment - 1, alignment), alignment);
49*09537850SAkhilesh Sanikop EXPECT_EQ(Align(2 * alignment - 1, alignment), 2 * alignment);
50*09537850SAkhilesh Sanikop }
51*09537850SAkhilesh Sanikop }
52*09537850SAkhilesh Sanikop }
53*09537850SAkhilesh Sanikop
TEST(CommonUtilsTest,AlignAddr)54*09537850SAkhilesh Sanikop TEST(CommonUtilsTest, AlignAddr) {
55*09537850SAkhilesh Sanikop auto buf = MakeAlignedUniquePtr<uint8_t>(/*alignment=*/1024, 512);
56*09537850SAkhilesh Sanikop ASSERT_NE(buf, nullptr);
57*09537850SAkhilesh Sanikop auto* const bufptr = buf.get();
58*09537850SAkhilesh Sanikop ASSERT_EQ(reinterpret_cast<uintptr_t>(bufptr) % 1024, 0);
59*09537850SAkhilesh Sanikop
60*09537850SAkhilesh Sanikop for (int i = 0; i <= 8; ++i) {
61*09537850SAkhilesh Sanikop const int alignment = 1 << i;
62*09537850SAkhilesh Sanikop ASSERT_LE(alignment, 1024);
63*09537850SAkhilesh Sanikop SCOPED_TRACE("alignment: " + std::to_string(alignment));
64*09537850SAkhilesh Sanikop EXPECT_EQ(AlignAddr(nullptr, alignment), nullptr);
65*09537850SAkhilesh Sanikop EXPECT_EQ(AlignAddr(bufptr, alignment), bufptr);
66*09537850SAkhilesh Sanikop EXPECT_EQ(AlignAddr(bufptr + 1, alignment), bufptr + alignment);
67*09537850SAkhilesh Sanikop EXPECT_EQ(AlignAddr(bufptr + alignment + 1, alignment),
68*09537850SAkhilesh Sanikop bufptr + 2 * alignment);
69*09537850SAkhilesh Sanikop if (i > 1) {
70*09537850SAkhilesh Sanikop EXPECT_EQ(AlignAddr(bufptr + alignment - 1, alignment),
71*09537850SAkhilesh Sanikop bufptr + alignment);
72*09537850SAkhilesh Sanikop EXPECT_EQ(AlignAddr(bufptr + 2 * alignment - 1, alignment),
73*09537850SAkhilesh Sanikop bufptr + 2 * alignment);
74*09537850SAkhilesh Sanikop }
75*09537850SAkhilesh Sanikop }
76*09537850SAkhilesh Sanikop }
77*09537850SAkhilesh Sanikop
TEST(CommonUtilsTest,Clip3)78*09537850SAkhilesh Sanikop TEST(CommonUtilsTest, Clip3) {
79*09537850SAkhilesh Sanikop // Value <= lower boundary.
80*09537850SAkhilesh Sanikop EXPECT_EQ(Clip3(10, 20, 30), 20);
81*09537850SAkhilesh Sanikop EXPECT_EQ(Clip3(20, 20, 30), 20);
82*09537850SAkhilesh Sanikop // Value >= higher boundary.
83*09537850SAkhilesh Sanikop EXPECT_EQ(Clip3(40, 20, 30), 30);
84*09537850SAkhilesh Sanikop EXPECT_EQ(Clip3(30, 20, 30), 30);
85*09537850SAkhilesh Sanikop // Value within boundary.
86*09537850SAkhilesh Sanikop EXPECT_EQ(Clip3(25, 20, 30), 25);
87*09537850SAkhilesh Sanikop // Clipping based on bitdepth (clamp between 0 and 2^bitdepth - 1). Make sure
88*09537850SAkhilesh Sanikop // that the resulting values are always in the pixel range for the
89*09537850SAkhilesh Sanikop // corresponding bitdepth.
90*09537850SAkhilesh Sanikop static constexpr int bitdepths[] = {8, 10, 12};
91*09537850SAkhilesh Sanikop static constexpr int pixels[] = {100, 500, 5000, -100, -500, -5000};
92*09537850SAkhilesh Sanikop for (const auto& bitdepth : bitdepths) {
93*09537850SAkhilesh Sanikop for (const auto& pixel : pixels) {
94*09537850SAkhilesh Sanikop const int clipped_pixel = Clip3(pixel, 0, (1 << bitdepth) - 1);
95*09537850SAkhilesh Sanikop EXPECT_GE(clipped_pixel, 0)
96*09537850SAkhilesh Sanikop << "Clip3 mismatch for bitdepth: " << bitdepth << " pixel: " << pixel;
97*09537850SAkhilesh Sanikop EXPECT_LE(clipped_pixel, (1 << bitdepth) - 1)
98*09537850SAkhilesh Sanikop << "Clip3 mismatch for bitdepth: " << bitdepth << " pixel: " << pixel;
99*09537850SAkhilesh Sanikop }
100*09537850SAkhilesh Sanikop }
101*09537850SAkhilesh Sanikop }
102*09537850SAkhilesh Sanikop
103*09537850SAkhilesh Sanikop template <typename Pixel>
TestExtendLine(int width,const int left,int right,Pixel left_value,Pixel right_value)104*09537850SAkhilesh Sanikop void TestExtendLine(int width, const int left, int right, Pixel left_value,
105*09537850SAkhilesh Sanikop Pixel right_value) {
106*09537850SAkhilesh Sanikop constexpr int size = 1000;
107*09537850SAkhilesh Sanikop ASSERT_LE(width + left + right, size);
108*09537850SAkhilesh Sanikop Pixel line[size];
109*09537850SAkhilesh Sanikop Pixel* line_start = line + left;
110*09537850SAkhilesh Sanikop line_start[0] = left_value;
111*09537850SAkhilesh Sanikop line_start[width - 1] = right_value;
112*09537850SAkhilesh Sanikop ExtendLine<Pixel>(line_start, width, left, right);
113*09537850SAkhilesh Sanikop for (int x = 0; x < left; x++) {
114*09537850SAkhilesh Sanikop EXPECT_EQ(left_value, line[x]) << "Left side mismatch at x: " << x;
115*09537850SAkhilesh Sanikop }
116*09537850SAkhilesh Sanikop for (int x = 0; x < right; x++) {
117*09537850SAkhilesh Sanikop EXPECT_EQ(right_value, line[left + width + x])
118*09537850SAkhilesh Sanikop << "Right side mismatch at x: " << x;
119*09537850SAkhilesh Sanikop }
120*09537850SAkhilesh Sanikop }
121*09537850SAkhilesh Sanikop
TEST(CommonUtilsTest,ExtendLine)122*09537850SAkhilesh Sanikop TEST(CommonUtilsTest, ExtendLine) {
123*09537850SAkhilesh Sanikop TestExtendLine<uint8_t>(300, 0, 0, 31, 13);
124*09537850SAkhilesh Sanikop TestExtendLine<uint8_t>(100, 10, 20, 31, 13);
125*09537850SAkhilesh Sanikop TestExtendLine<uint8_t>(257, 31, 77, 59, 255);
126*09537850SAkhilesh Sanikop TestExtendLine<uint16_t>(600, 0, 0, 1234, 4321);
127*09537850SAkhilesh Sanikop TestExtendLine<uint16_t>(200, 55, 88, 12345, 54321);
128*09537850SAkhilesh Sanikop TestExtendLine<uint16_t>(2, 99, 333, 257, 513);
129*09537850SAkhilesh Sanikop }
130*09537850SAkhilesh Sanikop
131*09537850SAkhilesh Sanikop template <typename T>
TestMemSetBlock(int rows,int columns,ptrdiff_t stride,T value)132*09537850SAkhilesh Sanikop void TestMemSetBlock(int rows, int columns, ptrdiff_t stride, T value) {
133*09537850SAkhilesh Sanikop constexpr int size = 1000;
134*09537850SAkhilesh Sanikop T block[size];
135*09537850SAkhilesh Sanikop static_assert(sizeof(T) == 1, "");
136*09537850SAkhilesh Sanikop ASSERT_LE(rows * stride, size);
137*09537850SAkhilesh Sanikop ASSERT_LE(columns, stride);
138*09537850SAkhilesh Sanikop MemSetBlock<T>(rows, columns, value, block, stride);
139*09537850SAkhilesh Sanikop for (int y = 0; y < rows; y++) {
140*09537850SAkhilesh Sanikop for (int x = 0; x < columns; x++) {
141*09537850SAkhilesh Sanikop EXPECT_EQ(value, block[y * stride + x])
142*09537850SAkhilesh Sanikop << "Mismatch at y: " << y << " x: " << x;
143*09537850SAkhilesh Sanikop }
144*09537850SAkhilesh Sanikop }
145*09537850SAkhilesh Sanikop }
146*09537850SAkhilesh Sanikop
TEST(CommonUtilsTest,MemSetBlock)147*09537850SAkhilesh Sanikop TEST(CommonUtilsTest, MemSetBlock) {
148*09537850SAkhilesh Sanikop TestMemSetBlock<bool>(15, 28, 29, true);
149*09537850SAkhilesh Sanikop TestMemSetBlock<bool>(17, 1, 24, false);
150*09537850SAkhilesh Sanikop TestMemSetBlock<bool>(7, 2, 13, true);
151*09537850SAkhilesh Sanikop TestMemSetBlock<int8_t>(35, 17, 19, 123);
152*09537850SAkhilesh Sanikop TestMemSetBlock<uint8_t>(19, 16, 16, 234);
153*09537850SAkhilesh Sanikop }
154*09537850SAkhilesh Sanikop
155*09537850SAkhilesh Sanikop template <typename T>
TestSetBlock(int rows,int columns,ptrdiff_t stride,T value)156*09537850SAkhilesh Sanikop void TestSetBlock(int rows, int columns, ptrdiff_t stride, T value) {
157*09537850SAkhilesh Sanikop constexpr int size = 1000;
158*09537850SAkhilesh Sanikop T block[size];
159*09537850SAkhilesh Sanikop ASSERT_LE(rows * stride, size);
160*09537850SAkhilesh Sanikop ASSERT_LE(columns, stride);
161*09537850SAkhilesh Sanikop SetBlock<T>(rows, columns, value, block, stride);
162*09537850SAkhilesh Sanikop for (int y = 0; y < rows; y++) {
163*09537850SAkhilesh Sanikop for (int x = 0; x < columns; x++) {
164*09537850SAkhilesh Sanikop EXPECT_EQ(value, block[y * stride + x])
165*09537850SAkhilesh Sanikop << "Mismatch at y: " << y << " x: " << x;
166*09537850SAkhilesh Sanikop }
167*09537850SAkhilesh Sanikop }
168*09537850SAkhilesh Sanikop }
169*09537850SAkhilesh Sanikop
TEST(CommonUtilsTest,SetBlock)170*09537850SAkhilesh Sanikop TEST(CommonUtilsTest, SetBlock) {
171*09537850SAkhilesh Sanikop // Test 1-byte block set.
172*09537850SAkhilesh Sanikop TestSetBlock<bool>(15, 28, 29, true);
173*09537850SAkhilesh Sanikop TestSetBlock<bool>(17, 1, 24, false);
174*09537850SAkhilesh Sanikop TestSetBlock<bool>(7, 2, 13, true);
175*09537850SAkhilesh Sanikop TestSetBlock<int8_t>(35, 17, 19, 123);
176*09537850SAkhilesh Sanikop TestSetBlock<uint8_t>(19, 16, 16, 234);
177*09537850SAkhilesh Sanikop // Test 2-byte block set.
178*09537850SAkhilesh Sanikop TestSetBlock<int16_t>(23, 27, 28, 1234);
179*09537850SAkhilesh Sanikop TestSetBlock<uint16_t>(13, 39, 44, 4321);
180*09537850SAkhilesh Sanikop // Test 4-byte block set.
181*09537850SAkhilesh Sanikop TestSetBlock<int>(14, 7, 7, 12345);
182*09537850SAkhilesh Sanikop TestSetBlock<int>(33, 4, 15, 54321);
183*09537850SAkhilesh Sanikop // Test pointer block set.
184*09537850SAkhilesh Sanikop int data;
185*09537850SAkhilesh Sanikop TestSetBlock<int*>(23, 8, 25, &data);
186*09537850SAkhilesh Sanikop }
187*09537850SAkhilesh Sanikop
TEST(CommonUtilsTest,CountTrailingZeros)188*09537850SAkhilesh Sanikop TEST(CommonUtilsTest, CountTrailingZeros) {
189*09537850SAkhilesh Sanikop EXPECT_EQ(CountTrailingZeros(0x1), 0);
190*09537850SAkhilesh Sanikop EXPECT_EQ(CountTrailingZeros(0x3), 0);
191*09537850SAkhilesh Sanikop EXPECT_EQ(CountTrailingZeros(0x7), 0);
192*09537850SAkhilesh Sanikop EXPECT_EQ(CountTrailingZeros(0xF), 0);
193*09537850SAkhilesh Sanikop EXPECT_EQ(CountTrailingZeros(0x2), 1);
194*09537850SAkhilesh Sanikop EXPECT_EQ(CountTrailingZeros(0x6), 1);
195*09537850SAkhilesh Sanikop EXPECT_EQ(CountTrailingZeros(0xE), 1);
196*09537850SAkhilesh Sanikop EXPECT_EQ(CountTrailingZeros(0x4), 2);
197*09537850SAkhilesh Sanikop EXPECT_EQ(CountTrailingZeros(0xC), 2);
198*09537850SAkhilesh Sanikop EXPECT_EQ(CountTrailingZeros(0x8), 3);
199*09537850SAkhilesh Sanikop EXPECT_EQ(CountTrailingZeros(0x10), 4);
200*09537850SAkhilesh Sanikop EXPECT_EQ(CountTrailingZeros(0x30), 4);
201*09537850SAkhilesh Sanikop EXPECT_EQ(CountTrailingZeros(0x70), 4);
202*09537850SAkhilesh Sanikop EXPECT_EQ(CountTrailingZeros(0xF0), 4);
203*09537850SAkhilesh Sanikop EXPECT_EQ(CountTrailingZeros(0x20), 5);
204*09537850SAkhilesh Sanikop EXPECT_EQ(CountTrailingZeros(0x60), 5);
205*09537850SAkhilesh Sanikop EXPECT_EQ(CountTrailingZeros(0xE0), 5);
206*09537850SAkhilesh Sanikop EXPECT_EQ(CountTrailingZeros(0x40), 6);
207*09537850SAkhilesh Sanikop EXPECT_EQ(CountTrailingZeros(0xC0), 6);
208*09537850SAkhilesh Sanikop EXPECT_EQ(CountTrailingZeros(0x80), 7);
209*09537850SAkhilesh Sanikop EXPECT_EQ(CountTrailingZeros(0x31), 0);
210*09537850SAkhilesh Sanikop EXPECT_EQ(CountTrailingZeros(0x32), 1);
211*09537850SAkhilesh Sanikop EXPECT_EQ(CountTrailingZeros(0x34), 2);
212*09537850SAkhilesh Sanikop EXPECT_EQ(CountTrailingZeros(0x38), 3);
213*09537850SAkhilesh Sanikop EXPECT_EQ(CountTrailingZeros(0x310), 4);
214*09537850SAkhilesh Sanikop EXPECT_EQ(CountTrailingZeros(0x320), 5);
215*09537850SAkhilesh Sanikop EXPECT_EQ(CountTrailingZeros(0x340), 6);
216*09537850SAkhilesh Sanikop EXPECT_EQ(CountTrailingZeros(0x380), 7);
217*09537850SAkhilesh Sanikop }
218*09537850SAkhilesh Sanikop
TEST(CommonUtilsTest,FloorLog2)219*09537850SAkhilesh Sanikop TEST(CommonUtilsTest, FloorLog2) {
220*09537850SAkhilesh Sanikop // Powers of 2.
221*09537850SAkhilesh Sanikop EXPECT_EQ(FloorLog2(1), 0);
222*09537850SAkhilesh Sanikop EXPECT_EQ(FloorLog2(2), 1);
223*09537850SAkhilesh Sanikop EXPECT_EQ(FloorLog2(8), 3);
224*09537850SAkhilesh Sanikop EXPECT_EQ(FloorLog2(64), 6);
225*09537850SAkhilesh Sanikop // Powers of 2 +/- 1.
226*09537850SAkhilesh Sanikop EXPECT_EQ(FloorLog2(9), 3);
227*09537850SAkhilesh Sanikop EXPECT_EQ(FloorLog2(15), 3);
228*09537850SAkhilesh Sanikop EXPECT_EQ(FloorLog2(63), 5);
229*09537850SAkhilesh Sanikop // Large value, smaller than 32 bit.
230*09537850SAkhilesh Sanikop EXPECT_EQ(FloorLog2(0x7fffffff), 30);
231*09537850SAkhilesh Sanikop EXPECT_EQ(FloorLog2(0x80000000), 31);
232*09537850SAkhilesh Sanikop // Larger than 32 bit.
233*09537850SAkhilesh Sanikop EXPECT_EQ(FloorLog2(uint64_t{0x7fffffffffffffff}), 62);
234*09537850SAkhilesh Sanikop EXPECT_EQ(FloorLog2(uint64_t{0x8000000000000000}), 63);
235*09537850SAkhilesh Sanikop EXPECT_EQ(FloorLog2(uint64_t{0xffffffffffffffff}), 63);
236*09537850SAkhilesh Sanikop }
237*09537850SAkhilesh Sanikop
TEST(CommonUtilsTest,CeilLog2)238*09537850SAkhilesh Sanikop TEST(CommonUtilsTest, CeilLog2) {
239*09537850SAkhilesh Sanikop // Even though log2(0) is -inf, here we explicitly define it to be 0.
240*09537850SAkhilesh Sanikop EXPECT_EQ(CeilLog2(0), 0);
241*09537850SAkhilesh Sanikop // Powers of 2.
242*09537850SAkhilesh Sanikop EXPECT_EQ(CeilLog2(1), 0);
243*09537850SAkhilesh Sanikop EXPECT_EQ(CeilLog2(2), 1);
244*09537850SAkhilesh Sanikop EXPECT_EQ(CeilLog2(8), 3);
245*09537850SAkhilesh Sanikop EXPECT_EQ(CeilLog2(64), 6);
246*09537850SAkhilesh Sanikop // Powers of 2 +/- 1.
247*09537850SAkhilesh Sanikop EXPECT_EQ(CeilLog2(9), 4);
248*09537850SAkhilesh Sanikop EXPECT_EQ(CeilLog2(15), 4);
249*09537850SAkhilesh Sanikop EXPECT_EQ(CeilLog2(63), 6);
250*09537850SAkhilesh Sanikop // Large value.
251*09537850SAkhilesh Sanikop EXPECT_EQ(CeilLog2(0x7fffffff), 31);
252*09537850SAkhilesh Sanikop }
253*09537850SAkhilesh Sanikop
TEST(CommonUtilsTest,RightShiftWithCeiling)254*09537850SAkhilesh Sanikop TEST(CommonUtilsTest, RightShiftWithCeiling) {
255*09537850SAkhilesh Sanikop // Shift 1 bit.
256*09537850SAkhilesh Sanikop EXPECT_EQ(RightShiftWithCeiling(1, 1), 1);
257*09537850SAkhilesh Sanikop EXPECT_EQ(RightShiftWithCeiling(2, 1), 1);
258*09537850SAkhilesh Sanikop EXPECT_EQ(RightShiftWithCeiling(3, 1), 2);
259*09537850SAkhilesh Sanikop EXPECT_EQ(RightShiftWithCeiling(4, 1), 2);
260*09537850SAkhilesh Sanikop EXPECT_EQ(RightShiftWithCeiling(5, 1), 3);
261*09537850SAkhilesh Sanikop // Shift 2 bits.
262*09537850SAkhilesh Sanikop EXPECT_EQ(RightShiftWithCeiling(1, 2), 1);
263*09537850SAkhilesh Sanikop EXPECT_EQ(RightShiftWithCeiling(2, 2), 1);
264*09537850SAkhilesh Sanikop EXPECT_EQ(RightShiftWithCeiling(3, 2), 1);
265*09537850SAkhilesh Sanikop EXPECT_EQ(RightShiftWithCeiling(4, 2), 1);
266*09537850SAkhilesh Sanikop EXPECT_EQ(RightShiftWithCeiling(5, 2), 2);
267*09537850SAkhilesh Sanikop // Shift 20 bits.
268*09537850SAkhilesh Sanikop EXPECT_EQ(RightShiftWithCeiling(1, 20), 1);
269*09537850SAkhilesh Sanikop EXPECT_EQ(RightShiftWithCeiling((1 << 20) - 1, 20), 1);
270*09537850SAkhilesh Sanikop EXPECT_EQ(RightShiftWithCeiling(1 << 20, 20), 1);
271*09537850SAkhilesh Sanikop EXPECT_EQ(RightShiftWithCeiling((1 << 20) + 1, 20), 2);
272*09537850SAkhilesh Sanikop EXPECT_EQ(RightShiftWithCeiling((1 << 21) - 1, 20), 2);
273*09537850SAkhilesh Sanikop }
274*09537850SAkhilesh Sanikop
275*09537850SAkhilesh Sanikop template <typename Input, typename Output>
VerifyRightShiftWithRounding(const Input * const values,const int * const bits,const Output * const rounded_values,size_t count)276*09537850SAkhilesh Sanikop void VerifyRightShiftWithRounding(const Input* const values,
277*09537850SAkhilesh Sanikop const int* const bits,
278*09537850SAkhilesh Sanikop const Output* const rounded_values,
279*09537850SAkhilesh Sanikop size_t count) {
280*09537850SAkhilesh Sanikop for (size_t i = 0; i < count; ++i) {
281*09537850SAkhilesh Sanikop const Output rounded_value = RightShiftWithRounding(values[i], bits[i]);
282*09537850SAkhilesh Sanikop EXPECT_EQ(rounded_value, rounded_values[i]) << "Mismatch at index " << i;
283*09537850SAkhilesh Sanikop // Rounding reduces the bit length by |bits[i]| - 1.
284*09537850SAkhilesh Sanikop EXPECT_LE(BitLength(rounded_value), BitLength(values[i]) - (bits[i] - 1))
285*09537850SAkhilesh Sanikop << "Mismatch at index " << i;
286*09537850SAkhilesh Sanikop }
287*09537850SAkhilesh Sanikop }
288*09537850SAkhilesh Sanikop
TEST(CommonUtilTest,RightShiftWithRoundingInt32)289*09537850SAkhilesh Sanikop TEST(CommonUtilTest, RightShiftWithRoundingInt32) {
290*09537850SAkhilesh Sanikop static constexpr int32_t values[] = {5, 203, 204, 255, 40000, 50000};
291*09537850SAkhilesh Sanikop static constexpr int bits[] = {0, 3, 3, 3, 12, 12};
292*09537850SAkhilesh Sanikop static constexpr int32_t rounded_values[] = {5, 25, 26, 32, 10, 12};
293*09537850SAkhilesh Sanikop static_assert(ABSL_ARRAYSIZE(values) == ABSL_ARRAYSIZE(bits), "");
294*09537850SAkhilesh Sanikop static_assert(ABSL_ARRAYSIZE(values) == ABSL_ARRAYSIZE(rounded_values), "");
295*09537850SAkhilesh Sanikop VerifyRightShiftWithRounding<int32_t, int32_t>(values, bits, rounded_values,
296*09537850SAkhilesh Sanikop ABSL_ARRAYSIZE(values));
297*09537850SAkhilesh Sanikop }
298*09537850SAkhilesh Sanikop
TEST(CommonUtilTest,RightShiftWithRoundingUint32)299*09537850SAkhilesh Sanikop TEST(CommonUtilTest, RightShiftWithRoundingUint32) {
300*09537850SAkhilesh Sanikop static constexpr uint32_t values[] = {5, 203, 204, 255,
301*09537850SAkhilesh Sanikop 40000, 50000, 0x7fffffff};
302*09537850SAkhilesh Sanikop static constexpr int bits[] = {0, 3, 3, 3, 12, 12, 20};
303*09537850SAkhilesh Sanikop static constexpr uint32_t rounded_values[] = {5, 25, 26, 32, 10, 12, 2048};
304*09537850SAkhilesh Sanikop static_assert(ABSL_ARRAYSIZE(values) == ABSL_ARRAYSIZE(bits), "");
305*09537850SAkhilesh Sanikop static_assert(ABSL_ARRAYSIZE(values) == ABSL_ARRAYSIZE(rounded_values), "");
306*09537850SAkhilesh Sanikop VerifyRightShiftWithRounding<uint32_t, uint32_t>(values, bits, rounded_values,
307*09537850SAkhilesh Sanikop ABSL_ARRAYSIZE(values));
308*09537850SAkhilesh Sanikop }
309*09537850SAkhilesh Sanikop
TEST(CommonUtilTest,RightShiftWithRoundingInt64)310*09537850SAkhilesh Sanikop TEST(CommonUtilTest, RightShiftWithRoundingInt64) {
311*09537850SAkhilesh Sanikop static constexpr int64_t values[] = {5, 203, 204, 255,
312*09537850SAkhilesh Sanikop 40000, 50000, 0x7fffffff, 0x8fffffff};
313*09537850SAkhilesh Sanikop static constexpr int bits[] = {0, 3, 3, 3, 12, 12, 20, 20};
314*09537850SAkhilesh Sanikop static constexpr int32_t rounded_values[] = {5, 25, 26, 32,
315*09537850SAkhilesh Sanikop 10, 12, 2048, 2304};
316*09537850SAkhilesh Sanikop static_assert(ABSL_ARRAYSIZE(values) == ABSL_ARRAYSIZE(bits), "");
317*09537850SAkhilesh Sanikop static_assert(ABSL_ARRAYSIZE(values) == ABSL_ARRAYSIZE(rounded_values), "");
318*09537850SAkhilesh Sanikop VerifyRightShiftWithRounding<int64_t, int32_t>(values, bits, rounded_values,
319*09537850SAkhilesh Sanikop ABSL_ARRAYSIZE(values));
320*09537850SAkhilesh Sanikop }
321*09537850SAkhilesh Sanikop
322*09537850SAkhilesh Sanikop template <typename Input>
VerifyRightShiftWithRoundingSigned(const Input * const values,const int * const bits,const int32_t * const rounded_values,int count)323*09537850SAkhilesh Sanikop void VerifyRightShiftWithRoundingSigned(const Input* const values,
324*09537850SAkhilesh Sanikop const int* const bits,
325*09537850SAkhilesh Sanikop const int32_t* const rounded_values,
326*09537850SAkhilesh Sanikop int count) {
327*09537850SAkhilesh Sanikop for (int i = 0; i < count; ++i) {
328*09537850SAkhilesh Sanikop int32_t rounded_value = RightShiftWithRoundingSigned(values[i], bits[i]);
329*09537850SAkhilesh Sanikop EXPECT_EQ(rounded_value, rounded_values[i]) << "Mismatch at index " << i;
330*09537850SAkhilesh Sanikop rounded_value = RightShiftWithRoundingSigned(-values[i], bits[i]);
331*09537850SAkhilesh Sanikop EXPECT_EQ(rounded_value, -rounded_values[i]) << "Mismatch at index " << i;
332*09537850SAkhilesh Sanikop }
333*09537850SAkhilesh Sanikop }
334*09537850SAkhilesh Sanikop
TEST(CommonUtilTest,RightShiftWithRoundingSignedInt32)335*09537850SAkhilesh Sanikop TEST(CommonUtilTest, RightShiftWithRoundingSignedInt32) {
336*09537850SAkhilesh Sanikop static constexpr int32_t values[] = {203, 204, 255, 40000, 50000};
337*09537850SAkhilesh Sanikop static constexpr int bits[] = {3, 3, 3, 12, 12};
338*09537850SAkhilesh Sanikop static constexpr int32_t rounded_values[] = {25, 26, 32, 10, 12};
339*09537850SAkhilesh Sanikop static_assert(ABSL_ARRAYSIZE(values) == ABSL_ARRAYSIZE(bits), "");
340*09537850SAkhilesh Sanikop static_assert(ABSL_ARRAYSIZE(values) == ABSL_ARRAYSIZE(rounded_values), "");
341*09537850SAkhilesh Sanikop VerifyRightShiftWithRoundingSigned<int32_t>(values, bits, rounded_values,
342*09537850SAkhilesh Sanikop ABSL_ARRAYSIZE(values));
343*09537850SAkhilesh Sanikop }
344*09537850SAkhilesh Sanikop
TEST(CommonUtilTest,RightShiftWithRoundingSignedInt64)345*09537850SAkhilesh Sanikop TEST(CommonUtilTest, RightShiftWithRoundingSignedInt64) {
346*09537850SAkhilesh Sanikop static constexpr int64_t values[] = {203, 204, 255, 40000,
347*09537850SAkhilesh Sanikop 50000, 0x7fffffff, 0x8fffffff};
348*09537850SAkhilesh Sanikop static constexpr int bits[] = {3, 3, 3, 12, 12, 20, 20};
349*09537850SAkhilesh Sanikop static constexpr int32_t rounded_values[] = {25, 26, 32, 10, 12, 2048, 2304};
350*09537850SAkhilesh Sanikop static_assert(ABSL_ARRAYSIZE(values) == ABSL_ARRAYSIZE(bits), "");
351*09537850SAkhilesh Sanikop static_assert(ABSL_ARRAYSIZE(values) == ABSL_ARRAYSIZE(rounded_values), "");
352*09537850SAkhilesh Sanikop VerifyRightShiftWithRoundingSigned<int64_t>(values, bits, rounded_values,
353*09537850SAkhilesh Sanikop ABSL_ARRAYSIZE(values));
354*09537850SAkhilesh Sanikop }
355*09537850SAkhilesh Sanikop
TEST(CommonUtilTest,GetResidualBufferSize)356*09537850SAkhilesh Sanikop TEST(CommonUtilTest, GetResidualBufferSize) {
357*09537850SAkhilesh Sanikop // No subsampling.
358*09537850SAkhilesh Sanikop EXPECT_EQ(GetResidualBufferSize(64, 64, 0, 0, 2),
359*09537850SAkhilesh Sanikop /* 2*(64*64*3/1 + 32*4) = */ 24832);
360*09537850SAkhilesh Sanikop // Only X is subsampled.
361*09537850SAkhilesh Sanikop EXPECT_EQ(GetResidualBufferSize(64, 64, 1, 0, 2),
362*09537850SAkhilesh Sanikop /* 2*(64*64*2/1 + 32*4) = */ 16640);
363*09537850SAkhilesh Sanikop // Only Y is subsampled.
364*09537850SAkhilesh Sanikop EXPECT_EQ(GetResidualBufferSize(64, 64, 0, 1, 2),
365*09537850SAkhilesh Sanikop /* 2*(64*64*2/1 + 32*4) = */ 16640);
366*09537850SAkhilesh Sanikop // Both X and Y are subsampled.
367*09537850SAkhilesh Sanikop EXPECT_EQ(GetResidualBufferSize(64, 64, 1, 1, 2),
368*09537850SAkhilesh Sanikop /* 2*(64*64*3/2 + 32*4) = */ 12544);
369*09537850SAkhilesh Sanikop }
370*09537850SAkhilesh Sanikop
371*09537850SAkhilesh Sanikop //------------------------------------------------------------------------------
372*09537850SAkhilesh Sanikop // Tests for bitstream util functions
373*09537850SAkhilesh Sanikop
TEST(BitstreamUtilTest,IsIntraFrame)374*09537850SAkhilesh Sanikop TEST(BitstreamUtilTest, IsIntraFrame) {
375*09537850SAkhilesh Sanikop EXPECT_TRUE(IsIntraFrame(kFrameKey));
376*09537850SAkhilesh Sanikop EXPECT_TRUE(IsIntraFrame(kFrameIntraOnly));
377*09537850SAkhilesh Sanikop EXPECT_FALSE(IsIntraFrame(kFrameInter));
378*09537850SAkhilesh Sanikop EXPECT_FALSE(IsIntraFrame(kFrameSwitch));
379*09537850SAkhilesh Sanikop }
380*09537850SAkhilesh Sanikop
TEST(BitstreamUtilTest,GetTransformClass)381*09537850SAkhilesh Sanikop TEST(BitstreamUtilTest, GetTransformClass) {
382*09537850SAkhilesh Sanikop static constexpr TransformClass expected_classes[kNumTransformTypes] = {
383*09537850SAkhilesh Sanikop kTransformClass2D, kTransformClass2D,
384*09537850SAkhilesh Sanikop kTransformClass2D, kTransformClass2D,
385*09537850SAkhilesh Sanikop kTransformClass2D, kTransformClass2D,
386*09537850SAkhilesh Sanikop kTransformClass2D, kTransformClass2D,
387*09537850SAkhilesh Sanikop kTransformClass2D, kTransformClass2D,
388*09537850SAkhilesh Sanikop kTransformClassVertical, kTransformClassHorizontal,
389*09537850SAkhilesh Sanikop kTransformClassVertical, kTransformClassHorizontal,
390*09537850SAkhilesh Sanikop kTransformClassVertical, kTransformClassHorizontal,
391*09537850SAkhilesh Sanikop };
392*09537850SAkhilesh Sanikop for (int i = 0; i < kNumTransformTypes; ++i) {
393*09537850SAkhilesh Sanikop EXPECT_EQ(GetTransformClass(static_cast<TransformType>(i)),
394*09537850SAkhilesh Sanikop expected_classes[i])
395*09537850SAkhilesh Sanikop << "Mismatch at index " << i;
396*09537850SAkhilesh Sanikop }
397*09537850SAkhilesh Sanikop }
398*09537850SAkhilesh Sanikop
TEST(BitstreamUtilTest,RowOrColumn4x4ToPixel)399*09537850SAkhilesh Sanikop TEST(BitstreamUtilTest, RowOrColumn4x4ToPixel) {
400*09537850SAkhilesh Sanikop EXPECT_EQ(RowOrColumn4x4ToPixel(10, kPlaneY, 0), 40);
401*09537850SAkhilesh Sanikop EXPECT_EQ(RowOrColumn4x4ToPixel(10, kPlaneY, 1),
402*09537850SAkhilesh Sanikop 40); // Subsampling should have no effect on Y plane.
403*09537850SAkhilesh Sanikop EXPECT_EQ(RowOrColumn4x4ToPixel(10, kPlaneU, 0), 40);
404*09537850SAkhilesh Sanikop EXPECT_EQ(RowOrColumn4x4ToPixel(10, kPlaneU, 1), 20);
405*09537850SAkhilesh Sanikop EXPECT_EQ(RowOrColumn4x4ToPixel(10, kPlaneV, 0), 40);
406*09537850SAkhilesh Sanikop EXPECT_EQ(RowOrColumn4x4ToPixel(10, kPlaneV, 1), 20);
407*09537850SAkhilesh Sanikop }
408*09537850SAkhilesh Sanikop
TEST(BitstreamUtilTest,GetPlaneType)409*09537850SAkhilesh Sanikop TEST(BitstreamUtilTest, GetPlaneType) {
410*09537850SAkhilesh Sanikop EXPECT_EQ(GetPlaneType(kPlaneY), kPlaneTypeY);
411*09537850SAkhilesh Sanikop EXPECT_EQ(GetPlaneType(kPlaneU), kPlaneTypeUV);
412*09537850SAkhilesh Sanikop EXPECT_EQ(GetPlaneType(kPlaneV), kPlaneTypeUV);
413*09537850SAkhilesh Sanikop }
414*09537850SAkhilesh Sanikop
TEST(BitstreamUtils,IsDirectionalMode)415*09537850SAkhilesh Sanikop TEST(BitstreamUtils, IsDirectionalMode) {
416*09537850SAkhilesh Sanikop static constexpr bool is_directional_modes[kNumPredictionModes] = {
417*09537850SAkhilesh Sanikop false, true, true, true, true, true, true, true, true,
418*09537850SAkhilesh Sanikop false, false, false, false, false, false, false, false, false,
419*09537850SAkhilesh Sanikop false, false, false, false, false, false, false, false,
420*09537850SAkhilesh Sanikop };
421*09537850SAkhilesh Sanikop for (int i = 0; i < kNumPredictionModes; ++i) {
422*09537850SAkhilesh Sanikop EXPECT_EQ(IsDirectionalMode(static_cast<PredictionMode>(i)),
423*09537850SAkhilesh Sanikop is_directional_modes[i])
424*09537850SAkhilesh Sanikop << "Mismatch at index " << i;
425*09537850SAkhilesh Sanikop }
426*09537850SAkhilesh Sanikop }
427*09537850SAkhilesh Sanikop
TEST(BitstreamUtils,GetRelativeDistance)428*09537850SAkhilesh Sanikop TEST(BitstreamUtils, GetRelativeDistance) {
429*09537850SAkhilesh Sanikop // Both order_hint_bits and order_hint_shift_bits are zero. (a and b must be
430*09537850SAkhilesh Sanikop // zero.)
431*09537850SAkhilesh Sanikop EXPECT_EQ(GetRelativeDistance(0, 0, 0), 0);
432*09537850SAkhilesh Sanikop EXPECT_EQ(GetRelativeDistance(10, 20, 27), -10);
433*09537850SAkhilesh Sanikop
434*09537850SAkhilesh Sanikop EXPECT_EQ(GetRelativeDistance(2, 1, 30), 1);
435*09537850SAkhilesh Sanikop EXPECT_EQ(GetRelativeDistance(2, 1, 29), 1);
436*09537850SAkhilesh Sanikop
437*09537850SAkhilesh Sanikop EXPECT_EQ(GetRelativeDistance(1, 2, 30), -1);
438*09537850SAkhilesh Sanikop EXPECT_EQ(GetRelativeDistance(1, 2, 29), -1);
439*09537850SAkhilesh Sanikop
440*09537850SAkhilesh Sanikop // With an order_hint_bits of 4 and an order_hint_shift_bits of 28, 16 is the
441*09537850SAkhilesh Sanikop // same as 0, 17 is the same as 1, etc. The most positive distance is 7, and
442*09537850SAkhilesh Sanikop // the most negative distance is -8.
443*09537850SAkhilesh Sanikop
444*09537850SAkhilesh Sanikop EXPECT_EQ(GetRelativeDistance(2, 6, 28), -4);
445*09537850SAkhilesh Sanikop EXPECT_EQ(GetRelativeDistance(6, 2, 28), 4);
446*09537850SAkhilesh Sanikop // 18 - 14 = 4.
447*09537850SAkhilesh Sanikop EXPECT_EQ(GetRelativeDistance(2, 14, 28), 4);
448*09537850SAkhilesh Sanikop // 14 - 18 = -4.
449*09537850SAkhilesh Sanikop EXPECT_EQ(GetRelativeDistance(14, 2, 28), -4);
450*09537850SAkhilesh Sanikop // If a and b are exactly 8 apart, GetRelativeDistance() cannot tell whether
451*09537850SAkhilesh Sanikop // a is before or after b. GetRelativeDistance(a, b) and
452*09537850SAkhilesh Sanikop // GetRelativeDistance(b, a) are both -8.
453*09537850SAkhilesh Sanikop // 1 - 9 = -8.
454*09537850SAkhilesh Sanikop EXPECT_EQ(GetRelativeDistance(1, 9, 28), -8);
455*09537850SAkhilesh Sanikop // 9 - 17 = -8.
456*09537850SAkhilesh Sanikop EXPECT_EQ(GetRelativeDistance(9, 1, 28), -8);
457*09537850SAkhilesh Sanikop
458*09537850SAkhilesh Sanikop // With an order_hint_bits of 5 and an order_hint_shift_bits of 27, 32 is the
459*09537850SAkhilesh Sanikop // same as 0, 33 is the same as 1, etc. The most positive distance is 15, and
460*09537850SAkhilesh Sanikop // the most negative distance is -16.
461*09537850SAkhilesh Sanikop
462*09537850SAkhilesh Sanikop // 31 - 32 = -1.
463*09537850SAkhilesh Sanikop EXPECT_EQ(GetRelativeDistance(31, 0, 27), -1);
464*09537850SAkhilesh Sanikop // 32 - 31 = 1.
465*09537850SAkhilesh Sanikop EXPECT_EQ(GetRelativeDistance(0, 31, 27), 1);
466*09537850SAkhilesh Sanikop // 30 - 33 = -3.
467*09537850SAkhilesh Sanikop EXPECT_EQ(GetRelativeDistance(30, 1, 27), -3);
468*09537850SAkhilesh Sanikop // 33 - 30 = 3.
469*09537850SAkhilesh Sanikop EXPECT_EQ(GetRelativeDistance(1, 30, 27), 3);
470*09537850SAkhilesh Sanikop // 25 - 36 = -11.
471*09537850SAkhilesh Sanikop EXPECT_EQ(GetRelativeDistance(25, 4, 27), -11);
472*09537850SAkhilesh Sanikop // 36 - 25 = 11.
473*09537850SAkhilesh Sanikop EXPECT_EQ(GetRelativeDistance(4, 25, 27), 11);
474*09537850SAkhilesh Sanikop // 15 - 0 = 15.
475*09537850SAkhilesh Sanikop EXPECT_EQ(GetRelativeDistance(15, 0, 27), 15);
476*09537850SAkhilesh Sanikop // If a and b are exactly 16 apart, GetRelativeDistance() cannot tell whether
477*09537850SAkhilesh Sanikop // a is before or after b. GetRelativeDistance(a, b) and
478*09537850SAkhilesh Sanikop // GetRelativeDistance(b, a) are both -16.
479*09537850SAkhilesh Sanikop // 16 - 32 = -16.
480*09537850SAkhilesh Sanikop EXPECT_EQ(GetRelativeDistance(16, 0, 27), -16);
481*09537850SAkhilesh Sanikop // 0 - 16 = -16.
482*09537850SAkhilesh Sanikop EXPECT_EQ(GetRelativeDistance(0, 16, 27), -16);
483*09537850SAkhilesh Sanikop }
484*09537850SAkhilesh Sanikop
TEST(BitstreamUtils,ApplySign)485*09537850SAkhilesh Sanikop TEST(BitstreamUtils, ApplySign) {
486*09537850SAkhilesh Sanikop // ApplyPositive(0) = 0
487*09537850SAkhilesh Sanikop EXPECT_EQ(ApplySign(0, 0), 0);
488*09537850SAkhilesh Sanikop // ApplyNegative(0) = 0
489*09537850SAkhilesh Sanikop EXPECT_EQ(ApplySign(0, -1), 0);
490*09537850SAkhilesh Sanikop
491*09537850SAkhilesh Sanikop // ApplyPositive(1) = 1
492*09537850SAkhilesh Sanikop EXPECT_EQ(ApplySign(1, 0), 1);
493*09537850SAkhilesh Sanikop // ApplyNegative(1) = -1
494*09537850SAkhilesh Sanikop EXPECT_EQ(ApplySign(1, -1), -1);
495*09537850SAkhilesh Sanikop
496*09537850SAkhilesh Sanikop // ApplyPositive(-1) = -1
497*09537850SAkhilesh Sanikop EXPECT_EQ(ApplySign(-1, 0), -1);
498*09537850SAkhilesh Sanikop // ApplyNegative(-1) = 1
499*09537850SAkhilesh Sanikop EXPECT_EQ(ApplySign(-1, -1), 1);
500*09537850SAkhilesh Sanikop
501*09537850SAkhilesh Sanikop // ApplyPositive(1234) = 1234
502*09537850SAkhilesh Sanikop EXPECT_EQ(ApplySign(1234, 0), 1234);
503*09537850SAkhilesh Sanikop // ApplyNegative(1234) = -1234
504*09537850SAkhilesh Sanikop EXPECT_EQ(ApplySign(1234, -1), -1234);
505*09537850SAkhilesh Sanikop
506*09537850SAkhilesh Sanikop // ApplyPositive(-1234) = -1234
507*09537850SAkhilesh Sanikop EXPECT_EQ(ApplySign(-1234, 0), -1234);
508*09537850SAkhilesh Sanikop // ApplyNegative(-1234) = 1234
509*09537850SAkhilesh Sanikop EXPECT_EQ(ApplySign(-1234, -1), 1234);
510*09537850SAkhilesh Sanikop }
511*09537850SAkhilesh Sanikop
512*09537850SAkhilesh Sanikop // 7.9.3. (without the clamp for numerator and denominator).
SpecGetMvProjectionKernel(int mv,int numerator,int denominator)513*09537850SAkhilesh Sanikop int SpecGetMvProjectionKernel(int mv, int numerator, int denominator) {
514*09537850SAkhilesh Sanikop int value = mv * numerator * kProjectionMvDivisionLookup[denominator];
515*09537850SAkhilesh Sanikop if (value >= 0) {
516*09537850SAkhilesh Sanikop value += 1 << 13;
517*09537850SAkhilesh Sanikop value >>= 14;
518*09537850SAkhilesh Sanikop } else {
519*09537850SAkhilesh Sanikop value = -value;
520*09537850SAkhilesh Sanikop value += 1 << 13;
521*09537850SAkhilesh Sanikop value >>= 14;
522*09537850SAkhilesh Sanikop value = -value;
523*09537850SAkhilesh Sanikop }
524*09537850SAkhilesh Sanikop if (value < (-(1 << 14) + 1)) value = -(1 << 14) + 1;
525*09537850SAkhilesh Sanikop if (value > (1 << 14) - 1) value = (1 << 14) - 1;
526*09537850SAkhilesh Sanikop return value;
527*09537850SAkhilesh Sanikop }
528*09537850SAkhilesh Sanikop
SpecGetMvProjectionNoClamp(const MotionVector & mv,int numerator,int denominator,MotionVector * projection_mv)529*09537850SAkhilesh Sanikop void SpecGetMvProjectionNoClamp(const MotionVector& mv, int numerator,
530*09537850SAkhilesh Sanikop int denominator, MotionVector* projection_mv) {
531*09537850SAkhilesh Sanikop for (int i = 0; i < 2; ++i) {
532*09537850SAkhilesh Sanikop projection_mv->mv[i] =
533*09537850SAkhilesh Sanikop SpecGetMvProjectionKernel(mv.mv[i], numerator, denominator);
534*09537850SAkhilesh Sanikop }
535*09537850SAkhilesh Sanikop }
536*09537850SAkhilesh Sanikop
TEST(BitstreamUtils,GetMvProjection)537*09537850SAkhilesh Sanikop TEST(BitstreamUtils, GetMvProjection) {
538*09537850SAkhilesh Sanikop const int16_t mvs[5][2] = {
539*09537850SAkhilesh Sanikop {0, 0}, {11, 73}, {-84, 272}, {733, -827}, {-472, -697}};
540*09537850SAkhilesh Sanikop for (auto& mv_value : mvs) {
541*09537850SAkhilesh Sanikop for (int numerator = -kMaxFrameDistance; numerator <= kMaxFrameDistance;
542*09537850SAkhilesh Sanikop ++numerator) {
543*09537850SAkhilesh Sanikop for (int denominator = 0; denominator <= kMaxFrameDistance;
544*09537850SAkhilesh Sanikop ++denominator) {
545*09537850SAkhilesh Sanikop MotionVector mv, projection_mv, spec_projection_mv;
546*09537850SAkhilesh Sanikop mv.mv[0] = mv_value[0];
547*09537850SAkhilesh Sanikop mv.mv[1] = mv_value[1];
548*09537850SAkhilesh Sanikop GetMvProjection(mv, numerator, kProjectionMvDivisionLookup[denominator],
549*09537850SAkhilesh Sanikop &projection_mv);
550*09537850SAkhilesh Sanikop SpecGetMvProjectionNoClamp(mv, numerator, denominator,
551*09537850SAkhilesh Sanikop &spec_projection_mv);
552*09537850SAkhilesh Sanikop EXPECT_EQ(projection_mv.mv32, spec_projection_mv.mv32);
553*09537850SAkhilesh Sanikop }
554*09537850SAkhilesh Sanikop }
555*09537850SAkhilesh Sanikop }
556*09537850SAkhilesh Sanikop }
557*09537850SAkhilesh Sanikop
558*09537850SAkhilesh Sanikop // 7.9.4.
SpecProject(int value,int delta,int dst_sign)559*09537850SAkhilesh Sanikop int SpecProject(int value, int delta, int dst_sign) {
560*09537850SAkhilesh Sanikop constexpr int kMiSizeLog2 = 2;
561*09537850SAkhilesh Sanikop const int sign = (dst_sign == 0) ? 1 : dst_sign;
562*09537850SAkhilesh Sanikop int offset;
563*09537850SAkhilesh Sanikop if (delta >= 0) {
564*09537850SAkhilesh Sanikop offset = delta >> (3 + 1 + kMiSizeLog2);
565*09537850SAkhilesh Sanikop } else {
566*09537850SAkhilesh Sanikop offset = -((-delta) >> (3 + 1 + kMiSizeLog2));
567*09537850SAkhilesh Sanikop }
568*09537850SAkhilesh Sanikop return value + sign * offset;
569*09537850SAkhilesh Sanikop }
570*09537850SAkhilesh Sanikop
TEST(BitstreamUtils,Project)571*09537850SAkhilesh Sanikop TEST(BitstreamUtils, Project) {
572*09537850SAkhilesh Sanikop for (int value = -10; value <= 10; ++value) {
573*09537850SAkhilesh Sanikop for (int delta = -256; delta <= 256; ++delta) {
574*09537850SAkhilesh Sanikop for (int dst_sign = -1; dst_sign <= 0; ++dst_sign) {
575*09537850SAkhilesh Sanikop EXPECT_EQ(Project(value, delta, dst_sign),
576*09537850SAkhilesh Sanikop SpecProject(value, delta, dst_sign));
577*09537850SAkhilesh Sanikop }
578*09537850SAkhilesh Sanikop }
579*09537850SAkhilesh Sanikop }
580*09537850SAkhilesh Sanikop }
581*09537850SAkhilesh Sanikop
TEST(BitstreamUtils,IsBlockSmallerThan8x8)582*09537850SAkhilesh Sanikop TEST(BitstreamUtils, IsBlockSmallerThan8x8) {
583*09537850SAkhilesh Sanikop static constexpr bool is_block_smaller_than8x8[kMaxBlockSizes] = {
584*09537850SAkhilesh Sanikop true, true, false, true, false, false, false, false,
585*09537850SAkhilesh Sanikop false, false, false, false, false, false, false, false,
586*09537850SAkhilesh Sanikop false, false, false, false, false, false,
587*09537850SAkhilesh Sanikop };
588*09537850SAkhilesh Sanikop for (int i = 0; i < kMaxBlockSizes; ++i) {
589*09537850SAkhilesh Sanikop EXPECT_EQ(IsBlockSmallerThan8x8(static_cast<BlockSize>(i)),
590*09537850SAkhilesh Sanikop is_block_smaller_than8x8[i])
591*09537850SAkhilesh Sanikop << "Mismatch at index " << i;
592*09537850SAkhilesh Sanikop }
593*09537850SAkhilesh Sanikop }
594*09537850SAkhilesh Sanikop
TEST(BitstreamUtils,TransformSizeToSquareTransformIndex)595*09537850SAkhilesh Sanikop TEST(BitstreamUtils, TransformSizeToSquareTransformIndex) {
596*09537850SAkhilesh Sanikop EXPECT_EQ(TransformSizeToSquareTransformIndex(kTransformSize4x4), 0);
597*09537850SAkhilesh Sanikop EXPECT_EQ(TransformSizeToSquareTransformIndex(kTransformSize8x8), 1);
598*09537850SAkhilesh Sanikop EXPECT_EQ(TransformSizeToSquareTransformIndex(kTransformSize16x16), 2);
599*09537850SAkhilesh Sanikop EXPECT_EQ(TransformSizeToSquareTransformIndex(kTransformSize32x32), 3);
600*09537850SAkhilesh Sanikop EXPECT_EQ(TransformSizeToSquareTransformIndex(kTransformSize64x64), 4);
601*09537850SAkhilesh Sanikop }
602*09537850SAkhilesh Sanikop
603*09537850SAkhilesh Sanikop } // namespace
604*09537850SAkhilesh Sanikop } // namespace libgav1
605