Commit 8d3942e0 authored by Max Kellermann's avatar Max Kellermann

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.
parent 180d78a8
...@@ -56,19 +56,30 @@ static void player_wakeup_decoder(void) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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: ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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();
} }
...@@ -33,6 +33,13 @@ enum decoder_state { ...@@ -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 { ...@@ -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;
......
...@@ -177,7 +177,7 @@ void flac_error_common_cb(const char *plugin, ...@@ -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) {
......
...@@ -394,11 +394,11 @@ static int aac_decode(char *path) ...@@ -394,11 +394,11 @@ static int aac_decode(char *path)
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) ...@@ -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();
} }
......
...@@ -91,12 +91,12 @@ static int audiofile_decode(char *path) ...@@ -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();
} }
...@@ -109,13 +109,12 @@ static int audiofile_decode(char *path) ...@@ -109,13 +109,12 @@ static int audiofile_decode(char *path)
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.stop) if (dc.command == DECODE_COMMAND_STOP)
break; break;
} }
} }
......
...@@ -35,14 +35,15 @@ static flac_read_status flacRead(mpd_unused const flac_decoder * flacDec, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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();
} }
......
...@@ -187,13 +187,13 @@ static int mod_decode(char *path) ...@@ -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())
......
...@@ -684,13 +684,17 @@ static int decodeFirstFrame(mp3DecodeData * data, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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();
} }
......
...@@ -178,7 +178,7 @@ static int mp4_decode(InputStream * inStream) ...@@ -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) ...@@ -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();
} }
...@@ -274,7 +274,7 @@ static int mp4_decode(InputStream * inStream) ...@@ -274,7 +274,7 @@ static int mp4_decode(InputStream * inStream)
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) ...@@ -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();
......
...@@ -36,7 +36,8 @@ static mpc_int32_t mpc_read_cb(void *vdata, void *ptr, mpc_int32_t size) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 =
......
...@@ -50,14 +50,15 @@ static OggFLAC__SeekableStreamDecoderReadStatus of_read_cb(const ...@@ -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 ...@@ -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) ...@@ -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) ...@@ -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();
} }
......
...@@ -60,7 +60,7 @@ static size_t ogg_read_cb(void *ptr, size_t size, size_t nmemb, void *vdata) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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,
......
...@@ -171,7 +171,7 @@ static void wavpack_decode(WavpackContext *wpc, int canseek, ...@@ -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, ...@@ -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) ...@@ -501,7 +501,7 @@ static int wavpack_streamdecode(InputStream *is)
break; break;
} }
if (dc.stop) { if (dc.command == DECODE_COMMAND_STOP) {
break; break;
} }
......
...@@ -171,15 +171,15 @@ static int tailChunk(InputStream * inStream, ...@@ -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();
} }
} }
......
...@@ -84,6 +84,7 @@ void initPlayerData(void) ...@@ -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;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment