From 07b93dcf8084bcae92fa1f33652723ca9c990db2 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 22 May 2014 10:10:16 +0200 Subject: InputStream: make Seek() always absolute Remove the "whence" parameter that is not actually necessary, and only complicates the InputStream implementations. --- src/decoder/plugins/AudiofileDecoderPlugin.cxx | 10 +++++--- src/decoder/plugins/DsdLib.cxx | 6 ++--- src/decoder/plugins/FaadDecoderPlugin.cxx | 2 +- src/decoder/plugins/FfmpegDecoderPlugin.cxx | 23 +++++++++++++++-- src/decoder/plugins/FlacIOHandle.cxx | 25 ++++++++++++++++--- src/decoder/plugins/FlacInput.cxx | 2 +- src/decoder/plugins/MadDecoderPlugin.cxx | 2 +- src/decoder/plugins/MpcdecDecoderPlugin.cxx | 2 +- src/decoder/plugins/OggFind.cxx | 13 +++++----- src/decoder/plugins/OggFind.hxx | 2 +- src/decoder/plugins/OpusDecoderPlugin.cxx | 4 +-- src/decoder/plugins/PcmDecoderPlugin.cxx | 3 +-- src/decoder/plugins/SndfileDecoderPlugin.cxx | 24 ++++++++++++++++-- src/decoder/plugins/VorbisDecoderPlugin.cxx | 34 +++++++++++++++++++++----- src/decoder/plugins/WavpackDecoderPlugin.cxx | 26 ++++++++++++++++++-- 15 files changed, 141 insertions(+), 37 deletions(-) (limited to 'src/decoder') diff --git a/src/decoder/plugins/AudiofileDecoderPlugin.cxx b/src/decoder/plugins/AudiofileDecoderPlugin.cxx index 262c4a5bf..a3f0ee380 100644 --- a/src/decoder/plugins/AudiofileDecoderPlugin.cxx +++ b/src/decoder/plugins/AudiofileDecoderPlugin.cxx @@ -92,13 +92,17 @@ audiofile_file_destroy(AFvirtualfile *vfile) } static AFfileoffset -audiofile_file_seek(AFvirtualfile *vfile, AFfileoffset offset, int is_relative) +audiofile_file_seek(AFvirtualfile *vfile, AFfileoffset _offset, + int is_relative) { InputStream &is = *(InputStream *)vfile->closure; - int whence = (is_relative ? SEEK_CUR : SEEK_SET); + + InputStream::offset_type offset = _offset; + if (is_relative) + offset += is.GetOffset(); Error error; - if (is.LockSeek(offset, whence, error)) { + if (is.LockSeek(offset, IgnoreError())) { return is.GetOffset(); } else { return -1; diff --git a/src/decoder/plugins/DsdLib.cxx b/src/decoder/plugins/DsdLib.cxx index f77d8f59a..2bd532a05 100644 --- a/src/decoder/plugins/DsdLib.cxx +++ b/src/decoder/plugins/DsdLib.cxx @@ -30,9 +30,7 @@ #include "tag/TagId3.hxx" #include "util/Error.hxx" -#include #include -#include /* for SEEK_SET, SEEK_CUR */ #ifdef HAVE_ID3TAG #include @@ -63,7 +61,7 @@ dsdlib_skip_to(Decoder *decoder, InputStream &is, int64_t offset) { if (is.IsSeekable()) - return is.Seek(offset, SEEK_SET, IgnoreError()); + return is.Seek(offset, IgnoreError()); if (is.GetOffset() > offset) return false; @@ -96,7 +94,7 @@ dsdlib_skip(Decoder *decoder, InputStream &is, return true; if (is.IsSeekable()) - return is.Seek(delta, SEEK_CUR, IgnoreError()); + return is.Seek(is.GetOffset() + delta, IgnoreError()); char buffer[8192]; while (delta > 0) { diff --git a/src/decoder/plugins/FaadDecoderPlugin.cxx b/src/decoder/plugins/FaadDecoderPlugin.cxx index e80665d24..c7f72da15 100644 --- a/src/decoder/plugins/FaadDecoderPlugin.cxx +++ b/src/decoder/plugins/FaadDecoderPlugin.cxx @@ -186,7 +186,7 @@ faad_song_duration(DecoderBuffer *buffer, InputStream &is) /* obtain the duration from the ADTS header */ float song_length = adts_song_duration(buffer); - is.LockSeek(tagsize, SEEK_SET, IgnoreError()); + is.LockSeek(tagsize, IgnoreError()); decoder_buffer_clear(buffer); decoder_buffer_fill(buffer); diff --git a/src/decoder/plugins/FfmpegDecoderPlugin.cxx b/src/decoder/plugins/FfmpegDecoderPlugin.cxx index 22a42477d..9139a622b 100644 --- a/src/decoder/plugins/FfmpegDecoderPlugin.cxx +++ b/src/decoder/plugins/FfmpegDecoderPlugin.cxx @@ -120,10 +120,29 @@ mpd_ffmpeg_stream_seek(void *opaque, int64_t pos, int whence) { AvioStream *stream = (AvioStream *)opaque; - if (whence == AVSEEK_SIZE) + switch (whence) { + case SEEK_SET: + break; + + case SEEK_CUR: + pos += stream->input.GetOffset(); + break; + + case SEEK_END: + if (!stream->input.KnownSize()) + return -1; + + pos += stream->input.GetSize(); + break; + + case AVSEEK_SIZE: return stream->input.GetSize(); - if (!stream->input.LockSeek(pos, whence, IgnoreError())) + default: + return -1; + } + + if (!stream->input.LockSeek(pos, IgnoreError())) return -1; return stream->input.GetOffset(); diff --git a/src/decoder/plugins/FlacIOHandle.cxx b/src/decoder/plugins/FlacIOHandle.cxx index 6444e02cf..b5f9f5ec0 100644 --- a/src/decoder/plugins/FlacIOHandle.cxx +++ b/src/decoder/plugins/FlacIOHandle.cxx @@ -62,12 +62,31 @@ FlacIORead(void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle) } static int -FlacIOSeek(FLAC__IOHandle handle, FLAC__int64 offset, int whence) +FlacIOSeek(FLAC__IOHandle handle, FLAC__int64 _offset, int whence) { InputStream *is = (InputStream *)handle; - Error error; - return is->LockSeek(offset, whence, error) ? 0 : -1; + InputStream::offset_type offset = _offset; + switch (whence) { + case SEEK_SET: + break; + + case SEEK_CUR: + offset += is->GetOffset(); + break; + + case SEEK_END: + if (!is->KnownSize()) + return -1; + + offset += is->GetSize(); + break; + + default: + return -1; + } + + return is->LockSeek(offset, IgnoreError()) ? 0 : -1; } static FLAC__int64 diff --git a/src/decoder/plugins/FlacInput.cxx b/src/decoder/plugins/FlacInput.cxx index d7fc72025..5b4c3104d 100644 --- a/src/decoder/plugins/FlacInput.cxx +++ b/src/decoder/plugins/FlacInput.cxx @@ -51,7 +51,7 @@ FlacInput::Seek(FLAC__uint64 absolute_byte_offset) return FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED; ::Error error; - if (!input_stream.LockSeek(absolute_byte_offset, SEEK_SET, error)) { + if (!input_stream.LockSeek(absolute_byte_offset, error)) { LogError(error); return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR; } diff --git a/src/decoder/plugins/MadDecoderPlugin.cxx b/src/decoder/plugins/MadDecoderPlugin.cxx index ffd63a2ac..886aa1795 100644 --- a/src/decoder/plugins/MadDecoderPlugin.cxx +++ b/src/decoder/plugins/MadDecoderPlugin.cxx @@ -208,7 +208,7 @@ inline bool MadDecoder::Seek(long offset) { Error error; - if (!input_stream.LockSeek(offset, SEEK_SET, error)) + if (!input_stream.LockSeek(offset, error)) return false; mad_stream_buffer(&stream, input_buffer, 0); diff --git a/src/decoder/plugins/MpcdecDecoderPlugin.cxx b/src/decoder/plugins/MpcdecDecoderPlugin.cxx index 18f6e7673..f86cb3c81 100644 --- a/src/decoder/plugins/MpcdecDecoderPlugin.cxx +++ b/src/decoder/plugins/MpcdecDecoderPlugin.cxx @@ -57,7 +57,7 @@ mpc_seek_cb(mpc_reader *reader, mpc_int32_t offset) struct mpc_decoder_data *data = (struct mpc_decoder_data *)reader->data; - return data->is.LockSeek(offset, SEEK_SET, IgnoreError()); + return data->is.LockSeek(offset, IgnoreError()); } static mpc_int32_t diff --git a/src/decoder/plugins/OggFind.cxx b/src/decoder/plugins/OggFind.cxx index d7a3dc04a..15e9c5c92 100644 --- a/src/decoder/plugins/OggFind.cxx +++ b/src/decoder/plugins/OggFind.cxx @@ -22,8 +22,6 @@ #include "OggSyncState.hxx" #include "util/Error.hxx" -#include - bool OggFindEOS(OggSyncState &oy, ogg_stream_state &os, ogg_packet &packet) { @@ -41,7 +39,7 @@ OggFindEOS(OggSyncState &oy, ogg_stream_state &os, ogg_packet &packet) bool OggSeekPageAtOffset(OggSyncState &oy, ogg_stream_state &os, InputStream &is, - InputStream::offset_type offset, int whence) + InputStream::offset_type offset) { oy.Reset(); @@ -49,7 +47,7 @@ OggSeekPageAtOffset(OggSyncState &oy, ogg_stream_state &os, InputStream &is, data */ ogg_stream_reset(&os); - return is.LockSeek(offset, whence, IgnoreError()) && + return is.LockSeek(offset, IgnoreError()) && oy.ExpectPageSeekIn(os); } @@ -57,12 +55,15 @@ bool OggSeekFindEOS(OggSyncState &oy, ogg_stream_state &os, ogg_packet &packet, InputStream &is) { - if (is.KnownSize() && is.GetRest() < 65536) + if (!is.KnownSize()) + return false; + + if (is.GetRest() < 65536) return OggFindEOS(oy, os, packet); if (!is.CheapSeeking()) return false; - return OggSeekPageAtOffset(oy, os, is, -65536, SEEK_END) && + return OggSeekPageAtOffset(oy, os, is, is.GetSize() - 65536) && OggFindEOS(oy, os, packet); } diff --git a/src/decoder/plugins/OggFind.hxx b/src/decoder/plugins/OggFind.hxx index d93b87505..8ced7fd86 100644 --- a/src/decoder/plugins/OggFind.hxx +++ b/src/decoder/plugins/OggFind.hxx @@ -41,7 +41,7 @@ OggFindEOS(OggSyncState &oy, ogg_stream_state &os, ogg_packet &packet); */ bool OggSeekPageAtOffset(OggSyncState &oy, ogg_stream_state &os, InputStream &is, - InputStream::offset_type offset, int whence); + InputStream::offset_type offset); /** * Try to find the end-of-stream (EOS) packet. Seek to the end of the diff --git a/src/decoder/plugins/OpusDecoderPlugin.cxx b/src/decoder/plugins/OpusDecoderPlugin.cxx index 983d17278..27c559272 100644 --- a/src/decoder/plugins/OpusDecoderPlugin.cxx +++ b/src/decoder/plugins/OpusDecoderPlugin.cxx @@ -199,7 +199,7 @@ LoadEOSPacket(InputStream &is, Decoder *decoder, int serialno, ogg_stream_clear(&os); /* restore the previous file position */ - is.Seek(old_offset, SEEK_SET, IgnoreError()); + is.Seek(old_offset, IgnoreError()); return result; } @@ -344,7 +344,7 @@ MPDOpusDecoder::Seek(OggSyncState &oy, double where_s) InputStream::offset_type offset(where_granulepos * input_stream.GetSize() / eos_granulepos); - if (!OggSeekPageAtOffset(oy, os, input_stream, offset, SEEK_SET)) + if (!OggSeekPageAtOffset(oy, os, input_stream, offset)) return false; decoder_timestamp(decoder, where_s); diff --git a/src/decoder/plugins/PcmDecoderPlugin.cxx b/src/decoder/plugins/PcmDecoderPlugin.cxx index e7e593550..3b9c60691 100644 --- a/src/decoder/plugins/PcmDecoderPlugin.cxx +++ b/src/decoder/plugins/PcmDecoderPlugin.cxx @@ -26,7 +26,6 @@ #include "Log.hxx" #include -#include /* for SEEK_SET */ static void pcm_stream_decode(Decoder &decoder, InputStream &is) @@ -76,7 +75,7 @@ pcm_stream_decode(Decoder &decoder, InputStream &is) decoder_seek_where(decoder)); Error error; - if (is.LockSeek(offset, SEEK_SET, error)) { + if (is.LockSeek(offset, error)) { decoder_command_finished(decoder); } else { LogError(error); diff --git a/src/decoder/plugins/SndfileDecoderPlugin.cxx b/src/decoder/plugins/SndfileDecoderPlugin.cxx index 6d9e0d31e..cf3aa61d5 100644 --- a/src/decoder/plugins/SndfileDecoderPlugin.cxx +++ b/src/decoder/plugins/SndfileDecoderPlugin.cxx @@ -41,11 +41,31 @@ sndfile_vio_get_filelen(void *user_data) } static sf_count_t -sndfile_vio_seek(sf_count_t offset, int whence, void *user_data) +sndfile_vio_seek(sf_count_t _offset, int whence, void *user_data) { InputStream &is = *(InputStream *)user_data; - if (!is.LockSeek(offset, whence, IgnoreError())) + InputStream::offset_type offset = _offset; + switch (whence) { + case SEEK_SET: + break; + + case SEEK_CUR: + offset += is.GetOffset(); + break; + + case SEEK_END: + if (!is.KnownSize()) + return -1; + + offset += is.GetSize(); + break; + + default: + return -1; + } + + if (!is.LockSeek(offset, IgnoreError())) return -1; return is.GetOffset(); diff --git a/src/decoder/plugins/VorbisDecoderPlugin.cxx b/src/decoder/plugins/VorbisDecoderPlugin.cxx index 4fe44e9e8..72542e3a2 100644 --- a/src/decoder/plugins/VorbisDecoderPlugin.cxx +++ b/src/decoder/plugins/VorbisDecoderPlugin.cxx @@ -70,15 +70,37 @@ static size_t ogg_read_cb(void *ptr, size_t size, size_t nmemb, void *data) return ret / size; } -static int ogg_seek_cb(void *data, ogg_int64_t offset, int whence) +static int ogg_seek_cb(void *data, ogg_int64_t _offset, int whence) { VorbisInputStream *vis = (VorbisInputStream *)data; + InputStream &is = vis->input_stream; - Error error; - return vis->seekable && - (vis->decoder == nullptr || - decoder_get_command(*vis->decoder) != DecoderCommand::STOP) && - vis->input_stream.LockSeek(offset, whence, error) + if (!vis->seekable || + (vis->decoder != nullptr && + decoder_get_command(*vis->decoder) == DecoderCommand::STOP)) + return -1; + + InputStream::offset_type offset = _offset; + switch (whence) { + case SEEK_SET: + break; + + case SEEK_CUR: + offset += is.GetOffset(); + break; + + case SEEK_END: + if (!is.KnownSize()) + return -1; + + offset += is.GetSize(); + break; + + default: + return -1; + } + + return is.LockSeek(offset, IgnoreError()) ? 0 : -1; } diff --git a/src/decoder/plugins/WavpackDecoderPlugin.cxx b/src/decoder/plugins/WavpackDecoderPlugin.cxx index 9d65775c1..2f60090c1 100644 --- a/src/decoder/plugins/WavpackDecoderPlugin.cxx +++ b/src/decoder/plugins/WavpackDecoderPlugin.cxx @@ -392,13 +392,35 @@ wavpack_input_get_pos(void *id) static int wavpack_input_set_pos_abs(void *id, uint32_t pos) { - return wpin(id)->is.LockSeek(pos, SEEK_SET, IgnoreError()) ? 0 : -1; + return wpin(id)->is.LockSeek(pos, IgnoreError()) ? 0 : -1; } static int wavpack_input_set_pos_rel(void *id, int32_t delta, int mode) { - return wpin(id)->is.LockSeek(delta, mode, IgnoreError()) ? 0 : -1; + InputStream &is = wpin(id)->is; + + InputStream::offset_type offset = delta; + switch (mode) { + case SEEK_SET: + break; + + case SEEK_CUR: + offset += is.GetOffset(); + break; + + case SEEK_END: + if (!is.KnownSize()) + return -1; + + offset += is.GetSize(); + break; + + default: + return -1; + } + + return is.LockSeek(offset, IgnoreError()) ? 0 : -1; } static int -- cgit v1.2.3