aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2014-07-11 22:52:26 +0200
committerMax Kellermann <max@duempel.org>2014-07-12 00:37:00 +0200
commita960e2ef48d21e73c7db7ead6f73c1b1d3ee8d42 (patch)
tree8b5ee25d414559a3bd297b815ffee71a87d75dd8
parent4fe272a7fbe45ab76f3af417d989c37fd4298ed1 (diff)
downloadmpd-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.
-rw-r--r--NEWS1
-rw-r--r--src/decoder/FaadDecoderPlugin.cxx22
2 files changed, 23 insertions, 0 deletions
diff --git a/NEWS b/NEWS
index 1deecbe56..7acf48cc9 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,7 @@ ver 0.18.12 (not yet released)
- audiofile: improve responsiveness
- audiofile: fix WAV stream playback
- dsdiff, dsf: fix stream playback
+ - faad: estimate song duration for remote files
- sndfile: improve responsiveness
* randomize next song when enabling "random" mode while not playing
* randomize next song when adding to single-song queue
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)