diff options
Diffstat (limited to 'src/decoder/OpusDecoderPlugin.cxx')
-rw-r--r-- | src/decoder/OpusDecoderPlugin.cxx | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/src/decoder/OpusDecoderPlugin.cxx b/src/decoder/OpusDecoderPlugin.cxx index c4d6c2d12..9c2f86d05 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); |