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 368693 fc4037a05b5c1c5af797cb71f7db41bddf640ebf
parent 368692 224978e8eded9419f30ce13736a01b5d66923f32
child 368694 32ad1dcb413657927c33950dd0aa0038b334705d
child 368723 1e56d8ef5fd5526a9f0f2c67136022989c71388f
push id18628
push userbmo:jyavenard@mozilla.com
push dateThu, 19 May 2016 10:33:09 +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
@@ -1920,16 +1920,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);
@@ -1945,20 +1946,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; i--) {
+      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,