summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/rtc_base/bit_buffer_unittest.cc
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /third_party/libwebrtc/rtc_base/bit_buffer_unittest.cc
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/libwebrtc/rtc_base/bit_buffer_unittest.cc')
-rw-r--r--third_party/libwebrtc/rtc_base/bit_buffer_unittest.cc256
1 files changed, 256 insertions, 0 deletions
diff --git a/third_party/libwebrtc/rtc_base/bit_buffer_unittest.cc b/third_party/libwebrtc/rtc_base/bit_buffer_unittest.cc
new file mode 100644
index 0000000000..7dfe0c808d
--- /dev/null
+++ b/third_party/libwebrtc/rtc_base/bit_buffer_unittest.cc
@@ -0,0 +1,256 @@
+/*
+ * Copyright 2015 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "rtc_base/bit_buffer.h"
+
+#include <limits>
+
+#include "api/array_view.h"
+#include "rtc_base/arraysize.h"
+#include "rtc_base/bitstream_reader.h"
+#include "rtc_base/byte_buffer.h"
+#include "test/gmock.h"
+#include "test/gtest.h"
+
+namespace rtc {
+
+using ::testing::ElementsAre;
+using ::webrtc::BitstreamReader;
+
+TEST(BitBufferWriterTest, ConsumeBits) {
+ uint8_t bytes[64] = {0};
+ BitBufferWriter buffer(bytes, 32);
+ uint64_t total_bits = 32 * 8;
+ EXPECT_EQ(total_bits, buffer.RemainingBitCount());
+ EXPECT_TRUE(buffer.ConsumeBits(3));
+ total_bits -= 3;
+ EXPECT_EQ(total_bits, buffer.RemainingBitCount());
+ EXPECT_TRUE(buffer.ConsumeBits(3));
+ total_bits -= 3;
+ EXPECT_EQ(total_bits, buffer.RemainingBitCount());
+ EXPECT_TRUE(buffer.ConsumeBits(15));
+ total_bits -= 15;
+ EXPECT_EQ(total_bits, buffer.RemainingBitCount());
+ EXPECT_TRUE(buffer.ConsumeBits(37));
+ total_bits -= 37;
+ EXPECT_EQ(total_bits, buffer.RemainingBitCount());
+
+ EXPECT_FALSE(buffer.ConsumeBits(32 * 8));
+ EXPECT_EQ(total_bits, buffer.RemainingBitCount());
+}
+
+TEST(BitBufferWriterDeathTest, SetOffsetValues) {
+ uint8_t bytes[4] = {0};
+ BitBufferWriter buffer(bytes, 4);
+
+ size_t byte_offset, bit_offset;
+ // Bit offsets are [0,7].
+ EXPECT_TRUE(buffer.Seek(0, 0));
+ EXPECT_TRUE(buffer.Seek(0, 7));
+ buffer.GetCurrentOffset(&byte_offset, &bit_offset);
+ EXPECT_EQ(0u, byte_offset);
+ EXPECT_EQ(7u, bit_offset);
+ EXPECT_FALSE(buffer.Seek(0, 8));
+ buffer.GetCurrentOffset(&byte_offset, &bit_offset);
+ EXPECT_EQ(0u, byte_offset);
+ EXPECT_EQ(7u, bit_offset);
+ // Byte offsets are [0,length]. At byte offset length, the bit offset must be
+ // 0.
+ EXPECT_TRUE(buffer.Seek(0, 0));
+ EXPECT_TRUE(buffer.Seek(2, 4));
+ buffer.GetCurrentOffset(&byte_offset, &bit_offset);
+ EXPECT_EQ(2u, byte_offset);
+ EXPECT_EQ(4u, bit_offset);
+ EXPECT_TRUE(buffer.Seek(4, 0));
+ EXPECT_FALSE(buffer.Seek(5, 0));
+ buffer.GetCurrentOffset(&byte_offset, &bit_offset);
+ EXPECT_EQ(4u, byte_offset);
+ EXPECT_EQ(0u, bit_offset);
+ EXPECT_FALSE(buffer.Seek(4, 1));
+
+// Disable death test on Android because it relies on fork() and doesn't play
+// nicely.
+#if GTEST_HAS_DEATH_TEST
+#if !defined(WEBRTC_ANDROID)
+ // Passing a null out parameter is death.
+ EXPECT_DEATH(buffer.GetCurrentOffset(&byte_offset, nullptr), "");
+#endif
+#endif
+}
+
+TEST(BitBufferWriterTest,
+ WriteNonSymmetricSameNumberOfBitsWhenNumValuesPowerOf2) {
+ uint8_t bytes[2] = {};
+ BitBufferWriter writer(bytes, 2);
+
+ ASSERT_EQ(writer.RemainingBitCount(), 16u);
+ EXPECT_TRUE(writer.WriteNonSymmetric(0xf, /*num_values=*/1 << 4));
+ ASSERT_EQ(writer.RemainingBitCount(), 12u);
+ EXPECT_TRUE(writer.WriteNonSymmetric(0x3, /*num_values=*/1 << 4));
+ ASSERT_EQ(writer.RemainingBitCount(), 8u);
+ EXPECT_TRUE(writer.WriteNonSymmetric(0xa, /*num_values=*/1 << 4));
+ ASSERT_EQ(writer.RemainingBitCount(), 4u);
+ EXPECT_TRUE(writer.WriteNonSymmetric(0x0, /*num_values=*/1 << 4));
+ ASSERT_EQ(writer.RemainingBitCount(), 0u);
+
+ EXPECT_THAT(bytes, ElementsAre(0xf3, 0xa0));
+}
+
+TEST(BitBufferWriterTest, NonSymmetricReadsMatchesWrites) {
+ uint8_t bytes[2] = {};
+ BitBufferWriter writer(bytes, 2);
+
+ EXPECT_EQ(BitBufferWriter::SizeNonSymmetricBits(/*val=*/1, /*num_values=*/6),
+ 2u);
+ EXPECT_EQ(BitBufferWriter::SizeNonSymmetricBits(/*val=*/2, /*num_values=*/6),
+ 3u);
+ // Values [0, 1] can fit into two bit.
+ ASSERT_EQ(writer.RemainingBitCount(), 16u);
+ EXPECT_TRUE(writer.WriteNonSymmetric(/*val=*/0, /*num_values=*/6));
+ ASSERT_EQ(writer.RemainingBitCount(), 14u);
+ EXPECT_TRUE(writer.WriteNonSymmetric(/*val=*/1, /*num_values=*/6));
+ ASSERT_EQ(writer.RemainingBitCount(), 12u);
+ // Values [2, 5] require 3 bits.
+ EXPECT_TRUE(writer.WriteNonSymmetric(/*val=*/2, /*num_values=*/6));
+ ASSERT_EQ(writer.RemainingBitCount(), 9u);
+ EXPECT_TRUE(writer.WriteNonSymmetric(/*val=*/3, /*num_values=*/6));
+ ASSERT_EQ(writer.RemainingBitCount(), 6u);
+ EXPECT_TRUE(writer.WriteNonSymmetric(/*val=*/4, /*num_values=*/6));
+ ASSERT_EQ(writer.RemainingBitCount(), 3u);
+ EXPECT_TRUE(writer.WriteNonSymmetric(/*val=*/5, /*num_values=*/6));
+ ASSERT_EQ(writer.RemainingBitCount(), 0u);
+
+ // Bit values are
+ // 00.01.100.101.110.111 = 00011001|01110111 = 0x19|77
+ EXPECT_THAT(bytes, ElementsAre(0x19, 0x77));
+
+ BitstreamReader reader(bytes);
+ EXPECT_EQ(reader.ReadNonSymmetric(/*num_values=*/6), 0u);
+ EXPECT_EQ(reader.ReadNonSymmetric(/*num_values=*/6), 1u);
+ EXPECT_EQ(reader.ReadNonSymmetric(/*num_values=*/6), 2u);
+ EXPECT_EQ(reader.ReadNonSymmetric(/*num_values=*/6), 3u);
+ EXPECT_EQ(reader.ReadNonSymmetric(/*num_values=*/6), 4u);
+ EXPECT_EQ(reader.ReadNonSymmetric(/*num_values=*/6), 5u);
+ EXPECT_TRUE(reader.Ok());
+}
+
+TEST(BitBufferWriterTest, WriteNonSymmetricOnlyValueConsumesNoBits) {
+ uint8_t bytes[2] = {};
+ BitBufferWriter writer(bytes, 2);
+ ASSERT_EQ(writer.RemainingBitCount(), 16u);
+
+ EXPECT_TRUE(writer.WriteNonSymmetric(0, /*num_values=*/1));
+
+ EXPECT_EQ(writer.RemainingBitCount(), 16u);
+}
+
+TEST(BitBufferWriterTest, SymmetricReadWrite) {
+ uint8_t bytes[16] = {0};
+ BitBufferWriter buffer(bytes, 4);
+
+ // Write some bit data at various sizes.
+ EXPECT_TRUE(buffer.WriteBits(0x2u, 3));
+ EXPECT_TRUE(buffer.WriteBits(0x1u, 2));
+ EXPECT_TRUE(buffer.WriteBits(0x53u, 7));
+ EXPECT_TRUE(buffer.WriteBits(0x0u, 2));
+ EXPECT_TRUE(buffer.WriteBits(0x1u, 1));
+ EXPECT_TRUE(buffer.WriteBits(0x1ABCDu, 17));
+ // That should be all that fits in the buffer.
+ EXPECT_FALSE(buffer.WriteBits(1, 1));
+
+ BitstreamReader reader(rtc::MakeArrayView(bytes, 4));
+ EXPECT_EQ(reader.ReadBits(3), 0x2u);
+ EXPECT_EQ(reader.ReadBits(2), 0x1u);
+ EXPECT_EQ(reader.ReadBits(7), 0x53u);
+ EXPECT_EQ(reader.ReadBits(2), 0x0u);
+ EXPECT_EQ(reader.ReadBits(1), 0x1u);
+ EXPECT_EQ(reader.ReadBits(17), 0x1ABCDu);
+ // And there should be nothing left.
+ EXPECT_EQ(reader.RemainingBitCount(), 0);
+}
+
+TEST(BitBufferWriterTest, SymmetricBytesMisaligned) {
+ uint8_t bytes[16] = {0};
+ BitBufferWriter buffer(bytes, 16);
+
+ // Offset 3, to get things misaligned.
+ EXPECT_TRUE(buffer.ConsumeBits(3));
+ EXPECT_TRUE(buffer.WriteUInt8(0x12u));
+ EXPECT_TRUE(buffer.WriteUInt16(0x3456u));
+ EXPECT_TRUE(buffer.WriteUInt32(0x789ABCDEu));
+
+ BitstreamReader reader(bytes);
+ reader.ConsumeBits(3);
+ EXPECT_EQ(reader.Read<uint8_t>(), 0x12u);
+ EXPECT_EQ(reader.Read<uint16_t>(), 0x3456u);
+ EXPECT_EQ(reader.Read<uint32_t>(), 0x789ABCDEu);
+ EXPECT_TRUE(reader.Ok());
+}
+
+TEST(BitBufferWriterTest, SymmetricGolomb) {
+ char test_string[] = "my precious";
+ uint8_t bytes[64] = {0};
+ BitBufferWriter buffer(bytes, 64);
+ for (size_t i = 0; i < arraysize(test_string); ++i) {
+ EXPECT_TRUE(buffer.WriteExponentialGolomb(test_string[i]));
+ }
+ BitstreamReader reader(bytes);
+ for (size_t i = 0; i < arraysize(test_string); ++i) {
+ EXPECT_EQ(int64_t{reader.ReadExponentialGolomb()}, int64_t{test_string[i]});
+ }
+ EXPECT_TRUE(reader.Ok());
+}
+
+TEST(BitBufferWriterTest, WriteClearsBits) {
+ uint8_t bytes[] = {0xFF, 0xFF};
+ BitBufferWriter buffer(bytes, 2);
+ EXPECT_TRUE(buffer.ConsumeBits(3));
+ EXPECT_TRUE(buffer.WriteBits(0, 1));
+ EXPECT_EQ(0xEFu, bytes[0]);
+ EXPECT_TRUE(buffer.WriteBits(0, 3));
+ EXPECT_EQ(0xE1u, bytes[0]);
+ EXPECT_TRUE(buffer.WriteBits(0, 2));
+ EXPECT_EQ(0xE0u, bytes[0]);
+ EXPECT_EQ(0x7F, bytes[1]);
+}
+
+TEST(BitBufferWriterTest, WriteLeb128) {
+ uint8_t small_number[2];
+ BitBufferWriter small_buffer(small_number, sizeof(small_number));
+ EXPECT_TRUE(small_buffer.WriteLeb128(129));
+ EXPECT_THAT(small_number, ElementsAre(0x81, 0x01));
+
+ uint8_t large_number[10];
+ BitBufferWriter large_buffer(large_number, sizeof(large_number));
+ EXPECT_TRUE(large_buffer.WriteLeb128(std::numeric_limits<uint64_t>::max()));
+ EXPECT_THAT(large_number, ElementsAre(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x01));
+}
+
+TEST(BitBufferWriterTest, WriteLeb128TooSmallBuffer) {
+ uint8_t bytes[1];
+ BitBufferWriter buffer(bytes, sizeof(bytes));
+ EXPECT_FALSE(buffer.WriteLeb128(12345));
+}
+
+TEST(BitBufferWriterTest, WriteString) {
+ uint8_t buffer[2];
+ BitBufferWriter writer(buffer, sizeof(buffer));
+ EXPECT_TRUE(writer.WriteString("ab"));
+ EXPECT_THAT(buffer, ElementsAre('a', 'b'));
+}
+
+TEST(BitBufferWriterTest, WriteStringTooSmallBuffer) {
+ uint8_t buffer[2];
+ BitBufferWriter writer(buffer, sizeof(buffer));
+ EXPECT_FALSE(writer.WriteString("abc"));
+}
+
+} // namespace rtc