aboutsummaryrefslogtreecommitdiffstats
path: root/src/outputBuffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/outputBuffer.c')
-rw-r--r--src/outputBuffer.c80
1 files changed, 51 insertions, 29 deletions
diff --git a/src/outputBuffer.c b/src/outputBuffer.c
index cf4be8f1b..d8c4e816a 100644
--- a/src/outputBuffer.c
+++ b/src/outputBuffer.c
@@ -30,7 +30,7 @@ void initOutputBuffer(OutputBuffer * cb, unsigned int size)
cb->size = size;
cb->begin = 0;
cb->end = 0;
- cb->currentChunk = -1;
+ cb->chunks[0].chunkSize = 0;
}
void output_buffer_free(OutputBuffer * cb)
@@ -42,7 +42,7 @@ void output_buffer_free(OutputBuffer * cb)
void clearOutputBuffer(OutputBuffer * cb)
{
cb->end = cb->begin;
- cb->currentChunk = -1;
+ cb->chunks[cb->end].chunkSize = 0;
}
/** return the index of the chunk after i */
@@ -66,7 +66,7 @@ static void output_buffer_expand(OutputBuffer * cb, unsigned i)
assert(i != cb->end);
cb->end = i;
- cb->currentChunk = -1;
+ cb->chunks[i].chunkSize = 0;
if (was_empty)
/* if the buffer was empty, the player thread might be
waiting for us; wake it up now that another decoded
@@ -76,8 +76,18 @@ static void output_buffer_expand(OutputBuffer * cb, unsigned i)
void flushOutputBuffer(OutputBuffer * cb)
{
- if (cb->currentChunk == (int)cb->end)
- output_buffer_expand(cb, successor(cb, cb->end));
+ OutputBufferChunk *chunk = outputBufferGetChunk(cb, cb->end);
+
+ if (chunk->chunkSize > 0) {
+ unsigned int next = successor(cb, cb->end);
+ if (next == cb->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(cb, next);
+ }
}
int outputBufferEmpty(const OutputBuffer * cb)
@@ -146,35 +156,47 @@ static int tailChunk(OutputBuffer * cb, InputStream * inStream,
unsigned int next;
OutputBufferChunk *chunk;
- if (cb->currentChunk == (int)cb->end)
- return cb->currentChunk;
-
- next = successor(cb, cb->end);
- while (cb->begin == next && !dc->stop) {
- if (dc->seek) {
- if (seekable) {
- return OUTPUT_BUFFER_DC_SEEK;
- } else {
- dc->seekError = 1;
- dc->seek = 0;
- decoder_wakeup_player();
+ chunk = outputBufferGetChunk(cb, cb->end);
+ assert(chunk->chunkSize <= sizeof(chunk->data));
+ if (chunk->chunkSize == sizeof(chunk->data)) {
+ /* this chunk is full; allocate a new chunk */
+ next = successor(cb, cb->end);
+ while (cb->begin == next && !dc->stop) {
+ /* all chunks are full of decoded data; wait
+ for the player to free one */
+
+ if (dc->seek) {
+ if (seekable) {
+ return OUTPUT_BUFFER_DC_SEEK;
+ } else {
+ dc->seekError = 1;
+ dc->seek = 0;
+ decoder_wakeup_player();
+ }
+ }
+ if (!inStream ||
+ bufferInputStream(inStream) <= 0) {
+ decoder_sleep(dc);
}
}
- if (!inStream ||
- bufferInputStream(inStream) <= 0) {
- decoder_sleep(dc);
- }
+
+ if (dc->stop)
+ return OUTPUT_BUFFER_DC_STOP;
+
+ output_buffer_expand(cb, next);
+ chunk = outputBufferGetChunk(cb, next);
+ assert(chunk->chunkSize == 0);
}
- if (dc->stop)
- return OUTPUT_BUFFER_DC_STOP;
- cb->currentChunk = cb->end;
- chunk = outputBufferGetChunk(cb, cb->currentChunk);
- chunk->chunkSize = 0;
- chunk->bitRate = bitRate;
- chunk->times = data_time;
+ if (chunk->chunkSize == 0) {
+ /* if the chunk is empty, nobody has set bitRate and
+ times yet */
+
+ chunk->bitRate = bitRate;
+ chunk->times = data_time;
+ }
- return cb->currentChunk;
+ return cb->end;
}
int sendDataToOutputBuffer(OutputBuffer * cb, InputStream * inStream,