1 /*
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 "rtc_base/bit_buffer.h"
12
13 #include <limits>
14
15 #include "api/array_view.h"
16 #include "rtc_base/arraysize.h"
17 #include "rtc_base/bitstream_reader.h"
18 #include "rtc_base/byte_buffer.h"
19 #include "test/gmock.h"
20 #include "test/gtest.h"
21
22 namespace rtc {
23
24 using ::testing::ElementsAre;
25 using ::webrtc::BitstreamReader;
26
TEST(BitBufferWriterTest,ConsumeBits)27 TEST(BitBufferWriterTest, ConsumeBits) {
28 uint8_t bytes[64] = {0};
29 BitBufferWriter buffer(bytes, 32);
30 uint64_t total_bits = 32 * 8;
31 EXPECT_EQ(total_bits, buffer.RemainingBitCount());
32 EXPECT_TRUE(buffer.ConsumeBits(3));
33 total_bits -= 3;
34 EXPECT_EQ(total_bits, buffer.RemainingBitCount());
35 EXPECT_TRUE(buffer.ConsumeBits(3));
36 total_bits -= 3;
37 EXPECT_EQ(total_bits, buffer.RemainingBitCount());
38 EXPECT_TRUE(buffer.ConsumeBits(15));
39 total_bits -= 15;
40 EXPECT_EQ(total_bits, buffer.RemainingBitCount());
41 EXPECT_TRUE(buffer.ConsumeBits(37));
42 total_bits -= 37;
43 EXPECT_EQ(total_bits, buffer.RemainingBitCount());
44
45 EXPECT_FALSE(buffer.ConsumeBits(32 * 8));
46 EXPECT_EQ(total_bits, buffer.RemainingBitCount());
47 }
48
TEST(BitBufferWriterDeathTest,SetOffsetValues)49 TEST(BitBufferWriterDeathTest, SetOffsetValues) {
50 uint8_t bytes[4] = {0};
51 BitBufferWriter buffer(bytes, 4);
52
53 size_t byte_offset, bit_offset;
54 // Bit offsets are [0,7].
55 EXPECT_TRUE(buffer.Seek(0, 0));
56 EXPECT_TRUE(buffer.Seek(0, 7));
57 buffer.GetCurrentOffset(&byte_offset, &bit_offset);
58 EXPECT_EQ(0u, byte_offset);
59 EXPECT_EQ(7u, bit_offset);
60 EXPECT_FALSE(buffer.Seek(0, 8));
61 buffer.GetCurrentOffset(&byte_offset, &bit_offset);
62 EXPECT_EQ(0u, byte_offset);
63 EXPECT_EQ(7u, bit_offset);
64 // Byte offsets are [0,length]. At byte offset length, the bit offset must be
65 // 0.
66 EXPECT_TRUE(buffer.Seek(0, 0));
67 EXPECT_TRUE(buffer.Seek(2, 4));
68 buffer.GetCurrentOffset(&byte_offset, &bit_offset);
69 EXPECT_EQ(2u, byte_offset);
70 EXPECT_EQ(4u, bit_offset);
71 EXPECT_TRUE(buffer.Seek(4, 0));
72 EXPECT_FALSE(buffer.Seek(5, 0));
73 buffer.GetCurrentOffset(&byte_offset, &bit_offset);
74 EXPECT_EQ(4u, byte_offset);
75 EXPECT_EQ(0u, bit_offset);
76 EXPECT_FALSE(buffer.Seek(4, 1));
77
78 // Disable death test on Android because it relies on fork() and doesn't play
79 // nicely.
80 #if GTEST_HAS_DEATH_TEST
81 #if !defined(WEBRTC_ANDROID)
82 // Passing a null out parameter is death.
83 EXPECT_DEATH(buffer.GetCurrentOffset(&byte_offset, nullptr), "");
84 #endif
85 #endif
86 }
87
TEST(BitBufferWriterTest,WriteNonSymmetricSameNumberOfBitsWhenNumValuesPowerOf2)88 TEST(BitBufferWriterTest,
89 WriteNonSymmetricSameNumberOfBitsWhenNumValuesPowerOf2) {
90 uint8_t bytes[2] = {};
91 BitBufferWriter writer(bytes, 2);
92
93 ASSERT_EQ(writer.RemainingBitCount(), 16u);
94 EXPECT_TRUE(writer.WriteNonSymmetric(0xf, /*num_values=*/1 << 4));
95 ASSERT_EQ(writer.RemainingBitCount(), 12u);
96 EXPECT_TRUE(writer.WriteNonSymmetric(0x3, /*num_values=*/1 << 4));
97 ASSERT_EQ(writer.RemainingBitCount(), 8u);
98 EXPECT_TRUE(writer.WriteNonSymmetric(0xa, /*num_values=*/1 << 4));
99 ASSERT_EQ(writer.RemainingBitCount(), 4u);
100 EXPECT_TRUE(writer.WriteNonSymmetric(0x0, /*num_values=*/1 << 4));
101 ASSERT_EQ(writer.RemainingBitCount(), 0u);
102
103 EXPECT_THAT(bytes, ElementsAre(0xf3, 0xa0));
104 }
105
TEST(BitBufferWriterTest,NonSymmetricReadsMatchesWrites)106 TEST(BitBufferWriterTest, NonSymmetricReadsMatchesWrites) {
107 uint8_t bytes[2] = {};
108 BitBufferWriter writer(bytes, 2);
109
110 EXPECT_EQ(BitBufferWriter::SizeNonSymmetricBits(/*val=*/1, /*num_values=*/6),
111 2u);
112 EXPECT_EQ(BitBufferWriter::SizeNonSymmetricBits(/*val=*/2, /*num_values=*/6),
113 3u);
114 // Values [0, 1] can fit into two bit.
115 ASSERT_EQ(writer.RemainingBitCount(), 16u);
116 EXPECT_TRUE(writer.WriteNonSymmetric(/*val=*/0, /*num_values=*/6));
117 ASSERT_EQ(writer.RemainingBitCount(), 14u);
118 EXPECT_TRUE(writer.WriteNonSymmetric(/*val=*/1, /*num_values=*/6));
119 ASSERT_EQ(writer.RemainingBitCount(), 12u);
120 // Values [2, 5] require 3 bits.
121 EXPECT_TRUE(writer.WriteNonSymmetric(/*val=*/2, /*num_values=*/6));
122 ASSERT_EQ(writer.RemainingBitCount(), 9u);
123 EXPECT_TRUE(writer.WriteNonSymmetric(/*val=*/3, /*num_values=*/6));
124 ASSERT_EQ(writer.RemainingBitCount(), 6u);
125 EXPECT_TRUE(writer.WriteNonSymmetric(/*val=*/4, /*num_values=*/6));
126 ASSERT_EQ(writer.RemainingBitCount(), 3u);
127 EXPECT_TRUE(writer.WriteNonSymmetric(/*val=*/5, /*num_values=*/6));
128 ASSERT_EQ(writer.RemainingBitCount(), 0u);
129
130 // Bit values are
131 // 00.01.100.101.110.111 = 00011001|01110111 = 0x19|77
132 EXPECT_THAT(bytes, ElementsAre(0x19, 0x77));
133
134 BitstreamReader reader(bytes);
135 EXPECT_EQ(reader.ReadNonSymmetric(/*num_values=*/6), 0u);
136 EXPECT_EQ(reader.ReadNonSymmetric(/*num_values=*/6), 1u);
137 EXPECT_EQ(reader.ReadNonSymmetric(/*num_values=*/6), 2u);
138 EXPECT_EQ(reader.ReadNonSymmetric(/*num_values=*/6), 3u);
139 EXPECT_EQ(reader.ReadNonSymmetric(/*num_values=*/6), 4u);
140 EXPECT_EQ(reader.ReadNonSymmetric(/*num_values=*/6), 5u);
141 EXPECT_TRUE(reader.Ok());
142 }
143
TEST(BitBufferWriterTest,WriteNonSymmetricOnlyValueConsumesNoBits)144 TEST(BitBufferWriterTest, WriteNonSymmetricOnlyValueConsumesNoBits) {
145 uint8_t bytes[2] = {};
146 BitBufferWriter writer(bytes, 2);
147 ASSERT_EQ(writer.RemainingBitCount(), 16u);
148
149 EXPECT_TRUE(writer.WriteNonSymmetric(0, /*num_values=*/1));
150
151 EXPECT_EQ(writer.RemainingBitCount(), 16u);
152 }
153
TEST(BitBufferWriterTest,SymmetricReadWrite)154 TEST(BitBufferWriterTest, SymmetricReadWrite) {
155 uint8_t bytes[16] = {0};
156 BitBufferWriter buffer(bytes, 4);
157
158 // Write some bit data at various sizes.
159 EXPECT_TRUE(buffer.WriteBits(0x2u, 3));
160 EXPECT_TRUE(buffer.WriteBits(0x1u, 2));
161 EXPECT_TRUE(buffer.WriteBits(0x53u, 7));
162 EXPECT_TRUE(buffer.WriteBits(0x0u, 2));
163 EXPECT_TRUE(buffer.WriteBits(0x1u, 1));
164 EXPECT_TRUE(buffer.WriteBits(0x1ABCDu, 17));
165 // That should be all that fits in the buffer.
166 EXPECT_FALSE(buffer.WriteBits(1, 1));
167
168 BitstreamReader reader(rtc::MakeArrayView(bytes, 4));
169 EXPECT_EQ(reader.ReadBits(3), 0x2u);
170 EXPECT_EQ(reader.ReadBits(2), 0x1u);
171 EXPECT_EQ(reader.ReadBits(7), 0x53u);
172 EXPECT_EQ(reader.ReadBits(2), 0x0u);
173 EXPECT_EQ(reader.ReadBits(1), 0x1u);
174 EXPECT_EQ(reader.ReadBits(17), 0x1ABCDu);
175 // And there should be nothing left.
176 EXPECT_EQ(reader.RemainingBitCount(), 0);
177 }
178
TEST(BitBufferWriterTest,SymmetricBytesMisaligned)179 TEST(BitBufferWriterTest, SymmetricBytesMisaligned) {
180 uint8_t bytes[16] = {0};
181 BitBufferWriter buffer(bytes, 16);
182
183 // Offset 3, to get things misaligned.
184 EXPECT_TRUE(buffer.ConsumeBits(3));
185 EXPECT_TRUE(buffer.WriteUInt8(0x12u));
186 EXPECT_TRUE(buffer.WriteUInt16(0x3456u));
187 EXPECT_TRUE(buffer.WriteUInt32(0x789ABCDEu));
188
189 BitstreamReader reader(bytes);
190 reader.ConsumeBits(3);
191 EXPECT_EQ(reader.Read<uint8_t>(), 0x12u);
192 EXPECT_EQ(reader.Read<uint16_t>(), 0x3456u);
193 EXPECT_EQ(reader.Read<uint32_t>(), 0x789ABCDEu);
194 EXPECT_TRUE(reader.Ok());
195 }
196
TEST(BitBufferWriterTest,SymmetricGolomb)197 TEST(BitBufferWriterTest, SymmetricGolomb) {
198 char test_string[] = "my precious";
199 uint8_t bytes[64] = {0};
200 BitBufferWriter buffer(bytes, 64);
201 for (size_t i = 0; i < arraysize(test_string); ++i) {
202 EXPECT_TRUE(buffer.WriteExponentialGolomb(test_string[i]));
203 }
204 BitstreamReader reader(bytes);
205 for (size_t i = 0; i < arraysize(test_string); ++i) {
206 EXPECT_EQ(int64_t{reader.ReadExponentialGolomb()}, int64_t{test_string[i]});
207 }
208 EXPECT_TRUE(reader.Ok());
209 }
210
TEST(BitBufferWriterTest,WriteClearsBits)211 TEST(BitBufferWriterTest, WriteClearsBits) {
212 uint8_t bytes[] = {0xFF, 0xFF};
213 BitBufferWriter buffer(bytes, 2);
214 EXPECT_TRUE(buffer.ConsumeBits(3));
215 EXPECT_TRUE(buffer.WriteBits(0, 1));
216 EXPECT_EQ(0xEFu, bytes[0]);
217 EXPECT_TRUE(buffer.WriteBits(0, 3));
218 EXPECT_EQ(0xE1u, bytes[0]);
219 EXPECT_TRUE(buffer.WriteBits(0, 2));
220 EXPECT_EQ(0xE0u, bytes[0]);
221 EXPECT_EQ(0x7F, bytes[1]);
222 }
223
224 } // namespace rtc
225