summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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)