Bug 1500713: P3 - Prevent duration in GetBuffered from being overestimated. r=kinetik
☠☠ backed out by 89988d424c06 ☠ ☠
authorChun-Min Chang <chun.m.chang@gmail.com>
Sat, 09 Mar 2019 01:09:37 +0000
changeset 521482 98265537ef341ae6062cdaa82a7d75afab83be19
parent 521481 670b24af24d4c8d1adcdf67eff46e73346e83ab1
child 521483 d25ff3b04eeb7529ad27086f151a1d3b7231e5cc
push id10866
push usernerli@mozilla.com
push dateTue, 12 Mar 2019 18:59:09 +0000
treeherdermozilla-beta@445c24a51727 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskinetik
bugs1500713
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1500713: P3 - Prevent duration in GetBuffered from being overestimated. r=kinetik Depends on D19097 Differential Revision: https://phabricator.services.mozilla.com/D22048
dom/media/mp3/MP3Demuxer.cpp
dom/media/mp3/MP3Demuxer.h
--- a/dom/media/mp3/MP3Demuxer.cpp
+++ b/dom/media/mp3/MP3Demuxer.cpp
@@ -292,54 +292,59 @@ MP3TrackDemuxer::SkipToNextRandomAccessP
   return SkipAccessPointPromise::CreateAndReject(
       SkipFailureHolder(NS_ERROR_DOM_MEDIA_DEMUXER_ERR, 0), __func__);
 }
 
 int64_t MP3TrackDemuxer::GetResourceOffset() const { return mOffset; }
 
 TimeIntervals MP3TrackDemuxer::GetBuffered() {
   AutoPinned<MediaResource> stream(mSource.GetResource());
-  TimeIntervals buffered;
+  TimeIntervals duration;
+  duration += TimeInterval(TimeUnit(), Duration());
 
   if (Duration() > TimeUnit() && stream->IsDataCachedToEndOfResource(0)) {
     // Special case completely cached files. This also handles local files.
-    buffered += TimeInterval(TimeUnit(), Duration());
     MP3LOGV("buffered = [[%" PRId64 ", %" PRId64 "]]",
             TimeUnit().ToMicroseconds(), Duration().ToMicroseconds());
-    return buffered;
+    return duration;
   }
 
+  TimeIntervals buffered;
   MediaByteRangeSet ranges;
   nsresult rv = stream->GetCachedRanges(ranges);
   NS_ENSURE_SUCCESS(rv, buffered);
 
   for (const auto& range : ranges) {
     if (range.IsEmpty()) {
       continue;
     }
     TimeUnit start = Duration(FrameIndexFromOffset(range.mStart));
     TimeUnit end = Duration(FrameIndexFromOffset(range.mEnd));
     MP3LOGV("buffered += [%" PRId64 ", %" PRId64 "]", start.ToMicroseconds(),
             end.ToMicroseconds());
     buffered += TimeInterval(start, end);
   }
 
-  return buffered;
+  // If the number of frames presented in header is valid, the duration
+  // calculated from it should be the maximal duration.
+  return ValidNumAudioFrames().isSome() && buffered.GetEnd() > duration.GetEnd()
+             ? duration
+             : buffered;
 }
 
 int64_t MP3TrackDemuxer::StreamLength() const { return mSource.GetLength(); }
 
 TimeUnit MP3TrackDemuxer::Duration() const {
   if (!mNumParsedFrames) {
     return TimeUnit::FromMicroseconds(-1);
   }
 
   int64_t numFrames = 0;
-  const auto numAudioFrames = mParser.VBRInfo().NumAudioFrames();
-  if (mParser.VBRInfo().IsValid() && numAudioFrames.valueOr(0) + 1 > 1) {
+  const auto numAudioFrames = ValidNumAudioFrames();
+  if (numAudioFrames.isSome()) {
     // VBR headers don't include the VBR header frame.
     numFrames = numAudioFrames.value() + 1;
     return Duration(numFrames);
   }
 
   const int64_t streamLen = StreamLength();
   if (streamLen < 0) {  // Live streams.
     // Unknown length, we can't estimate duration.
@@ -723,12 +728,19 @@ double MP3TrackDemuxer::AverageFrameLeng
   const auto& vbr = mParser.VBRInfo();
   if (vbr.IsComplete() && vbr.NumAudioFrames().value() + 1) {
     return static_cast<double>(vbr.NumBytes().value()) /
            (vbr.NumAudioFrames().value() + 1);
   }
   return 0.0;
 }
 
+Maybe<uint32_t> MP3TrackDemuxer::ValidNumAudioFrames() const {
+  return mParser.VBRInfo().IsValid() &&
+                 mParser.VBRInfo().NumAudioFrames().valueOr(0) + 1 > 1
+             ? mParser.VBRInfo().NumAudioFrames()
+             : Maybe<uint32_t>();
+}
+
 }  // namespace mozilla
 
 #undef MP3LOG
 #undef MP3LOGV
--- a/dom/media/mp3/MP3Demuxer.h
+++ b/dom/media/mp3/MP3Demuxer.h
@@ -117,16 +117,20 @@ class MP3TrackDemuxer : public MediaTrac
 
   // Reads aSize bytes into aBuffer from the source starting at aOffset.
   // Returns the actual size read.
   int32_t Read(uint8_t* aBuffer, int64_t aOffset, int32_t aSize);
 
   // Returns the average frame length derived from the previously parsed frames.
   double AverageFrameLength() const;
 
+  // Returns the number of frames reported by the header if it's valid. Nothing
+  // otherwise.
+  Maybe<uint32_t> ValidNumAudioFrames() const;
+
   // The (hopefully) MPEG resource.
   MediaResourceIndex mSource;
 
   // MPEG frame parser used to detect frames and extract side info.
   FrameParser mParser;
 
   // Whether we've locked onto a valid sequence of frames or not.
   bool mFrameLock;