aboutsummaryrefslogtreecommitdiffstats
path: root/src/encoder/wave_encoder.c
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2011-11-28 08:09:49 +0100
committerMax Kellermann <max@duempel.org>2011-11-28 09:23:12 +0100
commit399a3abefc00f913945189fdb3a646759f082054 (patch)
tree4070253bd7bbc0628fe591ee2f6237c3675f0d04 /src/encoder/wave_encoder.c
parentcee5036aca85f37a28f2d52a2fc5ad19878ad511 (diff)
downloadmpd-399a3abefc00f913945189fdb3a646759f082054.tar.gz
mpd-399a3abefc00f913945189fdb3a646759f082054.tar.xz
mpd-399a3abefc00f913945189fdb3a646759f082054.zip
encoder/wave: 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.
Diffstat (limited to '')
-rw-r--r--src/encoder/wave_encoder.c46
1 files changed, 27 insertions, 19 deletions
diff --git a/src/encoder/wave_encoder.c b/src/encoder/wave_encoder.c
index 938be5e5e..4e830bd14 100644
--- a/src/encoder/wave_encoder.c
+++ b/src/encoder/wave_encoder.c
@@ -20,7 +20,8 @@
#include "config.h"
#include "encoder_api.h"
#include "encoder_plugin.h"
-#include "pcm_buffer.h"
+#include "fifo_buffer.h"
+#include "growing_fifo.h"
#include <assert.h>
#include <string.h>
@@ -29,8 +30,7 @@ struct wave_encoder {
struct encoder encoder;
unsigned bits;
- struct pcm_buffer buffer;
- size_t buffer_length;
+ struct fifo_buffer *buffer;
};
struct wave_header {
@@ -92,7 +92,6 @@ wave_encoder_init(G_GNUC_UNUSED const struct config_param *param,
encoder = g_new(struct wave_encoder, 1);
encoder_struct_init(&encoder->encoder, &wave_encoder_plugin);
- pcm_buffer_init(&encoder->buffer);
return &encoder->encoder;
}
@@ -102,7 +101,6 @@ wave_encoder_finish(struct encoder *_encoder)
{
struct wave_encoder *encoder = (struct wave_encoder *)_encoder;
- pcm_buffer_deinit(&encoder->buffer);
g_free(encoder);
}
@@ -112,7 +110,6 @@ wave_encoder_open(struct encoder *_encoder,
G_GNUC_UNUSED GError **error)
{
struct wave_encoder *encoder = (struct wave_encoder *)_encoder;
- void *buffer;
assert(audio_format_valid(audio_format));
@@ -139,19 +136,29 @@ wave_encoder_open(struct encoder *_encoder,
break;
}
- buffer = pcm_buffer_get(&encoder->buffer, sizeof(struct wave_header) );
+ encoder->buffer = growing_fifo_new();
+ struct wave_header *header =
+ growing_fifo_write(&encoder->buffer, sizeof(*header));
/* create PCM wave header in initial buffer */
- fill_wave_header((struct wave_header *) buffer,
+ fill_wave_header(header,
audio_format->channels,
encoder->bits,
audio_format->sample_rate,
(encoder->bits / 8) * audio_format->channels );
+ fifo_buffer_append(encoder->buffer, sizeof(*header));
- encoder->buffer_length = sizeof(struct wave_header);
return true;
}
+static void
+wave_encoder_close(struct encoder *_encoder)
+{
+ struct wave_encoder *encoder = (struct wave_encoder *)_encoder;
+
+ fifo_buffer_free(encoder->buffer);
+}
+
static inline size_t
pcm16_to_wave(uint16_t *dst16, const uint16_t *src16, size_t length)
{
@@ -198,9 +205,8 @@ wave_encoder_write(struct encoder *_encoder,
G_GNUC_UNUSED GError **error)
{
struct wave_encoder *encoder = (struct wave_encoder *)_encoder;
- void *dst;
- dst = pcm_buffer_get(&encoder->buffer, encoder->buffer_length + length);
+ void *dst = growing_fifo_write(&encoder->buffer, length);
#if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
switch (encoder->bits) {
@@ -232,7 +238,7 @@ wave_encoder_write(struct encoder *_encoder,
#error G_BYTE_ORDER set to G_PDP_ENDIAN is not supported by wave_encoder
#endif
- encoder->buffer_length += length;
+ fifo_buffer_append(encoder->buffer, length);
return true;
}
@@ -240,16 +246,17 @@ static size_t
wave_encoder_read(struct encoder *_encoder, void *dest, size_t length)
{
struct wave_encoder *encoder = (struct wave_encoder *)_encoder;
- uint8_t *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 void *src = fifo_buffer_read(encoder->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->buffer, length);
return length;
}
@@ -264,6 +271,7 @@ const struct encoder_plugin wave_encoder_plugin = {
.init = wave_encoder_init,
.finish = wave_encoder_finish,
.open = wave_encoder_open,
+ .close = wave_encoder_close,
.write = wave_encoder_write,
.read = wave_encoder_read,
.get_mime_type = wave_encoder_get_mime_type,