bit_buffer.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  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. #ifndef RTC_BASE_BIT_BUFFER_H_
  11. #define RTC_BASE_BIT_BUFFER_H_
  12. #include <stddef.h> // For size_t.
  13. #include <stdint.h> // For integer types.
  14. #include "rtc_base/constructor_magic.h"
  15. namespace rtc {
  16. // A class, similar to ByteBuffer, that can parse bit-sized data out of a set of
  17. // bytes. Has a similar API to ByteBuffer, plus methods for reading bit-sized
  18. // and exponential golomb encoded data. For a writable version, use
  19. // BitBufferWriter. Unlike ByteBuffer, this class doesn't make a copy of the
  20. // source bytes, so it can be used on read-only data.
  21. // Sizes/counts specify bits/bytes, for clarity.
  22. // Byte order is assumed big-endian/network.
  23. class BitBuffer {
  24. public:
  25. BitBuffer(const uint8_t* bytes, size_t byte_count);
  26. // Gets the current offset, in bytes/bits, from the start of the buffer. The
  27. // bit offset is the offset into the current byte, in the range [0,7].
  28. void GetCurrentOffset(size_t* out_byte_offset, size_t* out_bit_offset);
  29. // The remaining bits in the byte buffer.
  30. uint64_t RemainingBitCount() const;
  31. // Reads byte-sized values from the buffer. Returns false if there isn't
  32. // enough data left for the specified type.
  33. bool ReadUInt8(uint8_t* val);
  34. bool ReadUInt16(uint16_t* val);
  35. bool ReadUInt32(uint32_t* val);
  36. // Reads bit-sized values from the buffer. Returns false if there isn't enough
  37. // data left for the specified bit count.
  38. bool ReadBits(uint32_t* val, size_t bit_count);
  39. // Peeks bit-sized values from the buffer. Returns false if there isn't enough
  40. // data left for the specified number of bits. Doesn't move the current
  41. // offset.
  42. bool PeekBits(uint32_t* val, size_t bit_count);
  43. // Reads value in range [0, num_values - 1].
  44. // This encoding is similar to ReadBits(val, Ceil(Log2(num_values)),
  45. // but reduces wastage incurred when encoding non-power of two value ranges
  46. // Non symmetric values are encoded as:
  47. // 1) n = countbits(num_values)
  48. // 2) k = (1 << n) - num_values
  49. // Value v in range [0, k - 1] is encoded in (n-1) bits.
  50. // Value v in range [k, num_values - 1] is encoded as (v+k) in n bits.
  51. // https://aomediacodec.github.io/av1-spec/#nsn
  52. // Returns false if there isn't enough data left.
  53. bool ReadNonSymmetric(uint32_t* val, uint32_t num_values);
  54. // Reads the exponential golomb encoded value at the current offset.
  55. // Exponential golomb values are encoded as:
  56. // 1) x = source val + 1
  57. // 2) In binary, write [countbits(x) - 1] 0s, then x
  58. // To decode, we count the number of leading 0 bits, read that many + 1 bits,
  59. // and increment the result by 1.
  60. // Returns false if there isn't enough data left for the specified type, or if
  61. // the value wouldn't fit in a uint32_t.
  62. bool ReadExponentialGolomb(uint32_t* val);
  63. // Reads signed exponential golomb values at the current offset. Signed
  64. // exponential golomb values are just the unsigned values mapped to the
  65. // sequence 0, 1, -1, 2, -2, etc. in order.
  66. bool ReadSignedExponentialGolomb(int32_t* val);
  67. // Moves current position |byte_count| bytes forward. Returns false if
  68. // there aren't enough bytes left in the buffer.
  69. bool ConsumeBytes(size_t byte_count);
  70. // Moves current position |bit_count| bits forward. Returns false if
  71. // there aren't enough bits left in the buffer.
  72. bool ConsumeBits(size_t bit_count);
  73. // Sets the current offset to the provied byte/bit offsets. The bit
  74. // offset is from the given byte, in the range [0,7].
  75. bool Seek(size_t byte_offset, size_t bit_offset);
  76. protected:
  77. const uint8_t* const bytes_;
  78. // The total size of |bytes_|.
  79. 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_;
  84. RTC_DISALLOW_COPY_AND_ASSIGN(BitBuffer);
  85. };
  86. // A BitBuffer API for write operations. Supports symmetric write APIs to the
  87. // reading APIs of BitBuffer. Note that the read/write offset is shared with the
  88. // BitBuffer API, so both reading and writing will consume bytes/bits.
  89. class BitBufferWriter : public BitBuffer {
  90. public:
  91. // Constructs a bit buffer for the writable buffer of |bytes|.
  92. BitBufferWriter(uint8_t* bytes, size_t byte_count);
  93. // Writes byte-sized values from the buffer. Returns false if there isn't
  94. // enough data left for the specified type.
  95. bool WriteUInt8(uint8_t val);
  96. bool WriteUInt16(uint16_t val);
  97. bool WriteUInt32(uint32_t val);
  98. // Writes bit-sized values to the buffer. Returns false if there isn't enough
  99. // room left for the specified number of bits.
  100. bool WriteBits(uint64_t val, size_t bit_count);
  101. // Writes value in range [0, num_values - 1]
  102. // See ReadNonSymmetric documentation for the format,
  103. // Call SizeNonSymmetricBits to get number of bits needed to store the value.
  104. // Returns false if there isn't enough room left for the value.
  105. bool WriteNonSymmetric(uint32_t val, uint32_t num_values);
  106. // Returns number of bits required to store |val| with NonSymmetric encoding.
  107. static size_t SizeNonSymmetricBits(uint32_t val, uint32_t num_values);
  108. // Writes the exponential golomb encoded version of the supplied value.
  109. // Returns false if there isn't enough room left for the value.
  110. bool WriteExponentialGolomb(uint32_t val);
  111. // Writes the signed exponential golomb version of the supplied value.
  112. // Signed exponential golomb values are just the unsigned values mapped to the
  113. // sequence 0, 1, -1, 2, -2, etc. in order.
  114. bool WriteSignedExponentialGolomb(int32_t val);
  115. private:
  116. // The buffer, as a writable array.
  117. uint8_t* const writable_bytes_;
  118. RTC_DISALLOW_COPY_AND_ASSIGN(BitBufferWriter);
  119. };
  120. } // namespace rtc
  121. #endif // RTC_BASE_BIT_BUFFER_H_