blob: b9c348eb0d0030e4fc01722182d1697524f65131 [file] [log] [blame]
Noah Richardsbbf7c862015-04-21 23:30:131/*
2 * Copyright 2015 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 "webrtc/base/bitbuffer.h"
12#include "webrtc/base/bytebuffer.h"
13#include "webrtc/base/common.h"
14#include "webrtc/base/gunit.h"
15
16namespace rtc {
17
18TEST(BitBufferTest, ConsumeBits) {
19 const uint8 bytes[64] = {0};
20 BitBuffer buffer(bytes, 32);
21 uint64 total_bits = 32 * 8;
22 EXPECT_EQ(total_bits, buffer.RemainingBitCount());
23 EXPECT_TRUE(buffer.ConsumeBits(3));
24 total_bits -= 3;
25 EXPECT_EQ(total_bits, buffer.RemainingBitCount());
26 EXPECT_TRUE(buffer.ConsumeBits(3));
27 total_bits -= 3;
28 EXPECT_EQ(total_bits, buffer.RemainingBitCount());
29 EXPECT_TRUE(buffer.ConsumeBits(15));
30 total_bits -= 15;
31 EXPECT_EQ(total_bits, buffer.RemainingBitCount());
32 EXPECT_TRUE(buffer.ConsumeBits(37));
33 total_bits -= 37;
34 EXPECT_EQ(total_bits, buffer.RemainingBitCount());
35
36 EXPECT_FALSE(buffer.ConsumeBits(32 * 8));
37 EXPECT_EQ(total_bits, buffer.RemainingBitCount());
38}
39
40TEST(BitBufferTest, ReadBytesAligned) {
41 const uint8 bytes[] = {0x0A, 0xBC, 0xDE, 0xF1, 0x23, 0x45, 0x67, 0x89};
42 uint8 val8;
43 uint16 val16;
44 uint32 val32;
45 BitBuffer buffer(bytes, 8);
46 EXPECT_TRUE(buffer.ReadUInt8(&val8));
47 EXPECT_EQ(0x0Au, val8);
48 EXPECT_TRUE(buffer.ReadUInt8(&val8));
49 EXPECT_EQ(0xBCu, val8);
50 EXPECT_TRUE(buffer.ReadUInt16(&val16));
51 EXPECT_EQ(0xDEF1u, val16);
52 EXPECT_TRUE(buffer.ReadUInt32(&val32));
53 EXPECT_EQ(0x23456789u, val32);
54}
55
56TEST(BitBufferTest, ReadBytesOffset4) {
57 const uint8 bytes[] = {0x0A, 0xBC, 0xDE, 0xF1, 0x23, 0x45, 0x67, 0x89, 0x0A};
58 uint8 val8;
59 uint16 val16;
60 uint32 val32;
61 BitBuffer buffer(bytes, 9);
62 EXPECT_TRUE(buffer.ConsumeBits(4));
63
64 EXPECT_TRUE(buffer.ReadUInt8(&val8));
65 EXPECT_EQ(0xABu, val8);
66 EXPECT_TRUE(buffer.ReadUInt8(&val8));
67 EXPECT_EQ(0xCDu, val8);
68 EXPECT_TRUE(buffer.ReadUInt16(&val16));
69 EXPECT_EQ(0xEF12u, val16);
70 EXPECT_TRUE(buffer.ReadUInt32(&val32));
71 EXPECT_EQ(0x34567890u, val32);
72}
73
74TEST(BitBufferTest, ReadBytesOffset3) {
75 // The pattern we'll check against is counting down from 0b1111. It looks
76 // weird here because it's all offset by 3.
77 // Byte pattern is:
78 // 56701234
79 // 0b00011111,
80 // 0b11011011,
81 // 0b10010111,
82 // 0b01010011,
83 // 0b00001110,
84 // 0b11001010,
85 // 0b10000110,
86 // 0b01000010
87 // xxxxx <-- last 5 bits unused.
88
89 // The bytes. It almost looks like counting down by two at a time, except the
90 // jump at 5->3->0, since that's when the high bit is turned off.
91 const uint8 bytes[] = {0x1F, 0xDB, 0x97, 0x53, 0x0E, 0xCA, 0x86, 0x42};
92
93 uint8 val8;
94 uint16 val16;
95 uint32 val32;
96 BitBuffer buffer(bytes, 8);
97 EXPECT_TRUE(buffer.ConsumeBits(3));
98 EXPECT_TRUE(buffer.ReadUInt8(&val8));
99 EXPECT_EQ(0xFEu, val8);
100 EXPECT_TRUE(buffer.ReadUInt16(&val16));
101 EXPECT_EQ(0xDCBAu, val16);
102 EXPECT_TRUE(buffer.ReadUInt32(&val32));
103 EXPECT_EQ(0x98765432u, val32);
104 // 5 bits left unread. Not enough to read a uint8.
105 EXPECT_EQ(5u, buffer.RemainingBitCount());
106 EXPECT_FALSE(buffer.ReadUInt8(&val8));
107}
108
109TEST(BitBufferTest, ReadBits) {
110 // Bit values are:
111 // 0b01001101,
112 // 0b00110010
113 const uint8 bytes[] = {0x4D, 0x32};
114 uint32_t val;
115 BitBuffer buffer(bytes, 2);
116 EXPECT_TRUE(buffer.ReadBits(&val, 3));
117 // 0b010
118 EXPECT_EQ(0x2u, val);
119 EXPECT_TRUE(buffer.ReadBits(&val, 2));
120 // 0b01
121 EXPECT_EQ(0x1u, val);
122 EXPECT_TRUE(buffer.ReadBits(&val, 7));
123 // 0b1010011
124 EXPECT_EQ(0x53u, val);
125 EXPECT_TRUE(buffer.ReadBits(&val, 2));
126 // 0b00
127 EXPECT_EQ(0x0u, val);
128 EXPECT_TRUE(buffer.ReadBits(&val, 1));
129 // 0b1
130 EXPECT_EQ(0x1u, val);
131 EXPECT_TRUE(buffer.ReadBits(&val, 1));
132 // 0b0
133 EXPECT_EQ(0x0u, val);
134
135 EXPECT_FALSE(buffer.ReadBits(&val, 1));
136}
137
Noah Richards86153c22015-04-28 22:13:44138TEST(BitBufferTest, SetOffsetValues) {
139 uint8 bytes[4] = {0};
140 BitBufferWriter buffer(bytes, 4);
141
142 size_t byte_offset, bit_offset;
143 // Bit offsets are [0,7].
144 EXPECT_TRUE(buffer.Seek(0, 0));
145 EXPECT_TRUE(buffer.Seek(0, 7));
146 buffer.GetCurrentOffset(&byte_offset, &bit_offset);
147 EXPECT_EQ(0u, byte_offset);
148 EXPECT_EQ(7u, bit_offset);
149 EXPECT_FALSE(buffer.Seek(0, 8));
150 buffer.GetCurrentOffset(&byte_offset, &bit_offset);
151 EXPECT_EQ(0u, byte_offset);
152 EXPECT_EQ(7u, bit_offset);
153 // Byte offsets are [0,length]. At byte offset length, the bit offset must be
154 // 0.
155 EXPECT_TRUE(buffer.Seek(0, 0));
156 EXPECT_TRUE(buffer.Seek(2, 4));
157 buffer.GetCurrentOffset(&byte_offset, &bit_offset);
158 EXPECT_EQ(2u, byte_offset);
159 EXPECT_EQ(4u, bit_offset);
160 EXPECT_TRUE(buffer.Seek(4, 0));
161 EXPECT_FALSE(buffer.Seek(5, 0));
162 buffer.GetCurrentOffset(&byte_offset, &bit_offset);
163 EXPECT_EQ(4u, byte_offset);
164 EXPECT_EQ(0u, bit_offset);
165 EXPECT_FALSE(buffer.Seek(4, 1));
166
Donald E Curtis97bce582015-05-19 20:18:00167 // Disable death test on Android because it relies on fork() and doesn't play
168 // nicely.
Zeke Chin2d3b7e22015-07-14 19:55:44169#if defined(GTEST_HAS_DEATH_TEST)
Donald E Curtis97bce582015-05-19 20:18:00170#if !defined(WEBRTC_ANDROID)
Noah Richards86153c22015-04-28 22:13:44171 // Passing a NULL out parameter is death.
172 EXPECT_DEATH(buffer.GetCurrentOffset(&byte_offset, NULL), "");
Donald E Curtis97bce582015-05-19 20:18:00173#endif
Zeke Chin2d3b7e22015-07-14 19:55:44174#endif
Noah Richards86153c22015-04-28 22:13:44175}
176
Noah Richardsbbf7c862015-04-21 23:30:13177uint64 GolombEncoded(uint32 val) {
178 val++;
179 uint32 bit_counter = val;
180 uint64 bit_count = 0;
181 while (bit_counter > 0) {
182 bit_count++;
183 bit_counter >>= 1;
184 }
185 return static_cast<uint64>(val) << (64 - (bit_count * 2 - 1));
186}
187
Noah Richards86153c22015-04-28 22:13:44188TEST(BitBufferTest, GolombUint32Values) {
189 ByteBuffer byteBuffer;
190 byteBuffer.Resize(16);
191 BitBuffer buffer(reinterpret_cast<const uint8*>(byteBuffer.Data()),
192 byteBuffer.Capacity());
193 // Test over the uint32 range with a large enough step that the test doesn't
194 // take forever. Around 20,000 iterations should do.
195 const int kStep = std::numeric_limits<uint32>::max() / 20000;
196 for (uint32 i = 0; i < std::numeric_limits<uint32>::max() - kStep;
197 i += kStep) {
198 uint64 encoded_val = GolombEncoded(i);
199 byteBuffer.Clear();
Noah Richardsbbf7c862015-04-21 23:30:13200 byteBuffer.WriteUInt64(encoded_val);
Noah Richardsbbf7c862015-04-21 23:30:13201 uint32 decoded_val;
Noah Richards86153c22015-04-28 22:13:44202 EXPECT_TRUE(buffer.Seek(0, 0));
Noah Richardsbbf7c862015-04-21 23:30:13203 EXPECT_TRUE(buffer.ReadExponentialGolomb(&decoded_val));
Noah Richards86153c22015-04-28 22:13:44204 EXPECT_EQ(i, decoded_val);
Noah Richardsbbf7c862015-04-21 23:30:13205 }
206}
207
Peter Boström8c266e62015-09-24 13:06:50208TEST(BitBufferTest, SignedGolombValues) {
209 uint8_t golomb_bits[] = {
210 0x80, // 1
211 0x40, // 010
212 0x60, // 011
213 0x20, // 00100
214 0x38, // 00111
215 };
216 int32_t expected[] = {0, 1, -1, 2, -3};
217 for (size_t i = 0; i < sizeof(golomb_bits); ++i) {
218 BitBuffer buffer(&golomb_bits[i], 1);
219 int32_t decoded_val;
220 ASSERT_TRUE(buffer.ReadSignedExponentialGolomb(&decoded_val));
221 EXPECT_EQ(expected[i], decoded_val)
222 << "Mismatch in expected/decoded value for golomb_bits[" << i
223 << "]: " << static_cast<int>(golomb_bits[i]);
224 }
225}
226
Noah Richardsbbf7c862015-04-21 23:30:13227TEST(BitBufferTest, NoGolombOverread) {
228 const uint8 bytes[] = {0x00, 0xFF, 0xFF};
229 // Make sure the bit buffer correctly enforces byte length on golomb reads.
230 // If it didn't, the above buffer would be valid at 3 bytes.
231 BitBuffer buffer(bytes, 1);
232 uint32 decoded_val;
233 EXPECT_FALSE(buffer.ReadExponentialGolomb(&decoded_val));
234
235 BitBuffer longer_buffer(bytes, 2);
236 EXPECT_FALSE(longer_buffer.ReadExponentialGolomb(&decoded_val));
237
238 BitBuffer longest_buffer(bytes, 3);
239 EXPECT_TRUE(longest_buffer.ReadExponentialGolomb(&decoded_val));
240 // Golomb should have read 9 bits, so 0x01FF, and since it is golomb, the
241 // result is 0x01FF - 1 = 0x01FE.
242 EXPECT_EQ(0x01FEu, decoded_val);
243}
244
Noah Richards86153c22015-04-28 22:13:44245TEST(BitBufferWriterTest, SymmetricReadWrite) {
246 uint8 bytes[16] = {0};
247 BitBufferWriter buffer(bytes, 4);
248
249 // Write some bit data at various sizes.
250 EXPECT_TRUE(buffer.WriteBits(0x2u, 3));
251 EXPECT_TRUE(buffer.WriteBits(0x1u, 2));
252 EXPECT_TRUE(buffer.WriteBits(0x53u, 7));
253 EXPECT_TRUE(buffer.WriteBits(0x0u, 2));
254 EXPECT_TRUE(buffer.WriteBits(0x1u, 1));
255 EXPECT_TRUE(buffer.WriteBits(0x1ABCDu, 17));
256 // That should be all that fits in the buffer.
257 EXPECT_FALSE(buffer.WriteBits(1, 1));
258
259 EXPECT_TRUE(buffer.Seek(0, 0));
260 uint32 val;
261 EXPECT_TRUE(buffer.ReadBits(&val, 3));
262 EXPECT_EQ(0x2u, val);
263 EXPECT_TRUE(buffer.ReadBits(&val, 2));
264 EXPECT_EQ(0x1u, val);
265 EXPECT_TRUE(buffer.ReadBits(&val, 7));
266 EXPECT_EQ(0x53u, val);
267 EXPECT_TRUE(buffer.ReadBits(&val, 2));
268 EXPECT_EQ(0x0u, val);
269 EXPECT_TRUE(buffer.ReadBits(&val, 1));
270 EXPECT_EQ(0x1u, val);
271 EXPECT_TRUE(buffer.ReadBits(&val, 17));
272 EXPECT_EQ(0x1ABCDu, val);
273 // And there should be nothing left.
274 EXPECT_FALSE(buffer.ReadBits(&val, 1));
275}
276
277TEST(BitBufferWriterTest, SymmetricBytesMisaligned) {
278 uint8 bytes[16] = {0};
279 BitBufferWriter buffer(bytes, 16);
280
281 // Offset 3, to get things misaligned.
282 EXPECT_TRUE(buffer.ConsumeBits(3));
283 EXPECT_TRUE(buffer.WriteUInt8(0x12u));
284 EXPECT_TRUE(buffer.WriteUInt16(0x3456u));
285 EXPECT_TRUE(buffer.WriteUInt32(0x789ABCDEu));
286
287 buffer.Seek(0, 3);
288 uint8 val8;
289 uint16 val16;
290 uint32 val32;
291 EXPECT_TRUE(buffer.ReadUInt8(&val8));
292 EXPECT_EQ(0x12u, val8);
293 EXPECT_TRUE(buffer.ReadUInt16(&val16));
294 EXPECT_EQ(0x3456u, val16);
295 EXPECT_TRUE(buffer.ReadUInt32(&val32));
296 EXPECT_EQ(0x789ABCDEu, val32);
297}
298
299TEST(BitBufferWriterTest, SymmetricGolomb) {
300 char test_string[] = "my precious";
301 uint8 bytes[64] = {0};
302 BitBufferWriter buffer(bytes, 64);
303 for (size_t i = 0; i < ARRAY_SIZE(test_string); ++i) {
304 EXPECT_TRUE(buffer.WriteExponentialGolomb(test_string[i]));
305 }
306 buffer.Seek(0, 0);
307 for (size_t i = 0; i < ARRAY_SIZE(test_string); ++i) {
308 uint32 val;
309 EXPECT_TRUE(buffer.ReadExponentialGolomb(&val));
310 EXPECT_LE(val, std::numeric_limits<uint8>::max());
311 EXPECT_EQ(test_string[i], static_cast<char>(val));
312 }
313}
314
315TEST(BitBufferWriterTest, WriteClearsBits) {
316 uint8 bytes[] = {0xFF, 0xFF};
317 BitBufferWriter buffer(bytes, 2);
318 EXPECT_TRUE(buffer.ConsumeBits(3));
319 EXPECT_TRUE(buffer.WriteBits(0, 1));
320 EXPECT_EQ(0xEFu, bytes[0]);
321 EXPECT_TRUE(buffer.WriteBits(0, 3));
322 EXPECT_EQ(0xE1u, bytes[0]);
323 EXPECT_TRUE(buffer.WriteBits(0, 2));
324 EXPECT_EQ(0xE0u, bytes[0]);
325 EXPECT_EQ(0x7F, bytes[1]);
326}
327
Noah Richardsbbf7c862015-04-21 23:30:13328} // namespace rtc