diff options
author | Max Kellermann <max@duempel.org> | 2011-11-28 08:00:10 +0100 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2011-11-28 09:21:32 +0100 |
commit | cee5036aca85f37a28f2d52a2fc5ad19878ad511 (patch) | |
tree | 72e1498b0d2f41b8bbba8b5980ce818d224e2038 | |
parent | 790823abb4671e6d94c8cb491f29e6448f2b1f85 (diff) | |
download | mpd-cee5036aca85f37a28f2d52a2fc5ad19878ad511.tar.gz mpd-cee5036aca85f37a28f2d52a2fc5ad19878ad511.tar.xz mpd-cee5036aca85f37a28f2d52a2fc5ad19878ad511.zip |
encoder/flac: use fifo_buffer instead of pcm_buffer
This fixes a buffer corruption bug; pcm_buffer is not designed to be a
persistent buffers, and will discard anything between two consecutive
calls.
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | src/encoder/flac_encoder.c | 36 |
3 files changed, 24 insertions, 17 deletions
diff --git a/Makefile.am b/Makefile.am index 7478ffcc2..6401e3a48 100644 --- a/Makefile.am +++ b/Makefile.am @@ -994,6 +994,7 @@ test_run_encoder_SOURCES = test/run_encoder.c \ src/audio_format.c \ src/audio_parser.c \ src/pcm_buffer.c \ + src/fifo_buffer.c src/growing_fifo.c \ $(ENCODER_SRC) test_run_encoder_CPPFLAGS = $(AM_CPPFLAGS) \ $(ENCODER_CFLAGS) @@ -1057,7 +1058,7 @@ test_run_output_SOURCES = test/run_output.c \ src/audio_parser.c \ src/timer.c \ src/tag.c src/tag_pool.c \ - src/fifo_buffer.c \ + src/fifo_buffer.c src/growing_fifo.c \ src/page.c \ src/socket_util.c \ src/output_init.c src/output_list.c \ @@ -1,6 +1,8 @@ ver 0.16.6 (2010/??/??) * decoder: - fix assertion failure when resuming streams +* encoder: + - flac: fix buffer corruption bug * event_pipe: fix WIN32 regression * define WINVER in ./configure * WIN32: autodetect filesystem encoding diff --git a/src/encoder/flac_encoder.c b/src/encoder/flac_encoder.c index c34faad00..6389513ef 100644 --- a/src/encoder/flac_encoder.c +++ b/src/encoder/flac_encoder.c @@ -22,6 +22,8 @@ #include "encoder_plugin.h" #include "audio_format.h" #include "pcm_buffer.h" +#include "fifo_buffer.h" +#include "growing_fifo.h" #include <assert.h> #include <string.h> @@ -38,8 +40,11 @@ struct flac_encoder { struct pcm_buffer expand_buffer; - struct pcm_buffer buffer; - size_t buffer_length; + /** + * This buffer will hold encoded data from libFLAC until it is + * picked up with flac_encoder_read(). + */ + struct fifo_buffer *output_buffer; }; extern const struct encoder_plugin flac_encoder_plugin; @@ -140,11 +145,8 @@ flac_write_callback(G_GNUC_UNUSED const FLAC__StreamEncoder *fse, { struct flac_encoder *encoder = (struct flac_encoder *) client_data; - char *buffer = pcm_buffer_get(&encoder->buffer, encoder->buffer_length + bytes); - //transfer data to buffer - memcpy( buffer + encoder->buffer_length, data, bytes); - encoder->buffer_length += bytes; + growing_fifo_append(&encoder->output_buffer, data, bytes); return FLAC__STREAM_ENCODER_WRITE_STATUS_OK; } @@ -156,8 +158,8 @@ flac_encoder_close(struct encoder *_encoder) FLAC__stream_encoder_delete(encoder->fse); - pcm_buffer_deinit(&encoder->buffer); pcm_buffer_deinit(&encoder->expand_buffer); + fifo_buffer_free(encoder->output_buffer); } static bool @@ -201,10 +203,10 @@ flac_encoder_open(struct encoder *_encoder, struct audio_format *audio_format, return false; } - encoder->buffer_length = 0; - pcm_buffer_init(&encoder->buffer); pcm_buffer_init(&encoder->expand_buffer); + encoder->output_buffer = growing_fifo_new(); + /* this immediatelly outputs data throught callback */ #if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7 @@ -325,16 +327,18 @@ static size_t flac_encoder_read(struct encoder *_encoder, void *dest, size_t length) { struct flac_encoder *encoder = (struct flac_encoder *)_encoder; - char *buffer = pcm_buffer_get(&encoder->buffer, encoder->buffer_length); - - if (length > encoder->buffer_length) - length = encoder->buffer_length; - memcpy(dest, buffer, length); + size_t max_length; + const char *src = fifo_buffer_read(encoder->output_buffer, + &max_length); + if (src == NULL) + return 0; - encoder->buffer_length -= length; - memmove(buffer, buffer + length, encoder->buffer_length); + if (length > max_length) + length = max_length; + memcpy(dest, src, length); + fifo_buffer_consume(encoder->output_buffer, length); return length; } |