Bug 1105066 - Seek after switching reader; r=mattwoodrow
authorAnthony Jones <ajones@mozilla.com>
Mon, 12 Jan 2015 15:10:15 +1300
changeset 249008 a0954dd9d40ae52531631bba4116f7531175d60d
parent 249007 db991158a2fed494e4d36093a620536470b6b6a7
child 249009 225fd7ea8fc6cb4e1f5e5f0fc21c43facfa4c419
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1105066
milestone37.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 1105066 - Seek after switching reader; r=mattwoodrow
dom/media/mediasource/MediaSourceReader.cpp
dom/media/mediasource/MediaSourceReader.h
--- a/dom/media/mediasource/MediaSourceReader.cpp
+++ b/dom/media/mediasource/MediaSourceReader.cpp
@@ -117,21 +117,39 @@ MediaSourceReader::RequestAudioData()
   nsRefPtr<AudioDataPromise> p = mAudioPromise.Ensure(__func__);
   MSE_DEBUGV("MediaSourceReader(%p)::RequestAudioData", this);
   if (!mAudioReader) {
     MSE_DEBUG("MediaSourceReader(%p)::RequestAudioData called with no audio reader", this);
     mAudioPromise.Reject(DECODE_ERROR, __func__);
     return p;
   }
   mAudioIsSeeking = false;
-  SwitchAudioReader(mLastAudioTime);
+  if (SwitchAudioReader(mLastAudioTime)) {
+    mAudioReader->Seek(mLastAudioTime, 0, 0, 0)
+                ->Then(GetTaskQueue(), __func__, this,
+                       &MediaSourceReader::RequestAudioDataComplete,
+                       &MediaSourceReader::RequestAudioDataFailed);
+  } else {
+    RequestAudioDataComplete(0);
+  }
+  return p;
+}
+
+void
+MediaSourceReader::RequestAudioDataComplete(int64_t aTime)
+{
   mAudioReader->RequestAudioData()->Then(GetTaskQueue(), __func__, this,
                                          &MediaSourceReader::OnAudioDecoded,
                                          &MediaSourceReader::OnAudioNotDecoded);
-  return p;
+}
+
+void
+MediaSourceReader::RequestAudioDataFailed(nsresult aResult)
+{
+  OnAudioNotDecoded(DECODE_ERROR);
 }
 
 void
 MediaSourceReader::OnAudioDecoded(AudioData* aSample)
 {
   MSE_DEBUGV("MediaSourceReader(%p)::OnAudioDecoded [mTime=%lld mDuration=%lld mDiscontinuity=%d]",
              this, aSample->mTime, aSample->mDuration, aSample->mDiscontinuity);
   if (mDropAudioBeforeThreshold) {
@@ -197,19 +215,20 @@ MediaSourceReader::OnAudioNotDecoded(Not
   if (mAudioReader) {
     AdjustEndTime(&mLastAudioTime, mAudioReader);
   }
 
   // See if we can find a different reader that can pick up where we left off. We use the
   // EOS_FUZZ_US to allow for the fact that our end time can be inaccurate due to bug
   // 1065207.
   if (SwitchAudioReader(mLastAudioTime, EOS_FUZZ_US)) {
-    mAudioReader->RequestAudioData()->Then(GetTaskQueue(), __func__, this,
-                                           &MediaSourceReader::OnAudioDecoded,
-                                           &MediaSourceReader::OnAudioNotDecoded);
+    mAudioReader->Seek(mLastAudioTime, 0, 0, 0)
+                ->Then(GetTaskQueue(), __func__, this,
+                       &MediaSourceReader::RequestAudioDataComplete,
+                       &MediaSourceReader::RequestAudioDataFailed);
     return;
   }
 
   // If the entire MediaSource is done, generate an EndOfStream.
   if (IsEnded()) {
     mAudioPromise.Reject(END_OF_STREAM, __func__);
     return;
   }
@@ -232,22 +251,42 @@ MediaSourceReader::RequestVideoData(bool
     return p;
   }
   if (aSkipToNextKeyframe) {
     mTimeThreshold = aTimeThreshold;
     mDropAudioBeforeThreshold = true;
     mDropVideoBeforeThreshold = true;
   }
   mVideoIsSeeking = false;
-  SwitchVideoReader(mLastVideoTime);
+  if (SwitchVideoReader(mLastVideoTime)) {
+    mVideoReader->Seek(mLastVideoTime, 0, 0, 0)
+                ->Then(GetTaskQueue(), __func__, this,
+                       &MediaSourceReader::RequestVideoDataComplete,
+                       &MediaSourceReader::RequestVideoDataFailed);
+  } else {
+    mVideoReader->RequestVideoData(aSkipToNextKeyframe, aTimeThreshold)
+                ->Then(GetTaskQueue(), __func__, this,
+                       &MediaSourceReader::OnVideoDecoded, &MediaSourceReader::OnVideoNotDecoded);
+  }
 
-  mVideoReader->RequestVideoData(aSkipToNextKeyframe, aTimeThreshold)
+  return p;
+}
+
+void
+MediaSourceReader::RequestVideoDataComplete(int64_t aTime)
+{
+  mVideoReader->RequestVideoData(false, 0)
               ->Then(GetTaskQueue(), __func__, this,
                      &MediaSourceReader::OnVideoDecoded, &MediaSourceReader::OnVideoNotDecoded);
-  return p;
+}
+
+void
+MediaSourceReader::RequestVideoDataFailed(nsresult aResult)
+{
+  OnVideoNotDecoded(DECODE_ERROR);
 }
 
 void
 MediaSourceReader::OnVideoDecoded(VideoData* aSample)
 {
   MSE_DEBUGV("MediaSourceReader(%p)::OnVideoDecoded [mTime=%lld mDuration=%lld mDiscontinuity=%d]",
              this, aSample->mTime, aSample->mDuration, aSample->mDiscontinuity);
   if (mDropVideoBeforeThreshold) {
@@ -287,20 +326,20 @@ MediaSourceReader::OnVideoNotDecoded(Not
   if (mVideoReader) {
     AdjustEndTime(&mLastVideoTime, mVideoReader);
   }
 
   // See if we can find a different reader that can pick up where we left off. We use the
   // EOS_FUZZ_US to allow for the fact that our end time can be inaccurate due to bug
   // 1065207.
   if (SwitchVideoReader(mLastVideoTime, EOS_FUZZ_US)) {
-    mVideoReader->RequestVideoData(false, 0)
+    mVideoReader->Seek(mLastVideoTime, 0, 0, 0)
                 ->Then(GetTaskQueue(), __func__, this,
-                       &MediaSourceReader::OnVideoDecoded,
-                       &MediaSourceReader::OnVideoNotDecoded);
+                       &MediaSourceReader::RequestVideoDataComplete,
+                       &MediaSourceReader::RequestVideoDataFailed);
     return;
   }
 
   // If the entire MediaSource is done, generate an EndOfStream.
   if (IsEnded()) {
     mVideoPromise.Reject(END_OF_STREAM, __func__);
     return;
   }
--- a/dom/media/mediasource/MediaSourceReader.h
+++ b/dom/media/mediasource/MediaSourceReader.h
@@ -131,16 +131,20 @@ public:
 #endif
 
 private:
   // Switch the current audio/video reader to the reader that
   // contains aTarget (or up to aError after target). Both
   // aTarget and aError are in microseconds.
   bool SwitchAudioReader(int64_t aTarget, int64_t aError = 0);
   bool SwitchVideoReader(int64_t aTarget, int64_t aError = 0);
+  void RequestAudioDataComplete(int64_t aTime);
+  void RequestAudioDataFailed(nsresult aResult);
+  void RequestVideoDataComplete(int64_t aTime);
+  void RequestVideoDataFailed(nsresult aResult);
 
   // Return a reader from the set available in aTrackDecoders that has data
   // available in the range requested by aTarget.
   already_AddRefed<MediaDecoderReader> SelectReader(int64_t aTarget,
                                                     int64_t aError,
                                                     const nsTArray<nsRefPtr<SourceBufferDecoder>>& aTrackDecoders);
   bool HaveData(int64_t aTarget, MediaData::Type aType);