From d8fc77101dcf80a3643a00b3446dca1e390ce997 Mon Sep 17 00:00:00 2001 From: jacqueline Date: Thu, 10 Aug 2023 15:33:00 +1000 Subject: Give codecs complete control of their input files --- src/codecs/source_buffer.cpp | 75 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 src/codecs/source_buffer.cpp (limited to 'src/codecs/source_buffer.cpp') 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 + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#include "source_buffer.hpp" +#include + +#include +#include + +#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( + 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 buf) -> size_t { + size_t bytes_read = src->Read(buf); + eof = bytes_read == 0; + return bytes_read; + }); + return eof; +} + +auto SourceBuffer::AddBytes(std::function)> 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)> 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 -- cgit v1.2.3