added decoder_seek_where() and decoder_seek_error()
Provide access to seeking for the decoder plugins; they have to know where to seek, and they need a way to tell us that seeking has failed.
This commit is contained in:
parent
78c55e2432
commit
17e9cc84c5
@ -58,6 +58,21 @@ void decoder_command_finished(mpd_unused struct decoder * decoder)
|
|||||||
notify_signal(&pc.notify);
|
notify_signal(&pc.notify);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double decoder_seek_where(mpd_unused struct decoder * decoder)
|
||||||
|
{
|
||||||
|
assert(dc.command == DECODE_COMMAND_SEEK);
|
||||||
|
|
||||||
|
return dc.seekWhere;
|
||||||
|
}
|
||||||
|
|
||||||
|
void decoder_seek_error(struct decoder * decoder)
|
||||||
|
{
|
||||||
|
assert(dc.command == DECODE_COMMAND_SEEK);
|
||||||
|
|
||||||
|
dc.seekError = 1;
|
||||||
|
decoder_command_finished(decoder);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All chunks are full of decoded data; wait for the player to free
|
* All chunks are full of decoded data; wait for the player to free
|
||||||
* one.
|
* one.
|
||||||
@ -72,8 +87,7 @@ static int need_chunks(struct decoder *decoder, InputStream * inStream,
|
|||||||
if (seekable) {
|
if (seekable) {
|
||||||
return OUTPUT_BUFFER_DC_SEEK;
|
return OUTPUT_BUFFER_DC_SEEK;
|
||||||
} else {
|
} else {
|
||||||
dc.seekError = 1;
|
decoder_seek_error(decoder);
|
||||||
decoder_command_finished(decoder);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,6 +112,10 @@ enum decoder_command decoder_get_command(struct decoder * decoder);
|
|||||||
*/
|
*/
|
||||||
void decoder_command_finished(struct decoder * decoder);
|
void decoder_command_finished(struct decoder * decoder);
|
||||||
|
|
||||||
|
double decoder_seek_where(struct decoder * decoder);
|
||||||
|
|
||||||
|
void decoder_seek_error(struct decoder * decoder);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function is called by the decoder plugin when it has
|
* This function is called by the decoder plugin when it has
|
||||||
* successfully decoded block of input data.
|
* successfully decoded block of input data.
|
||||||
|
@ -389,10 +389,9 @@ static int aac_decode(struct decoder * mpd_decoder, char *path)
|
|||||||
decoder_data(mpd_decoder, NULL, 0, sampleBuffer,
|
decoder_data(mpd_decoder, NULL, 0, sampleBuffer,
|
||||||
sampleBufferLen, file_time,
|
sampleBufferLen, file_time,
|
||||||
bitRate, NULL);
|
bitRate, NULL);
|
||||||
if (decoder_get_command(decoder) == DECODE_COMMAND_SEEK) {
|
if (decoder_get_command(mpd_decoder) == DECODE_COMMAND_SEEK) {
|
||||||
dc.seekError = 1;
|
decoder_seek_error(mpd_decoder);
|
||||||
decoder_command_finished(decoder);
|
} else if (decoder_get_command(mpd_decoder) == DECODE_COMMAND_STOP)
|
||||||
} else if (decoder_get_command(decoder) == DECODE_COMMAND_STOP)
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -405,9 +404,8 @@ static int aac_decode(struct decoder * mpd_decoder, char *path)
|
|||||||
if (dc.state != DECODE_STATE_DECODE)
|
if (dc.state != DECODE_STATE_DECODE)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (decoder_get_command(decoder) == DECODE_COMMAND_SEEK) {
|
if (decoder_get_command(mpd_decoder) == DECODE_COMMAND_SEEK) {
|
||||||
dc.seekError = 1;
|
decoder_seek_error(mpd_decoder);
|
||||||
decoder_command_finished(decoder);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -92,7 +92,7 @@ static int audiofile_decode(struct decoder * decoder, char *path)
|
|||||||
do {
|
do {
|
||||||
if (decoder_get_command(decoder) == DECODE_COMMAND_SEEK) {
|
if (decoder_get_command(decoder) == DECODE_COMMAND_SEEK) {
|
||||||
decoder_clear(decoder);
|
decoder_clear(decoder);
|
||||||
current = dc.seekWhere *
|
current = decoder_seek_where(decoder) *
|
||||||
audio_format.sampleRate;
|
audio_format.sampleRate;
|
||||||
afSeekFrame(af_fp, AF_DEFAULT_TRACK, current);
|
afSeekFrame(af_fp, AF_DEFAULT_TRACK, current);
|
||||||
decoder_command_finished(decoder);
|
decoder_command_finished(decoder);
|
||||||
|
@ -424,16 +424,16 @@ static int flac_decode_internal(struct decoder * decoder,
|
|||||||
if (flac_get_state(flacDec) == flac_decoder_eof)
|
if (flac_get_state(flacDec) == flac_decoder_eof)
|
||||||
break;
|
break;
|
||||||
if (decoder_get_command(decoder) == DECODE_COMMAND_SEEK) {
|
if (decoder_get_command(decoder) == DECODE_COMMAND_SEEK) {
|
||||||
FLAC__uint64 sampleToSeek = dc.seekWhere *
|
FLAC__uint64 sampleToSeek = decoder_seek_where(decoder) *
|
||||||
data.audio_format.sampleRate + 0.5;
|
data.audio_format.sampleRate + 0.5;
|
||||||
if (flac_seek_absolute(flacDec, sampleToSeek)) {
|
if (flac_seek_absolute(flacDec, sampleToSeek)) {
|
||||||
decoder_clear(decoder);
|
decoder_clear(decoder);
|
||||||
data.time = ((float)sampleToSeek) /
|
data.time = ((float)sampleToSeek) /
|
||||||
data.audio_format.sampleRate;
|
data.audio_format.sampleRate;
|
||||||
data.position = 0;
|
data.position = 0;
|
||||||
|
decoder_command_finished(decoder);
|
||||||
} else
|
} else
|
||||||
dc.seekError = 1;
|
decoder_seek_error(decoder);
|
||||||
decoder_command_finished(decoder);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (decoder_get_command(decoder) != DECODE_COMMAND_STOP) {
|
if (decoder_get_command(decoder) != DECODE_COMMAND_STOP) {
|
||||||
|
@ -188,8 +188,7 @@ static int mod_decode(struct decoder * decoder, char *path)
|
|||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (decoder_get_command(decoder) == DECODE_COMMAND_SEEK) {
|
if (decoder_get_command(decoder) == DECODE_COMMAND_SEEK) {
|
||||||
dc.seekError = 1;
|
decoder_seek_error(decoder);
|
||||||
decoder_command_finished(decoder);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (decoder_get_command(decoder) == DECODE_COMMAND_STOP)
|
if (decoder_get_command(decoder) == DECODE_COMMAND_STOP)
|
||||||
|
@ -851,7 +851,7 @@ static int mp3Read(mp3DecodeData * data, struct decoder *decoder,
|
|||||||
data->muteFrame = 0;
|
data->muteFrame = 0;
|
||||||
break;
|
break;
|
||||||
case MUTEFRAME_SEEK:
|
case MUTEFRAME_SEEK:
|
||||||
if (dc.seekWhere <= data->elapsedTime) {
|
if (decoder_seek_where(decoder) <= data->elapsedTime) {
|
||||||
data->outputPtr = data->outputBuffer;
|
data->outputPtr = data->outputBuffer;
|
||||||
decoder_clear(decoder);
|
decoder_clear(decoder);
|
||||||
data->muteFrame = 0;
|
data->muteFrame = 0;
|
||||||
@ -952,7 +952,8 @@ static int mp3Read(mp3DecodeData * data, struct decoder *decoder,
|
|||||||
data->inStream->seekable) {
|
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 &&
|
||||||
|
decoder_seek_where(decoder) >
|
||||||
((float)mad_timer_count(data->times[j],
|
((float)mad_timer_count(data->times[j],
|
||||||
MAD_UNITS_MILLISECONDS))
|
MAD_UNITS_MILLISECONDS))
|
||||||
/ 1000) {
|
/ 1000) {
|
||||||
@ -965,15 +966,14 @@ static int mp3Read(mp3DecodeData * data, struct decoder *decoder,
|
|||||||
data->outputPtr = data->outputBuffer;
|
data->outputPtr = data->outputBuffer;
|
||||||
decoder_clear(decoder);
|
decoder_clear(decoder);
|
||||||
data->currentFrame = j;
|
data->currentFrame = j;
|
||||||
|
decoder_command_finished(decoder);
|
||||||
} else
|
} else
|
||||||
dc.seekError = 1;
|
decoder_seek_error(decoder);
|
||||||
data->muteFrame = 0;
|
data->muteFrame = 0;
|
||||||
decoder_command_finished(decoder);
|
|
||||||
}
|
}
|
||||||
} else if (decoder_get_command(decoder) == DECODE_COMMAND_SEEK &&
|
} else if (decoder_get_command(decoder) == DECODE_COMMAND_SEEK &&
|
||||||
!data->inStream->seekable) {
|
!data->inStream->seekable) {
|
||||||
dc.seekError = 1;
|
decoder_seek_error(decoder);
|
||||||
decoder_command_finished(decoder);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,6 +106,7 @@ static int mp4_decode(struct decoder * mpd_decoder, InputStream * inStream)
|
|||||||
long offset;
|
long offset;
|
||||||
mpd_uint16 bitRate = 0;
|
mpd_uint16 bitRate = 0;
|
||||||
int seeking = 0;
|
int seeking = 0;
|
||||||
|
double seek_where = 0;
|
||||||
|
|
||||||
mp4cb = xmalloc(sizeof(mp4ff_callback_t));
|
mp4cb = xmalloc(sizeof(mp4ff_callback_t));
|
||||||
mp4cb->read = mp4_inputStreamReadCallback;
|
mp4cb->read = mp4_inputStreamReadCallback;
|
||||||
@ -178,13 +179,15 @@ static int mp4_decode(struct decoder * mpd_decoder, InputStream * inStream)
|
|||||||
seekTable = xmalloc(sizeof(float) * numSamples);
|
seekTable = xmalloc(sizeof(float) * numSamples);
|
||||||
|
|
||||||
for (sampleId = 0; sampleId < numSamples; sampleId++) {
|
for (sampleId = 0; sampleId < numSamples; sampleId++) {
|
||||||
if (decoder_get_command(mpd_decoder) == DECODE_COMMAND_SEEK)
|
if (decoder_get_command(mpd_decoder) == DECODE_COMMAND_SEEK) {
|
||||||
seeking = 1;
|
seeking = 1;
|
||||||
|
seek_where = decoder_seek_where(mpd_decoder);
|
||||||
|
}
|
||||||
|
|
||||||
if (seeking && seekTableEnd > 1 &&
|
if (seeking && seekTableEnd > 1 &&
|
||||||
seekTable[seekTableEnd] >= dc.seekWhere) {
|
seekTable[seekTableEnd] >= seek_where) {
|
||||||
int i = 2;
|
int i = 2;
|
||||||
while (seekTable[i] < dc.seekWhere)
|
while (seekTable[i] < seek_where)
|
||||||
i++;
|
i++;
|
||||||
sampleId = i - 1;
|
sampleId = i - 1;
|
||||||
file_time = seekTable[sampleId];
|
file_time = seekTable[sampleId];
|
||||||
@ -206,7 +209,7 @@ static int mp4_decode(struct decoder * mpd_decoder, InputStream * inStream)
|
|||||||
dur -= offset;
|
dur -= offset;
|
||||||
file_time += ((float)dur) / scale;
|
file_time += ((float)dur) / scale;
|
||||||
|
|
||||||
if (seeking && file_time > dc.seekWhere)
|
if (seeking && file_time > seek_where)
|
||||||
seekPositionFound = 1;
|
seekPositionFound = 1;
|
||||||
|
|
||||||
if (seeking && seekPositionFound) {
|
if (seeking && seekPositionFound) {
|
||||||
|
@ -178,14 +178,15 @@ static int mpc_decode(struct decoder * mpd_decoder, InputStream * inStream)
|
|||||||
|
|
||||||
while (!eof) {
|
while (!eof) {
|
||||||
if (decoder_get_command(mpd_decoder) == DECODE_COMMAND_SEEK) {
|
if (decoder_get_command(mpd_decoder) == DECODE_COMMAND_SEEK) {
|
||||||
samplePos = dc.seekWhere * audio_format.sampleRate;
|
samplePos = decoder_seek_where(mpd_decoder) *
|
||||||
|
audio_format.sampleRate;
|
||||||
if (mpc_decoder_seek_sample(&decoder, samplePos)) {
|
if (mpc_decoder_seek_sample(&decoder, samplePos)) {
|
||||||
decoder_clear(mpd_decoder);
|
decoder_clear(mpd_decoder);
|
||||||
s16 = (mpd_sint16 *) chunk;
|
s16 = (mpd_sint16 *) chunk;
|
||||||
chunkpos = 0;
|
chunkpos = 0;
|
||||||
|
decoder_command_finished(mpd_decoder);
|
||||||
} else
|
} else
|
||||||
dc.seekError = 1;
|
decoder_seek_error(mpd_decoder);
|
||||||
decoder_command_finished(mpd_decoder);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vbrUpdateAcc = 0;
|
vbrUpdateAcc = 0;
|
||||||
|
@ -333,7 +333,6 @@ static unsigned int oggflac_try_decode(InputStream * inStream)
|
|||||||
|
|
||||||
static int oggflac_decode(struct decoder * mpd_decoder, InputStream * inStream)
|
static int oggflac_decode(struct decoder * mpd_decoder, InputStream * inStream)
|
||||||
{
|
{
|
||||||
DecoderControl *dc = mpd_decoder->dc;
|
|
||||||
OggFLAC__SeekableStreamDecoder *decoder = NULL;
|
OggFLAC__SeekableStreamDecoder *decoder = NULL;
|
||||||
FlacData data;
|
FlacData data;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@ -354,7 +353,7 @@ static int oggflac_decode(struct decoder * mpd_decoder, InputStream * inStream)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (decoder_get_command(mpd_decoder) == DECODE_COMMAND_SEEK) {
|
if (decoder_get_command(mpd_decoder) == DECODE_COMMAND_SEEK) {
|
||||||
FLAC__uint64 sampleToSeek = dc->seekWhere *
|
FLAC__uint64 sampleToSeek = decoder_seek_where(mpd_decoder) *
|
||||||
data.audio_format.sampleRate + 0.5;
|
data.audio_format.sampleRate + 0.5;
|
||||||
if (OggFLAC__seekable_stream_decoder_seek_absolute
|
if (OggFLAC__seekable_stream_decoder_seek_absolute
|
||||||
(decoder, sampleToSeek)) {
|
(decoder, sampleToSeek)) {
|
||||||
@ -362,9 +361,9 @@ static int oggflac_decode(struct decoder * mpd_decoder, InputStream * inStream)
|
|||||||
data.time = ((float)sampleToSeek) /
|
data.time = ((float)sampleToSeek) /
|
||||||
data.audio_format.sampleRate;
|
data.audio_format.sampleRate;
|
||||||
data.position = 0;
|
data.position = 0;
|
||||||
|
decoder_command_finished(mpd_decoder);
|
||||||
} else
|
} else
|
||||||
dc.seekError = 1;
|
decoder_seek_error(mpd_decoder);
|
||||||
decoder_command_finished(mpd_decoder);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,12 +268,13 @@ static int oggvorbis_decode(struct decoder * decoder, InputStream * inStream)
|
|||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (decoder_get_command(decoder) == DECODE_COMMAND_SEEK) {
|
if (decoder_get_command(decoder) == DECODE_COMMAND_SEEK) {
|
||||||
if (0 == ov_time_seek_page(&vf, dc.seekWhere)) {
|
double seek_where = decoder_seek_where(decoder);
|
||||||
|
if (0 == ov_time_seek_page(&vf, seek_where)) {
|
||||||
decoder_clear(decoder);
|
decoder_clear(decoder);
|
||||||
chunkpos = 0;
|
chunkpos = 0;
|
||||||
|
decoder_command_finished(decoder);
|
||||||
} else
|
} else
|
||||||
dc.seekError = 1;
|
decoder_seek_error(decoder);
|
||||||
decoder_command_finished(decoder);
|
|
||||||
}
|
}
|
||||||
ret = ov_read(&vf, chunk + chunkpos,
|
ret = ov_read(&vf, chunk + chunkpos,
|
||||||
OGG_CHUNK_SIZE - chunkpos,
|
OGG_CHUNK_SIZE - chunkpos,
|
||||||
|
@ -178,17 +178,16 @@ static void wavpack_decode(struct decoder * decoder,
|
|||||||
|
|
||||||
decoder_clear(decoder);
|
decoder_clear(decoder);
|
||||||
|
|
||||||
where = dc.seekWhere *
|
where = decoder_seek_where(decoder) *
|
||||||
audio_format.sampleRate;
|
audio_format.sampleRate;
|
||||||
if (WavpackSeekSample(wpc, where))
|
if (WavpackSeekSample(wpc, where)) {
|
||||||
position = where;
|
position = where;
|
||||||
else
|
decoder_command_finished(decoder);
|
||||||
dc.seekError = 1;
|
} else
|
||||||
|
decoder_seek_error(decoder);
|
||||||
} else {
|
} else {
|
||||||
dc.seekError = 1;
|
decoder_seek_error(decoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
decoder_command_finished(decoder);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (decoder_get_command(decoder) == DECODE_COMMAND_STOP)
|
if (decoder_get_command(decoder) == DECODE_COMMAND_STOP)
|
||||||
|
Loading…
Reference in New Issue
Block a user