Skip to content

Commit

Permalink
Create StreamBasedReadBitBuffer class which extends the base `ReadB…
Browse files Browse the repository at this point in the history
…itBuffer` class.

This will be used by the iterative decoder in order to process data based on chunking provided by the caller. This cl provides the generic structure; subsequent cls will add implementation.

Sample usage pattern:
1) Create()
2) for chunk in stream:
   PushBytes(chunk)
   *ReadObu() & Flush() until not enough data available

Within read obu, we can use tell() at the beginning of the function (after reading the obu header) to see if there is enough data to read a whole obu, since we already know the expected obu size at this point.

If tell signals that we do not have enough data, we use seek to reset the buffer to before having read the header & also ask the caller to provide more data via PushBytes().

If tell signals we do have enough data, then we simply read and process the obu accordingly.

*Note that ReadObu() is not a function within the read bit buffer. This refers to an obu processing function (of which there are many) which calls some combination of reading methods of the read bit buffer class.

PiperOrigin-RevId: 707614225
  • Loading branch information
Googler authored and jwcullen committed Dec 18, 2024
1 parent 41f12f3 commit 22b0357
Showing 1 changed file with 62 additions and 0 deletions.
62 changes: 62 additions & 0 deletions iamf/common/read_bit_buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,68 @@ class FileBasedReadBitBuffer : public ReadBitBuffer {
std::ifstream source_ifs_;
};

/*!\brief Stream-based read bit buffer.
*
* The buffer is loaded from a stream. The user should Create() the stream
* and push data to the buffer using PushBytes() as needed; calls to Read*()
* methods will read data from the stream and provide it to the caller, or else
* will instruct the caller to push more data if necessary.
*/
class StreamBasedReadBitBuffer : public ReadBitBuffer {
public:
/*!\brief Creates an instance of a stream-based read bit buffer.
*
* \param capacity Capacity of the internal buffer in bytes.
* \return Unique pointer of the created instance. `nullptr` if the creation
* fails.
*/
static std::unique_ptr<StreamBasedReadBitBuffer> Create(int64_t capacity);

/*!\brief Adds some chunk of data to StreamBasedReadBitBuffer.
*
* \param bytes Bytes to push.
* \return `absl::OkStatus()` on success. `absl::InvalidArgumentError()` if
* the stream push fails.
*/
absl::Status PushBytes(const std::vector<uint8_t>& bytes);

/*!\brief Flush already processed data from StreamBasedReadBitBuffer.
*
* Should be called whenever the caller no longer needs the first `num_bytes`
* of data.
*
* \param num_bytes Bytes to flush from StreamBasedReadBitBuffer
* \return `absl::OkStatus()` on success. Specific statuses on failure.
*/
absl::Status Flush(int64_t num_bytes);

/*!\brief Destructor.*/
~StreamBasedReadBitBuffer() override = default;

private:
/*!\brief Private constructor.
*
* \param capacity Capacity of the internal buffer in bytes.
*
*/
StreamBasedReadBitBuffer(size_t capacity);

/*!\brief Load bytes from the source stream to the buffer.
*
* \param starting_byte Starting byte to load from source.
* \param num_bytes Number of bytes to load.
* \return `absl::OkStatus()` on success. `absl::InvalidArgumentError()` if
* the stream reading fails. `absl::ResourceExhaustedError()` if there
* is not enough data in the stream to load the requested bytes.
*/
absl::Status LoadBytesToBuffer(int64_t starting_byte,
int64_t num_bytes) override;

// Source data stored in a vector. Calls to Flush() will remove the first
// `num_bytes` elements from this vector.
std::vector<uint8_t> source_vector_;
};

} // namespace iamf_tools

#endif // COMMON_READ_BIT_BUFFER_H_

0 comments on commit 22b0357

Please sign in to comment.