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:
parent
180d78a8e6
commit
8d3942e0c3
54
src/decode.c
54
src/decode.c
@ -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();
|
||||||
}
|
}
|
||||||
|
11
src/decode.h
11
src/decode.h
@ -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;
|
||||||
|
@ -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) {
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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,
|
|||||||
|
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
@ -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 =
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
|||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user