• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024, Alliance for Open Media. All rights reserved
3  *
4  * This source code is subject to the terms of the BSD 3-Clause Clear License
5  * and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear
6  * License was not distributed with this source code in the LICENSE file, you
7  * can obtain it at www.aomedia.org/license/software-license/bsd-3-c-c. If the
8  * Alliance for Open Media Patent License 1.0 was not distributed with this
9  * source code in the PATENTS file, you can obtain it at
10  * www.aomedia.org/license/patent.
11  */
12 
13 #include "iamf/common/read_bit_buffer.h"
14 
15 #include <algorithm>
16 #include <cstddef>
17 #include <cstdint>
18 #include <cstdio>
19 #include <filesystem>
20 #include <fstream>
21 #include <ios>
22 #include <limits>
23 #include <memory>
24 #include <string>
25 #include <utility>
26 #include <vector>
27 
28 #include "absl/functional/any_invocable.h"
29 #include "absl/log/check.h"
30 #include "absl/log/log.h"
31 #include "absl/memory/memory.h"
32 #include "absl/status/status.h"
33 #include "absl/strings/str_cat.h"
34 #include "absl/types/span.h"
35 #include "iamf/common/utils/bit_buffer_util.h"
36 #include "iamf/common/utils/macros.h"
37 #include "iamf/obu/types.h"
38 
39 namespace iamf_tools {
40 
41 namespace {
42 
CanReadByteAligned(const int64_t & buffer_bit_offset,const int64_t & num_bits)43 bool CanReadByteAligned(const int64_t& buffer_bit_offset,
44                         const int64_t& num_bits) {
45   const bool buffer_bit_offset_is_aligned = (buffer_bit_offset % 8 == 0);
46   const bool num_bits_to_read_is_aligned = (num_bits % 8 == 0);
47   return buffer_bit_offset_is_aligned && num_bits_to_read_is_aligned;
48 }
49 
50 // Reads one bit from source_data at position `offset`. Reads in order of most
51 // significant to least significant - that is, offset = 0 refers to the bit in
52 // position 2^7, offset = 1 refers to the bit in position 2^6, etc. Caller
53 // should ensure that offset/8 is < data.size().
GetUpperBit(const int64_t & offset,const std::vector<uint8_t> & source_data)54 uint8_t GetUpperBit(const int64_t& offset,
55                     const std::vector<uint8_t>& source_data) {
56   int64_t byte_index = offset / 8;
57   uint8_t bit_index = 7 - (offset % 8);
58   return (source_data.at(byte_index) >> bit_index) & 0x01;
59 }
60 
61 // Read unsigned literal bit by bit. Data is read into the lower
62 // `remaining_bits_to_read` of `output` from the upper `remaining_bits_to_read`
63 // of bit_offer[buffer_bit_offset].
64 //
65 // Ex: Input: bit_buffer = 10000111, buffer_bit_offset = 0,
66 //        remaining_bits_to_read = 5, output = 0
67 //     Output: output = {59 leading zeroes} + 10000, buffer_bit_offset = 5,
68 //        remaining_bits_to_read = 0.
ReadUnsignedLiteralBits(const std::vector<uint8_t> & bit_buffer,const int64_t buffer_size,int64_t & buffer_bit_offset,int64_t & remaining_bits_to_read,uint64_t & output)69 void ReadUnsignedLiteralBits(const std::vector<uint8_t>& bit_buffer,
70                              const int64_t buffer_size,
71                              int64_t& buffer_bit_offset,
72                              int64_t& remaining_bits_to_read,
73                              uint64_t& output) {
74   while (((buffer_bit_offset / 8) < bit_buffer.size()) &&
75          remaining_bits_to_read > 0 && (buffer_bit_offset < buffer_size)) {
76     uint8_t upper_bit = GetUpperBit(buffer_bit_offset, bit_buffer);
77     output <<= 1;
78     output |= static_cast<uint64_t>(upper_bit);
79     remaining_bits_to_read--;
80     buffer_bit_offset++;
81   }
82 }
83 
84 // Read unsigned literal byte by byte.
ReadUnsignedLiteralBytes(const std::vector<uint8_t> & bit_buffer,int64_t & buffer_bit_offset,int64_t & remaining_bits_to_read,uint64_t & output)85 void ReadUnsignedLiteralBytes(const std::vector<uint8_t>& bit_buffer,
86                               int64_t& buffer_bit_offset,
87                               int64_t& remaining_bits_to_read,
88                               uint64_t& output) {
89   while (((buffer_bit_offset / 8) < bit_buffer.size()) &&
90          remaining_bits_to_read > 0) {
91     output <<= 8;
92     output |= static_cast<uint64_t>(bit_buffer.at(buffer_bit_offset / 8));
93     remaining_bits_to_read -= 8;
94     buffer_bit_offset += 8;
95   }
96 }
97 
98 typedef absl::AnyInvocable<void(uint64_t, int, uint64_t&) const>
99     ByteAccumulator;
100 
AccumulateUleb128Byte(const ByteAccumulator & accumulator,uint32_t max_output,const uint64_t & byte,const int index,bool & is_terminal_block,uint64_t & accumulated_value)101 absl::Status AccumulateUleb128Byte(const ByteAccumulator& accumulator,
102                                    uint32_t max_output, const uint64_t& byte,
103                                    const int index, bool& is_terminal_block,
104                                    uint64_t& accumulated_value) {
105   accumulator(byte, index, accumulated_value);
106   is_terminal_block = ((byte & 0x80) == 0);
107   if ((index == (kMaxLeb128Size - 1)) && !is_terminal_block) {
108     return absl::InvalidArgumentError(
109         "Have read the max allowable bytes for a uleb128, but bitstream "
110         "says to keep reading.");
111   }
112   if (accumulated_value > max_output) {
113     return absl::InvalidArgumentError(
114         absl::StrCat("Overflow - data is larger than max_output=", max_output));
115   }
116   return absl::OkStatus();
117 }
118 
119 // Common internal function for reading uleb128 and iso14496_1 expanded. They
120 // have similar logic except the bytes are accumulated in different orders, and
121 // they have different max output values.
AccumulateUleb128OrIso14496_1Internal(const ByteAccumulator & accumulator,const uint32_t max_output,ReadBitBuffer & rb,uint32_t & output,int8_t & encoded_size)122 absl::Status AccumulateUleb128OrIso14496_1Internal(
123     const ByteAccumulator& accumulator, const uint32_t max_output,
124     ReadBitBuffer& rb, uint32_t& output, int8_t& encoded_size) {
125   uint64_t accumulated_value = 0;
126   uint64_t byte = 0;
127   bool terminal_block = false;
128   encoded_size = 0;
129   for (int i = 0; i < kMaxLeb128Size; ++i) {
130     RETURN_IF_NOT_OK(rb.ReadUnsignedLiteral(8, byte));
131     encoded_size++;
132     RETURN_IF_NOT_OK(AccumulateUleb128Byte(accumulator, max_output, byte, i,
133                                            terminal_block, accumulated_value));
134 
135     if (terminal_block) {
136       break;
137     }
138   }
139   // Accumulated value is guaranteed to fit into a `uint32_t` at this
140   // stage.
141   output = static_cast<uint32_t>(accumulated_value);
142   return absl::OkStatus();
143 }
144 
145 }  // namespace
146 
147 // Reads n = `num_bits` bits from the buffer. These are the upper n bits of
148 // `bit_buffer_`. n must be <= 64. The read data is consumed, meaning
149 // `buffer_bit_offset_` is incremented by n as a side effect of this fxn.
ReadUnsignedLiteral(const int num_bits,uint64_t & output)150 absl::Status ReadBitBuffer::ReadUnsignedLiteral(const int num_bits,
151                                                 uint64_t& output) {
152   return ReadUnsignedLiteralInternal(num_bits, 64, output);
153 }
154 
ReadUnsignedLiteral(const int num_bits,uint32_t & output)155 absl::Status ReadBitBuffer::ReadUnsignedLiteral(const int num_bits,
156                                                 uint32_t& output) {
157   uint64_t value;
158   RETURN_IF_NOT_OK(ReadUnsignedLiteralInternal(num_bits, 32, value));
159   output = static_cast<uint32_t>(value);
160   return absl::OkStatus();
161 }
162 
ReadUnsignedLiteral(const int num_bits,uint16_t & output)163 absl::Status ReadBitBuffer::ReadUnsignedLiteral(const int num_bits,
164                                                 uint16_t& output) {
165   uint64_t value;
166   RETURN_IF_NOT_OK(ReadUnsignedLiteralInternal(num_bits, 16, value));
167   output = static_cast<uint16_t>(value);
168   return absl::OkStatus();
169 }
170 
ReadUnsignedLiteral(const int num_bits,uint8_t & output)171 absl::Status ReadBitBuffer::ReadUnsignedLiteral(const int num_bits,
172                                                 uint8_t& output) {
173   uint64_t value;
174   RETURN_IF_NOT_OK(ReadUnsignedLiteralInternal(num_bits, 8, value));
175   output = static_cast<uint8_t>(value);
176   return absl::OkStatus();
177 }
178 
179 // Reads a standard int16_t in two's complement form from the read buffer.
ReadSigned16(int16_t & output)180 absl::Status ReadBitBuffer::ReadSigned16(int16_t& output) {
181   uint64_t value;
182   RETURN_IF_NOT_OK(ReadUnsignedLiteral(16, value));
183   output = static_cast<int16_t>(value) & 0xffff;
184   return absl::OkStatus();
185 }
186 
187 // Reads a null terminated C-style string from the buffer.
ReadString(std::string & output)188 absl::Status ReadBitBuffer::ReadString(std::string& output) {
189   // Read up to the first `kIamfMaxStringSize` characters. Exit after seeing the
190   // null terminator. Override anything in `output`.
191   output = "";
192   for (int i = 0; i < kIamfMaxStringSize; i++) {
193     uint8_t byte;
194     RETURN_IF_NOT_OK(ReadUnsignedLiteral(8, byte));
195     if (byte == '\0') {
196       return absl::OkStatus();
197     }
198     output.push_back(byte);
199   }
200 
201   // Failed to find the null terminator within `kIamfMaxStringSize` bytes.
202   return absl::InvalidArgumentError(
203       "Failed to find the null terminator for data= ");
204 }
205 
ReadULeb128(DecodedUleb128 & uleb128)206 absl::Status ReadBitBuffer::ReadULeb128(DecodedUleb128& uleb128) {
207   int8_t unused_size;
208   return ReadULeb128(uleb128, unused_size);
209 }
210 
ReadULeb128(DecodedUleb128 & uleb128,int8_t & encoded_uleb128_size)211 absl::Status ReadBitBuffer::ReadULeb128(DecodedUleb128& uleb128,
212                                         int8_t& encoded_uleb128_size) {
213   static const ByteAccumulator little_endian_accumulator =
214       [&](uint64_t byte, int index, uint64_t& accumulated_value) {
215         accumulated_value |= (byte & 0x7f) << (7 * index);
216       };
217   // IAMF requires all `leb128`s to decode to a value that fits in 32 bits.
218   const uint32_t kMaxUleb128 = std::numeric_limits<uint32_t>::max();
219   return AccumulateUleb128OrIso14496_1Internal(little_endian_accumulator,
220                                                kMaxUleb128, *this, uleb128,
221                                                encoded_uleb128_size);
222 }
223 
ReadIso14496_1Expanded(uint32_t max_class_size,uint32_t & size_of_instance)224 absl::Status ReadBitBuffer::ReadIso14496_1Expanded(uint32_t max_class_size,
225                                                    uint32_t& size_of_instance) {
226   static const ByteAccumulator big_endian_accumulator =
227       [](uint64_t byte, int /*index*/, uint64_t& accumulated_value) {
228         accumulated_value = accumulated_value << 7 | (byte & 0x7f);
229       };
230   int8_t unused_encoded_size = 0;
231   return AccumulateUleb128OrIso14496_1Internal(
232       big_endian_accumulator, max_class_size, *this, size_of_instance,
233       unused_encoded_size);
234 }
235 
ReadUint8Span(absl::Span<uint8_t> output)236 absl::Status ReadBitBuffer::ReadUint8Span(absl::Span<uint8_t> output) {
237   for (auto& byte : output) {
238     RETURN_IF_NOT_OK(ReadUnsignedLiteral(8, byte));
239   }
240   return absl::OkStatus();
241 }
242 
ReadBoolean(bool & output)243 absl::Status ReadBitBuffer::ReadBoolean(bool& output) {
244   uint64_t bit;
245   RETURN_IF_NOT_OK(ReadUnsignedLiteral(1, bit));
246   output = static_cast<bool>(bit);
247   return absl::OkStatus();
248 }
249 
ReadBitBuffer(size_t capacity,int64_t source_size)250 ReadBitBuffer::ReadBitBuffer(size_t capacity, int64_t source_size)
251     : bit_buffer_(capacity),
252       buffer_bit_offset_(0),
253       buffer_size_(0),
254       source_size_(source_size),
255       source_bit_offset_(0) {}
256 
IsDataAvailable() const257 bool ReadBitBuffer::IsDataAvailable() const {
258   const bool valid_data_in_buffer =
259       (buffer_bit_offset_ >= 0 && buffer_bit_offset_ < buffer_size_);
260   const bool valid_data_in_source =
261       (source_bit_offset_ >= 0 && source_bit_offset_ < source_size_);
262   return valid_data_in_buffer || valid_data_in_source;
263 }
264 
CanReadBytes(int64_t num_bytes_requested) const265 bool ReadBitBuffer::CanReadBytes(int64_t num_bytes_requested) const {
266   CHECK_GE(num_bytes_requested, 0);
267   CHECK(source_bit_offset_ >= 0 && source_bit_offset_ <= source_size_);
268   const int64_t num_bytes_in_source = (source_size_ - source_bit_offset_) / 8;
269   CHECK(buffer_bit_offset_ >= 0 && buffer_bit_offset_ <= buffer_size_);
270   const int64_t num_bytes_in_buffer = (buffer_size_ - buffer_bit_offset_) / 8;
271   return (num_bytes_in_source + num_bytes_in_buffer) >= num_bytes_requested;
272 }
273 
Tell()274 int64_t ReadBitBuffer::Tell() {
275   is_position_valid_ = true;
276   return source_bit_offset_ - buffer_size_ + buffer_bit_offset_;
277 }
278 
Seek(const int64_t position)279 absl::Status ReadBitBuffer::Seek(const int64_t position) {
280   if (!is_position_valid_) {
281     return absl::FailedPreconditionError(
282         "Seeking to position has been disabled. This can happen if Flush() has "
283         "been called after Tell().");
284   }
285   if (position < 0) {
286     return absl::InvalidArgumentError(
287         absl::StrCat("Invalid source position: ", position));
288   }
289 
290   if (position >= source_size_) {
291     return absl::ResourceExhaustedError(
292         absl::StrCat("Not enough bits in source: position= ", position,
293                      " >= #(bits in source)= ", source_size_));
294   }
295 
296   // Simply move the `buffer_bit_offset_` if the requested position lies within
297   // the current buffer.
298   if ((source_bit_offset_ - buffer_size_ <= position) &&
299       (position < source_bit_offset_)) {
300     buffer_bit_offset_ = position - (source_bit_offset_ - buffer_size_);
301     return absl::OkStatus();
302   }
303 
304   // Load the data from the source, starting from the byte that the requested
305   // position is at.
306   const int64_t starting_byte = position / 8;
307   const int64_t num_bytes =
308       std::min(static_cast<int64_t>(bit_buffer_.capacity()),
309                source_size_ / 8 - starting_byte);
310 
311   RETURN_IF_NOT_OK(LoadBytesToBuffer(starting_byte, num_bytes));
312 
313   // Update other bookkeeping data.
314   buffer_bit_offset_ = position % 8;
315   source_bit_offset_ = (starting_byte + num_bytes) * 8;
316   buffer_size_ = num_bytes * 8;
317 
318   return absl::OkStatus();
319 }
320 
ReadUnsignedLiteralInternal(const int num_bits,const int max_num_bits,uint64_t & output)321 absl::Status ReadBitBuffer::ReadUnsignedLiteralInternal(const int num_bits,
322                                                         const int max_num_bits,
323                                                         uint64_t& output) {
324   if (num_bits > max_num_bits) {
325     return absl::InvalidArgumentError("num_bits must be <= max_num_bits.");
326   }
327   if (num_bits < 0) {
328     return absl::InvalidArgumentError("num_bits must be >= 0.");
329   }
330   if (buffer_bit_offset_ < 0) {
331     return absl::InvalidArgumentError("buffer_bit_offset_ must be >= 0.");
332   }
333   output = 0;
334 
335   // Early return if 0 bit is requested to be read.
336   if (num_bits == 0) {
337     return absl::OkStatus();
338   }
339 
340   // Now at least one bit is needed, make sure the buffer has some data in it.
341   RETURN_IF_NOT_OK(Seek(Tell()));
342   int64_t remaining_bits_to_read = num_bits;
343   const int64_t expected_final_position = Tell() + remaining_bits_to_read;
344 
345   // If the final position and the current position lies within the same byte.
346   if (expected_final_position / 8 == Tell() / 8) {
347     ReadUnsignedLiteralBits(bit_buffer_, buffer_size_, buffer_bit_offset_,
348                             remaining_bits_to_read, output);
349     CHECK_EQ(remaining_bits_to_read, 0) << remaining_bits_to_read;
350     return absl::OkStatus();
351   }
352 
353   // Read the first several bits so that the `buffer_bit_offset_` is byte
354   // aligned.
355   if (buffer_bit_offset_ % 8 != 0) {
356     int64_t num_bits_to_byte_aligned = 8 - (buffer_bit_offset_ % 8);
357     remaining_bits_to_read -= num_bits_to_byte_aligned;
358     ReadUnsignedLiteralBits(bit_buffer_, buffer_size_, buffer_bit_offset_,
359                             num_bits_to_byte_aligned, output);
360   }
361 
362   // Read consecutive complete bytes.
363   while (remaining_bits_to_read >= 8) {
364     // Make sure the reading position has some buffer to read if possible.
365     RETURN_IF_NOT_OK(Seek(Tell()));
366 
367     // Read as much as possible from the buffer.
368     int64_t num_bits_from_buffer = std::min(buffer_size_ - buffer_bit_offset_,
369                                             (remaining_bits_to_read / 8) * 8);
370 
371     CHECK(CanReadByteAligned(buffer_bit_offset_, num_bits_from_buffer));
372     remaining_bits_to_read -= num_bits_from_buffer;
373     ReadUnsignedLiteralBytes(bit_buffer_, buffer_bit_offset_,
374                              num_bits_from_buffer, output);
375   }
376 
377   // Read the final several bits in the last byte.
378   int64_t num_bits_in_final_byte = expected_final_position % 8;
379   remaining_bits_to_read -= num_bits_in_final_byte;
380   ReadUnsignedLiteralBits(bit_buffer_, buffer_size_, buffer_bit_offset_,
381                           num_bits_in_final_byte, output);
382   CHECK_EQ(remaining_bits_to_read, 0) << remaining_bits_to_read;
383   return absl::OkStatus();
384 }
385 
386 // ----- MemoryBasedReadBitBuffer -----
387 
388 std::unique_ptr<MemoryBasedReadBitBuffer>
CreateFromSpan(int64_t capacity,absl::Span<const uint8_t> source)389 MemoryBasedReadBitBuffer::CreateFromSpan(int64_t capacity,
390                                          absl::Span<const uint8_t> source) {
391   if (capacity < 0) {
392     LOG(ERROR) << "MemoryBasedReadBitBuffer capacity must be >= 0.";
393     return nullptr;
394   }
395   return absl::WrapUnique(new MemoryBasedReadBitBuffer(capacity, source));
396 }
397 
LoadBytesToBuffer(int64_t starting_byte,int64_t num_bytes)398 absl::Status MemoryBasedReadBitBuffer::LoadBytesToBuffer(int64_t starting_byte,
399                                                          int64_t num_bytes) {
400   if (starting_byte > source_vector_.size() ||
401       (starting_byte + num_bytes) > source_vector_.size()) {
402     return absl::InvalidArgumentError(
403         "Invalid starting or ending position to read from the vector");
404   }
405 
406   std::copy(source_vector_.begin() + starting_byte,
407             source_vector_.begin() + starting_byte + num_bytes,
408             bit_buffer_.begin());
409   return absl::OkStatus();
410 }
411 
MemoryBasedReadBitBuffer(size_t capacity,absl::Span<const uint8_t> source)412 MemoryBasedReadBitBuffer::MemoryBasedReadBitBuffer(
413     size_t capacity, absl::Span<const uint8_t> source)
414     : ReadBitBuffer(capacity, static_cast<int64_t>(source.size()) * 8),
415       source_vector_(source.begin(), source.end()) {}
416 
417 // ----- FileBasedReadBitBuffer -----
418 
419 std::unique_ptr<FileBasedReadBitBuffer>
CreateFromFilePath(const int64_t capacity,const std::filesystem::path & file_path)420 FileBasedReadBitBuffer::CreateFromFilePath(
421     const int64_t capacity, const std::filesystem::path& file_path) {
422   if (capacity < 0) {
423     LOG(ERROR) << "FileBasedReadBitBuffer capacity must be >= 0.";
424     return nullptr;
425   }
426   if (!std::filesystem::exists(file_path)) {
427     LOG(ERROR) << "File not found: " << file_path;
428     return nullptr;
429   }
430   std::ifstream ifs(file_path, std::ios::binary | std::ios::in);
431   ifs.seekg(0, ifs.end);
432   const auto file_size = static_cast<size_t>(ifs.tellg());
433   ifs.seekg(0, ifs.beg);
434   if (!ifs.good()) {
435     LOG(ERROR) << "Error accessing " << file_path;
436     return nullptr;
437   }
438 
439   // File size is in bytes, `source_size` is in bits.
440   return absl::WrapUnique(
441       new FileBasedReadBitBuffer(capacity, file_size * 8, std::move(ifs)));
442 }
443 
LoadBytesToBuffer(int64_t starting_byte,int64_t num_bytes)444 absl::Status FileBasedReadBitBuffer::LoadBytesToBuffer(int64_t starting_byte,
445                                                        int64_t num_bytes) {
446   source_ifs_.seekg(starting_byte);
447   source_ifs_.read(reinterpret_cast<char*>(bit_buffer_.data()), num_bytes);
448   if (!source_ifs_.good()) {
449     return absl::InvalidArgumentError(
450         absl::StrCat("File reading failed. State= ", source_ifs_.rdstate()));
451   }
452 
453   return absl::OkStatus();
454 }
455 
FileBasedReadBitBuffer(size_t capacity,int64_t source_size,std::ifstream && ifs)456 FileBasedReadBitBuffer::FileBasedReadBitBuffer(size_t capacity,
457                                                int64_t source_size,
458                                                std::ifstream&& ifs)
459     : ReadBitBuffer(capacity, source_size), source_ifs_(std::move(ifs)) {}
460 
461 // ----- StreamBasedReadBitBuffer -----
Create(int64_t capacity)462 std::unique_ptr<StreamBasedReadBitBuffer> StreamBasedReadBitBuffer::Create(
463     int64_t capacity) {
464   if (capacity < 0) {
465     LOG(ERROR) << "StreamBasedReadBitBuffer capacity must be >= 0.";
466     return nullptr;
467   }
468   // Since this is a stream based buffer, we do not initialize with any data,
469   // hence the source size is initially set to 0.
470   return absl::WrapUnique(
471       new StreamBasedReadBitBuffer(capacity, /*source_size=*/0));
472 }
473 
PushBytes(absl::Span<const uint8_t> bytes)474 absl::Status StreamBasedReadBitBuffer::PushBytes(
475     absl::Span<const uint8_t> bytes) {
476   if (bytes.size() > ((max_source_size_ / 8) - source_vector_.size())) {
477     return absl::InvalidArgumentError(
478         "Cannot push more bytes than the available space in the source.");
479   }
480   // Copy the bytes to the source vector; this is added to the end in case there
481   // are already some bytes in the source.
482   source_vector_.insert(source_vector_.end(), bytes.begin(), bytes.end());
483   // The source grows as bytes are pushed.
484   source_size_ += bytes.size() * 8;
485   return absl::OkStatus();
486 }
487 
488 // Flush should be called in a reasonable manner, i.e. not every time a read
489 // operation is performed, as the removal of elements from the source vector
490 // is an O(n) operation, where n is the number of elements in the source vector.
491 // In general, it is a trade-off: the more often it is called, the more
492 // space-efficient the buffer is (since it holds less data in the source vector)
493 // while simultaneously being less time-efficient (since it takes time to remove
494 // elements from the source vector).
Flush(int64_t num_bytes)495 absl::Status StreamBasedReadBitBuffer::Flush(int64_t num_bytes) {
496   if (num_bytes > source_vector_.size()) {
497     return absl::InvalidArgumentError(
498         "Cannot flush more bytes than are in the source.");
499   }
500   source_vector_.erase(source_vector_.begin(),
501                        source_vector_.begin() + num_bytes);
502   // Offset needs to be moved back as erase moves the elements of a vector that
503   // are not removed to the beginning of the vector.
504   source_bit_offset_ -= num_bytes * 8;
505   source_size_ -= num_bytes * 8;
506   // Disable seeking as the position returned by a previous Tell() call is no
507   // longer valid.
508   is_position_valid_ = false;
509   return absl::OkStatus();
510 }
511 
StreamBasedReadBitBuffer(size_t capacity,int64_t source_size)512 StreamBasedReadBitBuffer::StreamBasedReadBitBuffer(size_t capacity,
513                                                    int64_t source_size)
514     : MemoryBasedReadBitBuffer(capacity, absl::Span<const uint8_t>()) {
515   max_source_size_ = kEntireObuSizeMaxTwoMegabytes * 2 * 8;
516 }
517 
518 }  // namespace iamf_tools
519