merged start, stop, seek into DecoderControl.command

Much of the existing code queries all three variables sequentially.
Since only one of them can be set at a time, this can be optimized and
unified by merging all of them into one enum variable.  Later, the
"command" checks can be expressed in a "switch" statement.
This commit is contained in:
Max Kellermann 2008-08-26 08:27:04 +02:00
parent 180d78a8e6
commit 8d3942e0c3
15 changed files with 139 additions and 108 deletions

View File

@ -56,19 +56,30 @@ static void player_wakeup_decoder(void)
player_sleep(); player_sleep();
} }
static void dc_command_wait(void)
{
while (dc.command != DECODE_COMMAND_NONE)
player_wakeup_decoder_nb();
}
static void dc_command(enum decoder_command cmd)
{
dc.command = cmd;
dc_command_wait();
}
static void stopDecode(void) static void stopDecode(void)
{ {
if (dc.start || dc.state != DECODE_STATE_STOP) { if (dc.command == DECODE_COMMAND_START ||
dc.stop = 1; dc.state != DECODE_STATE_STOP)
do { player_wakeup_decoder_nb(); } while (dc.stop); dc_command(DECODE_COMMAND_STOP);
}
} }
static void quitDecode(void) static void quitDecode(void)
{ {
stopDecode(); stopDecode();
pc.state = PLAYER_STATE_STOP; pc.state = PLAYER_STATE_STOP;
dc.seek = 0; dc.command = DECODE_COMMAND_NONE;
pc.play = 0; pc.play = 0;
pc.stop = 0; pc.stop = 0;
pc.pause = 0; pc.pause = 0;
@ -101,7 +112,7 @@ static unsigned calculateCrossFadeChunks(AudioFormat * af, float totalTime)
static int waitOnDecode(int *decodeWaitedOn) static int waitOnDecode(int *decodeWaitedOn)
{ {
while (dc.start) while (dc.command == DECODE_COMMAND_START)
player_wakeup_decoder(); player_wakeup_decoder();
if (dc.error != DECODE_ERROR_NOERROR) { if (dc.error != DECODE_ERROR_NOERROR) {
@ -133,7 +144,7 @@ static int decodeSeek(int *decodeWaitedOn, int *next)
ob_clear(); ob_clear();
dc.next_song = pc.next_song; dc.next_song = pc.next_song;
dc.error = DECODE_ERROR_NOERROR; dc.error = DECODE_ERROR_NOERROR;
dc.start = 1; dc.command = DECODE_COMMAND_START;
waitOnDecode(decodeWaitedOn); waitOnDecode(decodeWaitedOn);
} }
if (dc.state != DECODE_STATE_STOP && dc.seekable) { if (dc.state != DECODE_STATE_STOP && dc.seekable) {
@ -142,8 +153,7 @@ static int decodeSeek(int *decodeWaitedOn, int *next)
pc.totalTime - 0.1 : pc.seekWhere; pc.totalTime - 0.1 : pc.seekWhere;
dc.seekWhere = 0 > dc.seekWhere ? 0 : dc.seekWhere; dc.seekWhere = 0 > dc.seekWhere ? 0 : dc.seekWhere;
dc.seekError = 0; dc.seekError = 0;
dc.seek = 1; dc_command(DECODE_COMMAND_SEEK);
do { player_wakeup_decoder(); } while (dc.seek);
if (!dc.seekError) { if (!dc.seekError) {
pc.elapsedTime = dc.seekWhere; pc.elapsedTime = dc.seekWhere;
ret = 0; ret = 0;
@ -231,12 +241,12 @@ static void decodeStart(void)
} }
dc.state = DECODE_STATE_START; dc.state = DECODE_STATE_START;
dc.start = 0; dc.command = DECODE_COMMAND_NONE;
/* for http streams, seekable is determined in bufferInputStream */ /* for http streams, seekable is determined in bufferInputStream */
dc.seekable = inStream.seekable; dc.seekable = inStream.seekable;
if (dc.stop) if (dc.command == DECODE_COMMAND_STOP)
goto stop; goto stop;
ret = DECODE_ERROR_UNKTYPE; ret = DECODE_ERROR_UNKTYPE;
@ -318,7 +328,7 @@ stop:
closeInputStream(&inStream); closeInputStream(&inStream);
stop_no_close: stop_no_close:
dc.state = DECODE_STATE_STOP; dc.state = DECODE_STATE_STOP;
dc.stop = 0; dc.command = DECODE_COMMAND_NONE;
} }
static void * decoder_task(mpd_unused void *arg) static void * decoder_task(mpd_unused void *arg)
@ -328,10 +338,11 @@ static void * decoder_task(mpd_unused void *arg)
while (1) { while (1) {
assert(dc.state == DECODE_STATE_STOP); assert(dc.state == DECODE_STATE_STOP);
if (dc.start || dc.seek) { if (dc.command == DECODE_COMMAND_START ||
dc.command == DECODE_COMMAND_SEEK) {
decodeStart(); decodeStart();
} else if (dc.stop) { } else if (dc.command == DECODE_COMMAND_STOP) {
dc.stop = 0; dc.command = DECODE_COMMAND_NONE;
decoder_wakeup_player(); decoder_wakeup_player();
} else { } else {
decoder_sleep(); decoder_sleep();
@ -480,12 +491,13 @@ static void decodeParent(void)
next = ob.end; next = ob.end;
dc.next_song = pc.next_song; dc.next_song = pc.next_song;
dc.error = DECODE_ERROR_NOERROR; dc.error = DECODE_ERROR_NOERROR;
dc.start = 1; dc.command = DECODE_COMMAND_START;
pc.queueState = PLAYER_QUEUE_DECODE; pc.queueState = PLAYER_QUEUE_DECODE;
wakeup_main_task(); wakeup_main_task();
player_wakeup_decoder_nb(); player_wakeup_decoder_nb();
} }
if (next >= 0 && do_xfade == XFADE_UNKNOWN && !dc.start && if (next >= 0 && do_xfade == XFADE_UNKNOWN &&
dc.command != DECODE_COMMAND_START &&
dc.state != DECODE_STATE_START) { dc.state != DECODE_STATE_START) {
/* enable cross fading in this song? if yes, /* enable cross fading in this song? if yes,
calculate how many chunks will be required calculate how many chunks will be required
@ -578,7 +590,8 @@ static void decodeParent(void)
pc.queueState = PLAYER_QUEUE_EMPTY; pc.queueState = PLAYER_QUEUE_EMPTY;
wakeup_main_task(); wakeup_main_task();
} else if (dc.state == DECODE_STATE_STOP && !dc.start) { } else if (dc.state == DECODE_STATE_STOP &&
dc.command != DECODE_COMMAND_START) {
break; break;
} else { } else {
/*DEBUG("waiting for decoded audio, play silence\n");*/ /*DEBUG("waiting for decoded audio, play silence\n");*/
@ -600,10 +613,7 @@ void decode(void)
ob_clear(); ob_clear();
dc.next_song = pc.next_song; dc.next_song = pc.next_song;
dc.error = DECODE_ERROR_NOERROR; dc.error = DECODE_ERROR_NOERROR;
dc.seek = 0; dc_command(DECODE_COMMAND_START);
dc.stop = 0;
dc.start = 1;
do { player_wakeup_decoder(); } while (dc.start);
decodeParent(); decodeParent();
} }

View File

@ -33,6 +33,13 @@ enum decoder_state {
DECODE_STATE_DECODE DECODE_STATE_DECODE
}; };
enum decoder_command {
DECODE_COMMAND_NONE = 0,
DECODE_COMMAND_START,
DECODE_COMMAND_STOP,
DECODE_COMMAND_SEEK
};
#define DECODE_ERROR_NOERROR 0 #define DECODE_ERROR_NOERROR 0
#define DECODE_ERROR_UNKTYPE 10 #define DECODE_ERROR_UNKTYPE 10
#define DECODE_ERROR_FILE 20 #define DECODE_ERROR_FILE 20
@ -41,10 +48,8 @@ typedef struct _DecoderControl {
Notify notify; Notify notify;
volatile enum decoder_state state; volatile enum decoder_state state;
volatile mpd_sint8 stop; volatile enum decoder_command command;
volatile mpd_sint8 start;
volatile mpd_uint16 error; volatile mpd_uint16 error;
volatile mpd_sint8 seek;
volatile mpd_sint8 seekError; volatile mpd_sint8 seekError;
volatile mpd_sint8 seekable; volatile mpd_sint8 seekable;
volatile double seekWhere; volatile double seekWhere;

View File

@ -177,7 +177,7 @@ void flac_error_common_cb(const char *plugin,
const FLAC__StreamDecoderErrorStatus status, const FLAC__StreamDecoderErrorStatus status,
mpd_unused FlacData * data) mpd_unused FlacData * data)
{ {
if (dc.stop) if (dc.command == DECODE_COMMAND_STOP)
return; return;
switch (status) { switch (status) {

View File

@ -392,13 +392,13 @@ static int aac_decode(char *path)
sampleBufferLen = sampleCount * 2; sampleBufferLen = sampleCount * 2;
ob_send(NULL, 0, sampleBuffer, ob_send(NULL, 0, sampleBuffer,
sampleBufferLen, file_time, sampleBufferLen, file_time,
bitRate, NULL); bitRate, NULL);
if (dc.seek) { if (dc.command == DECODE_COMMAND_SEEK) {
dc.seekError = 1; dc.seekError = 1;
dc.seek = 0; dc.command = DECODE_COMMAND_NONE;
decoder_wakeup_player(); decoder_wakeup_player();
} else if (dc.stop) { } else if (dc.command == DECODE_COMMAND_STOP) {
eof = 1; eof = 1;
break; break;
} }
@ -413,9 +413,9 @@ static int aac_decode(char *path)
if (dc.state != DECODE_STATE_DECODE) if (dc.state != DECODE_STATE_DECODE)
return -1; return -1;
if (dc.seek) { if (dc.command == DECODE_COMMAND_SEEK) {
dc.seekError = 1; dc.seekError = 1;
dc.seek = 0; dc.command = DECODE_COMMAND_NONE;
decoder_wakeup_player(); decoder_wakeup_player();
} }

View File

@ -91,12 +91,12 @@ static int audiofile_decode(char *path)
char chunk[CHUNK_SIZE]; char chunk[CHUNK_SIZE];
while (!eof) { while (!eof) {
if (dc.seek) { if (dc.command == DECODE_COMMAND_SEEK) {
ob_clear(); ob_clear();
current = dc.seekWhere * current = dc.seekWhere *
dc.audioFormat.sampleRate; dc.audioFormat.sampleRate;
afSeekFrame(af_fp, AF_DEFAULT_TRACK, current); afSeekFrame(af_fp, AF_DEFAULT_TRACK, current);
dc.seek = 0; dc.command = DECODE_COMMAND_NONE;
decoder_wakeup_player(); decoder_wakeup_player();
} }
@ -108,14 +108,13 @@ static int audiofile_decode(char *path)
else { else {
current += ret; current += ret;
ob_send(NULL, ob_send(NULL,
1, 1,
chunk, chunk, ret * fs,
ret * fs, (float)current /
(float)current / (float)dc.audioFormat.
(float)dc.audioFormat. sampleRate, bitRate,
sampleRate, bitRate, NULL);
NULL); if (dc.command == DECODE_COMMAND_STOP)
if (dc.stop)
break; break;
} }
} }

View File

@ -35,14 +35,15 @@ static flac_read_status flacRead(mpd_unused const flac_decoder * flacDec,
while (1) { while (1) {
r = readFromInputStream(data->inStream, (void *)buf, 1, *bytes); r = readFromInputStream(data->inStream, (void *)buf, 1, *bytes);
if (r == 0 && !inputStreamAtEOF(data->inStream) && !dc.stop) if (r == 0 && !inputStreamAtEOF(data->inStream) &&
dc.command != DECODE_COMMAND_STOP)
my_usleep(10000); my_usleep(10000);
else else
break; break;
} }
*bytes = r; *bytes = r;
if (r == 0 && !dc.stop) { if (r == 0 && dc.command != DECODE_COMMAND_STOP) {
if (inputStreamAtEOF(data->inStream)) if (inputStreamAtEOF(data->inStream))
return flac_read_status_eof; return flac_read_status_eof;
else else
@ -285,7 +286,7 @@ static FLAC__StreamDecoderWriteStatus flacWrite(const flac_decoder *dec,
FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
} }
data->chunk_length = 0; data->chunk_length = 0;
if (dc.seek) { if (dc.command == DECODE_COMMAND_SEEK) {
return return
FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
} }
@ -420,7 +421,7 @@ static int flac_decode_internal(InputStream * inStream, int is_ogg)
break; break;
if (flac_get_state(flacDec) == flac_decoder_eof) if (flac_get_state(flacDec) == flac_decoder_eof)
break; break;
if (dc.seek) { if (dc.command == DECODE_COMMAND_SEEK) {
FLAC__uint64 sampleToSeek = dc.seekWhere * FLAC__uint64 sampleToSeek = dc.seekWhere *
dc.audioFormat.sampleRate + 0.5; dc.audioFormat.sampleRate + 0.5;
if (flac_seek_absolute(flacDec, sampleToSeek)) { if (flac_seek_absolute(flacDec, sampleToSeek)) {
@ -430,16 +431,16 @@ static int flac_decode_internal(InputStream * inStream, int is_ogg)
data.position = 0; data.position = 0;
} else } else
dc.seekError = 1; dc.seekError = 1;
dc.seek = 0; dc.command = DECODE_COMMAND_NONE;
decoder_wakeup_player(); decoder_wakeup_player();
} }
} }
if (!dc.stop) { if (dc.command != DECODE_COMMAND_STOP) {
flacPrintErroredState(flac_get_state(flacDec)); flacPrintErroredState(flac_get_state(flacDec));
flac_finish(flacDec); flac_finish(flacDec);
} }
/* send last little bit */ /* send last little bit */
if (data.chunk_length > 0 && !dc.stop) { if (data.chunk_length > 0 && dc.command != DECODE_COMMAND_STOP) {
flacSendChunk(&data); flacSendChunk(&data);
ob_flush(); ob_flush();
} }

View File

@ -187,13 +187,13 @@ static int mod_decode(char *path)
dc.state = DECODE_STATE_DECODE; dc.state = DECODE_STATE_DECODE;
while (1) { while (1) {
if (dc.seek) { if (dc.command == DECODE_COMMAND_SEEK) {
dc.seekError = 1; dc.seekError = 1;
dc.seek = 0; dc.command = DECODE_COMMAND_NONE;
decoder_wakeup_player(); decoder_wakeup_player();
} }
if (dc.stop) if (dc.command == DECODE_COMMAND_STOP)
break; break;
if (!Player_Active()) if (!Player_Active())

View File

@ -684,13 +684,17 @@ static int decodeFirstFrame(mp3DecodeData * data,
while (1) { while (1) {
while ((ret = decodeNextFrameHeader(data, tag, replayGainInfo)) == DECODE_CONT && while ((ret = decodeNextFrameHeader(data, tag, replayGainInfo)) == DECODE_CONT &&
!dc.stop); dc.command != DECODE_COMMAND_STOP);
if (ret == DECODE_BREAK || dc.stop) return -1; if (ret == DECODE_BREAK ||
(dc.command == DECODE_COMMAND_STOP))
return -1;
if (ret == DECODE_SKIP) continue; if (ret == DECODE_SKIP) continue;
while ((ret = decodeNextFrame(data)) == DECODE_CONT && while ((ret = decodeNextFrame(data)) == DECODE_CONT &&
!dc.stop); dc.command != DECODE_COMMAND_STOP);
if (ret == DECODE_BREAK || dc.stop) return -1; if (ret == DECODE_BREAK ||
(dc.command == DECODE_COMMAND_STOP))
return -1;
if (ret == DECODE_OK) break; if (ret == DECODE_OK) break;
} }
@ -850,7 +854,7 @@ static int mp3Read(mp3DecodeData * data, ReplayGainInfo ** replayGainInfo)
data->outputPtr = data->outputBuffer; data->outputPtr = data->outputBuffer;
ob_clear(); ob_clear();
data->muteFrame = 0; data->muteFrame = 0;
dc.seek = 0; dc.command = DECODE_COMMAND_NONE;
decoder_wakeup_player(); decoder_wakeup_player();
} }
break; break;
@ -944,7 +948,8 @@ static int mp3Read(mp3DecodeData * data, ReplayGainInfo ** replayGainInfo)
data->decodedFirstFrame = 1; data->decodedFirstFrame = 1;
if (dc.seek && data->inStream->seekable) { if (dc.command == DECODE_COMMAND_SEEK &&
data->inStream->seekable) {
long j = 0; long j = 0;
data->muteFrame = MUTEFRAME_SEEK; data->muteFrame = MUTEFRAME_SEEK;
while (j < data->highestFrame && dc.seekWhere > while (j < data->highestFrame && dc.seekWhere >
@ -963,11 +968,12 @@ static int mp3Read(mp3DecodeData * data, ReplayGainInfo ** replayGainInfo)
} else } else
dc.seekError = 1; dc.seekError = 1;
data->muteFrame = 0; data->muteFrame = 0;
dc.seek = 0; dc.command = DECODE_COMMAND_NONE;
decoder_wakeup_player(); decoder_wakeup_player();
} }
} else if (dc.seek && !data->inStream->seekable) { } else if (dc.command == DECODE_COMMAND_SEEK &&
dc.seek = 0; !data->inStream->seekable) {
dc.command = DECODE_COMMAND_NONE;
dc.seekError = 1; dc.seekError = 1;
decoder_wakeup_player(); decoder_wakeup_player();
} }
@ -978,22 +984,27 @@ static int mp3Read(mp3DecodeData * data, ReplayGainInfo ** replayGainInfo)
while ((ret = while ((ret =
decodeNextFrameHeader(data, NULL, decodeNextFrameHeader(data, NULL,
replayGainInfo)) == DECODE_CONT replayGainInfo)) == DECODE_CONT
&& !dc.stop) ; && dc.command != DECODE_COMMAND_STOP) ;
if (ret == DECODE_BREAK || dc.stop || dc.seek) if (ret == DECODE_BREAK ||
dc.command == DECODE_COMMAND_STOP ||
dc.command == DECODE_COMMAND_SEEK)
break; break;
else if (ret == DECODE_SKIP) else if (ret == DECODE_SKIP)
skip = 1; skip = 1;
if (!data->muteFrame) { if (!data->muteFrame) {
while ((ret = decodeNextFrame(data)) == DECODE_CONT && while ((ret = decodeNextFrame(data)) == DECODE_CONT &&
!dc.stop && !dc.seek) ; dc.command != DECODE_COMMAND_STOP &&
if (ret == DECODE_BREAK || dc.stop || dc.seek) dc.command != DECODE_COMMAND_SEEK) ;
if (ret == DECODE_BREAK ||
dc.command == DECODE_COMMAND_STOP ||
dc.command == DECODE_COMMAND_SEEK)
break; break;
} }
if (!skip && ret == DECODE_OK) if (!skip && ret == DECODE_OK)
break; break;
} }
if (dc.stop) if (dc.command == DECODE_COMMAND_STOP)
return DECODE_BREAK; return DECODE_BREAK;
return ret; return ret;
@ -1015,7 +1026,7 @@ static int mp3_decode(InputStream * inStream)
if (openMp3FromInputStream(inStream, &data, &tag, &replayGainInfo) < if (openMp3FromInputStream(inStream, &data, &tag, &replayGainInfo) <
0) { 0) {
if (!dc.stop) { if (dc.command != DECODE_COMMAND_STOP) {
ERROR ERROR
("Input does not appear to be a mp3 bit stream.\n"); ("Input does not appear to be a mp3 bit stream.\n");
return -1; return -1;
@ -1056,8 +1067,9 @@ static int mp3_decode(InputStream * inStream)
dc.state = DECODE_STATE_DECODE; dc.state = DECODE_STATE_DECODE;
while (mp3Read(&data, &replayGainInfo) != DECODE_BREAK) ; while (mp3Read(&data, &replayGainInfo) != DECODE_BREAK) ;
/* send last little bit if not dc.stop */ /* send last little bit if not DECODE_COMMAND_STOP */
if (!dc.stop && data.outputPtr != data.outputBuffer && data.flush) { if (dc.command != DECODE_COMMAND_STOP &&
data.outputPtr != data.outputBuffer && data.flush) {
ob_send(NULL, ob_send(NULL,
data.inStream->seekable, data.inStream->seekable,
data.outputBuffer, data.outputBuffer,
@ -1069,9 +1081,10 @@ static int mp3_decode(InputStream * inStream)
if (replayGainInfo) if (replayGainInfo)
freeReplayGainInfo(replayGainInfo); freeReplayGainInfo(replayGainInfo);
if (dc.seek && data.muteFrame == MUTEFRAME_SEEK) { if (dc.command == DECODE_COMMAND_SEEK &&
data.muteFrame == MUTEFRAME_SEEK) {
ob_clear(); ob_clear();
dc.seek = 0; dc.command = DECODE_COMMAND_NONE;
decoder_wakeup_player(); decoder_wakeup_player();
} }

View File

@ -178,7 +178,7 @@ static int mp4_decode(InputStream * inStream)
seekTable = xmalloc(sizeof(float) * numSamples); seekTable = xmalloc(sizeof(float) * numSamples);
for (sampleId = 0; sampleId < numSamples && !eof; sampleId++) { for (sampleId = 0; sampleId < numSamples && !eof; sampleId++) {
if (dc.seek) if (dc.command == DECODE_COMMAND_SEEK)
seeking = 1; seeking = 1;
if (seeking && seekTableEnd > 1 && if (seeking && seekTableEnd > 1 &&
@ -213,7 +213,7 @@ static int mp4_decode(InputStream * inStream)
seekPositionFound = 0; seekPositionFound = 0;
ob_clear(); ob_clear();
seeking = 0; seeking = 0;
dc.seek = 0; dc.command = DECODE_COMMAND_NONE;
decoder_wakeup_player(); decoder_wakeup_player();
} }
@ -272,9 +272,9 @@ static int mp4_decode(InputStream * inStream)
sampleBuffer += offset * channels * 2; sampleBuffer += offset * channels * 2;
ob_send(inStream, 1, sampleBuffer, ob_send(inStream, 1, sampleBuffer,
sampleBufferLen, file_time, sampleBufferLen, file_time,
bitRate, NULL); bitRate, NULL);
if (dc.stop) { if (dc.command == DECODE_COMMAND_STOP) {
eof = 1; eof = 1;
break; break;
} }
@ -288,9 +288,9 @@ static int mp4_decode(InputStream * inStream)
if (dc.state != DECODE_STATE_DECODE) if (dc.state != DECODE_STATE_DECODE)
return -1; return -1;
if (dc.seek && seeking) { if (dc.command == DECODE_COMMAND_SEEK && seeking) {
ob_clear(); ob_clear();
dc.seek = 0; dc.command = DECODE_COMMAND_NONE;
decoder_wakeup_player(); decoder_wakeup_player();
} }
ob_flush(); ob_flush();

View File

@ -36,7 +36,8 @@ static mpc_int32_t mpc_read_cb(void *vdata, void *ptr, mpc_int32_t size)
while (1) { while (1) {
ret = readFromInputStream(data->inStream, ptr, 1, size); ret = readFromInputStream(data->inStream, ptr, 1, size);
if (ret == 0 && !inputStreamAtEOF(data->inStream) && !dc.stop) if (ret == 0 && !inputStreamAtEOF(data->inStream) &&
(dc.command != DECODE_COMMAND_STOP))
my_usleep(10000); my_usleep(10000);
else else
break; break;
@ -141,7 +142,7 @@ static int mpc_decode(InputStream * inStream)
mpc_streaminfo_init(&info); mpc_streaminfo_init(&info);
if ((ret = mpc_streaminfo_read(&info, &reader)) != ERROR_CODE_OK) { if ((ret = mpc_streaminfo_read(&info, &reader)) != ERROR_CODE_OK) {
if (!dc.stop) { if (dc.command != DECODE_COMMAND_STOP) {
ERROR("Not a valid musepack stream\n"); ERROR("Not a valid musepack stream\n");
return -1; return -1;
} }
@ -151,7 +152,7 @@ static int mpc_decode(InputStream * inStream)
mpc_decoder_setup(&decoder, &reader); mpc_decoder_setup(&decoder, &reader);
if (!mpc_decoder_initialize(&decoder, &info)) { if (!mpc_decoder_initialize(&decoder, &info)) {
if (!dc.stop) { if (dc.command != DECODE_COMMAND_STOP) {
ERROR("Not a valid musepack stream\n"); ERROR("Not a valid musepack stream\n");
return -1; return -1;
} }
@ -175,7 +176,7 @@ static int mpc_decode(InputStream * inStream)
dc.state = DECODE_STATE_DECODE; dc.state = DECODE_STATE_DECODE;
while (!eof) { while (!eof) {
if (dc.seek) { if (dc.command == DECODE_COMMAND_SEEK) {
samplePos = dc.seekWhere * dc.audioFormat.sampleRate; samplePos = dc.seekWhere * dc.audioFormat.sampleRate;
if (mpc_decoder_seek_sample(&decoder, samplePos)) { if (mpc_decoder_seek_sample(&decoder, samplePos)) {
ob_clear(); ob_clear();
@ -183,7 +184,7 @@ static int mpc_decode(InputStream * inStream)
chunkpos = 0; chunkpos = 0;
} else } else
dc.seekError = 1; dc.seekError = 1;
dc.seek = 0; dc.command = DECODE_COMMAND_NONE;
decoder_wakeup_player(); decoder_wakeup_player();
} }
@ -192,7 +193,7 @@ static int mpc_decode(InputStream * inStream)
ret = mpc_decoder_decode(&decoder, sample_buffer, ret = mpc_decoder_decode(&decoder, sample_buffer,
&vbrUpdateAcc, &vbrUpdateBits); &vbrUpdateAcc, &vbrUpdateBits);
if (ret <= 0 || dc.stop) { if (ret <= 0 || dc.command == DECODE_COMMAND_STOP) {
eof = 1; eof = 1;
break; break;
} }
@ -223,7 +224,7 @@ static int mpc_decode(InputStream * inStream)
chunkpos = 0; chunkpos = 0;
s16 = (mpd_sint16 *) chunk; s16 = (mpd_sint16 *) chunk;
if (dc.stop) { if (dc.command == DECODE_COMMAND_STOP) {
eof = 1; eof = 1;
break; break;
} }
@ -231,7 +232,7 @@ static int mpc_decode(InputStream * inStream)
} }
} }
if (!dc.stop && chunkpos > 0) { if (dc.command != DECODE_COMMAND_STOP && chunkpos > 0) {
total_time = ((float)samplePos) / dc.audioFormat.sampleRate; total_time = ((float)samplePos) / dc.audioFormat.sampleRate;
bitRate = bitRate =

View File

@ -50,14 +50,15 @@ static OggFLAC__SeekableStreamDecoderReadStatus of_read_cb(const
while (1) { while (1) {
r = readFromInputStream(data->inStream, (void *)buf, 1, *bytes); r = readFromInputStream(data->inStream, (void *)buf, 1, *bytes);
if (r == 0 && !inputStreamAtEOF(data->inStream) && if (r == 0 && !inputStreamAtEOF(data->inStream) &&
!dc.stop) dc.command != DECODE_COMMAND_STOP)
my_usleep(10000); my_usleep(10000);
else else
break; break;
} }
*bytes = r; *bytes = r;
if (r == 0 && !inputStreamAtEOF(data->inStream) && !dc.stop) if (r == 0 && !inputStreamAtEOF(data->inStream) &&
dc.command != DECODE_COMMAND_STOP)
return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR; return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK; return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
@ -194,7 +195,7 @@ static FLAC__StreamDecoderWriteStatus oggflacWrite(const
FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
} }
data->chunk_length = 0; data->chunk_length = 0;
if (dc.seek) { if (dc.command == DECODE_COMMAND_SEEK) {
return return
FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
} }
@ -351,7 +352,7 @@ static int oggflac_decode(InputStream * inStream)
OggFLAC__SEEKABLE_STREAM_DECODER_OK) { OggFLAC__SEEKABLE_STREAM_DECODER_OK) {
break; break;
} }
if (dc.seek) { if (dc.command == DECODE_COMMAND_SEEK) {
FLAC__uint64 sampleToSeek = dc.seekWhere * FLAC__uint64 sampleToSeek = dc.seekWhere *
dc.audioFormat.sampleRate + 0.5; dc.audioFormat.sampleRate + 0.5;
if (OggFLAC__seekable_stream_decoder_seek_absolute if (OggFLAC__seekable_stream_decoder_seek_absolute
@ -362,18 +363,18 @@ static int oggflac_decode(InputStream * inStream)
data.position = 0; data.position = 0;
} else } else
dc.seekError = 1; dc.seekError = 1;
dc.seek = 0; dc.command = DECODE_COMMAND_NONE;
decoder_wakeup_player(); decoder_wakeup_player();
} }
} }
if (!dc.stop) { if (dc.command != DECODE_COMMAND_STOP) {
oggflacPrintErroredState oggflacPrintErroredState
(OggFLAC__seekable_stream_decoder_get_state(decoder)); (OggFLAC__seekable_stream_decoder_get_state(decoder));
OggFLAC__seekable_stream_decoder_finish(decoder); OggFLAC__seekable_stream_decoder_finish(decoder);
} }
/* send last little bit */ /* send last little bit */
if (data.chunk_length > 0 && !dc.stop) { if (data.chunk_length > 0 && dc.command != DECODE_COMMAND_STOP) {
flacSendChunk(&data); flacSendChunk(&data);
ob_flush(); ob_flush();
} }

View File

@ -60,7 +60,7 @@ static size_t ogg_read_cb(void *ptr, size_t size, size_t nmemb, void *vdata)
while (1) { while (1) {
ret = readFromInputStream(data->inStream, ptr, size, nmemb); ret = readFromInputStream(data->inStream, ptr, size, nmemb);
if (ret == 0 && !inputStreamAtEOF(data->inStream) && if (ret == 0 && !inputStreamAtEOF(data->inStream) &&
!dc.stop) { dc.command != DECODE_COMMAND_STOP) {
my_usleep(10000); my_usleep(10000);
} else } else
break; break;
@ -74,7 +74,7 @@ static size_t ogg_read_cb(void *ptr, size_t size, size_t nmemb, void *vdata)
static int ogg_seek_cb(void *vdata, ogg_int64_t offset, int whence) static int ogg_seek_cb(void *vdata, ogg_int64_t offset, int whence)
{ {
const OggCallbackData *data = (const OggCallbackData *) vdata; const OggCallbackData *data = (const OggCallbackData *) vdata;
if (dc.stop) if(dc.command == DECODE_COMMAND_STOP)
return -1; return -1;
return seekInputStream(data->inStream, offset, whence); return seekInputStream(data->inStream, offset, whence);
} }
@ -234,7 +234,7 @@ static int oggvorbis_decode(InputStream * inStream)
callbacks.close_func = ogg_close_cb; callbacks.close_func = ogg_close_cb;
callbacks.tell_func = ogg_tell_cb; callbacks.tell_func = ogg_tell_cb;
if ((ret = ov_open_callbacks(&data, &vf, NULL, 0, callbacks)) < 0) { if ((ret = ov_open_callbacks(&data, &vf, NULL, 0, callbacks)) < 0) {
if (!dc.stop) { if (dc.command != DECODE_COMMAND_STOP) {
switch (ret) { switch (ret) {
case OV_EREAD: case OV_EREAD:
errorStr = "read error"; errorStr = "read error";
@ -267,13 +267,13 @@ static int oggvorbis_decode(InputStream * inStream)
dc.audioFormat.bits = 16; dc.audioFormat.bits = 16;
while (1) { while (1) {
if (dc.seek) { if (dc.command == DECODE_COMMAND_SEEK) {
if (0 == ov_time_seek_page(&vf, dc.seekWhere)) { if (0 == ov_time_seek_page(&vf, dc.seekWhere)) {
ob_clear(); ob_clear();
chunkpos = 0; chunkpos = 0;
} else } else
dc.seekError = 1; dc.seekError = 1;
dc.seek = 0; dc.command = DECODE_COMMAND_NONE;
decoder_wakeup_player(); decoder_wakeup_player();
} }
ret = ov_read(&vf, chunk + chunkpos, ret = ov_read(&vf, chunk + chunkpos,
@ -317,12 +317,12 @@ static int oggvorbis_decode(InputStream * inStream)
dc.audioFormat.sampleRate, dc.audioFormat.sampleRate,
bitRate, replayGainInfo); bitRate, replayGainInfo);
chunkpos = 0; chunkpos = 0;
if (dc.stop) if (dc.command == DECODE_COMMAND_STOP)
break; break;
} }
} }
if (!dc.stop && chunkpos > 0) { if (dc.command != DECODE_COMMAND_STOP && chunkpos > 0) {
ob_send(NULL, inStream->seekable, ob_send(NULL, inStream->seekable,
chunk, chunkpos, chunk, chunkpos,
ov_time_tell(&vf), bitRate, ov_time_tell(&vf), bitRate,

View File

@ -171,7 +171,7 @@ static void wavpack_decode(WavpackContext *wpc, int canseek,
position = 0; position = 0;
do { do {
if (dc.seek) { if (dc.command == DECODE_COMMAND_SEEK) {
if (canseek) { if (canseek) {
int where; int where;
@ -187,11 +187,11 @@ static void wavpack_decode(WavpackContext *wpc, int canseek,
dc.seekError = 1; dc.seekError = 1;
} }
dc.seek = 0; dc.command = DECODE_COMMAND_NONE;
decoder_wakeup_player(); decoder_wakeup_player();
} }
if (dc.stop) if (dc.command == DECODE_COMMAND_STOP)
break; break;
samplesgot = WavpackUnpackSamples(wpc, samplesgot = WavpackUnpackSamples(wpc,
@ -501,7 +501,7 @@ static int wavpack_streamdecode(InputStream *is)
break; break;
} }
if (dc.stop) { if (dc.command == DECODE_COMMAND_STOP) {
break; break;
} }

View File

@ -171,15 +171,15 @@ static int tailChunk(InputStream * inStream,
/* all chunks are full of decoded data; wait /* all chunks are full of decoded data; wait
for the player to free one */ for the player to free one */
if (dc.stop) if (dc.command == DECODE_COMMAND_STOP)
return OUTPUT_BUFFER_DC_STOP; return OUTPUT_BUFFER_DC_STOP;
if (dc.seek) { if (dc.command == DECODE_COMMAND_SEEK) {
if (seekable) { if (seekable) {
return OUTPUT_BUFFER_DC_SEEK; return OUTPUT_BUFFER_DC_SEEK;
} else { } else {
dc.seekError = 1; dc.seekError = 1;
dc.seek = 0; dc.command = DECODE_COMMAND_NONE;
decoder_wakeup_player(); decoder_wakeup_player();
} }
} }

View File

@ -84,6 +84,7 @@ void initPlayerData(void)
notify_init(&dc.notify); notify_init(&dc.notify);
dc.state = DECODE_STATE_STOP; dc.state = DECODE_STATE_STOP;
dc.command = DECODE_COMMAND_NONE;
dc.error = DECODE_ERROR_NOERROR; dc.error = DECODE_ERROR_NOERROR;
} }