blob: 198be50e113acfe24ac0157d045048a5fc358b4a [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
Steve Anton10542f22019-01-11 09:11:00 -080011#include "rtc_base/bit_buffer.h"
Yves Gerey3e707812018-11-28 16:47:49 +010012
13#include <limits>
14
Danil Chapovalov48f95252021-09-16 13:20:48 +020015#include "api/array_view.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020016#include "rtc_base/arraysize.h"
Danil Chapovalov48f95252021-09-16 13:20:48 +020017#include "rtc_base/bitstream_reader.h"
Steve Anton10542f22019-01-11 09:11:00 -080018#include "rtc_base/byte_buffer.h"
Danil Chapovalova2b30d82019-07-03 14:41:50 +020019#include "test/gmock.h"
Yves Gerey3e707812018-11-28 16:47:49 +010020#include "test/gtest.h"
Noah Richardsbbf7c862015-04-21 16:30:13 -070021
22namespace rtc {
23
Danil Chapovalova2b30d82019-07-03 14:41:50 +020024using ::testing::ElementsAre;
Danil Chapovalov48f95252021-09-16 13:20:48 +020025using ::webrtc::BitstreamReader;
Danil Chapovalova2b30d82019-07-03 14:41:50 +020026
Danil Chapovalov48f95252021-09-16 13:20:48 +020027TEST(BitBufferWriterTest, ConsumeBits) {
28 uint8_t bytes[64] = {0};
29 BitBufferWriter buffer(bytes, 32);
Peter Boström0c4e06b2015-10-07 12:23:21 +020030 uint64_t total_bits = 32 * 8;
Noah Richardsbbf7c862015-04-21 16:30:13 -070031 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
Danil Chapovalov48f95252021-09-16 13:20:48 +020049TEST(BitBufferWriterDeathTest, SetOffsetValues) {
Peter Boström0c4e06b2015-10-07 12:23:21 +020050 uint8_t bytes[4] = {0};
Noah Richards86153c22015-04-28 15:13:44 -070051 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
Yves Gerey665174f2018-06-19 15:03:05 +020078// Disable death test on Android because it relies on fork() and doesn't play
79// nicely.
kwiberg77eab702016-09-28 17:42:01 -070080#if GTEST_HAS_DEATH_TEST
Donald E Curtis97bce582015-05-19 13:18:00 -070081#if !defined(WEBRTC_ANDROID)
deadbeef37f5ecf2017-02-27 14:06:41 -080082 // Passing a null out parameter is death.
83 EXPECT_DEATH(buffer.GetCurrentOffset(&byte_offset, nullptr), "");
Donald E Curtis97bce582015-05-19 13:18:00 -070084#endif
Zeke Chin2d3b7e22015-07-14 12:55:44 -070085#endif
Noah Richards86153c22015-04-28 15:13:44 -070086}
87
Danil Chapovalova2b30d82019-07-03 14:41:50 +020088TEST(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
106TEST(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
Danil Chapovalov48f95252021-09-16 13:20:48 +0200134 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());
Danil Chapovalova9e1b492020-07-08 11:24:19 +0200142}
143
144TEST(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
Noah Richards86153c22015-04-28 15:13:44 -0700154TEST(BitBufferWriterTest, SymmetricReadWrite) {
Peter Boström0c4e06b2015-10-07 12:23:21 +0200155 uint8_t bytes[16] = {0};
Noah Richards86153c22015-04-28 15:13:44 -0700156 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
Danil Chapovalov48f95252021-09-16 13:20:48 +0200168 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);
Noah Richards86153c22015-04-28 15:13:44 -0700175 // And there should be nothing left.
Danil Chapovalov48f95252021-09-16 13:20:48 +0200176 EXPECT_EQ(reader.RemainingBitCount(), 0);
Noah Richards86153c22015-04-28 15:13:44 -0700177}
178
179TEST(BitBufferWriterTest, SymmetricBytesMisaligned) {
Peter Boström0c4e06b2015-10-07 12:23:21 +0200180 uint8_t bytes[16] = {0};
Noah Richards86153c22015-04-28 15:13:44 -0700181 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
Danil Chapovalov48f95252021-09-16 13:20:48 +0200189 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());
Noah Richards86153c22015-04-28 15:13:44 -0700195}
196
197TEST(BitBufferWriterTest, SymmetricGolomb) {
198 char test_string[] = "my precious";
Peter Boström0c4e06b2015-10-07 12:23:21 +0200199 uint8_t bytes[64] = {0};
Noah Richards86153c22015-04-28 15:13:44 -0700200 BitBufferWriter buffer(bytes, 64);
tfarina5237aaf2015-11-10 23:44:30 -0800201 for (size_t i = 0; i < arraysize(test_string); ++i) {
Noah Richards86153c22015-04-28 15:13:44 -0700202 EXPECT_TRUE(buffer.WriteExponentialGolomb(test_string[i]));
203 }
Danil Chapovalov48f95252021-09-16 13:20:48 +0200204 BitstreamReader reader(bytes);
tfarina5237aaf2015-11-10 23:44:30 -0800205 for (size_t i = 0; i < arraysize(test_string); ++i) {
Danil Chapovalov48f95252021-09-16 13:20:48 +0200206 EXPECT_EQ(int64_t{reader.ReadExponentialGolomb()}, int64_t{test_string[i]});
Noah Richards86153c22015-04-28 15:13:44 -0700207 }
Danil Chapovalov48f95252021-09-16 13:20:48 +0200208 EXPECT_TRUE(reader.Ok());
Noah Richards86153c22015-04-28 15:13:44 -0700209}
210
211TEST(BitBufferWriterTest, WriteClearsBits) {
Peter Boström0c4e06b2015-10-07 12:23:21 +0200212 uint8_t bytes[] = {0xFF, 0xFF};
Noah Richards86153c22015-04-28 15:13:44 -0700213 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
Noah Richardsbbf7c862015-04-21 16:30:13 -0700224} // namespace rtc