Commit a81573ef authored by Warren Dukes's avatar Warren Dukes

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
parent c1fbcd03
......@@ -2,17 +2,9 @@
a) make seekings non-blocking:
1) player:
a) first check that seekWhere isn't already buffered
b) if not current song, stop it and play the song to
seek
c) set dc->seek and dc->seekWhere if not already set
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!
2) check that stream is seekable before seeking forward!
3) deal with seeking forward better by calling seek function
(for mp3 and mp4)!
b) bufferInput in outputBuffer waiting!
1) implement some sort of callback mechanism for this
for abstraction sake
......
......@@ -383,7 +383,7 @@ int aac_decode(OutputBuffer * cb, DecoderControl * dc) {
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->end;
......
......@@ -101,7 +101,7 @@ int audiofile_decode(OutputBuffer * cb, DecoderControl * dc) {
current = dc->seekWhere *
dc->audioFormat.sampleRate;
afSeekFrame(af_fp, AF_DEFAULT_TRACK,current);
dc->seekChunk = cb->end;
dc->seek = 0;
}
......@@ -114,7 +114,6 @@ int audiofile_decode(OutputBuffer * cb, DecoderControl * dc) {
(float)dc->audioFormat.sampleRate,
bitRate);
if(dc->stop) break;
else if(dc->seek) continue;
}
}
......
......@@ -128,7 +128,7 @@ int calculateCrossFadeChunks(PlayerControl * pc, AudioFormat * af) {
pc->channels = dc->audioFormat.channels; \
} \
else if(decodeWaitedOn) { \
my_usleep(10); \
my_usleep(10000); \
continue; \
}
......@@ -161,7 +161,7 @@ int decodeSeek(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb,
{
int ret = -1;
if(decode_pid && *decode_pid>0) {
if(decode_pid && *decode_pid>0 && !dc->seek) {
cb->next = -1;
if(dc->state==DECODE_STATE_STOP || dc->error ||
strcmp(dc->file,pc->file)!=0)
......@@ -180,13 +180,14 @@ int decodeSeek(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb,
pc->seekWhere;
dc->seekWhere = 0 > dc->seekWhere ? 0 : dc->seekWhere;
dc->seekError = 0;
dc->seekChunk = -1;
dc->seek = 1;
pc->bitRate = 0;
while(*decode_pid>0 && dc->seek) my_usleep(1000);
if(!dc->seekError) {
/*pc->bitRate = 0;*/
/*while(*decode_pid>0 && dc->seek) my_usleep(1000);*/
/*if(!dc->seekError) {*/
ret = 0;
pc->elapsedTime = dc->seekWhere;
}
/*}*/
}
}
pc->seek = 0;
......@@ -231,6 +232,7 @@ int decodeSeek(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb,
doCrossFade = 0; \
nextChunk = -1; \
bbp = 0; \
seeking = 1; \
} \
} \
if(pc->stop) { \
......@@ -254,7 +256,6 @@ void decodeStart(PlayerControl * pc, OutputBuffer * cb, DecoderControl * dc) {
return;
}
dc->seekable = inStream.seekable;
dc->state = DECODE_STATE_START;
dc->start = 0;
......@@ -386,6 +387,7 @@ void decodeParent(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb) {
int test;
int decodeWaitedOn = 0;
char silence[CHUNK_SIZE];
int seeking = 0;
memset(silence,0,CHUNK_SIZE);
......@@ -407,6 +409,10 @@ void decodeParent(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb) {
while(!quit) {
processDecodeInput();
handleDecodeStart();
if(!dc->seek && seeking) {
if(dc->seekChunk >= 0) cb->begin = dc->seekChunk;
seeking = 0;
}
if(dc->state==DECODE_STATE_STOP &&
pc->queueState==PLAYER_QUEUE_FULL &&
pc->queueLockState==PLAYER_QUEUE_UNLOCKED)
......@@ -481,7 +487,7 @@ void decodeParent(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb) {
else continue;
}
}
pc->elapsedTime = cb->times[cb->begin];
if(!seeking) pc->elapsedTime = cb->times[cb->begin];
pc->bitRate = cb->bitRate[cb->begin];
pcm_volumeChange(cb->chunks+cb->begin*
CHUNK_SIZE,
......
......@@ -46,12 +46,12 @@
#define DECODE_SUFFIX_WAVE 6
typedef struct _DecoderControl {
volatile mpd_sint8 seekable;
volatile mpd_sint8 state;
volatile mpd_sint8 stop;
volatile mpd_sint8 start;
volatile mpd_uint16 error;
volatile mpd_sint8 seek;
volatile mpd_sint16 seekChunk;
volatile mpd_sint8 seekError;
volatile mpd_sint8 cycleLogFiles;
volatile double seekWhere;
......
......@@ -154,6 +154,7 @@ int flac_decode(OutputBuffer * cb, DecoderControl *dc) {
dc->audioFormat.sampleRate;
data.position = 0;
}
dc->seekChunk = cb->end;
dc->seek = 0;
}
}
......
......@@ -461,6 +461,7 @@ int mp3Read(mp3DecodeData * data, OutputBuffer * cb, DecoderControl * dc) {
if(!dc->seek) data->muteFrame = 0;
else if(dc->seekWhere<=data->elapsedTime) {
clearOutputBuffer(cb);
dc->seekChunk = cb->end;
data->muteFrame = 0;
dc->seek = 0;
}
......@@ -517,6 +518,7 @@ int mp3Read(mp3DecodeData * data, OutputBuffer * cb, DecoderControl * dc) {
data->frameOffset[i]) == 0)
{
clearOutputBuffer(cb);
dc->seekChunk = cb->end;
data->currentFrame = i;
data->muteFrame = 0;
}
......@@ -529,13 +531,13 @@ int mp3Read(mp3DecodeData * data, OutputBuffer * cb, DecoderControl * dc) {
while(1) {
skip = 0;
while((ret = decodeNextFrameHeader(data))==DECODE_CONT &&
!dc->seek && !dc->stop);
!dc->stop);
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) {
while((ret = decodeNextFrame(data))==DECODE_CONT &&
!dc->seek && !dc->stop);
if(ret==DECODE_BREAK || dc->seek || dc->stop) break;
!dc->stop);
if(ret==DECODE_BREAK || dc->stop) break;
}
if(!skip && ret==DECODE_OK) break;
}
......
......@@ -221,6 +221,7 @@ int mp4_decode(OutputBuffer * cb, DecoderControl * dc) {
seekPositionFound = 0;
chunkLen = 0;
clearOutputBuffer(cb);
dc->seekChunk = cb->end;
dc->seek = 0;
}
......
......@@ -192,6 +192,7 @@ int ogg_decode(OutputBuffer * cb, DecoderControl * dc)
if(dc->seek) {
clearOutputBuffer(cb);
chunkpos = 0;
dc->seekChunk = cb->end;
ov_time_seek_page(&vf,dc->seekWhere);
dc->seek = 0;
}
......
......@@ -73,13 +73,11 @@ int sendDataToOutputBuffer(OutputBuffer * cb, DecoderControl * dc,
while(datalen) {
if(currentChunk != cb->end) {
while(cb->begin==cb->end && cb->wrap && !dc->stop &&
!dc->seek)
while(cb->begin==cb->end && cb->wrap && !dc->stop)
{
my_usleep(10000);
}
if(dc->stop) return OUTPUT_BUFFER_DC_STOP;
if(dc->seek) return OUTPUT_BUFFER_DC_SEEK;
currentChunk = cb->end;
cb->chunkSize[currentChunk] = 0;
......
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