encoder/null: 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:
		
							
								
								
									
										2
									
								
								NEWS
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								NEWS
									
									
									
									
									
								
							| @@ -2,7 +2,7 @@ ver 0.16.6 (2010/??/??) | |||||||
| * decoder: | * decoder: | ||||||
|   - fix assertion failure when resuming streams |   - fix assertion failure when resuming streams | ||||||
| * encoder: | * encoder: | ||||||
|   - flac, wave: fix buffer corruption bug |   - flac, null, wave: 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 | ||||||
|   | |||||||
| @@ -20,7 +20,8 @@ | |||||||
| #include "config.h" | #include "config.h" | ||||||
| #include "encoder_api.h" | #include "encoder_api.h" | ||||||
| #include "encoder_plugin.h" | #include "encoder_plugin.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> | ||||||
| @@ -28,8 +29,7 @@ | |||||||
| struct null_encoder { | struct null_encoder { | ||||||
| 	struct encoder encoder; | 	struct encoder encoder; | ||||||
|  |  | ||||||
| 	struct pcm_buffer buffer; | 	struct fifo_buffer *buffer; | ||||||
| 	size_t buffer_length; |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| extern const struct encoder_plugin null_encoder_plugin; | extern const struct encoder_plugin null_encoder_plugin; | ||||||
| @@ -65,7 +65,7 @@ null_encoder_close(struct encoder *_encoder) | |||||||
| { | { | ||||||
| 	struct null_encoder *encoder = (struct null_encoder *)_encoder; | 	struct null_encoder *encoder = (struct null_encoder *)_encoder; | ||||||
|  |  | ||||||
| 	pcm_buffer_deinit(&encoder->buffer); | 	fifo_buffer_free(encoder->buffer); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -76,9 +76,7 @@ null_encoder_open(struct encoder *_encoder, | |||||||
| { | { | ||||||
| 	struct null_encoder *encoder = (struct null_encoder *)_encoder; | 	struct null_encoder *encoder = (struct null_encoder *)_encoder; | ||||||
|  |  | ||||||
| 	encoder->buffer_length = 0; | 	encoder->buffer = growing_fifo_new(); | ||||||
| 	pcm_buffer_init(&encoder->buffer); |  | ||||||
|  |  | ||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -88,28 +86,26 @@ null_encoder_write(struct encoder *_encoder, | |||||||
| 		   G_GNUC_UNUSED GError **error) | 		   G_GNUC_UNUSED GError **error) | ||||||
| { | { | ||||||
| 	struct null_encoder *encoder = (struct null_encoder *)_encoder; | 	struct null_encoder *encoder = (struct null_encoder *)_encoder; | ||||||
| 	char *buffer = pcm_buffer_get(&encoder->buffer, encoder->buffer_length + length); |  | ||||||
|  |  | ||||||
| 	memcpy(buffer+encoder->buffer_length, data, length); | 	growing_fifo_append(&encoder->buffer, data, length); | ||||||
|  | 	return length; | ||||||
| 	encoder->buffer_length += length; |  | ||||||
| 	return true; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| static size_t | static size_t | ||||||
| null_encoder_read(struct encoder *_encoder, void *dest, size_t length) | null_encoder_read(struct encoder *_encoder, void *dest, size_t length) | ||||||
| { | { | ||||||
| 	struct null_encoder *encoder = (struct null_encoder *)_encoder; | 	struct null_encoder *encoder = (struct null_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 void *src = fifo_buffer_read(encoder->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->buffer, length); | ||||||
| 	return length; | 	return length; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Max Kellermann
					Max Kellermann