Noah Richards | bbf7c86 | 2015-04-21 16:30:13 -0700 | [diff] [blame] | 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 | |
Steve Anton | 10542f2 | 2019-01-11 09:11:00 -0800 | [diff] [blame] | 11 | #ifndef RTC_BASE_BIT_BUFFER_H_ |
| 12 | #define RTC_BASE_BIT_BUFFER_H_ |
Noah Richards | bbf7c86 | 2015-04-21 16:30:13 -0700 | [diff] [blame] | 13 | |
Henrik Kjellander | ec78f1c | 2017-06-29 07:52:50 +0200 | [diff] [blame] | 14 | #include <stddef.h> // For size_t. |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 15 | #include <stdint.h> // For integer types. |
Noah Richards | 9b9f1c4 | 2015-05-12 12:20:47 -0700 | [diff] [blame] | 16 | |
Steve Anton | 10542f2 | 2019-01-11 09:11:00 -0800 | [diff] [blame] | 17 | #include "rtc_base/constructor_magic.h" |
Henrik Kjellander | ec78f1c | 2017-06-29 07:52:50 +0200 | [diff] [blame] | 18 | |
| 19 | namespace rtc { |
| 20 | |
Danil Chapovalov | 48f9525 | 2021-09-16 13:20:48 +0200 | [diff] [blame] | 21 | // A BitBuffer API for write operations. Supports symmetric write APIs to the |
| 22 | // reading APIs of BitstreamReader. |
Henrik Kjellander | ec78f1c | 2017-06-29 07:52:50 +0200 | [diff] [blame] | 23 | // Sizes/counts specify bits/bytes, for clarity. |
| 24 | // Byte order is assumed big-endian/network. |
Danil Chapovalov | 48f9525 | 2021-09-16 13:20:48 +0200 | [diff] [blame] | 25 | class BitBufferWriter { |
Henrik Kjellander | ec78f1c | 2017-06-29 07:52:50 +0200 | [diff] [blame] | 26 | public: |
Danil Chapovalov | 48f9525 | 2021-09-16 13:20:48 +0200 | [diff] [blame] | 27 | // Constructs a bit buffer for the writable buffer of `bytes`. |
| 28 | BitBufferWriter(uint8_t* bytes, size_t byte_count); |
Henrik Kjellander | ec78f1c | 2017-06-29 07:52:50 +0200 | [diff] [blame] | 29 | |
| 30 | // Gets the current offset, in bytes/bits, from the start of the buffer. The |
| 31 | // bit offset is the offset into the current byte, in the range [0,7]. |
| 32 | void GetCurrentOffset(size_t* out_byte_offset, size_t* out_bit_offset); |
| 33 | |
| 34 | // The remaining bits in the byte buffer. |
| 35 | uint64_t RemainingBitCount() const; |
| 36 | |
Artem Titov | 96e3b99 | 2021-07-26 16:03:14 +0200 | [diff] [blame] | 37 | // Moves current position `byte_count` bytes forward. Returns false if |
Henrik Kjellander | ec78f1c | 2017-06-29 07:52:50 +0200 | [diff] [blame] | 38 | // there aren't enough bytes left in the buffer. |
| 39 | bool ConsumeBytes(size_t byte_count); |
Artem Titov | 96e3b99 | 2021-07-26 16:03:14 +0200 | [diff] [blame] | 40 | // Moves current position `bit_count` bits forward. Returns false if |
Henrik Kjellander | ec78f1c | 2017-06-29 07:52:50 +0200 | [diff] [blame] | 41 | // there aren't enough bits left in the buffer. |
| 42 | bool ConsumeBits(size_t bit_count); |
| 43 | |
| 44 | // Sets the current offset to the provied byte/bit offsets. The bit |
| 45 | // offset is from the given byte, in the range [0,7]. |
| 46 | bool Seek(size_t byte_offset, size_t bit_offset); |
| 47 | |
Henrik Kjellander | ec78f1c | 2017-06-29 07:52:50 +0200 | [diff] [blame] | 48 | // Writes byte-sized values from the buffer. Returns false if there isn't |
| 49 | // enough data left for the specified type. |
| 50 | bool WriteUInt8(uint8_t val); |
| 51 | bool WriteUInt16(uint16_t val); |
| 52 | bool WriteUInt32(uint32_t val); |
| 53 | |
| 54 | // Writes bit-sized values to the buffer. Returns false if there isn't enough |
| 55 | // room left for the specified number of bits. |
| 56 | bool WriteBits(uint64_t val, size_t bit_count); |
| 57 | |
Danil Chapovalov | a2b30d8 | 2019-07-03 14:41:50 +0200 | [diff] [blame] | 58 | // Writes value in range [0, num_values - 1] |
| 59 | // See ReadNonSymmetric documentation for the format, |
| 60 | // Call SizeNonSymmetricBits to get number of bits needed to store the value. |
| 61 | // Returns false if there isn't enough room left for the value. |
| 62 | bool WriteNonSymmetric(uint32_t val, uint32_t num_values); |
Artem Titov | 96e3b99 | 2021-07-26 16:03:14 +0200 | [diff] [blame] | 63 | // Returns number of bits required to store `val` with NonSymmetric encoding. |
Danil Chapovalov | a2b30d8 | 2019-07-03 14:41:50 +0200 | [diff] [blame] | 64 | static size_t SizeNonSymmetricBits(uint32_t val, uint32_t num_values); |
| 65 | |
Henrik Kjellander | ec78f1c | 2017-06-29 07:52:50 +0200 | [diff] [blame] | 66 | // Writes the exponential golomb encoded version of the supplied value. |
| 67 | // Returns false if there isn't enough room left for the value. |
| 68 | bool WriteExponentialGolomb(uint32_t val); |
| 69 | // Writes the signed exponential golomb version of the supplied value. |
| 70 | // Signed exponential golomb values are just the unsigned values mapped to the |
| 71 | // sequence 0, 1, -1, 2, -2, etc. in order. |
| 72 | bool WriteSignedExponentialGolomb(int32_t val); |
| 73 | |
| 74 | private: |
| 75 | // The buffer, as a writable array. |
| 76 | uint8_t* const writable_bytes_; |
Danil Chapovalov | 48f9525 | 2021-09-16 13:20:48 +0200 | [diff] [blame] | 77 | // The total size of `bytes_`. |
| 78 | const size_t byte_count_; |
| 79 | // The current offset, in bytes, from the start of `bytes_`. |
| 80 | size_t byte_offset_; |
| 81 | // The current offset, in bits, into the current byte. |
| 82 | size_t bit_offset_; |
Henrik Kjellander | ec78f1c | 2017-06-29 07:52:50 +0200 | [diff] [blame] | 83 | |
| 84 | RTC_DISALLOW_COPY_AND_ASSIGN(BitBufferWriter); |
| 85 | }; |
| 86 | |
| 87 | } // namespace rtc |
Noah Richards | bbf7c86 | 2015-04-21 16:30:13 -0700 | [diff] [blame] | 88 | |
Steve Anton | 10542f2 | 2019-01-11 09:11:00 -0800 | [diff] [blame] | 89 | #endif // RTC_BASE_BIT_BUFFER_H_ |