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:
		| @@ -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; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Max Kellermann
					Max Kellermann