Commit 61f2ce67 authored by Max Kellermann's avatar Max Kellermann

decoder/HybridDSD: implement seeking

parent 60dbf1be
...@@ -177,30 +177,33 @@ HybridDsdDecode(DecoderClient &client, InputStream &input) ...@@ -177,30 +177,33 @@ HybridDsdDecode(DecoderClient &client, InputStream &input)
streams */ streams */
return; return;
offset_type remaining_bytes; uint64_t total_frames;
size_t frame_size; size_t frame_size;
unsigned kbit_rate; unsigned kbit_rate;
try { try {
auto result = FindHybridDsdData(client, input); auto result = FindHybridDsdData(client, input);
auto duration = SignedSongTime::FromS(result.second / result.first.GetTimeToSize()); auto duration = SignedSongTime::FromS(result.second / result.first.GetTimeToSize());
client.Ready(result.first, client.Ready(result.first, true, duration);
/* TODO: implement seeking */ false,
duration);
frame_size = result.first.GetFrameSize(); frame_size = result.first.GetFrameSize();
kbit_rate = frame_size * result.first.sample_rate / kbit_rate = frame_size * result.first.sample_rate /
(1024u / 8u); (1024u / 8u);
remaining_bytes = result.second; total_frames = result.second / frame_size;
} catch (UnsupportedFile) { } catch (UnsupportedFile) {
/* not a Hybrid-DSD file; let the next decoder plugin /* not a Hybrid-DSD file; let the next decoder plugin
(e.g. FFmpeg) handle it */ (e.g. FFmpeg) handle it */
return; return;
} }
const offset_type start_offset = input.GetOffset();
offset_type remaining_bytes = total_frames * frame_size;
StaticFifoBuffer<uint8_t, 16384> buffer; StaticFifoBuffer<uint8_t, 16384> buffer;
auto cmd = client.GetCommand(); auto cmd = client.GetCommand();
while (remaining_bytes > 0) { while (remaining_bytes > 0) {
uint64_t seek_frame;
switch (cmd) { switch (cmd) {
case DecoderCommand::NONE: case DecoderCommand::NONE:
case DecoderCommand::START: case DecoderCommand::START:
...@@ -210,7 +213,24 @@ HybridDsdDecode(DecoderClient &client, InputStream &input) ...@@ -210,7 +213,24 @@ HybridDsdDecode(DecoderClient &client, InputStream &input)
return; return;
case DecoderCommand::SEEK: case DecoderCommand::SEEK:
// TODO: implement seeking seek_frame = client.GetSeekFrame();
if (seek_frame >= total_frames) {
/* seeking past the end */
client.CommandFinished();
return;
}
try {
input.LockSeek(start_offset + seek_frame * frame_size);
remaining_bytes = (total_frames - seek_frame) * frame_size;
buffer.Clear();
client.CommandFinished();
} catch (...) {
LogError(std::current_exception());
client.SeekError();
}
cmd = DecoderCommand::NONE;
break; break;
} }
......
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