diff options
author | Max Kellermann <max@duempel.org> | 2016-05-09 16:46:08 +0200 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2016-05-14 11:31:31 +0200 |
commit | bbbda7f8127136e766ce07db597874eacf9175b6 (patch) | |
tree | aa69eb112770f6a1582c86d4b7fcd50ece6a00e3 /src/decoder/plugins/OggDecoder.cxx | |
parent | e95890038068f552d92ceb6b62afbfc9e81d0c7a (diff) |
decoder/opus: move code to new class OggDecoder
Prepare to reuse the same code for a new Vorbis decoder plugin based
on libvorbis instead of libvorbisfile.
Diffstat (limited to 'src/decoder/plugins/OggDecoder.cxx')
-rw-r--r-- | src/decoder/plugins/OggDecoder.cxx | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/src/decoder/plugins/OggDecoder.cxx b/src/decoder/plugins/OggDecoder.cxx new file mode 100644 index 000000000..b987c45b0 --- /dev/null +++ b/src/decoder/plugins/OggDecoder.cxx @@ -0,0 +1,87 @@ +/* + * Copyright 2003-2016 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" /* must be first for large file support */ +#include "OggDecoder.hxx" +#include "lib/xiph/OggFind.hxx" +#include "input/InputStream.hxx" +#include "util/Error.hxx" + +/** + * Load the end-of-stream packet and restore the previous file + * position. + */ +bool +OggDecoder::LoadEndPacket(ogg_packet &packet) const +{ + if (!input_stream.CheapSeeking()) + /* we do this for local files only, because seeking + around remote files is expensive and not worth the + trouble */ + return false; + + const auto old_offset = input_stream.GetOffset(); + + /* create temporary Ogg objects for seeking and parsing the + EOS packet */ + + bool result; + + { + DecoderReader reader(decoder, input_stream); + OggSyncState sync2(reader); + OggStreamState stream2(GetSerialNo()); + result = OggSeekFindEOS(sync2, stream2, packet, + input_stream); + } + + /* restore the previous file position */ + input_stream.LockSeek(old_offset, IgnoreError()); + + return result; +} + +ogg_int64_t +OggDecoder::LoadEndGranulePos() const +{ + ogg_packet packet; + if (!LoadEndPacket(packet)) + return -1; + + return packet.granulepos; +} + +bool +OggDecoder::SeekGranulePos(ogg_int64_t where_granulepos, Error &error) +{ + assert(IsSeekable()); + + /* interpolate the file offset where we expect to find the + given granule position */ + /* TODO: implement binary search */ + offset_type offset(where_granulepos * input_stream.GetSize() + / end_granulepos); + + if (!input_stream.LockSeek(offset, error)) + return false; + + PostSeek(); + return true; +} + |