decoder/mad: pad the input buffer with zero bytes and end of file

libmad requires padding the input buffer with "MAD_BUFFER_GUARD" zero
bytes at the end of the file, or else it is unable to decode the last
frame.

This fixes yet another bug which prevented this plugin from decoding
the last frame, see
https://github.com/MusicPlayerDaemon/MPD/issues/601
This commit is contained in:
Max Kellermann 2019-08-02 22:18:45 +02:00
parent 9b99a9897a
commit 3e3d8c7f9d

View File

@ -132,6 +132,14 @@ class MadDecoder {
bool found_replay_gain = false;
bool found_first_frame = false;
bool decoded_first_frame = false;
/**
* If this flag is true, then end-of-file was seen and a
* padding of 8 zero bytes were appended to #input_buffer, to
* allow libmad to decode the last frame.
*/
bool was_eof = false;
DecoderClient *const client;
InputStream &input_stream;
enum mad_layer layer = mad_layer(0);
@ -247,7 +255,12 @@ MadDecoder::FillBuffer() noexcept
size_t nbytes = decoder_read(client, input_stream,
dest, max_read_size);
if (nbytes == 0) {
return false;
if (was_eof || max_read_size < MAD_BUFFER_GUARD)
return false;
was_eof = true;
nbytes = MAD_BUFFER_GUARD;
memset(dest, 0, nbytes);
}
mad_stream_buffer(&stream, input_buffer, rest_size + nbytes);
@ -922,6 +935,7 @@ MadDecoder::Read() noexcept
if (j < highest_frame) {
if (Seek(frame_offsets[j])) {
current_frame = j;
was_eof = false;
client->CommandFinished();
} else
client->SeekError();