Bug 1272964: [MSE] P5. Default to skipping to the next keyframe if no keyframe was found past currentTime. r?cpearce draft
authorJean-Yves Avenard <jyavenard@mozilla.com>
Thu, 19 May 2016 15:37:34 +0800
changeset 369141 20d8df7995c204680ce7eebcd8af9fb0960b1642
parent 369140 da231e9e1bd3a017597506f07e0f40412dd498b7
child 369142 9cfb446f8dd432da297641c16d24e8e613dd1fbd
push id18758
push userbmo:jyavenard@mozilla.com
push dateFri, 20 May 2016 13:58:31 +0000
reviewerscpearce
bugs1272964
milestone49.0a1
Bug 1272964: [MSE] P5. Default to skipping to the next keyframe if no keyframe was found past currentTime. r?cpearce If no keyframe are found after our time threshold, we can still skip to another keyframe (despite being prior the desired time). So this is just a workaround for our inability to tell the MDSM when to enter buffering mode and instead the MDSM incorrectly uses the time of the last frame returned. MozReview-Commit-ID: 5sGULpvqY5m
dom/media/mediasource/TrackBuffersManager.cpp
--- a/dom/media/mediasource/TrackBuffersManager.cpp
+++ b/dom/media/mediasource/TrackBuffersManager.cpp
@@ -1934,16 +1934,17 @@ TrackBuffersManager::SkipToNextRandomAcc
       }
       trackData.mNextGetSampleIndex = Some(uint32_t(pos));
     }
   }
 
   TimeUnit nextSampleTimecode = trackData.mNextSampleTimecode;
   TimeUnit nextSampleTime = trackData.mNextSampleTime;
   uint32_t i = trackData.mNextGetSampleIndex.ref();
+  int32_t originalPos = i;
 
   for (; i < track.Length(); i++) {
     const MediaRawData* sample =
       GetSample(aTrack,
                 i,
                 nextSampleTimecode,
                 nextSampleTime,
                 aFuzz);
@@ -1959,20 +1960,39 @@ TrackBuffersManager::SkipToNextRandomAcc
       TimeUnit::FromMicroseconds(sample->mTimecode + sample->mDuration);
     nextSampleTime = TimeUnit::FromMicroseconds(sample->GetEndTime());
     parsed++;
   }
 
   // Adjust the next demux time and index so that the next call to
   // SkipToNextRandomAccessPoint will not count again the parsed sample as
   // skipped.
-  trackData.mNextSampleTimecode = nextSampleTimecode;
-  trackData.mNextSampleTime = nextSampleTime;
-  trackData.mNextGetSampleIndex = Some(i);
-
+  if (aFound) {
+    trackData.mNextSampleTimecode = nextSampleTimecode;
+    trackData.mNextSampleTime = nextSampleTime;
+    trackData.mNextGetSampleIndex = Some(i);
+  } else if (i > 0) {
+    // Go back to the previous keyframe or the original position so the next
+    // demux can succeed and be decoded.
+    for (int j = i - 1; j >= originalPos; j--) {
+      const RefPtr<MediaRawData>& sample = track[j];
+      if (sample->mKeyframe) {
+        trackData.mNextSampleTimecode =
+          TimeUnit::FromMicroseconds(sample->mTimecode);
+        trackData.mNextSampleTime = TimeUnit::FromMicroseconds(sample->mTime);
+        trackData.mNextGetSampleIndex = Some(uint32_t(j));
+        // We are unable to skip to a keyframe past aTimeThreshold, however
+        // we are speeding up decoding by dropping the unplayable frames.
+        // So we can mark aFound as true.
+        aFound = true;
+        break;
+      }
+      parsed--;
+    }
+  }
   return parsed;
 }
 
 const MediaRawData*
 TrackBuffersManager::GetSample(TrackInfo::TrackType aTrack,
                                size_t aIndex,
                                const TimeUnit& aExpectedDts,
                                const TimeUnit& aExpectedPts,