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