diff --git a/rtc_base/bit_buffer.cc b/rtc_base/bit_buffer.cc index a6dc1c7ab8..540141fe52 100644 --- a/rtc_base/bit_buffer.cc +++ b/rtc_base/bit_buffer.cc @@ -162,6 +162,12 @@ bool BitBuffer::ConsumeBits(size_t bit_count) { bool BitBuffer::ReadNonSymmetric(uint32_t* val, uint32_t num_values) { RTC_DCHECK_GT(num_values, 0); RTC_DCHECK_LE(num_values, uint32_t{1} << 31); + if (num_values == 1) { + // When there is only one possible value, it requires zero bits to store it. + // But ReadBits doesn't support reading zero bits. + *val = 0; + return true; + } size_t count_bits = CountBits(num_values); uint32_t num_min_bits_values = (uint32_t{1} << count_bits) - num_values; @@ -308,6 +314,11 @@ bool BitBufferWriter::WriteBits(uint64_t val, size_t bit_count) { bool BitBufferWriter::WriteNonSymmetric(uint32_t val, uint32_t num_values) { RTC_DCHECK_LT(val, num_values); RTC_DCHECK_LE(num_values, uint32_t{1} << 31); + if (num_values == 1) { + // When there is only one possible value, it requires zero bits to store it. + // But WriteBits doesn't support writing zero bits. + return true; + } size_t count_bits = CountBits(num_values); uint32_t num_min_bits_values = (uint32_t{1} << count_bits) - num_values; diff --git a/rtc_base/bit_buffer_unittest.cc b/rtc_base/bit_buffer_unittest.cc index 441cd26495..656682c2ef 100644 --- a/rtc_base/bit_buffer_unittest.cc +++ b/rtc_base/bit_buffer_unittest.cc @@ -254,6 +254,28 @@ TEST(BitBufferWriterTest, NonSymmetricReadsMatchesWrites) { EXPECT_THAT(values, ElementsAre(0, 1, 2, 3, 4, 5)); } +TEST(BitBufferTest, ReadNonSymmetricOnlyValueConsumesNoBits) { + const uint8_t bytes[2] = {}; + BitBuffer reader(bytes, 2); + uint32_t value = 0xFFFFFFFF; + ASSERT_EQ(reader.RemainingBitCount(), 16u); + + EXPECT_TRUE(reader.ReadNonSymmetric(&value, /*num_values=*/1)); + + EXPECT_EQ(value, 0u); + EXPECT_EQ(reader.RemainingBitCount(), 16u); +} + +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); +} + uint64_t GolombEncoded(uint32_t val) { val++; uint32_t bit_counter = val;