diff options
author | Max Kellermann <max@duempel.org> | 2014-07-11 22:52:26 +0200 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2014-07-12 00:37:00 +0200 |
commit | a960e2ef48d21e73c7db7ead6f73c1b1d3ee8d42 (patch) | |
tree | 8b5ee25d414559a3bd297b815ffee71a87d75dd8 /src | |
parent | 4fe272a7fbe45ab76f3af417d989c37fd4298ed1 (diff) | |
download | mpd-a960e2ef48d21e73c7db7ead6f73c1b1d3ee8d42.tar.gz mpd-a960e2ef48d21e73c7db7ead6f73c1b1d3ee8d42.tar.xz mpd-a960e2ef48d21e73c7db7ead6f73c1b1d3ee8d42.zip |
decoder/faad: estimate song duration for remote files
Previously, MPD tried to slurp the whole song file, count the number
of frames and calculate the song duration from that. That however is
extremely expensive for remote files, and will delay playback for a
long time. Workaround: check only the first 128 frames and try to
extrapolate from here. Fixes Mantis ticket 0004035.
Diffstat (limited to '')
-rw-r--r-- | src/decoder/FaadDecoderPlugin.cxx | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/src/decoder/FaadDecoderPlugin.cxx b/src/decoder/FaadDecoderPlugin.cxx index 07c10fa69..b446ac5be 100644 --- a/src/decoder/FaadDecoderPlugin.cxx +++ b/src/decoder/FaadDecoderPlugin.cxx @@ -122,6 +122,12 @@ adts_find_frame(DecoderBuffer *buffer) static float adts_song_duration(DecoderBuffer *buffer) { + const InputStream &is = decoder_buffer_get_stream(buffer); + const bool estimate = !is.CheapSeeking(); + const auto file_size = is.GetSize(); + if (estimate && file_size <= 0) + return -1; + unsigned sample_rate = 0; /* Read all frames to ensure correct time and bitrate */ @@ -145,6 +151,22 @@ adts_song_duration(DecoderBuffer *buffer) } decoder_buffer_consume(buffer, frame_length); + + if (estimate && frames == 128) { + /* if this is a remote file, don't slurp the + whole file just for checking the song + duration; instead, stop after some time and + extrapolate the song duration from what we + have until now */ + + const auto offset = is.GetOffset() + - decoder_buffer_available(buffer); + if (offset <= 0) + return -1; + + frames = (frames * file_size) / offset; + break; + } } if (sample_rate == 0) |