diff options
Diffstat (limited to 'src/decoder/plugins/FaadDecoderPlugin.cxx')
-rw-r--r-- | src/decoder/plugins/FaadDecoderPlugin.cxx | 83 |
1 files changed, 36 insertions, 47 deletions
diff --git a/src/decoder/plugins/FaadDecoderPlugin.cxx b/src/decoder/plugins/FaadDecoderPlugin.cxx index 83fab7f9e..5b352c9f4 100644 --- a/src/decoder/plugins/FaadDecoderPlugin.cxx +++ b/src/decoder/plugins/FaadDecoderPlugin.cxx @@ -107,13 +107,13 @@ adts_find_frame(DecoderBuffer *buffer) } } -static float +static SignedSongTime adts_song_duration(DecoderBuffer *buffer) { const InputStream &is = decoder_buffer_get_stream(buffer); const bool estimate = !is.CheapSeeking(); if (estimate && !is.KnownSize()) - return -1; + return SignedSongTime::Negative(); unsigned sample_rate = 0; @@ -146,7 +146,7 @@ adts_song_duration(DecoderBuffer *buffer) const auto offset = is.GetOffset() - decoder_buffer_available(buffer); if (offset <= 0) - return -1; + return SignedSongTime::Negative(); const auto file_size = is.GetSize(); frames = (frames * file_size) / offset; @@ -155,20 +155,18 @@ adts_song_duration(DecoderBuffer *buffer) } if (sample_rate == 0) - return -1; + return SignedSongTime::Negative(); - float frames_per_second = (float)sample_rate / 1024.0; - assert(frames_per_second > 0); - - return (float)frames / frames_per_second; + return SignedSongTime::FromScale<uint64_t>(frames * uint64_t(1024), + sample_rate); } -static float +static SignedSongTime faad_song_duration(DecoderBuffer *buffer, InputStream &is) { auto data = ConstBuffer<uint8_t>::FromVoid(decoder_buffer_need(buffer, 5)); if (data.IsNull()) - return -1; + return SignedSongTime::Negative(); size_t tagsize = 0; if (data.size >= 10 && !memcmp(data.data, "ID3", 3)) { @@ -180,20 +178,20 @@ faad_song_duration(DecoderBuffer *buffer, InputStream &is) tagsize += 10; if (!decoder_buffer_skip(buffer, tagsize)) - return -1; + return SignedSongTime::Negative(); data = ConstBuffer<uint8_t>::FromVoid(decoder_buffer_need(buffer, 5)); if (data.IsNull()) - return -1; + return SignedSongTime::Negative(); } if (data.size >= 8 && adts_check_frame(data.data) > 0) { /* obtain the duration from the ADTS header */ if (!is.IsSeekable()) - return -1; + return SignedSongTime::Negative(); - float song_length = adts_song_duration(buffer); + auto song_length = adts_song_duration(buffer); is.LockSeek(tagsize, IgnoreError()); @@ -204,14 +202,14 @@ faad_song_duration(DecoderBuffer *buffer, InputStream &is) /* obtain the duration from the ADIF header */ if (!is.KnownSize()) - return -1; + return SignedSongTime::Negative(); size_t skip_size = (data.data[4] & 0x80) ? 9 : 0; if (8 + skip_size > data.size) /* not enough data yet; skip parsing this header */ - return -1; + return SignedSongTime::Negative(); unsigned bit_rate = ((data.data[4 + skip_size] & 0x0F) << 19) | (data.data[5 + skip_size] << 11) | @@ -220,11 +218,11 @@ faad_song_duration(DecoderBuffer *buffer, InputStream &is) const auto size = is.GetSize(); if (bit_rate == 0) - return -1; + return SignedSongTime::Negative(); - return size * 8.0 / bit_rate; + return SongTime::FromScale(size, bit_rate / 8); } else - return -1; + return SignedSongTime::Negative(); } static NeAACDecHandle @@ -301,19 +299,21 @@ faad_decoder_decode(NeAACDecHandle decoder, DecoderBuffer *buffer, } /** - * Get a song file's total playing time in seconds, as a float. - * Returns 0 if the duration is unknown, and a negative value if the - * file is invalid. + * Determine a song file's total playing time. + * + * The first return value specifies whether the file was recognized. + * The second return value is the duration. */ -static float -faad_get_file_time_float(InputStream &is) +static std::pair<bool, SignedSongTime> +faad_get_file_time(InputStream &is) { DecoderBuffer *buffer = decoder_buffer_new(nullptr, is, FAAD_MIN_STREAMSIZE * MAX_CHANNELS); - float length = faad_song_duration(buffer, is); + auto duration = faad_song_duration(buffer, is); + bool recognized = !duration.IsNegative(); - if (length < 0) { + if (!recognized) { NeAACDecHandle decoder = faad_decoder_new(); decoder_buffer_fill(buffer); @@ -321,36 +321,21 @@ faad_get_file_time_float(InputStream &is) AudioFormat audio_format; if (faad_decoder_init(decoder, buffer, audio_format, IgnoreError())) - length = 0; + recognized = true; NeAACDecClose(decoder); } decoder_buffer_free(buffer); - return length; -} - -/** - * Get a song file's total playing time in seconds, as an int. - * Returns 0 if the duration is unknown, and a negative value if the - * file is invalid. - */ -static int -faad_get_file_time(InputStream &is) -{ - float length = faad_get_file_time_float(is); - if (length < 0) - return -1; - - return int(length + 0.5); + return std::make_pair(recognized, duration); } static void faad_stream_decode(Decoder &mpd_decoder, InputStream &is, DecoderBuffer *buffer, const NeAACDecHandle decoder) { - const float total_time = faad_song_duration(buffer, is); + const auto total_time = faad_song_duration(buffer, is); if (adts_find_frame(buffer) == 0) return; @@ -449,11 +434,15 @@ static bool faad_scan_stream(InputStream &is, const struct tag_handler *handler, void *handler_ctx) { - int file_time = faad_get_file_time(is); - if (file_time < 0) + auto result = faad_get_file_time(is); + if (!result.first) return false; - tag_handler_invoke_duration(handler, handler_ctx, file_time); + unsigned duration = result.second.IsNegative() + ? 0 + : result.second.RoundS(); + + tag_handler_invoke_duration(handler, handler_ctx, duration); return true; } |