decoder/Client: add DecoderCommand/seek virtual methods

This commit is contained in:
Max Kellermann
2016-11-18 08:15:07 +01:00
parent 66fb352cca
commit 47a0f46ce8
24 changed files with 156 additions and 172 deletions

View File

@@ -228,10 +228,10 @@ audiofile_stream_decode(DecoderClient &client, InputStream &is)
kbit_rate);
if (cmd == DecoderCommand::SEEK) {
AFframecount frame = decoder_seek_where_frame(client);
AFframecount frame = client.GetSeekFrame();
afSeekFrame(fh, AF_DEFAULT_TRACK, frame);
decoder_command_finished(client);
client.CommandFinished();
cmd = DecoderCommand::NONE;
}
} while (cmd == DecoderCommand::NONE);

View File

@@ -372,23 +372,23 @@ dsdiff_decode_chunk(DecoderClient &client, InputStream &is,
const unsigned buffer_frames = sizeof(buffer) / frame_size;
const size_t buffer_size = buffer_frames * frame_size;
auto cmd = decoder_get_command(client);
auto cmd = client.GetCommand();
for (offset_type remaining_bytes = total_bytes;
remaining_bytes >= frame_size && cmd != DecoderCommand::STOP;) {
if (cmd == DecoderCommand::SEEK) {
uint64_t frame = decoder_seek_where_frame(client);
uint64_t frame = client.GetSeekFrame();
offset_type offset = FrameToOffset(frame, channels);
if (offset >= total_bytes) {
decoder_command_finished(client);
client.CommandFinished();
break;
}
if (dsdlib_skip_to(&client, is,
start_offset + offset)) {
decoder_command_finished(client);
client.CommandFinished();
remaining_bytes = total_bytes - offset;
} else
decoder_seek_error(client);
client.SeekError();
}
/* see how much aligned data from the remaining chunk

View File

@@ -259,23 +259,23 @@ dsf_decode_chunk(DecoderClient &client, InputStream &is,
const size_t block_size = channels * DSF_BLOCK_SIZE;
const offset_type start_offset = is.GetOffset();
auto cmd = decoder_get_command(client);
auto cmd = client.GetCommand();
for (offset_type i = 0; i < n_blocks && cmd != DecoderCommand::STOP;) {
if (cmd == DecoderCommand::SEEK) {
uint64_t frame = decoder_seek_where_frame(client);
uint64_t frame = client.GetSeekFrame();
offset_type block = FrameToBlock(frame);
if (block >= n_blocks) {
decoder_command_finished(client);
client.CommandFinished();
break;
}
offset_type offset =
start_offset + block * block_size;
if (dsdlib_skip_to(&client, is, offset)) {
decoder_command_finished(client);
client.CommandFinished();
i = block;
} else
decoder_seek_error(client);
client.SeekError();
}
/* worst-case buffer size */

View File

@@ -717,11 +717,11 @@ FfmpegDecode(DecoderClient &client, InputStream &input,
uint64_t min_frame = 0;
DecoderCommand cmd = decoder_get_command(client);
DecoderCommand cmd = client.GetCommand();
while (cmd != DecoderCommand::STOP) {
if (cmd == DecoderCommand::SEEK) {
int64_t where =
ToFfmpegTime(decoder_seek_time(client),
ToFfmpegTime(client.GetSeekTime(),
av_stream.time_base) +
start_time_fallback(av_stream);
@@ -730,11 +730,11 @@ FfmpegDecode(DecoderClient &client, InputStream &input,
stamp, not after */
if (av_seek_frame(&format_context, audio_stream, where,
AVSEEK_FLAG_ANY|AVSEEK_FLAG_BACKWARD) < 0)
decoder_seek_error(client);
client.SeekError();
else {
avcodec_flush_buffers(codec_context);
min_frame = decoder_seek_where_frame(client);
decoder_command_finished(client);
min_frame = client.GetSeekFrame();
client.CommandFinished();
}
}
@@ -757,7 +757,7 @@ FfmpegDecode(DecoderClient &client, InputStream &input,
interleaved_buffer);
min_frame = 0;
} else
cmd = decoder_get_command(client);
cmd = client.GetCommand();
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 25, 100)
av_packet_unref(&packet);

View File

@@ -151,16 +151,15 @@ flac_decoder_loop(FlacDecoder *data, FLAC__StreamDecoder *flac_dec)
std::move(data->tag));
data->tag.Clear();
} else
cmd = decoder_get_command(client);
cmd = client.GetCommand();
if (cmd == DecoderCommand::SEEK) {
FLAC__uint64 seek_sample =
decoder_seek_where_frame(client);
FLAC__uint64 seek_sample = client.GetSeekFrame();
if (FLAC__stream_decoder_seek_absolute(flac_dec, seek_sample)) {
data->position = 0;
decoder_command_finished(client);
client.CommandFinished();
} else
decoder_seek_error(client);
client.SeekError();
} else if (cmd == DecoderCommand::STOP)
break;
@@ -198,7 +197,7 @@ flac_decoder_loop(FlacDecoder *data, FLAC__StreamDecoder *flac_dec)
}
if (!FLAC__stream_decoder_process_single(flac_dec) &&
decoder_get_command(client) == DecoderCommand::NONE) {
client.GetCommand() == DecoderCommand::NONE) {
/* a failure that was not triggered by a
decoder command */
flacPrintErroredState(FLAC__stream_decoder_get_state(flac_dec));

View File

@@ -36,7 +36,7 @@ FlacInput::Read(FLAC__byte buffer[], size_t *bytes)
if (r == 0) {
if (input_stream.LockIsEOF() ||
(client != nullptr &&
decoder_get_command(*client) != DecoderCommand::NONE))
client->GetCommand() != DecoderCommand::NONE))
return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
else
return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
@@ -84,8 +84,8 @@ FLAC__bool
FlacInput::Eof()
{
return (client != nullptr &&
decoder_get_command(*client) != DecoderCommand::NONE &&
decoder_get_command(*client) != DecoderCommand::SEEK) ||
client->GetCommand() != DecoderCommand::NONE &&
client->GetCommand() != DecoderCommand::SEEK) ||
input_stream.LockIsEOF();
}
@@ -93,7 +93,7 @@ void
FlacInput::Error(FLAC__StreamDecoderErrorStatus status)
{
if (client == nullptr ||
decoder_get_command(*client) != DecoderCommand::STOP)
client->GetCommand() != DecoderCommand::STOP)
LogWarning(flac_domain,
FLAC__StreamDecoderErrorStatusString[status]);
}

View File

@@ -192,13 +192,13 @@ gme_file_decode(DecoderClient &client, Path path_fs)
cmd = decoder_data(client, nullptr, buf, sizeof(buf), 0);
if (cmd == DecoderCommand::SEEK) {
unsigned where = decoder_seek_time(client).ToMS();
unsigned where = client.GetSeekTime().ToMS();
gme_err = gme_seek(emu, where);
if (gme_err != nullptr) {
LogWarning(gme_domain, gme_err);
decoder_seek_error(client);
client.SeekError();
} else
decoder_command_finished(client);
client.CommandFinished();
}
if (gme_track_ended(emu))

View File

@@ -985,18 +985,18 @@ MadDecoder::Read()
if (cmd == DecoderCommand::SEEK) {
assert(input_stream.IsSeekable());
unsigned long j =
TimeToFrame(decoder_seek_time(*client));
const auto t = client->GetSeekTime();
unsigned long j = TimeToFrame(t);
if (j < highest_frame) {
if (Seek(frame_offsets[j])) {
current_frame = j;
decoder_command_finished(*client);
client->CommandFinished();
} else
decoder_seek_error(*client);
client->SeekError();
} else {
seek_time = decoder_seek_time(*client);
seek_time = t;
mute_frame = MUTEFRAME_SEEK;
decoder_command_finished(*client);
client->CommandFinished();
}
} else if (cmd != DecoderCommand::NONE)
return false;
@@ -1042,7 +1042,7 @@ mp3_decode(DecoderClient &client, InputStream &input_stream)
if (!data.DecodeFirstFrame(&tag)) {
delete tag;
if (decoder_get_command(client) == DecoderCommand::NONE)
if (client.GetCommand() == DecoderCommand::NONE)
LogError(mad_domain,
"input/Input does not appear to be a mp3 bit stream");
return;

View File

@@ -165,8 +165,8 @@ mod_decode(DecoderClient &client, InputStream &is)
0);
if (cmd == DecoderCommand::SEEK) {
ModPlug_Seek(f, decoder_seek_time(client).ToMS());
decoder_command_finished(client);
ModPlug_Seek(f, client.GetSeekTime().ToMS());
client.CommandFinished();
}
} while (cmd != DecoderCommand::STOP);

View File

@@ -152,7 +152,7 @@ mpcdec_decode(DecoderClient &client, InputStream &is)
mpc_demux *demux = mpc_demux_init(&reader);
if (demux == nullptr) {
if (decoder_get_command(client) != DecoderCommand::STOP)
if (client.GetCommand() != DecoderCommand::STOP)
LogWarning(mpcdec_domain,
"Not a valid musepack stream");
return;
@@ -180,16 +180,15 @@ mpcdec_decode(DecoderClient &client, InputStream &is)
DecoderCommand cmd = DecoderCommand::NONE;
do {
if (cmd == DecoderCommand::SEEK) {
mpc_int64_t where =
decoder_seek_where_frame(client);
mpc_int64_t where = client.GetSeekFrame();
bool success;
success = mpc_demux_seek_sample(demux, where)
== MPC_STATUS_OK;
if (success)
decoder_command_finished(client);
client.CommandFinished();
else
decoder_seek_error(client);
client.SeekError();
}
MPC_SAMPLE_FORMAT sample_buffer[MPC_DECODER_BUFFER_LENGTH];

View File

@@ -260,12 +260,12 @@ mpd_mpg123_file_decode(DecoderClient &client, Path path_fs)
cmd = decoder_data(client, nullptr, buffer, nbytes, info.bitrate);
if (cmd == DecoderCommand::SEEK) {
off_t c = decoder_seek_where_frame(client);
off_t c = client.GetSeekFrame();
c = mpg123_seek(handle, c, SEEK_SET);
if (c < 0)
decoder_seek_error(client);
client.SeekError();
else {
decoder_command_finished(client);
client.CommandFinished();
decoder_timestamp(client, c/(double)audio_format.sample_rate);
}

View File

@@ -181,7 +181,7 @@ MPDOpusDecoder::OnOggBeginning(const ogg_packet &packet)
output_buffer = new opus_int16[opus_output_buffer_frames
* audio_format.channels];
auto cmd = decoder_get_command(client);
auto cmd = client.GetCommand();
if (cmd != DecoderCommand::NONE)
throw cmd;
}
@@ -291,10 +291,10 @@ mpd_opus_stream_decode(DecoderClient &client,
break;
} catch (DecoderCommand cmd) {
if (cmd == DecoderCommand::SEEK) {
if (d.Seek(decoder_seek_where_frame(client)))
decoder_command_finished(client);
if (d.Seek(client.GetSeekFrame()))
client.CommandFinished();
else
decoder_seek_error(client);
client.SeekError();
} else if (cmd != DecoderCommand::NONE)
break;
}

View File

@@ -166,18 +166,18 @@ pcm_stream_decode(DecoderClient &client, InputStream &is)
cmd = !r.IsEmpty()
? decoder_data(client, is, r.data, r.size, 0)
: decoder_get_command(client);
: client.GetCommand();
if (cmd == DecoderCommand::SEEK) {
uint64_t frame = decoder_seek_where_frame(client);
uint64_t frame = client.GetSeekFrame();
offset_type offset = frame * frame_size;
try {
is.LockSeek(offset);
buffer.Clear();
decoder_command_finished(client);
client.CommandFinished();
} catch (const std::runtime_error &e) {
LogError(e);
decoder_seek_error(client);
client.SeekError();
}
cmd = DecoderCommand::NONE;

View File

@@ -373,7 +373,7 @@ sidplay_file_decode(DecoderClient &client, Path path_fs)
if (cmd == DecoderCommand::SEEK) {
unsigned data_time = player.time();
unsigned target_time =
decoder_seek_time(client).ToScale(timebase);
client.GetSeekTime().ToScale(timebase);
/* can't rewind so return to zero and seek forward */
if(target_time<data_time) {
@@ -386,7 +386,7 @@ sidplay_file_decode(DecoderClient &client, Path path_fs)
player.play(buffer, ARRAY_SIZE(buffer)) > 0)
data_time = player.time();
decoder_command_finished(client);
client.CommandFinished();
}
if (end > 0 && player.time() >= end)

View File

@@ -225,12 +225,12 @@ sndfile_stream_decode(DecoderClient &client, InputStream &is)
buffer, num_frames * frame_size,
0);
if (cmd == DecoderCommand::SEEK) {
sf_count_t c = decoder_seek_where_frame(client);
sf_count_t c = client.GetSeekFrame();
c = sf_seek(sf, c, SEEK_SET);
if (c < 0)
decoder_seek_error(client);
client.SeekError();
else
decoder_command_finished(client);
client.CommandFinished();
cmd = DecoderCommand::NONE;
}
} while (cmd == DecoderCommand::NONE);

View File

@@ -264,7 +264,7 @@ VorbisDecoder::OnOggPacket(const ogg_packet &_packet)
if (vorbis_synthesis(&block, &packet) != 0) {
/* ignore bad packets, but give the MPD core a
chance to stop us */
auto cmd = decoder_get_command(client);
auto cmd = client.GetCommand();
if (cmd != DecoderCommand::NONE)
throw cmd;
return;
@@ -322,10 +322,10 @@ vorbis_stream_decode(DecoderClient &client,
break;
} catch (DecoderCommand cmd) {
if (cmd == DecoderCommand::SEEK) {
if (d.Seek(decoder_seek_where_frame(client)))
decoder_command_finished(client);
if (d.Seek(client.GetSeekFrame()))
client.CommandFinished();
else
decoder_seek_error(client);
client.SeekError();
} else if (cmd != DecoderCommand::NONE)
break;
}

View File

@@ -170,19 +170,19 @@ wavpack_decode(DecoderClient &client, WavpackContext *wpc, bool can_seek)
client.Ready(audio_format, can_seek, total_time);
DecoderCommand cmd = decoder_get_command(client);
DecoderCommand cmd = client.GetCommand();
while (cmd != DecoderCommand::STOP) {
if (cmd == DecoderCommand::SEEK) {
if (can_seek) {
auto where = decoder_seek_where_frame(client);
auto where = client.GetSeekFrame();
if (WavpackSeekSample(wpc, where)) {
decoder_command_finished(client);
client.CommandFinished();
} else {
decoder_seek_error(client);
client.SeekError();
}
} else {
decoder_seek_error(client);
client.SeekError();
}
}

View File

@@ -114,11 +114,10 @@ wildmidi_file_decode(DecoderClient &client, Path path_fs)
cmd = wildmidi_output(client, wm);
if (cmd == DecoderCommand::SEEK) {
unsigned long seek_where =
decoder_seek_where_frame(client);
unsigned long seek_where = client.GetSeekFrame();
WildMidi_FastSeek(wm, &seek_where);
decoder_command_finished(client);
client.CommandFinished();
cmd = DecoderCommand::NONE;
}