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.
This commit is contained in:
parent
790823abb4
commit
cee5036aca
@ -994,6 +994,7 @@ test_run_encoder_SOURCES = test/run_encoder.c \
|
|||||||
src/audio_format.c \
|
src/audio_format.c \
|
||||||
src/audio_parser.c \
|
src/audio_parser.c \
|
||||||
src/pcm_buffer.c \
|
src/pcm_buffer.c \
|
||||||
|
src/fifo_buffer.c src/growing_fifo.c \
|
||||||
$(ENCODER_SRC)
|
$(ENCODER_SRC)
|
||||||
test_run_encoder_CPPFLAGS = $(AM_CPPFLAGS) \
|
test_run_encoder_CPPFLAGS = $(AM_CPPFLAGS) \
|
||||||
$(ENCODER_CFLAGS)
|
$(ENCODER_CFLAGS)
|
||||||
@ -1057,7 +1058,7 @@ test_run_output_SOURCES = test/run_output.c \
|
|||||||
src/audio_parser.c \
|
src/audio_parser.c \
|
||||||
src/timer.c \
|
src/timer.c \
|
||||||
src/tag.c src/tag_pool.c \
|
src/tag.c src/tag_pool.c \
|
||||||
src/fifo_buffer.c \
|
src/fifo_buffer.c src/growing_fifo.c \
|
||||||
src/page.c \
|
src/page.c \
|
||||||
src/socket_util.c \
|
src/socket_util.c \
|
||||||
src/output_init.c src/output_list.c \
|
src/output_init.c src/output_list.c \
|
||||||
|
2
NEWS
2
NEWS
@ -1,6 +1,8 @@
|
|||||||
ver 0.16.6 (2010/??/??)
|
ver 0.16.6 (2010/??/??)
|
||||||
* decoder:
|
* decoder:
|
||||||
- fix assertion failure when resuming streams
|
- fix assertion failure when resuming streams
|
||||||
|
* encoder:
|
||||||
|
- flac: fix buffer corruption bug
|
||||||
* event_pipe: fix WIN32 regression
|
* event_pipe: fix WIN32 regression
|
||||||
* define WINVER in ./configure
|
* define WINVER in ./configure
|
||||||
* WIN32: autodetect filesystem encoding
|
* WIN32: autodetect filesystem encoding
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
#include "encoder_plugin.h"
|
#include "encoder_plugin.h"
|
||||||
#include "audio_format.h"
|
#include "audio_format.h"
|
||||||
#include "pcm_buffer.h"
|
#include "pcm_buffer.h"
|
||||||
|
#include "fifo_buffer.h"
|
||||||
|
#include "growing_fifo.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -38,8 +40,11 @@ struct flac_encoder {
|
|||||||
|
|
||||||
struct pcm_buffer expand_buffer;
|
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;
|
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;
|
struct flac_encoder *encoder = (struct flac_encoder *) client_data;
|
||||||
|
|
||||||
char *buffer = pcm_buffer_get(&encoder->buffer, encoder->buffer_length + bytes);
|
|
||||||
|
|
||||||
//transfer data to buffer
|
//transfer data to buffer
|
||||||
memcpy( buffer + encoder->buffer_length, data, bytes);
|
growing_fifo_append(&encoder->output_buffer, data, bytes);
|
||||||
encoder->buffer_length += bytes;
|
|
||||||
|
|
||||||
return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
|
return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
|
||||||
}
|
}
|
||||||
@ -156,8 +158,8 @@ flac_encoder_close(struct encoder *_encoder)
|
|||||||
|
|
||||||
FLAC__stream_encoder_delete(encoder->fse);
|
FLAC__stream_encoder_delete(encoder->fse);
|
||||||
|
|
||||||
pcm_buffer_deinit(&encoder->buffer);
|
|
||||||
pcm_buffer_deinit(&encoder->expand_buffer);
|
pcm_buffer_deinit(&encoder->expand_buffer);
|
||||||
|
fifo_buffer_free(encoder->output_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
@ -201,10 +203,10 @@ flac_encoder_open(struct encoder *_encoder, struct audio_format *audio_format,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
encoder->buffer_length = 0;
|
|
||||||
pcm_buffer_init(&encoder->buffer);
|
|
||||||
pcm_buffer_init(&encoder->expand_buffer);
|
pcm_buffer_init(&encoder->expand_buffer);
|
||||||
|
|
||||||
|
encoder->output_buffer = growing_fifo_new();
|
||||||
|
|
||||||
/* this immediatelly outputs data throught callback */
|
/* this immediatelly outputs data throught callback */
|
||||||
|
|
||||||
#if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7
|
#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)
|
flac_encoder_read(struct encoder *_encoder, void *dest, size_t length)
|
||||||
{
|
{
|
||||||
struct flac_encoder *encoder = (struct flac_encoder *)_encoder;
|
struct flac_encoder *encoder = (struct flac_encoder *)_encoder;
|
||||||
char *buffer = pcm_buffer_get(&encoder->buffer, encoder->buffer_length);
|
|
||||||
|
|
||||||
if (length > encoder->buffer_length)
|
size_t max_length;
|
||||||
length = encoder->buffer_length;
|
const char *src = fifo_buffer_read(encoder->output_buffer,
|
||||||
|
&max_length);
|
||||||
|
if (src == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
memcpy(dest, buffer, length);
|
if (length > max_length)
|
||||||
|
length = max_length;
|
||||||
encoder->buffer_length -= length;
|
|
||||||
memmove(buffer, buffer + length, encoder->buffer_length);
|
|
||||||
|
|
||||||
|
memcpy(dest, src, length);
|
||||||
|
fifo_buffer_consume(encoder->output_buffer, length);
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user