Bug 657791 - Update WebM demuxer to clamp cueless seeks instead of failing. r=kinetik
authorBryce Van Dyk <bvandyk@mozilla.com>
Mon, 01 Feb 2016 13:46:02 +1300
changeset 288504 2e990a8d4553a9c2ce896681163fd33a74b78235
parent 288503 4261e08ba51aa5241a05d5a6da8c7557e870ef47
child 288505 fd6e5a3c2817dcaed4775e14ffcf4cef68eab6ee
push id73430
push userryanvm@gmail.com
push dateSun, 13 Mar 2016 17:40:31 +0000
treeherdermozilla-inbound@51766683141b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskinetik
bugs657791
milestone48.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 657791 - Update WebM demuxer to clamp cueless seeks instead of failing. r=kinetik Previously if a seek time is specified outside of the buffered range for certain WebMs (particularly those without cues) the WebMDemuxer would fail out of SeekInternal() with an error code. However, this would lead to issues due to inconsistent state (recovery was not made from a failed seek). This change attemps to address this by instead seeking to the final available cluster. MozReview-Commit-ID: GZLPZDWLcT1
dom/media/webm/WebMBufferedParser.cpp
dom/media/webm/WebMBufferedParser.h
--- a/dom/media/webm/WebMBufferedParser.cpp
+++ b/dom/media/webm/WebMBufferedParser.cpp
@@ -327,26 +327,32 @@ bool WebMBufferedState::CalculateBuffere
   *aEndTime = mTimeMapping[end].mTimecode + frameDuration;
   return true;
 }
 
 bool WebMBufferedState::GetOffsetForTime(uint64_t aTime, int64_t* aOffset)
 {
   ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
+  if(mTimeMapping.IsEmpty()) {
+    return false;
+  }
+
   uint64_t time = aTime;
   if (time > 0) {
     time = time - 1;
   }
   uint32_t idx = mTimeMapping.IndexOfFirstElementGt(time, TimeComparator());
   if (idx == mTimeMapping.Length()) {
-    return false;
+    // Clamp to end
+    *aOffset = mTimeMapping[mTimeMapping.Length() - 1].mSyncOffset;
+  } else {
+    // Idx is within array or has been clamped to start
+    *aOffset = mTimeMapping[idx].mSyncOffset;
   }
-
-  *aOffset = mTimeMapping[idx].mSyncOffset;
   return true;
 }
 
 void WebMBufferedState::NotifyDataArrived(const unsigned char* aBuffer, uint32_t aLength, int64_t aOffset)
 {
   uint32_t idx = mRangeParsers.IndexOfFirstElementGt(aOffset - 1);
   if (idx == 0 || !(mRangeParsers[idx-1] == aOffset)) {
     // If the incoming data overlaps an already parsed range, adjust the
--- a/dom/media/webm/WebMBufferedParser.h
+++ b/dom/media/webm/WebMBufferedParser.h
@@ -274,19 +274,21 @@ public:
   }
 
   void NotifyDataArrived(const unsigned char* aBuffer, uint32_t aLength, int64_t aOffset);
   void Reset();
   void UpdateIndex(const MediaByteRangeSet& aRanges, MediaResource* aResource);
   bool CalculateBufferedForRange(int64_t aStartOffset, int64_t aEndOffset,
                                  uint64_t* aStartTime, uint64_t* aEndTime);
 
-  // Returns true if aTime is is present in mTimeMapping and sets aOffset to
+  // Returns true if mTimeMapping is not empty and sets aOffset to
   // the latest offset for which decoding can resume without data
-  // dependencies to arrive at aTime.
+  // dependencies to arrive at aTime. aTime will be clamped to the start
+  // of mTimeMapping if it is earlier than the first element, and to the end
+  // if later than the last
   bool GetOffsetForTime(uint64_t aTime, int64_t* aOffset);
 
   // Returns end offset of init segment or -1 if none found.
   int64_t GetInitEndOffset();
   // Returns the end offset of the last complete block or -1 if none found.
   int64_t GetLastBlockOffset();
 
   // Returns start time