Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 42 additions & 8 deletions src/decoder/plugins/MadDecoderPlugin.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#include <algorithm> // for std::copy_n()
#include <cassert>
#include <new>

#include <stdlib.h>
#include <stdio.h>
Expand Down Expand Up @@ -149,13 +150,23 @@ class MadDecoder {

bool DecodeFirstFrame(Tag *tag) noexcept;

void AllocateBuffers() noexcept {
bool AllocateBuffers() noexcept {
assert(max_frames > 0);
assert(frame_offsets == nullptr);
assert(times == nullptr);

frame_offsets = new long[max_frames];
times = new mad_timer_t[max_frames];
frame_offsets = new (std::nothrow) long[max_frames];
if (frame_offsets == nullptr)
return false;

times = new (std::nothrow) mad_timer_t[max_frames];
if (times == nullptr) {
delete[] frame_offsets;
frame_offsets = nullptr;
return false;
}

return true;
}

[[nodiscard]] [[gnu::pure]]
Expand Down Expand Up @@ -690,10 +701,28 @@ MadDecoder::DecodeFirstFrame(Tag *tag) noexcept
mute_frame = MadDecoderMuteFrame::SKIP;

if ((xing.flags & XING_FRAMES) && xing.frames) {
mad_timer_t duration = frame.header.duration;
mad_timer_multiply(&duration, xing.frames);
total_time = ToSongTime(duration);
max_frames = xing.frames;
/*
* Each MPEG audio frame contains at least a four-byte
* header. Do not let a Xing header amplify a small
* input into a large seek table allocation. For
* streams of unknown size, retain the conservative
* estimate from FileSizeToSongLength().
*/
const offset_type available_frames =
input_stream.KnownSize()
? input_stream.GetSize() / 4
: FRAMES_CUSHION;

if (xing.frames > available_frames) {
FmtWarning(mad_domain,
"ignoring implausible Xing frame count: {}",
xing.frames);
} else {
mad_timer_t duration = frame.header.duration;
mad_timer_multiply(&duration, xing.frames);
total_time = ToSongTime(duration);
max_frames = xing.frames;
}
}

struct lame lame;
Expand Down Expand Up @@ -942,7 +971,12 @@ MadDecoder::RunDecoder() noexcept
return;
}

AllocateBuffers();
if (!AllocateBuffers()) {
FmtWarning(mad_domain,
"failed to allocate seek table for {} frames",
max_frames);
return;
}

client->Ready(CheckAudioFormat(frame.header.samplerate,
SampleFormat::S24_P32,
Expand Down
Loading