diff options
| author | jacqueline <me@jacqueline.id.au> | 2023-08-10 15:33:00 +1000 |
|---|---|---|
| committer | jacqueline <me@jacqueline.id.au> | 2023-08-10 15:33:00 +1000 |
| commit | d8fc77101dcf80a3643a00b3446dca1e390ce997 (patch) | |
| tree | 9e03881f3857c7b4c6a0b6e3a062947daecc69d1 /src/codecs/source_buffer.cpp | |
| parent | 67caeb6e3cda44205ba8fe783274b20dc7ea216e (diff) | |
| download | tangara-fw-d8fc77101dcf80a3643a00b3446dca1e390ce997.tar.gz | |
Give codecs complete control of their input files
Diffstat (limited to 'src/codecs/source_buffer.cpp')
| -rw-r--r-- | src/codecs/source_buffer.cpp | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/src/codecs/source_buffer.cpp b/src/codecs/source_buffer.cpp new file mode 100644 index 00000000..5955523e --- /dev/null +++ b/src/codecs/source_buffer.cpp @@ -0,0 +1,75 @@ +/* + * Copyright 2023 jacqueline <me@jacqueline.id.au> + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#include "source_buffer.hpp" +#include <sys/_stdint.h> + +#include <algorithm> +#include <cstring> + +#include "esp_heap_caps.h" +#include "esp_log.h" + +#include "codec.hpp" + +namespace codecs { + +static constexpr char kTag[] = "dec_buf"; +static constexpr size_t kBufferSize = 1024 * 8; + +SourceBuffer::SourceBuffer() + : buffer_(reinterpret_cast<std::byte*>( + heap_caps_malloc(kBufferSize, MALLOC_CAP_SPIRAM)), + kBufferSize), + bytes_in_buffer_(0), + offset_of_bytes_(0) { + assert(buffer_.data() != nullptr); +} + +SourceBuffer::~SourceBuffer() { + free(buffer_.data()); +} + +auto SourceBuffer::Refill(IStream* src) -> bool { + if (bytes_in_buffer_ == buffer_.size_bytes()) { + return false; + } + bool eof = false; + AddBytes([&](cpp::span<std::byte> buf) -> size_t { + size_t bytes_read = src->Read(buf); + eof = bytes_read == 0; + return bytes_read; + }); + return eof; +} + +auto SourceBuffer::AddBytes(std::function<size_t(cpp::span<std::byte>)> writer) + -> void { + if (offset_of_bytes_ > 0) { + std::memmove(buffer_.data(), buffer_.data() + offset_of_bytes_, + bytes_in_buffer_); + offset_of_bytes_ = 0; + } + size_t added_bytes = std::invoke(writer, buffer_.subspan(bytes_in_buffer_)); + assert(bytes_in_buffer_ + added_bytes <= buffer_.size_bytes()); + bytes_in_buffer_ += added_bytes; +} + +auto SourceBuffer::ConsumeBytes( + std::function<size_t(cpp::span<std::byte>)> reader) -> void { + size_t bytes_consumed = std::invoke( + reader, buffer_.subspan(offset_of_bytes_).first(bytes_in_buffer_)); + assert(bytes_consumed <= bytes_in_buffer_); + + bytes_in_buffer_ -= bytes_consumed; + if (bytes_in_buffer_ == 0) { + offset_of_bytes_ = 0; + } else { + offset_of_bytes_ += bytes_consumed; + } +} + +} // namespace codecs |
