blob: 45c4eca8d439c2361cd96464d8a3aaf9056190d3 [file] [log] [blame]
Danil Chapovalov5af152c2021-08-31 15:27:51 +02001/*
2 * Copyright 2021 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "rtc_base/bitstream_reader.h"
12
13#include <stddef.h>
14#include <stdint.h>
15
16#include <array>
17#include <limits>
18
19#include "absl/numeric/bits.h"
20#include "absl/types/optional.h"
21#include "api/array_view.h"
22#include "rtc_base/checks.h"
23#include "test/gmock.h"
24#include "test/gtest.h"
25
26namespace webrtc {
27namespace {
28
29TEST(BitstreamReaderTest, InDebugModeRequiresToCheckOkStatusBeforeDestruction) {
30 const uint8_t bytes[32] = {};
31 absl::optional<BitstreamReader> reader(absl::in_place, bytes);
32
33 EXPECT_GE(reader->ReadBits(7), 0u);
34#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(OS_ANDROID)
35 EXPECT_DEATH(reader = absl::nullopt, "");
36#endif
37 EXPECT_TRUE(reader->Ok());
38 reader = absl::nullopt;
39}
40
41TEST(BitstreamReaderTest, InDebugModeMayCheckRemainingBitsInsteadOfOkStatus) {
42 const uint8_t bytes[32] = {};
43 absl::optional<BitstreamReader> reader(absl::in_place, bytes);
44
45 EXPECT_GE(reader->ReadBit(), 0);
46#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(OS_ANDROID)
47 EXPECT_DEATH(reader = absl::nullopt, "");
48#endif
49 EXPECT_GE(reader->RemainingBitCount(), 0);
50 reader = absl::nullopt;
51}
52
53TEST(BitstreamReaderTest, ConsumeBits) {
54 const uint8_t bytes[32] = {};
55 BitstreamReader reader(bytes);
56
57 int total_bits = 32 * 8;
58 EXPECT_EQ(reader.RemainingBitCount(), total_bits);
59 reader.ConsumeBits(3);
60 total_bits -= 3;
61 EXPECT_EQ(reader.RemainingBitCount(), total_bits);
62 reader.ConsumeBits(3);
63 total_bits -= 3;
64 EXPECT_EQ(reader.RemainingBitCount(), total_bits);
65 reader.ConsumeBits(15);
66 total_bits -= 15;
67 EXPECT_EQ(reader.RemainingBitCount(), total_bits);
68 reader.ConsumeBits(67);
69 total_bits -= 67;
70 EXPECT_EQ(reader.RemainingBitCount(), total_bits);
71 EXPECT_TRUE(reader.Ok());
72
73 reader.ConsumeBits(32 * 8);
74 EXPECT_FALSE(reader.Ok());
75 EXPECT_LT(reader.RemainingBitCount(), 0);
76}
77
78TEST(BitstreamReaderTest, ReadBit) {
79 const uint8_t bytes[] = {0b0100'0001, 0b1011'0001};
80 BitstreamReader reader(bytes);
81 // First byte.
82 EXPECT_EQ(reader.ReadBit(), 0);
83 EXPECT_EQ(reader.ReadBit(), 1);
84 EXPECT_EQ(reader.ReadBit(), 0);
85 EXPECT_EQ(reader.ReadBit(), 0);
86
87 EXPECT_EQ(reader.ReadBit(), 0);
88 EXPECT_EQ(reader.ReadBit(), 0);
89 EXPECT_EQ(reader.ReadBit(), 0);
90 EXPECT_EQ(reader.ReadBit(), 1);
91
92 // Second byte.
93 EXPECT_EQ(reader.ReadBit(), 1);
94 EXPECT_EQ(reader.ReadBit(), 0);
95 EXPECT_EQ(reader.ReadBit(), 1);
96 EXPECT_EQ(reader.ReadBit(), 1);
97
98 EXPECT_EQ(reader.ReadBit(), 0);
99 EXPECT_EQ(reader.ReadBit(), 0);
100 EXPECT_EQ(reader.ReadBit(), 0);
101 EXPECT_EQ(reader.ReadBit(), 1);
102
103 EXPECT_TRUE(reader.Ok());
104 // Try to read beyound the buffer.
105 EXPECT_EQ(reader.ReadBit(), 0);
106 EXPECT_FALSE(reader.Ok());
107}
108
109TEST(BitstreamReaderTest, ReadBoolConsumesSingleBit) {
110 const uint8_t bytes[] = {0b1010'1010};
111 BitstreamReader reader(bytes);
112 ASSERT_EQ(reader.RemainingBitCount(), 8);
113 EXPECT_TRUE(reader.Read<bool>());
114 EXPECT_EQ(reader.RemainingBitCount(), 7);
115}
116
117TEST(BitstreamReaderTest, ReadBytesAligned) {
118 const uint8_t bytes[] = {0x0A, //
119 0xBC, //
120 0xDE, 0xF1, //
121 0x23, 0x45, 0x67, 0x89};
122 BitstreamReader reader(bytes);
123 EXPECT_EQ(reader.Read<uint8_t>(), 0x0Au);
124 EXPECT_EQ(reader.Read<uint8_t>(), 0xBCu);
125 EXPECT_EQ(reader.Read<uint16_t>(), 0xDEF1u);
126 EXPECT_EQ(reader.Read<uint32_t>(), 0x23456789u);
127 EXPECT_TRUE(reader.Ok());
128}
129
130TEST(BitstreamReaderTest, ReadBytesOffset4) {
131 const uint8_t bytes[] = {0x0A, 0xBC, 0xDE, 0xF1, 0x23,
132 0x45, 0x67, 0x89, 0x0A};
133 BitstreamReader reader(bytes);
134 reader.ConsumeBits(4);
135
136 EXPECT_EQ(reader.Read<uint8_t>(), 0xABu);
137 EXPECT_EQ(reader.Read<uint8_t>(), 0xCDu);
138 EXPECT_EQ(reader.Read<uint16_t>(), 0xEF12u);
139 EXPECT_EQ(reader.Read<uint32_t>(), 0x34567890u);
140 EXPECT_TRUE(reader.Ok());
141}
142
143TEST(BitstreamReaderTest, ReadBytesOffset3) {
144 // The pattern we'll check against is counting down from 0b1111. It looks
145 // weird here because it's all offset by 3.
146 // Byte pattern is:
147 // 56701234
148 // 0b00011111,
149 // 0b11011011,
150 // 0b10010111,
151 // 0b01010011,
152 // 0b00001110,
153 // 0b11001010,
154 // 0b10000110,
155 // 0b01000010
156 // xxxxx <-- last 5 bits unused.
157
158 // The bytes. It almost looks like counting down by two at a time, except the
159 // jump at 5->3->0, since that's when the high bit is turned off.
160 const uint8_t bytes[] = {0x1F, 0xDB, 0x97, 0x53, 0x0E, 0xCA, 0x86, 0x42};
161
162 BitstreamReader reader(bytes);
163 reader.ConsumeBits(3);
164 EXPECT_EQ(reader.Read<uint8_t>(), 0xFEu);
165 EXPECT_EQ(reader.Read<uint16_t>(), 0xDCBAu);
166 EXPECT_EQ(reader.Read<uint32_t>(), 0x98765432u);
167 EXPECT_TRUE(reader.Ok());
168
169 // 5 bits left unread. Not enough to read a uint8_t.
170 EXPECT_EQ(reader.RemainingBitCount(), 5);
171 EXPECT_EQ(reader.Read<uint8_t>(), 0);
172 EXPECT_FALSE(reader.Ok());
173}
174
175TEST(BitstreamReaderTest, ReadBits) {
176 const uint8_t bytes[] = {0b010'01'101, 0b0011'00'1'0};
177 BitstreamReader reader(bytes);
178 EXPECT_EQ(reader.ReadBits(3), 0b010u);
179 EXPECT_EQ(reader.ReadBits(2), 0b01u);
180 EXPECT_EQ(reader.ReadBits(7), 0b101'0011u);
181 EXPECT_EQ(reader.ReadBits(2), 0b00u);
182 EXPECT_EQ(reader.ReadBits(1), 0b1u);
183 EXPECT_EQ(reader.ReadBits(1), 0b0u);
184 EXPECT_TRUE(reader.Ok());
185
186 EXPECT_EQ(reader.ReadBits(1), 0u);
187 EXPECT_FALSE(reader.Ok());
188}
189
190TEST(BitstreamReaderTest, ReadZeroBits) {
191 BitstreamReader reader(rtc::ArrayView<const uint8_t>(nullptr, 0));
192
193 EXPECT_EQ(reader.ReadBits(0), 0u);
194 EXPECT_TRUE(reader.Ok());
195}
196
197TEST(BitstreamReaderTest, ReadBitFromEmptyArray) {
198 BitstreamReader reader(rtc::ArrayView<const uint8_t>(nullptr, 0));
199
200 // Trying to read from the empty array shouldn't dereference the pointer,
201 // i.e. shouldn't crash.
202 EXPECT_EQ(reader.ReadBit(), 0);
203 EXPECT_FALSE(reader.Ok());
204}
205
206TEST(BitstreamReaderTest, ReadBitsFromEmptyArray) {
207 BitstreamReader reader(rtc::ArrayView<const uint8_t>(nullptr, 0));
208
209 // Trying to read from the empty array shouldn't dereference the pointer,
210 // i.e. shouldn't crash.
211 EXPECT_EQ(reader.ReadBits(1), 0u);
212 EXPECT_FALSE(reader.Ok());
213}
214
215TEST(BitstreamReaderTest, ReadBits64) {
216 const uint8_t bytes[] = {0x4D, 0x32, 0xAB, 0x54, 0x00, 0xFF, 0xFE, 0x01,
217 0xAB, 0xCD, 0xEF, 0x01, 0x23, 0x45, 0x67, 0x89};
218 BitstreamReader reader(bytes);
219
220 EXPECT_EQ(reader.ReadBits(33), 0x4D32AB5400FFFE01u >> (64 - 33));
221
222 constexpr uint64_t kMask31Bits = (1ull << 32) - 1;
223 EXPECT_EQ(reader.ReadBits(31), 0x4D32AB5400FFFE01ull & kMask31Bits);
224
225 EXPECT_EQ(reader.ReadBits(64), 0xABCDEF0123456789ull);
226 EXPECT_TRUE(reader.Ok());
227
228 // Nothing more to read.
229 EXPECT_EQ(reader.ReadBit(), 0);
230 EXPECT_FALSE(reader.Ok());
231}
232
233TEST(BitstreamReaderTest, CanPeekBitsUsingCopyConstructor) {
234 // BitstreamReader doesn't have peek function. To simulate it, user may use
235 // cheap BitstreamReader copy constructor.
236 const uint8_t bytes[] = {0x0A, 0xBC};
237 BitstreamReader reader(bytes);
238 reader.ConsumeBits(4);
239 ASSERT_EQ(reader.RemainingBitCount(), 12);
240
241 BitstreamReader peeker = reader;
242 EXPECT_EQ(peeker.ReadBits(8), 0xABu);
243 EXPECT_EQ(peeker.RemainingBitCount(), 4);
244
245 EXPECT_EQ(reader.RemainingBitCount(), 12);
246 // Can resume reading from before peeker was created.
247 EXPECT_EQ(reader.ReadBits(4), 0xAu);
248 EXPECT_EQ(reader.RemainingBitCount(), 8);
249}
250
251TEST(BitstreamReaderTest,
252 ReadNonSymmetricSameNumberOfBitsWhenNumValuesPowerOf2) {
253 const uint8_t bytes[2] = {0xf3, 0xa0};
254 BitstreamReader reader(bytes);
255
256 ASSERT_EQ(reader.RemainingBitCount(), 16);
257 EXPECT_EQ(reader.ReadNonSymmetric(/*num_values=*/1 << 4), 0xfu);
258 EXPECT_EQ(reader.ReadNonSymmetric(/*num_values=*/1 << 4), 0x3u);
259 EXPECT_EQ(reader.ReadNonSymmetric(/*num_values=*/1 << 4), 0xau);
260 EXPECT_EQ(reader.ReadNonSymmetric(/*num_values=*/1 << 4), 0x0u);
261 EXPECT_EQ(reader.RemainingBitCount(), 0);
262 EXPECT_TRUE(reader.Ok());
263}
264
265TEST(BitstreamReaderTest, ReadNonSymmetricOnlyValueConsumesZeroBits) {
266 const uint8_t bytes[2] = {};
267 BitstreamReader reader(bytes);
268
269 ASSERT_EQ(reader.RemainingBitCount(), 16);
270 EXPECT_EQ(reader.ReadNonSymmetric(/*num_values=*/1), 0u);
271 EXPECT_EQ(reader.RemainingBitCount(), 16);
272}
273
274std::array<uint8_t, 8> GolombEncoded(uint32_t val) {
275 int val_width = absl::bit_width(val + 1);
276 int total_width = 2 * val_width - 1;
277 uint64_t representation = (uint64_t{val} + 1) << (64 - total_width);
278 std::array<uint8_t, 8> result;
279 for (int i = 0; i < 8; ++i) {
280 result[i] = representation >> (7 - i) * 8;
281 }
282 return result;
283}
284
285TEST(BitstreamReaderTest, GolombUint32Values) {
286 // Test over the uint32_t range with a large enough step that the test doesn't
287 // take forever. Around 20,000 iterations should do.
288 const int kStep = std::numeric_limits<uint32_t>::max() / 20000;
289 for (uint32_t i = 0; i < std::numeric_limits<uint32_t>::max() - kStep;
290 i += kStep) {
291 std::array<uint8_t, 8> buffer = GolombEncoded(i);
292 BitstreamReader reader(buffer);
293 // Use assert instead of EXPECT to avoid spamming thousands of failed
294 // expectation when this test fails.
295 ASSERT_EQ(reader.ReadExponentialGolomb(), i);
296 EXPECT_TRUE(reader.Ok());
297 }
298}
299
300TEST(BitstreamReaderTest, SignedGolombValues) {
301 uint8_t golomb_bits[][1] = {
302 {0b1'0000000}, {0b010'00000}, {0b011'00000}, {0b00100'000}, {0b00111'000},
303 };
304 int expected[] = {0, 1, -1, 2, -3};
305 for (size_t i = 0; i < sizeof(golomb_bits); ++i) {
306 BitstreamReader reader(golomb_bits[i]);
307 EXPECT_EQ(reader.ReadSignedExponentialGolomb(), expected[i])
308 << "Mismatch in expected/decoded value for golomb_bits[" << i
309 << "]: " << static_cast<int>(golomb_bits[i][0]);
310 EXPECT_TRUE(reader.Ok());
311 }
312}
313
314TEST(BitstreamReaderTest, NoGolombOverread) {
315 const uint8_t bytes[] = {0x00, 0xFF, 0xFF};
316 // Make sure the bit buffer correctly enforces byte length on golomb reads.
317 // If it didn't, the above buffer would be valid at 3 bytes.
318 BitstreamReader reader1(rtc::MakeArrayView(bytes, 1));
319 // When parse fails, `ReadExponentialGolomb` may return any number.
320 reader1.ReadExponentialGolomb();
321 EXPECT_FALSE(reader1.Ok());
322
323 BitstreamReader reader2(rtc::MakeArrayView(bytes, 2));
324 reader2.ReadExponentialGolomb();
325 EXPECT_FALSE(reader2.Ok());
326
327 BitstreamReader reader3(bytes);
328 // Golomb should have read 9 bits, so 0x01FF, and since it is golomb, the
329 // result is 0x01FF - 1 = 0x01FE.
330 EXPECT_EQ(reader3.ReadExponentialGolomb(), 0x01FEu);
331 EXPECT_TRUE(reader3.Ok());
332}
333
334} // namespace
335} // namespace webrtc