fixed seek, its now blocking again

git-svn-id: https://svn.musicpd.org/mpd/trunk@1237 09075e82-0dd4-0310-85a5-a0d7c8717e4f
This commit is contained in:
Warren Dukes 2004-05-30 13:33:13 +00:00
parent c4396a6be6
commit d80093fed6
10 changed files with 79 additions and 61 deletions

21
TODO
View File

@ -1,9 +1,4 @@
1) seek needs to be rethought! as it is, it hangs near end of songs! 1) play streams
a) prolly need to make it blocking again, argh!
1) in decodeInit(), if (dc->seek) decodeStart();
b) for sure, setting wrap = 0 in decode.c is not good!
2) play streams
a) put some sort of error reporting for streaming/inputStream! a) put some sort of error reporting for streaming/inputStream!
b) fetch metadata and store in DecoderControl and pass to b) fetch metadata and store in DecoderControl and pass to
PlayerControl PlayerControl
@ -13,23 +8,23 @@
or something or something
d) in songinfo add a metadata tag item for indicating stream d) in songinfo add a metadata tag item for indicating stream
3) resampling audio for compatibility, and better gapless/crossfading 2) resampling audio for compatibility, and better gapless/crossfading
a) use resampling from oggenc (is it fast enough for realtime?) a) use resampling from oggenc (is it fast enough for realtime?)
4) when writing combined interface for all decodes to use, be sure to add a 3) when writing combined interface for all decodes to use, be sure to add a
common function and abstrct dealing with DecoderControl * and put common function and abstrct dealing with DecoderControl * and put
cycleLogFiles in there, so we cycleLogFiles while decoding, not just when cycleLogFiles in there, so we cycleLogFiles while decoding, not just when
decoding has stopped. decoding has stopped.
5) ACK error codes 4) ACK error codes
6) cleanup main() 5) cleanup main()
7) handle '\n' in filenames 6) handle '\n' in filenames
8) compute average replaygain to use for non-replaygain songs 7) compute average replaygain to use for non-replaygain songs
9) pid file 8) pid file
Post-1.0 Post-1.0

View File

@ -364,7 +364,10 @@ int aac_decode(OutputBuffer * cb, DecoderControl * dc) {
sendDataToOutputBuffer(cb, NULL, dc, 0, sampleBuffer, sendDataToOutputBuffer(cb, NULL, dc, 0, sampleBuffer,
sampleBufferLen, time, bitRate); sampleBufferLen, time, bitRate);
if(dc->seek) dc->seek = 0; if(dc->seek) {
dc->seekError = 1;
dc->seek = 0;
}
else if(dc->stop) { else if(dc->stop) {
eof = 1; eof = 1;
break; break;
@ -379,7 +382,10 @@ 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->seek) dc->seek = 0; if(dc->seek) {
dc->seekError = 1;
dc->seek = 0;
}
if(dc->stop) { if(dc->stop) {
dc->state = DECODE_STATE_STOP; dc->state = DECODE_STATE_STOP;

View File

@ -101,7 +101,6 @@ 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;
} }
@ -124,7 +123,10 @@ int audiofile_decode(OutputBuffer * cb, DecoderControl * dc) {
flushOutputBuffer(cb); flushOutputBuffer(cb);
if(dc->seek) dc->seek = 0; /*if(dc->seek) {
dc->seekError = 1;
dc->seek = 0;
}*/
if(dc->stop) { if(dc->stop) {
dc->state = DECODE_STATE_STOP; dc->state = DECODE_STATE_STOP;

View File

@ -173,7 +173,7 @@ int decodeSeek(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb,
{ {
int ret = -1; int ret = -1;
if(decode_pid && *decode_pid>0 && !dc->seek) { if(decode_pid && *decode_pid>0) {
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)
@ -186,16 +186,21 @@ int decodeSeek(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb,
dc->start = 1; dc->start = 1;
waitOnDecode(pc,dc,cb,decodeWaitedOn); waitOnDecode(pc,dc,cb,decodeWaitedOn);
} }
if(*decode_pid>0 && dc->state!=DECODE_STATE_STOP) { if(*decode_pid>0 && dc->state!=DECODE_STATE_STOP &&
dc->seekable)
{
dc->seekWhere = pc->seekWhere > pc->totalTime-0.1 ? dc->seekWhere = pc->seekWhere > pc->totalTime-0.1 ?
pc->totalTime-0.1 : pc->totalTime-0.1 :
pc->seekWhere; pc->seekWhere;
dc->seekWhere = 0 > dc->seekWhere ? 0 : dc->seekWhere; dc->seekWhere = 0 > dc->seekWhere ? 0 : dc->seekWhere;
dc->seekChunk = -1; dc->seekError = 0;
dc->seek = 1; dc->seek = 1;
pc->elapsedTime = dc->seekWhere; while(*decode_pid>0 && dc->seek) my_usleep(10000);
pc->beginTime = pc->elapsedTime; if(!dc->seekError) {
ret = 0; pc->elapsedTime = dc->seekWhere;
pc->beginTime = pc->elapsedTime;
ret = 0;
}
} }
} }
pc->seek = 0; pc->seek = 0;
@ -239,7 +244,6 @@ 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) { \
@ -265,11 +269,12 @@ 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;
while(!inputStreamAtEOF(&inStream) && bufferInputStream(&inStream) < 0 while(!inputStreamAtEOF(&inStream) && bufferInputStream(&inStream) < 0
&& !pc->stop); && !dc->stop);
if(dc->stop) { if(dc->stop) {
dc->state = DECODE_STATE_STOP; dc->state = DECODE_STATE_STOP;
@ -368,7 +373,7 @@ int decoderInit(PlayerControl * pc, OutputBuffer * cb, DecoderControl * dc) {
myfprintfCloseAndOpenLogFile(); myfprintfCloseAndOpenLogFile();
dc->cycleLogFiles = 0; dc->cycleLogFiles = 0;
} }
else if(dc->start) decodeStart(pc, cb, dc); else if(dc->start || dc->seek) decodeStart(pc, cb, dc);
else if(dc->stop) { else if(dc->stop) {
dc->state = DECODE_STATE_STOP; dc->state = DECODE_STATE_STOP;
dc->stop = 0; dc->stop = 0;
@ -404,7 +409,6 @@ 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);
@ -426,13 +430,6 @@ 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;
cb->wrap = 0;
}
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)
@ -507,7 +504,7 @@ void decodeParent(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb) {
else continue; else continue;
} }
} }
if(!seeking) pc->elapsedTime = cb->times[cb->begin]; 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

@ -51,7 +51,8 @@ typedef struct _DecoderControl {
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 seekable;
volatile mpd_sint8 cycleLogFiles; volatile mpd_sint8 cycleLogFiles;
volatile double seekWhere; volatile double seekWhere;
char file[MAXPATHLEN+1]; char file[MAXPATHLEN+1];

View File

@ -146,15 +146,15 @@ int flac_decode(OutputBuffer * cb, DecoderControl *dc) {
if(dc->seek) { if(dc->seek) {
FLAC__uint64 sampleToSeek = dc->seekWhere* FLAC__uint64 sampleToSeek = dc->seekWhere*
dc->audioFormat.sampleRate+0.5; dc->audioFormat.sampleRate+0.5;
clearOutputBuffer(cb);
if(FLAC__seekable_stream_decoder_seek_absolute(flacDec, if(FLAC__seekable_stream_decoder_seek_absolute(flacDec,
sampleToSeek)) sampleToSeek))
{ {
clearOutputBuffer(cb);
data.time = ((float)sampleToSeek)/ data.time = ((float)sampleToSeek)/
dc->audioFormat.sampleRate; dc->audioFormat.sampleRate;
data.position = 0; data.position = 0;
} }
dc->seekChunk = cb->end; else dc->seekError = 1;
dc->seek = 0; dc->seek = 0;
} }
} }
@ -173,7 +173,10 @@ int flac_decode(OutputBuffer * cb, DecoderControl *dc) {
flushOutputBuffer(data.cb); flushOutputBuffer(data.cb);
} }
if(dc->seek) dc->seek = 0; /*if(dc->seek) {
dc->seekError = 1;
dc->seek = 0;
} */
if(dc->stop) { if(dc->stop) {
dc->state = DECODE_STATE_STOP; dc->state = DECODE_STATE_STOP;

View File

@ -468,7 +468,6 @@ int mp3Read(mp3DecodeData * data, OutputBuffer * cb, DecoderControl * dc) {
if(dc->seekWhere<=data->elapsedTime) { if(dc->seekWhere<=data->elapsedTime) {
data->outputPtr = data->outputBuffer; data->outputPtr = data->outputBuffer;
clearOutputBuffer(cb); clearOutputBuffer(cb);
dc->seekChunk = cb->end;
data->muteFrame = 0; data->muteFrame = 0;
dc->seek = 0; dc->seek = 0;
} }
@ -528,26 +527,29 @@ int mp3Read(mp3DecodeData * data, OutputBuffer * cb, DecoderControl * dc) {
{ {
data->outputPtr = data->outputBuffer; data->outputPtr = data->outputBuffer;
clearOutputBuffer(cb); clearOutputBuffer(cb);
dc->seekChunk = cb->end;
data->currentFrame = i; data->currentFrame = i;
} }
else dc->seekError = 1;
data->muteFrame = 0; data->muteFrame = 0;
dc->seek = 0; dc->seek = 0;
} }
} }
else if(dc->seek && !data->inStream->seekable) dc->seek = 0; else if(dc->seek && !data->inStream->seekable) {
dc->seek = 0;
dc->seekError = 1;
}
} }
while(1) { while(1) {
skip = 0; skip = 0;
while((ret = decodeNextFrameHeader(data))==DECODE_CONT && while((ret = decodeNextFrameHeader(data))==DECODE_CONT &&
!dc->stop); !dc->stop && !dc->seek);
if(ret==DECODE_SKIP) skip = 1; if(ret==DECODE_BREAK || dc->stop || dc->seek) break;
else if(ret==DECODE_BREAK || dc->stop) break; else if(ret==DECODE_SKIP) skip = 1;
if(!data->muteFrame) { if(!data->muteFrame) {
while((ret = decodeNextFrame(data))==DECODE_CONT && while((ret = decodeNextFrame(data))==DECODE_CONT &&
!dc->stop); !dc->stop && !dc->seek);
if(ret==DECODE_BREAK || dc->stop) break; if(ret==DECODE_BREAK || dc->stop || dc->seek) break;
} }
if(!skip && ret==DECODE_OK) break; if(!skip && ret==DECODE_OK) break;
} }
@ -590,17 +592,20 @@ int mp3_decode(OutputBuffer * cb, DecoderControl * dc, InputStream * inStream,
while(mp3Read(&data,cb,dc)!=DECODE_BREAK); while(mp3Read(&data,cb,dc)!=DECODE_BREAK);
/* send last little bit if not dc->stop */ /* send last little bit if not dc->stop */
if(data.outputPtr!=data.outputBuffer && data.flush) { if(data.outputPtr!=data.outputBuffer && data.flush) {
if(sendDataToOutputBuffer(cb,NULL,dc,0,data.outputBuffer, sendDataToOutputBuffer(cb, NULL, dc,
data.inStream->seekable,
data.outputBuffer,
data.outputPtr-data.outputBuffer, data.outputPtr-data.outputBuffer,
data.elapsedTime,data.bitRate/1000) == 0) data.elapsedTime,data.bitRate/1000);
{
flushOutputBuffer(cb);
}
} }
flushOutputBuffer(cb);
mp3DecodeDataFinalize(&data); mp3DecodeDataFinalize(&data);
if(dc->seek) dc->seek = 0; /*if(dc->seek) {
dc->seekError = 1;
dc->seek = 0;
}*/
if(dc->stop) { if(dc->stop) {
dc->state = DECODE_STATE_STOP; dc->state = DECODE_STATE_STOP;

View File

@ -27,6 +27,7 @@
#include "pcm_utils.h" #include "pcm_utils.h"
#include "inputStream.h" #include "inputStream.h"
#include "outputBuffer.h" #include "outputBuffer.h"
#include "decode.h"
#include "mp4ff/mp4ff.h" #include "mp4ff/mp4ff.h"
@ -220,7 +221,6 @@ int mp4_decode(OutputBuffer * cb, DecoderControl * dc) {
if(dc->seek && seekPositionFound) { if(dc->seek && seekPositionFound) {
seekPositionFound = 0; seekPositionFound = 0;
clearOutputBuffer(cb); clearOutputBuffer(cb);
dc->seekChunk = cb->end;
dc->seek = 0; dc->seek = 0;
} }
@ -298,7 +298,10 @@ int mp4_decode(OutputBuffer * cb, DecoderControl * dc) {
if(dc->state != DECODE_STATE_DECODE) return -1; if(dc->state != DECODE_STATE_DECODE) return -1;
if(dc->seek) dc->seek = 0; /*if(dc->seek) {
dc->seekError = 1;
dc->seek = 0;
}*/
if(dc->stop) { if(dc->stop) {
dc->state = DECODE_STATE_STOP; dc->state = DECODE_STATE_STOP;

View File

@ -219,8 +219,8 @@ int ogg_decode(OutputBuffer * cb, DecoderControl * dc, InputStream * inStream)
if(0 == ov_time_seek_page(&vf,dc->seekWhere)) { if(0 == ov_time_seek_page(&vf,dc->seekWhere)) {
clearOutputBuffer(cb); clearOutputBuffer(cb);
chunkpos = 0; chunkpos = 0;
dc->seekChunk = cb->end;
} }
else dc->seekError = 1;
dc->seek = 0; dc->seek = 0;
} }
ret = ov_read(&vf, chunk+chunkpos, ret = ov_read(&vf, chunk+chunkpos,
@ -251,7 +251,7 @@ int ogg_decode(OutputBuffer * cb, DecoderControl * dc, InputStream * inStream)
} }
if(!dc->stop && chunkpos > 0) { if(!dc->stop && chunkpos > 0) {
sendDataToOutputBuffer(cb, NULL, dc, 0, chunk, chunkpos, sendDataToOutputBuffer(cb, NULL, dc, inStream->seekable, chunk, chunkpos,
ov_time_tell(&vf), bitRate); ov_time_tell(&vf), bitRate);
} }
@ -259,7 +259,10 @@ int ogg_decode(OutputBuffer * cb, DecoderControl * dc, InputStream * inStream)
flushOutputBuffer(cb); flushOutputBuffer(cb);
if(dc->seek) dc->seek = 0; /*if(dc->seek) {
dc->seekError = 1;
dc->seek = 0;
}*/
if(dc->stop) { if(dc->stop) {
dc->state = DECODE_STATE_STOP; dc->state = DECODE_STATE_STOP;

View File

@ -28,8 +28,8 @@ static mpd_sint16 currentChunk = -1;
void clearOutputBuffer(OutputBuffer * cb) { void clearOutputBuffer(OutputBuffer * cb) {
currentChunk = -1; currentChunk = -1;
/*cb->end = cb->begin; cb->end = cb->begin;
cb->wrap = 0;*/ cb->wrap = 0;
} }
void flushOutputBuffer(OutputBuffer * cb) { void flushOutputBuffer(OutputBuffer * cb) {
@ -80,7 +80,10 @@ int sendDataToOutputBuffer(OutputBuffer * cb, InputStream * inStream,
if(seekable) { if(seekable) {
return OUTPUT_BUFFER_DC_SEEK; return OUTPUT_BUFFER_DC_SEEK;
} }
else dc->seek = 0; else {
dc->seekError = 1;
dc->seek = 0;
}
} }
if(!inStream || if(!inStream ||
bufferInputStream(inStream) <= 0) bufferInputStream(inStream) <= 0)