summaryrefslogtreecommitdiff
path: root/src/pipe.c
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2009-03-06 00:42:01 +0100
committerMax Kellermann <max@duempel.org>2009-03-06 00:42:01 +0100
commit000b2d4f3a9c4f761ab918aaff4705621bb8559f (patch)
tree5009a5548c99155e00b4b14d52f50728a337960f /src/pipe.c
parent10be8a8714b49bec5e6f869975962cbc26cebe61 (diff)
music_pipe: added music_pipe_push()
Added music_pipe_allocate(), music_pipe_push() and music_pipe_cancel(). Those functions allow the caller (decoder thread in this case) to do its own chunk management. The functions music_pipe_flush() and music_pipe_tag() can now be removed.
Diffstat (limited to 'src/pipe.c')
-rw-r--r--src/pipe.c104
1 files changed, 18 insertions, 86 deletions
diff --git a/src/pipe.c b/src/pipe.c
index 5aa931bd9..6f6fd816a 100644
--- a/src/pipe.c
+++ b/src/pipe.c
@@ -94,22 +94,6 @@ static void output_buffer_expand(unsigned i)
notify_signal(music_pipe.notify);
}
-void music_pipe_flush(void)
-{
- struct music_chunk *chunk = music_pipe_get_chunk(music_pipe.end);
-
- if (chunk->length > 0) {
- unsigned int next = successor(music_pipe.end);
- if (next == music_pipe.begin)
- /* all buffers are full; we have to wait for
- the player to free one, so don't flush
- right now */
- return;
-
- output_buffer_expand(next);
- }
-}
-
void music_pipe_set_lazy(bool lazy)
{
music_pipe.lazy = lazy;
@@ -163,92 +147,40 @@ music_pipe_get_chunk(const unsigned i)
return &music_pipe.chunks[i];
}
-/**
- * Return the tail chunk which has room for additional data.
- *
- * @return the chunk which has room for more data; NULL if there is no
- * room.
- */
-static struct music_chunk *
-tail_chunk(size_t frame_size)
+struct music_chunk *
+music_pipe_allocate(void)
{
- unsigned int next;
struct music_chunk *chunk;
+ /* the music_pipe.end chunk is always kept initialized */
chunk = music_pipe_get_chunk(music_pipe.end);
- assert(chunk->length <= sizeof(chunk->data));
- assert((chunk->length % frame_size) == 0);
-
- if (chunk->length + frame_size > sizeof(chunk->data)) {
- /* this chunk is full; allocate a new chunk */
- next = successor(music_pipe.end);
- if (music_pipe.begin == next)
- /* no chunks available */
- return NULL;
-
- output_buffer_expand(next);
- chunk = music_pipe_get_chunk(next);
- assert(chunk->length == 0);
- }
+ assert(chunk->length == 0);
return chunk;
}
-void *
-music_pipe_write(const struct audio_format *audio_format,
- float data_time, uint16_t bit_rate,
- size_t *max_length_r)
-{
- const size_t frame_size = audio_format_frame_size(audio_format);
- struct music_chunk *chunk;
-
- chunk = tail_chunk(frame_size);
- if (chunk == NULL)
- return NULL;
-
- return music_chunk_write(chunk, audio_format, data_time, bit_rate,
- max_length_r);
-}
-
-void
-music_pipe_expand(const struct audio_format *audio_format, size_t length)
+bool
+music_pipe_push(struct music_chunk *chunk)
{
- const size_t frame_size = audio_format_frame_size(audio_format);
- struct music_chunk *chunk;
- bool full;
+ unsigned int next;
- /* no partial frames allowed */
- assert(length % frame_size == 0);
+ assert(chunk == music_pipe_get_chunk(music_pipe.end));
- chunk = tail_chunk(frame_size);
- assert(chunk != NULL);
+ next = successor(music_pipe.end);
+ if (music_pipe.begin == next)
+ /* no room */
+ return false;
- full = music_chunk_expand(chunk, audio_format, length);
- if (full)
- music_pipe_flush();
+ output_buffer_expand(next);
+ return true;
}
-bool music_pipe_tag(const struct tag *tag)
+void
+music_pipe_cancel(struct music_chunk *chunk)
{
- struct music_chunk *chunk;
+ assert(chunk == music_pipe_get_chunk(music_pipe.end));
- chunk = music_pipe_get_chunk(music_pipe.end);
- if (chunk->length > 0 || chunk->tag != NULL) {
- /* this chunk is not empty; allocate a new chunk,
- because chunk.tag refers to the beginning of the
- chunk data */
- unsigned next = successor(music_pipe.end);
- if (music_pipe.begin == next)
- /* no chunks available */
- return false;
-
- output_buffer_expand(next);
- chunk = music_pipe_get_chunk(next);
- assert(chunk->length == 0 && chunk->tag == NULL);
- }
-
- chunk->tag = tag_dup(tag);
- return true;
+ music_chunk_free(chunk);
}
void music_pipe_skip(unsigned num)