xref: /aosp_15_r20/external/webrtc/rtc_base/bit_buffer_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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