diff --git a/taglib/mp4/mp4properties.cpp b/taglib/mp4/mp4properties.cpp index faa43c270..a577ac3e1 100644 --- a/taglib/mp4/mp4properties.cpp +++ b/taglib/mp4/mp4properties.cpp @@ -31,6 +31,27 @@ using namespace TagLib; +namespace +{ + // Calculate the total bytes used by audio data, used to calculate the bitrate + long long calculateMdatLength(const MP4::AtomList &list) + { + long long totalLength = 0; + for(MP4::AtomList::ConstIterator it = list.begin(); it != list.end(); ++it) { + long length = (*it)->length; + if(length == 0) + return 0; // for safety, see checkValid() in mp4file.cpp + + if((*it)->name == "mdat") + totalLength += length; + + totalLength += calculateMdatLength((*it)->children); + } + + return totalLength; + } +} + class MP4::Properties::PropertiesPrivate { public: @@ -224,6 +245,13 @@ MP4::Properties::read(File *file, Atoms *atoms) d->channels = data.at(73); d->bitrate = static_cast(data.toUInt(80U) / 1000.0 + 0.5); d->sampleRate = data.toUInt(84U); + + if(d->bitrate == 0 && d->length > 0) { + // There are files which do not contain a nominal bitrate, e.g. those + // generated by refalac64.exe. Calculate the bitrate from the audio + // data size (mdat atoms) and the duration. + d->bitrate = (calculateMdatLength(atoms->atoms) * 8) / d->length; + } } }