Add functions to read from/write to bitstream values with known max value

Bug: webrtc:10342
Change-Id: I701b09de574eb463daaf8d2c19008ac3452879eb
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/144033
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Philip Eliasson <philipel@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28465}
diff --git a/rtc_base/bit_buffer.h b/rtc_base/bit_buffer.h
index b03677c..de7bf02 100644
--- a/rtc_base/bit_buffer.h
+++ b/rtc_base/bit_buffer.h
@@ -51,6 +51,18 @@
   // offset.
   bool PeekBits(uint32_t* val, size_t bit_count);
 
+  // Reads value in range [0, num_values - 1].
+  // This encoding is similar to ReadBits(val, Ceil(Log2(num_values)),
+  // but reduces wastage incurred when encoding non-power of two value ranges
+  // Non symmetric values are encoded as:
+  // 1) n = countbits(num_values)
+  // 2) k = (1 << n) - num_values
+  // Value v in range [0, k - 1] is encoded in (n-1) bits.
+  // Value v in range [k, num_values - 1] is encoded as (v+k) in n bits.
+  // https://aomediacodec.github.io/av1-spec/#nsn
+  // Returns false if there isn't enough data left.
+  bool ReadNonSymmetric(uint32_t* val, uint32_t num_values);
+
   // Reads the exponential golomb encoded value at the current offset.
   // Exponential golomb values are encoded as:
   // 1) x = source val + 1
@@ -106,6 +118,14 @@
   // room left for the specified number of bits.
   bool WriteBits(uint64_t val, size_t bit_count);
 
+  // Writes value in range [0, num_values - 1]
+  // See ReadNonSymmetric documentation for the format,
+  // Call SizeNonSymmetricBits to get number of bits needed to store the value.
+  // Returns false if there isn't enough room left for the value.
+  bool WriteNonSymmetric(uint32_t val, uint32_t num_values);
+  // Returns number of bits required to store |val| with NonSymmetric encoding.
+  static size_t SizeNonSymmetricBits(uint32_t val, uint32_t num_values);
+
   // Writes the exponential golomb encoded version of the supplied value.
   // Returns false if there isn't enough room left for the value.
   bool WriteExponentialGolomb(uint32_t val);