Commit d00afc91 authored by Max Kellermann's avatar Max Kellermann

decoder/mad: eliminate the loop in SubmitPCM()

libmad has a hard-coded maximum PCM buffer size; if we make our output_buffer just as large, we can avoid the loop, because any possible size will fit.
parent 9d0fe725
...@@ -108,14 +108,13 @@ mad_plugin_init(const ConfigBlock &block) ...@@ -108,14 +108,13 @@ mad_plugin_init(const ConfigBlock &block)
class MadDecoder { class MadDecoder {
static constexpr size_t READ_BUFFER_SIZE = 40960; static constexpr size_t READ_BUFFER_SIZE = 40960;
static constexpr size_t MP3_DATA_OUTPUT_BUFFER_SIZE = 2048;
struct mad_stream stream; struct mad_stream stream;
struct mad_frame frame; struct mad_frame frame;
struct mad_synth synth; struct mad_synth synth;
mad_timer_t timer; mad_timer_t timer;
unsigned char input_buffer[READ_BUFFER_SIZE]; unsigned char input_buffer[READ_BUFFER_SIZE];
int32_t output_buffer[MP3_DATA_OUTPUT_BUFFER_SIZE]; int32_t output_buffer[sizeof(mad_pcm::samples) / sizeof(mad_fixed_t)];
SignedSongTime total_time; SignedSongTime total_time;
SongTime elapsed_time; SongTime elapsed_time;
SongTime seek_time; SongTime seek_time;
...@@ -847,30 +846,16 @@ MadDecoder::UpdateTimerNextFrame() noexcept ...@@ -847,30 +846,16 @@ MadDecoder::UpdateTimerNextFrame() noexcept
DecoderCommand DecoderCommand
MadDecoder::SubmitPCM(unsigned i, unsigned pcm_length) noexcept MadDecoder::SubmitPCM(unsigned i, unsigned pcm_length) noexcept
{ {
unsigned max_samples = sizeof(output_buffer) /
sizeof(output_buffer[0]) /
MAD_NCHANNELS(&frame.header);
while (i < pcm_length) {
unsigned int num_samples = pcm_length - i; unsigned int num_samples = pcm_length - i;
if (num_samples > max_samples)
num_samples = max_samples;
i += num_samples;
mad_fixed_to_24_buffer(output_buffer, &synth, mad_fixed_to_24_buffer(output_buffer, &synth,
i - num_samples, i, i, i + num_samples,
MAD_NCHANNELS(&frame.header)); MAD_NCHANNELS(&frame.header));
num_samples *= MAD_NCHANNELS(&frame.header); num_samples *= MAD_NCHANNELS(&frame.header);
auto cmd = client->SubmitData(input_stream, output_buffer, return client->SubmitData(input_stream, output_buffer,
sizeof(output_buffer[0]) * num_samples, sizeof(output_buffer[0]) * num_samples,
frame.header.bitrate / 1000); frame.header.bitrate / 1000);
if (cmd != DecoderCommand::NONE)
return cmd;
}
return DecoderCommand::NONE;
} }
inline DecoderCommand inline DecoderCommand
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment