Bug 1419736 - Calculate the mp3 duration by bitrate if it's CBR; r=jya
MozReview-Commit-ID: GftmYg50FTV
--- a/dom/media/gtest/TestMP3Demuxer.cpp
+++ b/dom/media/gtest/TestMP3Demuxer.cpp
@@ -120,17 +120,17 @@ protected:
res.mIsVBR = false;
res.mFileSize = 191302;
res.mMPEGLayer = 3;
res.mMPEGVersion = 1;
res.mID3MajorVersion = 3;
res.mID3MinorVersion = 0;
res.mID3Flags = 0;
res.mID3Size = 115304;
- res.mDuration = 3160816;
+ res.mDuration = 3166167;
res.mDurationError = 0.001f;
res.mSeekError = 0.02f;
res.mSampleRate = 44100;
res.mSamplesPerFrame = 1152;
res.mNumSamples = 139392;
res.mNumTrailingFrames = 0;
res.mBitrate = 192000;
res.mSlotSize = 1;
--- a/dom/media/mp3/MP3Demuxer.cpp
+++ b/dom/media/mp3/MP3Demuxer.cpp
@@ -380,26 +380,41 @@ MP3TrackDemuxer::Duration() const
return TimeUnit::FromMicroseconds(-1);
}
int64_t numFrames = 0;
const auto numAudioFrames = mParser.VBRInfo().NumAudioFrames();
if (mParser.VBRInfo().IsValid() && numAudioFrames.valueOr(0) + 1 > 1) {
// VBR headers don't include the VBR header frame.
numFrames = numAudioFrames.value() + 1;
- } else {
- const int64_t streamLen = StreamLength();
- if (streamLen < 0) {
- // Unknown length, we can't estimate duration.
- return TimeUnit::FromMicroseconds(-1);
- }
- if (AverageFrameLength() > 0) {
- numFrames = (streamLen - mFirstFrameOffset) / AverageFrameLength();
- }
+ return Duration(numFrames);
+ }
+
+ const int64_t streamLen = StreamLength();
+ if (streamLen < 0) { // Live streams.
+ // Unknown length, we can't estimate duration.
+ return TimeUnit::FromMicroseconds(-1);
}
+ // We can't early return when streamLen < 0 before checking numAudioFrames
+ // since some live radio will give an opening remark before playing music
+ // and the duration of the opening talk can be calculated by numAudioFrames.
+
+ const int64_t size = streamLen - mFirstFrameOffset;
+ MOZ_ASSERT(size);
+
+ // If it's CBR, calculate the duration by bitrate.
+ if (!mParser.VBRInfo().IsValid()) {
+ const int32_t bitrate = mParser.CurrentFrame().Header().Bitrate();
+ return media::TimeUnit::FromSeconds(static_cast<double>(size) * 8 / bitrate);
+ }
+
+ if (AverageFrameLength() > 0) {
+ numFrames = size / AverageFrameLength();
+ }
+
return Duration(numFrames);
}
TimeUnit
MP3TrackDemuxer::Duration(int64_t aNumFrames) const
{
if (!mSamplesPerSecond) {
return TimeUnit::FromMicroseconds(-1);