Bug 1419736 - Calculate the mp3 duration by bitrate if it's CBR; r=jya draft
authorChun-Min Chang <chun.m.chang@gmail.com>
Tue, 19 Dec 2017 15:14:57 +0800
changeset 712938 58b9c403b7b7248d347185f3ccf01c0f766c60f8
parent 703941 f5f03ee9e6abf77964f8dc1b9d69c6ccd3f655fd
child 744202 34f3a7b92277f92b95df04e609c47c46fd255c25
push id93500
push userbmo:cchang@mozilla.com
push dateTue, 19 Dec 2017 07:15:29 +0000
reviewersjya
bugs1419736
milestone59.0a1
Bug 1419736 - Calculate the mp3 duration by bitrate if it's CBR; r=jya MozReview-Commit-ID: GftmYg50FTV
dom/media/gtest/TestMP3Demuxer.cpp
dom/media/mp3/MP3Demuxer.cpp
--- 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);