aboutsummaryrefslogtreecommitdiff
path: root/src/decoder/OpusDecoderPlugin.cxx
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2013-01-07 23:06:02 +0100
committerMax Kellermann <max@duempel.org>2013-01-08 01:38:02 +0100
commit8f7adf79a3932b20a1cc9750648d6d12c4941a20 (patch)
tree93bc19c26fd7d3e32684afa6c4c2afb84c88a0ef /src/decoder/OpusDecoderPlugin.cxx
parent97b164d03b3f204f9fb0597d6a09fda712f4bb4e (diff)
decoder/Opus: read total time
Diffstat (limited to 'src/decoder/OpusDecoderPlugin.cxx')
-rw-r--r--src/decoder/OpusDecoderPlugin.cxx22
1 files changed, 22 insertions, 0 deletions
diff --git a/src/decoder/OpusDecoderPlugin.cxx b/src/decoder/OpusDecoderPlugin.cxx
index c4d6c2d1..9c2f86d0 100644
--- a/src/decoder/OpusDecoderPlugin.cxx
+++ b/src/decoder/OpusDecoderPlugin.cxx
@@ -22,6 +22,7 @@
#include "OpusHead.hxx"
#include "OpusTags.hxx"
#include "OggUtil.hxx"
+#include "OggFind.hxx"
#include "decoder_api.h"
#include "OggCodec.hxx"
#include "audio_check.h"
@@ -291,6 +292,23 @@ mpd_opus_stream_decode(struct decoder *decoder,
}
static bool
+SeekFindEOS(ogg_sync_state &oy, ogg_stream_state &os, ogg_packet &packet,
+ decoder *decoder, input_stream *is)
+{
+ if (is->size > 0 && is->size - is->offset < 65536)
+ return OggFindEOS(oy, os, packet, decoder, is);
+
+ if (!input_stream_cheap_seeking(is))
+ return false;
+
+ ogg_sync_reset(&oy);
+
+ return input_stream_lock_seek(is, -65536, SEEK_END, nullptr) &&
+ OggExpectPageSeekIn(oy, os, decoder, is) &&
+ OggFindEOS(oy, os, packet, decoder, is);
+}
+
+static bool
mpd_opus_scan_stream(struct input_stream *is,
const struct tag_handler *handler, void *handler_ctx)
{
@@ -351,6 +369,10 @@ mpd_opus_scan_stream(struct input_stream *is,
}
}
+ if (packet.e_o_s || SeekFindEOS(oy, os, packet, nullptr, is))
+ tag_handler_invoke_duration(handler, handler_ctx,
+ packet.granulepos / opus_sample_rate);
+
ogg_stream_clear(&os);
ogg_sync_clear(&oy);