blob: c47f92c59d332c738b4da903fd651d3bad2311ed [file] [log] [blame]
Noah Richardsbbf7c862015-04-21 16:30:13 -07001/*
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 15:13:44 -0700138TEST(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 13:18:00 -0700167 // Disable death test on Android because it relies on fork() and doesn't play
168 // nicely.
Zeke Chin2d3b7e22015-07-14 12:55:44 -0700169#if defined(GTEST_HAS_DEATH_TEST)
Donald E Curtis97bce582015-05-19 13:18:00 -0700170#if !defined(WEBRTC_ANDROID)
Noah Richards86153c22015-04-28 15:13:44 -0700171 // Passing a NULL out parameter is death.
172 EXPECT_DEATH(buffer.GetCurrentOffset(&byte_offset, NULL), "");
Donald E Curtis97bce582015-05-19 13:18:00 -0700173#endif
Zeke Chin2d3b7e22015-07-14 12:55:44 -0700174#endif
Noah Richards86153c22015-04-28 15:13:44 -0700175}
176
Noah Richardsbbf7c862015-04-21 16:30:13 -0700177uint64 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 15:13:44 -0700188TEST(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 16:30:13 -0700200 byteBuffer.WriteUInt64(encoded_val);
Noah Richardsbbf7c862015-04-21 16:30:13 -0700201 uint32 decoded_val;
Noah Richards86153c22015-04-28 15:13:44 -0700202 EXPECT_TRUE(buffer.Seek(0, 0));
Noah Richardsbbf7c862015-04-21 16:30:13 -0700203 EXPECT_TRUE(buffer.ReadExponentialGolomb(&decoded_val));
Noah Richards86153c22015-04-28 15:13:44 -0700204 EXPECT_EQ(i, decoded_val);
Noah Richardsbbf7c862015-04-21 16:30:13 -0700205 }
206}
207
208TEST(BitBufferTest, NoGolombOverread) {
209 const uint8 bytes[] = {0x00, 0xFF, 0xFF};
210 // Make sure the bit buffer correctly enforces byte length on golomb reads.
211 // If it didn't, the above buffer would be valid at 3 bytes.
212 BitBuffer buffer(bytes, 1);
213 uint32 decoded_val;
214 EXPECT_FALSE(buffer.ReadExponentialGolomb(&decoded_val));
215
216 BitBuffer longer_buffer(bytes, 2);
217 EXPECT_FALSE(longer_buffer.ReadExponentialGolomb(&decoded_val));
218
219 BitBuffer longest_buffer(bytes, 3);
220 EXPECT_TRUE(longest_buffer.ReadExponentialGolomb(&decoded_val));
221 // Golomb should have read 9 bits, so 0x01FF, and since it is golomb, the
222 // result is 0x01FF - 1 = 0x01FE.
223 EXPECT_EQ(0x01FEu, decoded_val);
224}
225
Noah Richards86153c22015-04-28 15:13:44 -0700226TEST(BitBufferWriterTest, SymmetricReadWrite) {
227 uint8 bytes[16] = {0};
228 BitBufferWriter buffer(bytes, 4);
229
230 // Write some bit data at various sizes.
231 EXPECT_TRUE(buffer.WriteBits(0x2u, 3));
232 EXPECT_TRUE(buffer.WriteBits(0x1u, 2));
233 EXPECT_TRUE(buffer.WriteBits(0x53u, 7));
234 EXPECT_TRUE(buffer.WriteBits(0x0u, 2));
235 EXPECT_TRUE(buffer.WriteBits(0x1u, 1));
236 EXPECT_TRUE(buffer.WriteBits(0x1ABCDu, 17));
237 // That should be all that fits in the buffer.
238 EXPECT_FALSE(buffer.WriteBits(1, 1));
239
240 EXPECT_TRUE(buffer.Seek(0, 0));
241 uint32 val;
242 EXPECT_TRUE(buffer.ReadBits(&val, 3));
243 EXPECT_EQ(0x2u, val);
244 EXPECT_TRUE(buffer.ReadBits(&val, 2));
245 EXPECT_EQ(0x1u, val);
246 EXPECT_TRUE(buffer.ReadBits(&val, 7));
247 EXPECT_EQ(0x53u, val);
248 EXPECT_TRUE(buffer.ReadBits(&val, 2));
249 EXPECT_EQ(0x0u, val);
250 EXPECT_TRUE(buffer.ReadBits(&val, 1));
251 EXPECT_EQ(0x1u, val);
252 EXPECT_TRUE(buffer.ReadBits(&val, 17));
253 EXPECT_EQ(0x1ABCDu, val);
254 // And there should be nothing left.
255 EXPECT_FALSE(buffer.ReadBits(&val, 1));
256}
257
258TEST(BitBufferWriterTest, SymmetricBytesMisaligned) {
259 uint8 bytes[16] = {0};
260 BitBufferWriter buffer(bytes, 16);
261
262 // Offset 3, to get things misaligned.
263 EXPECT_TRUE(buffer.ConsumeBits(3));
264 EXPECT_TRUE(buffer.WriteUInt8(0x12u));
265 EXPECT_TRUE(buffer.WriteUInt16(0x3456u));
266 EXPECT_TRUE(buffer.WriteUInt32(0x789ABCDEu));
267
268 buffer.Seek(0, 3);
269 uint8 val8;
270 uint16 val16;
271 uint32 val32;
272 EXPECT_TRUE(buffer.ReadUInt8(&val8));
273 EXPECT_EQ(0x12u, val8);
274 EXPECT_TRUE(buffer.ReadUInt16(&val16));
275 EXPECT_EQ(0x3456u, val16);
276 EXPECT_TRUE(buffer.ReadUInt32(&val32));
277 EXPECT_EQ(0x789ABCDEu, val32);
278}
279
280TEST(BitBufferWriterTest, SymmetricGolomb) {
281 char test_string[] = "my precious";
282 uint8 bytes[64] = {0};
283 BitBufferWriter buffer(bytes, 64);
284 for (size_t i = 0; i < ARRAY_SIZE(test_string); ++i) {
285 EXPECT_TRUE(buffer.WriteExponentialGolomb(test_string[i]));
286 }
287 buffer.Seek(0, 0);
288 for (size_t i = 0; i < ARRAY_SIZE(test_string); ++i) {
289 uint32 val;
290 EXPECT_TRUE(buffer.ReadExponentialGolomb(&val));
291 EXPECT_LE(val, std::numeric_limits<uint8>::max());
292 EXPECT_EQ(test_string[i], static_cast<char>(val));
293 }
294}
295
296TEST(BitBufferWriterTest, WriteClearsBits) {
297 uint8 bytes[] = {0xFF, 0xFF};
298 BitBufferWriter buffer(bytes, 2);
299 EXPECT_TRUE(buffer.ConsumeBits(3));
300 EXPECT_TRUE(buffer.WriteBits(0, 1));
301 EXPECT_EQ(0xEFu, bytes[0]);
302 EXPECT_TRUE(buffer.WriteBits(0, 3));
303 EXPECT_EQ(0xE1u, bytes[0]);
304 EXPECT_TRUE(buffer.WriteBits(0, 2));
305 EXPECT_EQ(0xE0u, bytes[0]);
306 EXPECT_EQ(0x7F, bytes[1]);
307}
308
Noah Richardsbbf7c862015-04-21 16:30:13 -0700309} // namespace rtc