Improve memory usage of mad codec

- fix leaks
 - ensure the synth data is always in internal ram
custom
jacqueline 1 year ago
parent b463ceaef4
commit 3abf599c4f
  1. 6
      src/codecs/include/mad.hpp
  2. 40
      src/codecs/mad.cpp

@ -45,9 +45,9 @@ class MadMp3Decoder : public ICodec {
std::shared_ptr<IStream> input_;
SourceBuffer buffer_;
mad_stream* stream_;
mad_frame* frame_;
mad_synth* synth_;
std::unique_ptr<mad_stream> stream_;
std::unique_ptr<mad_frame> frame_;
std::unique_ptr<mad_synth> synth_;
int current_sample_;
bool is_eof_;

@ -25,37 +25,29 @@ namespace codecs {
[[maybe_unused]] static constexpr char kTag[] = "mad";
static constexpr uint32_t kMallocCapsPrefer =
MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT;
static constexpr uint32_t kMallocCapsFallback =
MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT;
static constexpr uint32_t kMallocCaps = MALLOC_CAP_SPIRAM;
MadMp3Decoder::MadMp3Decoder()
: input_(),
buffer_(),
stream_(reinterpret_cast<mad_stream*>(
heap_caps_malloc_prefer(sizeof(mad_stream),
kMallocCapsPrefer,
kMallocCapsFallback))),
heap_caps_malloc(sizeof(mad_stream), kMallocCaps))),
frame_(reinterpret_cast<mad_frame*>(
heap_caps_malloc_prefer(sizeof(mad_frame),
kMallocCapsPrefer,
kMallocCapsFallback))),
heap_caps_malloc(sizeof(mad_frame), kMallocCaps))),
synth_(reinterpret_cast<mad_synth*>(
heap_caps_malloc_prefer(sizeof(mad_synth),
kMallocCapsPrefer,
kMallocCapsFallback))),
heap_caps_malloc(sizeof(mad_synth),
MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT))),
current_sample_(-1),
is_eof_(false),
is_eos_(false) {
mad_stream_init(stream_);
mad_frame_init(frame_);
mad_synth_init(synth_);
mad_stream_init(stream_.get());
mad_frame_init(frame_.get());
mad_synth_init(synth_.get());
}
MadMp3Decoder::~MadMp3Decoder() {
mad_stream_finish(stream_);
mad_frame_finish(frame_);
mad_synth_finish(synth_);
mad_stream_finish(stream_.get());
mad_frame_finish(frame_.get());
mad_synth_finish(synth_.get());
}
auto MadMp3Decoder::GetBytesUsed() -> std::size_t {
@ -82,11 +74,11 @@ auto MadMp3Decoder::OpenStream(std::shared_ptr<IStream> input)
eof = buffer_.Refill(input_.get());
buffer_.ConsumeBytes([&](cpp::span<std::byte> buf) -> size_t {
mad_stream_buffer(stream_,
mad_stream_buffer(stream_.get(),
reinterpret_cast<const unsigned char*>(buf.data()),
buf.size_bytes());
while (mad_header_decode(&header, stream_) < 0) {
while (mad_header_decode(&header, stream_.get()) < 0) {
if (MAD_RECOVERABLE(stream_->error)) {
// Recoverable errors are usually malformed parts of the stream.
// We can recover from them by just retrying the decode.
@ -142,13 +134,13 @@ auto MadMp3Decoder::DecodeTo(cpp::span<sample::Sample> output)
}
buffer_.ConsumeBytes([&](cpp::span<std::byte> buf) -> size_t {
mad_stream_buffer(stream_,
mad_stream_buffer(stream_.get(),
reinterpret_cast<const unsigned char*>(buf.data()),
buf.size());
// Decode the next frame. To signal errors, this returns -1 and
// stashes an error code in the stream structure.
while (mad_frame_decode(frame_, stream_) < 0) {
while (mad_frame_decode(frame_.get(), stream_.get()) < 0) {
if (MAD_RECOVERABLE(stream_->error)) {
// Recoverable errors are usually malformed parts of the stream.
// We can recover from them by just retrying the decode.
@ -168,7 +160,7 @@ auto MadMp3Decoder::DecodeTo(cpp::span<sample::Sample> output)
// We've successfully decoded a frame! Now synthesize samples to write
// out.
mad_synth_frame(synth_, frame_);
mad_synth_frame(synth_.get(), frame_.get());
current_sample_ = 0;
return GetBytesUsed();
});

Loading…
Cancel
Save