DecoderAPI: pass SignedSongTime to decoder_initialized()

This commit is contained in:
Max Kellermann
2014-08-29 20:52:39 +02:00
parent 94f6380d69
commit d9d97bd17b
26 changed files with 159 additions and 132 deletions

View File

@@ -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;
}