non-blocking seeking, needs some testing! (this is not just for streams

but new code for files seeking as well)

git-svn-id: https://svn.musicpd.org/mpd/trunk@1099 09075e82-0dd4-0310-85a5-a0d7c8717e4f
This commit is contained in:
Warren Dukes 2004-05-19 23:48:34 +00:00
parent c1fbcd03f0
commit a81573ef05
10 changed files with 30 additions and 30 deletions

14
TODO
View File

@ -2,17 +2,9 @@
a) make seekings non-blocking: a) make seekings non-blocking:
1) player: 1) player:
a) first check that seekWhere isn't already buffered a) first check that seekWhere isn't already buffered
b) if not current song, stop it and play the song to 2) check that stream is seekable before seeking forward!
seek 3) deal with seeking forward better by calling seek function
c) set dc->seek and dc->seekWhere if not already set (for mp3 and mp4)!
and set elapsed time to seekWhere and
then set pc->seek = 0
d) while seeking just continue to play buffer
until seek is done
2) decoder:
a) seek no longer blocks so don't worry about checking
seek in blocking portions, only check stop!
b) yay, less code mess!
b) bufferInput in outputBuffer waiting! b) bufferInput in outputBuffer waiting!
1) implement some sort of callback mechanism for this 1) implement some sort of callback mechanism for this
for abstraction sake for abstraction sake

View File

@ -383,7 +383,7 @@ int aac_decode(OutputBuffer * cb, DecoderControl * dc) {
if(dc->state != DECODE_STATE_DECODE) return -1; if(dc->state != DECODE_STATE_DECODE) return -1;
if(!dc->stop && !dc->seek && chunkLen>0) { if(!dc->stop && chunkLen>0) {
cb->chunkSize[cb->end] = chunkLen; cb->chunkSize[cb->end] = chunkLen;
++cb->end; ++cb->end;

View File

@ -101,7 +101,7 @@ int audiofile_decode(OutputBuffer * cb, DecoderControl * dc) {
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->seekChunk = cb->end;
dc->seek = 0; dc->seek = 0;
} }
@ -114,7 +114,6 @@ int audiofile_decode(OutputBuffer * cb, DecoderControl * dc) {
(float)dc->audioFormat.sampleRate, (float)dc->audioFormat.sampleRate,
bitRate); bitRate);
if(dc->stop) break; if(dc->stop) break;
else if(dc->seek) continue;
} }
} }

View File

@ -128,7 +128,7 @@ int calculateCrossFadeChunks(PlayerControl * pc, AudioFormat * af) {
pc->channels = dc->audioFormat.channels; \ pc->channels = dc->audioFormat.channels; \
} \ } \
else if(decodeWaitedOn) { \ else if(decodeWaitedOn) { \
my_usleep(10); \ my_usleep(10000); \
continue; \ continue; \
} }
@ -161,7 +161,7 @@ int decodeSeek(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb,
{ {
int ret = -1; int ret = -1;
if(decode_pid && *decode_pid>0) { if(decode_pid && *decode_pid>0 && !dc->seek) {
cb->next = -1; cb->next = -1;
if(dc->state==DECODE_STATE_STOP || dc->error || if(dc->state==DECODE_STATE_STOP || dc->error ||
strcmp(dc->file,pc->file)!=0) strcmp(dc->file,pc->file)!=0)
@ -180,13 +180,14 @@ int decodeSeek(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb,
pc->seekWhere; 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->seekChunk = -1;
dc->seek = 1; dc->seek = 1;
pc->bitRate = 0; /*pc->bitRate = 0;*/
while(*decode_pid>0 && dc->seek) my_usleep(1000); /*while(*decode_pid>0 && dc->seek) my_usleep(1000);*/
if(!dc->seekError) { /*if(!dc->seekError) {*/
ret = 0; ret = 0;
pc->elapsedTime = dc->seekWhere; pc->elapsedTime = dc->seekWhere;
} /*}*/
} }
} }
pc->seek = 0; pc->seek = 0;
@ -231,6 +232,7 @@ int decodeSeek(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb,
doCrossFade = 0; \ doCrossFade = 0; \
nextChunk = -1; \ nextChunk = -1; \
bbp = 0; \ bbp = 0; \
seeking = 1; \
} \ } \
} \ } \
if(pc->stop) { \ if(pc->stop) { \
@ -254,7 +256,6 @@ void decodeStart(PlayerControl * pc, OutputBuffer * cb, DecoderControl * dc) {
return; return;
} }
dc->seekable = inStream.seekable;
dc->state = DECODE_STATE_START; dc->state = DECODE_STATE_START;
dc->start = 0; dc->start = 0;
@ -386,6 +387,7 @@ void decodeParent(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb) {
int test; int test;
int decodeWaitedOn = 0; int decodeWaitedOn = 0;
char silence[CHUNK_SIZE]; char silence[CHUNK_SIZE];
int seeking = 0;
memset(silence,0,CHUNK_SIZE); memset(silence,0,CHUNK_SIZE);
@ -407,6 +409,10 @@ void decodeParent(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb) {
while(!quit) { while(!quit) {
processDecodeInput(); processDecodeInput();
handleDecodeStart(); handleDecodeStart();
if(!dc->seek && seeking) {
if(dc->seekChunk >= 0) cb->begin = dc->seekChunk;
seeking = 0;
}
if(dc->state==DECODE_STATE_STOP && if(dc->state==DECODE_STATE_STOP &&
pc->queueState==PLAYER_QUEUE_FULL && pc->queueState==PLAYER_QUEUE_FULL &&
pc->queueLockState==PLAYER_QUEUE_UNLOCKED) pc->queueLockState==PLAYER_QUEUE_UNLOCKED)
@ -481,7 +487,7 @@ void decodeParent(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb) {
else continue; else continue;
} }
} }
pc->elapsedTime = cb->times[cb->begin]; if(!seeking) pc->elapsedTime = cb->times[cb->begin];
pc->bitRate = cb->bitRate[cb->begin]; pc->bitRate = cb->bitRate[cb->begin];
pcm_volumeChange(cb->chunks+cb->begin* pcm_volumeChange(cb->chunks+cb->begin*
CHUNK_SIZE, CHUNK_SIZE,

View File

@ -46,12 +46,12 @@
#define DECODE_SUFFIX_WAVE 6 #define DECODE_SUFFIX_WAVE 6
typedef struct _DecoderControl { typedef struct _DecoderControl {
volatile mpd_sint8 seekable;
volatile mpd_sint8 state; volatile mpd_sint8 state;
volatile mpd_sint8 stop; volatile mpd_sint8 stop;
volatile mpd_sint8 start; volatile mpd_sint8 start;
volatile mpd_uint16 error; volatile mpd_uint16 error;
volatile mpd_sint8 seek; volatile mpd_sint8 seek;
volatile mpd_sint16 seekChunk;
volatile mpd_sint8 seekError; volatile mpd_sint8 seekError;
volatile mpd_sint8 cycleLogFiles; volatile mpd_sint8 cycleLogFiles;
volatile double seekWhere; volatile double seekWhere;

View File

@ -154,6 +154,7 @@ int flac_decode(OutputBuffer * cb, DecoderControl *dc) {
dc->audioFormat.sampleRate; dc->audioFormat.sampleRate;
data.position = 0; data.position = 0;
} }
dc->seekChunk = cb->end;
dc->seek = 0; dc->seek = 0;
} }
} }

View File

@ -461,6 +461,7 @@ int mp3Read(mp3DecodeData * data, OutputBuffer * cb, DecoderControl * dc) {
if(!dc->seek) data->muteFrame = 0; if(!dc->seek) data->muteFrame = 0;
else if(dc->seekWhere<=data->elapsedTime) { else if(dc->seekWhere<=data->elapsedTime) {
clearOutputBuffer(cb); clearOutputBuffer(cb);
dc->seekChunk = cb->end;
data->muteFrame = 0; data->muteFrame = 0;
dc->seek = 0; dc->seek = 0;
} }
@ -517,6 +518,7 @@ int mp3Read(mp3DecodeData * data, OutputBuffer * cb, DecoderControl * dc) {
data->frameOffset[i]) == 0) data->frameOffset[i]) == 0)
{ {
clearOutputBuffer(cb); clearOutputBuffer(cb);
dc->seekChunk = cb->end;
data->currentFrame = i; data->currentFrame = i;
data->muteFrame = 0; data->muteFrame = 0;
} }
@ -529,13 +531,13 @@ int mp3Read(mp3DecodeData * data, OutputBuffer * cb, DecoderControl * dc) {
while(1) { while(1) {
skip = 0; skip = 0;
while((ret = decodeNextFrameHeader(data))==DECODE_CONT && while((ret = decodeNextFrameHeader(data))==DECODE_CONT &&
!dc->seek && !dc->stop); !dc->stop);
if(ret==DECODE_SKIP) skip = 1; if(ret==DECODE_SKIP) skip = 1;
else if(ret==DECODE_BREAK || dc->stop || dc->seek) break; else if(ret==DECODE_BREAK || dc->stop) break;
if(!data->muteFrame) { if(!data->muteFrame) {
while((ret = decodeNextFrame(data))==DECODE_CONT && while((ret = decodeNextFrame(data))==DECODE_CONT &&
!dc->seek && !dc->stop); !dc->stop);
if(ret==DECODE_BREAK || dc->seek || dc->stop) break; if(ret==DECODE_BREAK || dc->stop) break;
} }
if(!skip && ret==DECODE_OK) break; if(!skip && ret==DECODE_OK) break;
} }

View File

@ -221,6 +221,7 @@ int mp4_decode(OutputBuffer * cb, DecoderControl * dc) {
seekPositionFound = 0; seekPositionFound = 0;
chunkLen = 0; chunkLen = 0;
clearOutputBuffer(cb); clearOutputBuffer(cb);
dc->seekChunk = cb->end;
dc->seek = 0; dc->seek = 0;
} }

View File

@ -192,6 +192,7 @@ int ogg_decode(OutputBuffer * cb, DecoderControl * dc)
if(dc->seek) { if(dc->seek) {
clearOutputBuffer(cb); clearOutputBuffer(cb);
chunkpos = 0; chunkpos = 0;
dc->seekChunk = cb->end;
ov_time_seek_page(&vf,dc->seekWhere); ov_time_seek_page(&vf,dc->seekWhere);
dc->seek = 0; dc->seek = 0;
} }

View File

@ -73,13 +73,11 @@ int sendDataToOutputBuffer(OutputBuffer * cb, DecoderControl * dc,
while(datalen) { while(datalen) {
if(currentChunk != cb->end) { if(currentChunk != cb->end) {
while(cb->begin==cb->end && cb->wrap && !dc->stop && while(cb->begin==cb->end && cb->wrap && !dc->stop)
!dc->seek)
{ {
my_usleep(10000); my_usleep(10000);
} }
if(dc->stop) return OUTPUT_BUFFER_DC_STOP; if(dc->stop) return OUTPUT_BUFFER_DC_STOP;
if(dc->seek) return OUTPUT_BUFFER_DC_SEEK;
currentChunk = cb->end; currentChunk = cb->end;
cb->chunkSize[currentChunk] = 0; cb->chunkSize[currentChunk] = 0;