Commit fd948571 authored by Max Kellermann's avatar Max Kellermann

music_pipe: added functions music_pipe_write() and music_pipe_expand()

This new API gives the caller a writable buffer to the music pipe chunk. This may allow the caller to eliminate several buffer copies, because it may manipulate the returned buffer, until it calls music_pipe_expand().
parent d83eff80
...@@ -207,25 +207,49 @@ tail_chunk(size_t frame_size) ...@@ -207,25 +207,49 @@ tail_chunk(size_t frame_size)
return chunk; return chunk;
} }
static size_t void *
music_chunk_append(struct music_chunk *chunk, const void *data, size_t length, music_pipe_write(const struct audio_format *audio_format,
size_t frame_size) float data_time, uint16_t bit_rate,
size_t *max_length_r)
{ {
size_t rest = sizeof(chunk->data) - chunk->length; const size_t frame_size = audio_format_frame_size(audio_format);
struct music_chunk *chunk;
size_t num_frames;
chunk = tail_chunk(frame_size);
if (chunk == NULL)
return NULL;
assert(rest >= frame_size); if (chunk->length == 0) {
/* if the chunk is empty, nobody has set bitRate and
times yet */
if (length > rest) chunk->bit_rate = bit_rate;
length = rest; chunk->times = data_time;
}
/* don't split frames */ num_frames = (sizeof(chunk->data) - chunk->length) / frame_size;
length /= frame_size; *max_length_r = num_frames * frame_size;
length *= frame_size; return chunk->data + chunk->length;
}
void
music_pipe_expand(const struct audio_format *audio_format, size_t length)
{
const size_t frame_size = audio_format_frame_size(audio_format);
struct music_chunk *chunk;
/* no partial frames allowed */
assert(length % frame_size == 0);
chunk = tail_chunk(frame_size);
assert(chunk != NULL);
assert(chunk->length + length <= sizeof(chunk->data));
memcpy(chunk->data + chunk->length, data, length);
chunk->length += length; chunk->length += length;
return length; if (chunk->length + frame_size > sizeof(chunk->data))
music_pipe_flush();
} }
size_t music_pipe_append(const void *data0, size_t datalen, size_t music_pipe_append(const void *data0, size_t datalen,
...@@ -233,38 +257,28 @@ size_t music_pipe_append(const void *data0, size_t datalen, ...@@ -233,38 +257,28 @@ size_t music_pipe_append(const void *data0, size_t datalen,
float data_time, uint16_t bit_rate) float data_time, uint16_t bit_rate)
{ {
const unsigned char *data = data0; const unsigned char *data = data0;
const size_t frame_size = audio_format_frame_size(audio_format);
size_t ret = 0, nbytes; size_t ret = 0, nbytes;
struct music_chunk *chunk = NULL; void *dest;
/* no partial frames allowed */
assert((datalen % frame_size) == 0);
while (datalen) { while (datalen) {
chunk = tail_chunk(frame_size); dest = music_pipe_write(audio_format, data_time, bit_rate,
if (chunk == NULL) &nbytes);
return ret; if (dest == NULL)
break;
if (chunk->length == 0) { assert(nbytes > 0);
/* if the chunk is empty, nobody has set bitRate and
times yet */
chunk->bit_rate = bit_rate; if (nbytes > datalen)
chunk->times = data_time; nbytes = datalen;
}
nbytes = music_chunk_append(chunk, data, datalen, memcpy(dest, data, nbytes);
frame_size); music_pipe_expand(audio_format, nbytes);
assert(nbytes > 0);
datalen -= nbytes; datalen -= nbytes;
data += nbytes; data += nbytes;
ret += nbytes; ret += nbytes;
} }
if (chunk != NULL && chunk->length == sizeof(chunk->data))
music_pipe_flush();
return ret; return ret;
} }
......
...@@ -148,6 +148,24 @@ music_pipe_peek(void) ...@@ -148,6 +148,24 @@ music_pipe_peek(void)
} }
/** /**
* Prepares appending to the music pipe. Returns a buffer where you
* may write into. After you are finished, call music_pipe_expand().
*
* @return a writable buffer
*/
void *
music_pipe_write(const struct audio_format *audio_format,
float data_time, uint16_t bit_rate,
size_t *max_length_r);
/**
* Tells the music pipe to move the end pointer, after you have
* written to the buffer returned by music_pipe_write().
*/
void
music_pipe_expand(const struct audio_format *audio_format, size_t length);
/**
* Append a data block to the buffer. * Append a data block to the buffer.
* *
* @return the number of bytes actually written * @return the number of bytes actually written
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment