eliminate OutputBuffer.currentChunk
OutputBuffer.currentChunk contains redundant data: it is either -1 when there is no chunk which is currently being written, or it equals "end". If we always keep chunk[end] in a valid state, we can remove OutputBuffer.currentChunk. This patch may look a bit clumsy, especially flushOutputBuffer(), but that will be fixed later with an major OutputBuffer API overhaul. git-svn-id: https://svn.musicpd.org/mpd/trunk@7339 09075e82-0dd4-0310-85a5-a0d7c8717e4f
This commit is contained in:
parent
3105280f26
commit
f0e78138d1
@ -30,7 +30,7 @@ void initOutputBuffer(OutputBuffer * cb, unsigned int size)
|
|||||||
cb->size = size;
|
cb->size = size;
|
||||||
cb->begin = 0;
|
cb->begin = 0;
|
||||||
cb->end = 0;
|
cb->end = 0;
|
||||||
cb->currentChunk = -1;
|
cb->chunks[0].chunkSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void output_buffer_free(OutputBuffer * cb)
|
void output_buffer_free(OutputBuffer * cb)
|
||||||
@ -42,7 +42,7 @@ void output_buffer_free(OutputBuffer * cb)
|
|||||||
void clearOutputBuffer(OutputBuffer * cb)
|
void clearOutputBuffer(OutputBuffer * cb)
|
||||||
{
|
{
|
||||||
cb->end = cb->begin;
|
cb->end = cb->begin;
|
||||||
cb->currentChunk = -1;
|
cb->chunks[cb->end].chunkSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** return the index of the chunk after i */
|
/** 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);
|
assert(i != cb->end);
|
||||||
|
|
||||||
cb->end = i;
|
cb->end = i;
|
||||||
cb->currentChunk = -1;
|
cb->chunks[i].chunkSize = 0;
|
||||||
if (was_empty)
|
if (was_empty)
|
||||||
/* if the buffer was empty, the player thread might be
|
/* if the buffer was empty, the player thread might be
|
||||||
waiting for us; wake it up now that another decoded
|
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)
|
void flushOutputBuffer(OutputBuffer * cb)
|
||||||
{
|
{
|
||||||
if (cb->currentChunk == (int)cb->end)
|
OutputBufferChunk *chunk = outputBufferGetChunk(cb, cb->end);
|
||||||
output_buffer_expand(cb, successor(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)
|
int outputBufferEmpty(const OutputBuffer * cb)
|
||||||
@ -146,35 +156,47 @@ static int tailChunk(OutputBuffer * cb, InputStream * inStream,
|
|||||||
unsigned int next;
|
unsigned int next;
|
||||||
OutputBufferChunk *chunk;
|
OutputBufferChunk *chunk;
|
||||||
|
|
||||||
if (cb->currentChunk == (int)cb->end)
|
chunk = outputBufferGetChunk(cb, cb->end);
|
||||||
return cb->currentChunk;
|
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 */
|
||||||
|
|
||||||
next = successor(cb, cb->end);
|
if (dc->seek) {
|
||||||
while (cb->begin == next && !dc->stop) {
|
if (seekable) {
|
||||||
if (dc->seek) {
|
return OUTPUT_BUFFER_DC_SEEK;
|
||||||
if (seekable) {
|
} else {
|
||||||
return OUTPUT_BUFFER_DC_SEEK;
|
dc->seekError = 1;
|
||||||
} else {
|
dc->seek = 0;
|
||||||
dc->seekError = 1;
|
decoder_wakeup_player();
|
||||||
dc->seek = 0;
|
}
|
||||||
decoder_wakeup_player();
|
}
|
||||||
|
if (!inStream ||
|
||||||
|
bufferInputStream(inStream) <= 0) {
|
||||||
|
decoder_sleep(dc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!inStream ||
|
|
||||||
bufferInputStream(inStream) <= 0) {
|
if (dc->stop)
|
||||||
decoder_sleep(dc);
|
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;
|
if (chunk->chunkSize == 0) {
|
||||||
chunk = outputBufferGetChunk(cb, cb->currentChunk);
|
/* if the chunk is empty, nobody has set bitRate and
|
||||||
chunk->chunkSize = 0;
|
times yet */
|
||||||
chunk->bitRate = bitRate;
|
|
||||||
chunk->times = data_time;
|
|
||||||
|
|
||||||
return cb->currentChunk;
|
chunk->bitRate = bitRate;
|
||||||
|
chunk->times = data_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cb->end;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sendDataToOutputBuffer(OutputBuffer * cb, InputStream * inStream,
|
int sendDataToOutputBuffer(OutputBuffer * cb, InputStream * inStream,
|
||||||
|
@ -53,8 +53,6 @@ typedef struct _OutputBuffer {
|
|||||||
/** the index after the last decoded chunk */
|
/** the index after the last decoded chunk */
|
||||||
unsigned int volatile end;
|
unsigned int volatile end;
|
||||||
|
|
||||||
int currentChunk;
|
|
||||||
|
|
||||||
AudioFormat audioFormat;
|
AudioFormat audioFormat;
|
||||||
ConvState convState;
|
ConvState convState;
|
||||||
} OutputBuffer;
|
} OutputBuffer;
|
||||||
|
Loading…
Reference in New Issue
Block a user