aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/outputBuffer.c91
1 files changed, 58 insertions, 33 deletions
diff --git a/src/outputBuffer.c b/src/outputBuffer.c
index 04641faa3..d15a947e3 100644
--- a/src/outputBuffer.c
+++ b/src/outputBuffer.c
@@ -57,6 +57,54 @@ void flushOutputBuffer(OutputBuffer * cb)
}
}
+/**
+ * Return the tail chunk has room for additional data. If there is no
+ * room in the queue, this function blocks until the player thread has
+ * finished playing its current chunk.
+ *
+ * @return the positive index of the new chunk; OUTPUT_BUFFER_DC_SEEK
+ * if another thread requested seeking; OUTPUT_BUFFER_DC_STOP if
+ * another thread requested stopping the decoder.
+ */
+static int tailChunk(OutputBuffer * cb, InputStream * inStream,
+ DecoderControl * dc, int seekable,
+ float data_time, mpd_uint16 bitRate)
+{
+ unsigned int next;
+
+ if (currentChunk == cb->end)
+ return currentChunk;
+
+ next = cb->end + 1;
+ if (next >= buffered_chunks) {
+ next = 0;
+ }
+ 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();
+ }
+ }
+ if (!inStream ||
+ bufferInputStream(inStream) <= 0) {
+ decoder_sleep();
+ }
+ }
+ if (dc->stop)
+ return OUTPUT_BUFFER_DC_STOP;
+
+ currentChunk = cb->end;
+ cb->chunkSize[currentChunk] = 0;
+ cb->bitRate[currentChunk] = bitRate;
+ cb->times[currentChunk] = data_time;
+
+ return currentChunk;
+}
+
int sendDataToOutputBuffer(OutputBuffer * cb, InputStream * inStream,
DecoderControl * dc, int seekable, void *dataIn,
size_t dataInLen, float data_time, mpd_uint16 bitRate,
@@ -93,45 +141,22 @@ int sendDataToOutputBuffer(OutputBuffer * cb, InputStream * inStream,
normalizeData(data, datalen, &cb->audioFormat);
while (datalen) {
- if (currentChunk != cb->end) {
- unsigned int next = cb->end + 1;
- if (next >= buffered_chunks) {
- next = 0;
- }
- 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();
- }
- }
- if (!inStream ||
- bufferInputStream(inStream) <= 0) {
- decoder_sleep();
- }
- }
- if (dc->stop)
- return OUTPUT_BUFFER_DC_STOP;
-
- currentChunk = cb->end;
- cb->chunkSize[currentChunk] = 0;
- cb->bitRate[currentChunk] = bitRate;
- cb->times[currentChunk] = data_time;
- }
+ int chunk_index = tailChunk(cb, inStream,
+ dc, seekable,
+ data_time, bitRate);
+ if (chunk_index < 0)
+ return chunk_index;
- chunkLeft = CHUNK_SIZE - cb->chunkSize[currentChunk];
+ chunkLeft = CHUNK_SIZE - cb->chunkSize[chunk_index];
dataToSend = datalen > chunkLeft ? chunkLeft : datalen;
- memcpy(cb->chunks + currentChunk * CHUNK_SIZE +
- cb->chunkSize[currentChunk], data, dataToSend);
- cb->chunkSize[currentChunk] += dataToSend;
+ memcpy(cb->chunks + chunk_index * CHUNK_SIZE +
+ cb->chunkSize[chunk_index], data, dataToSend);
+ cb->chunkSize[chunk_index] += dataToSend;
datalen -= dataToSend;
data += dataToSend;
- if (cb->chunkSize[currentChunk] == CHUNK_SIZE) {
+ if (cb->chunkSize[chunk_index] == CHUNK_SIZE) {
flushOutputBuffer(cb);
}
}