Bug 1322799 part 5 - move AccurateSeekTask::Handle{Audio,Video,Not}{Decoded,Waited}(); r?jwwang} draft
authorKaku Kuo <kaku@mozilla.com>
Fri, 09 Dec 2016 11:24:43 -1000
changeset 449367 3b7fd1027253b9ac2eb807136e0f5e76ec897c49
parent 449366 ce97116e32900b363a6f32a58caf07ea93d125a6
child 449368 5c354288bb00e7cb9ecfd892ff670a398e5e2404
push id38552
push userbmo:kaku@mozilla.com
push dateWed, 14 Dec 2016 02:51:42 +0000
reviewersjwwang
bugs1322799
milestone53.0a1
Bug 1322799 part 5 - move AccurateSeekTask::Handle{Audio,Video,Not}{Decoded,Waited}(); r?jwwang} MozReview-Commit-ID: 6ZulbXUFdf8
dom/media/AccurateSeekTask.cpp
dom/media/MediaDecoderStateMachine.cpp
--- a/dom/media/AccurateSeekTask.cpp
+++ b/dom/media/AccurateSeekTask.cpp
@@ -92,164 +92,41 @@ AccurateSeekTask::CalculateNewCurrentTim
 
   MOZ_ASSERT(false, "AccurateSeekTask doesn't handle other seek types.");
   return 0;
 }
 
 void
 AccurateSeekTask::HandleAudioDecoded(MediaData* aAudio)
 {
-  AssertOwnerThread();
-  MOZ_ASSERT(!mSeekTaskPromise.IsEmpty(), "Seek shouldn't be finished");
-
-  RefPtr<MediaData> audio(aAudio);
-  MOZ_ASSERT(audio);
-
-  // The MDSM::mDecodedAudioEndTime will be updated once the whole SeekTask is
-  // resolved.
-
-  SAMPLE_LOG("OnAudioDecoded [%lld,%lld]", audio->mTime, audio->GetEndTime());
-
-  // Video-only seek doesn't reset audio decoder. There might be pending audio
-  // requests when AccurateSeekTask::Seek() begins. We will just store the data
-  // without checking |mDiscontinuity| or calling DropAudioUpToSeekTarget().
-  if (mTarget.IsVideoOnly()) {
-    mSeekedAudioData = audio.forget();
-    return;
-  }
-
-  AdjustFastSeekIfNeeded(audio);
-
-  if (mTarget.IsFast()) {
-    // Non-precise seek; we can stop the seek at the first sample.
-    mSeekedAudioData = audio;
-    mDoneAudioSeeking = true;
-  } else {
-    nsresult rv = DropAudioUpToSeekTarget(audio);
-    if (NS_FAILED(rv)) {
-      RejectIfExist(rv, __func__);
-      return;
-    }
-  }
-
-  if (!mDoneAudioSeeking) {
-    RequestAudioData();
-    return;
-  }
-  MaybeFinishSeek();
 }
 
 void
 AccurateSeekTask::HandleVideoDecoded(MediaData* aVideo, TimeStamp aDecodeStart)
 {
-  AssertOwnerThread();
-  MOZ_ASSERT(!mSeekTaskPromise.IsEmpty(), "Seek shouldn't be finished");
-
-  RefPtr<MediaData> video(aVideo);
-  MOZ_ASSERT(video);
-
-  // The MDSM::mDecodedVideoEndTime will be updated once the whole SeekTask is
-  // resolved.
-
-  SAMPLE_LOG("OnVideoDecoded [%lld,%lld]", video->mTime, video->GetEndTime());
-
-  AdjustFastSeekIfNeeded(video);
-
-  if (mTarget.IsFast()) {
-    // Non-precise seek. We can stop the seek at the first sample.
-    mSeekedVideoData = video;
-    mDoneVideoSeeking = true;
-  } else {
-    nsresult rv = DropVideoUpToSeekTarget(video.get());
-    if (NS_FAILED(rv)) {
-      RejectIfExist(rv, __func__);
-      return;
-    }
-  }
-
-  if (!mDoneVideoSeeking) {
-    RequestVideoData();
-    return;
-  }
-  MaybeFinishSeek();
 }
 
 void
 AccurateSeekTask::HandleNotDecoded(MediaData::Type aType, const MediaResult& aError)
 {
-  AssertOwnerThread();
-  MOZ_ASSERT(!mSeekTaskPromise.IsEmpty(), "Seek shouldn't be finished");
-
-  SAMPLE_LOG("OnNotDecoded type=%d reason=%u", aType, aError.Code());
-
-  // Ignore pending requests from video-only seek.
-  if (aType == MediaData::AUDIO_DATA && mTarget.IsVideoOnly()) {
-    return;
-  }
-
-  // If the decoder is waiting for data, we tell it to call us back when the
-  // data arrives.
-  if (aError == NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA) {
-    mReader->WaitForData(aType);
-    return;
-  }
-
-  if (aError == NS_ERROR_DOM_MEDIA_CANCELED) {
-    if (aType == MediaData::AUDIO_DATA) {
-      RequestAudioData();
-    } else {
-      RequestVideoData();
-    }
-    return;
-  }
-
-  if (aError == NS_ERROR_DOM_MEDIA_END_OF_STREAM) {
-    if (aType == MediaData::AUDIO_DATA) {
-      mIsAudioQueueFinished = true;
-      mDoneAudioSeeking = true;
-    } else {
-      mIsVideoQueueFinished = true;
-      mDoneVideoSeeking = true;
-      if (mFirstVideoFrameAfterSeek) {
-        // Hit the end of stream. Move mFirstVideoFrameAfterSeek into
-        // mSeekedVideoData so we have something to display after seeking.
-        mSeekedVideoData = mFirstVideoFrameAfterSeek.forget();
-      }
-    }
-    MaybeFinishSeek();
-    return;
-  }
-
-  // This is a decode error, delegate to the generic error path.
-  RejectIfExist(aError, __func__);
 }
 
 void
 AccurateSeekTask::HandleAudioWaited(MediaData::Type aType)
 {
-  AssertOwnerThread();
-
-  // Ignore pending requests from video-only seek.
-  if (mTarget.IsVideoOnly()) {
-    return;
-  }
-  RequestAudioData();
 }
 
 void
 AccurateSeekTask::HandleVideoWaited(MediaData::Type aType)
 {
-  AssertOwnerThread();
-  RequestVideoData();
 }
 
 void
 AccurateSeekTask::HandleNotWaited(const WaitForDataRejectValue& aRejection)
 {
-  AssertOwnerThread();
 }
 
 RefPtr<AccurateSeekTask::SeekTaskPromise>
 AccurateSeekTask::Seek(const media::TimeUnit& aDuration)
 {
   AssertOwnerThread();
 
   return mSeekTaskPromise.Ensure(__func__);
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -81,16 +81,17 @@ using namespace mozilla::media;
 #define DECODER_WARN(x, ...) NS_WARNING(nsPrintfCString(FMT(x, ##__VA_ARGS__)).get())
 #define DUMP_LOG(x, ...) NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString(FMT(x, ##__VA_ARGS__)).get(), nullptr, nullptr, -1)
 
 // Used by StateObject and its sub-classes
 #define SFMT(x, ...) "Decoder=%p state=%s " x, mMaster->mDecoderID, ToStateStr(GetState()), ##__VA_ARGS__
 #define SLOG(x, ...) MOZ_LOG(gMediaDecoderLog, LogLevel::Debug, (SFMT(x, ##__VA_ARGS__)))
 #define SWARN(x, ...) NS_WARNING(nsPrintfCString(SFMT(x, ##__VA_ARGS__)).get())
 #define SDUMP(x, ...) NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString(SFMT(x, ##__VA_ARGS__)).get(), nullptr, nullptr, -1)
+#define SSAMPLELOG(x, ...) MOZ_LOG(gMediaSampleLog, LogLevel::Debug, (SFMT(x, ##__VA_ARGS__)))
 
 // Certain constants get stored as member variables and then adjusted by various
 // scale factors on a per-decoder basis. We want to make sure to avoid using these
 // constants directly, so we put them in a namespace.
 namespace detail {
 
 // If audio queue has less than this many usecs of decoded audio, we won't risk
 // trying to decode the video, we'll skip decoding video up to the next
@@ -884,16 +885,161 @@ public:
   void Exit() override
   {
     SeekingState::Exit();
 
     // Disconnect MediaDecoderReaderWrapper.
     mSeekRequest.DisconnectIfExists();
   }
 
+  void HandleAudioDecoded(MediaData* aAudio) override
+  {
+    MOZ_ASSERT(mSeekTaskRequest.Exists(), "Seek shouldn't be finished");
+
+    RefPtr<MediaData> audio(aAudio);
+    MOZ_ASSERT(audio);
+
+    // The MDSM::mDecodedAudioEndTime will be updated once the whole SeekTask is
+    // resolved.
+
+    SSAMPLELOG("HandleAudioDecoded [%lld,%lld]", audio->mTime, audio->GetEndTime());
+
+    // Video-only seek doesn't reset audio decoder. There might be pending audio
+    // requests when AccurateSeekTask::Seek() begins. We will just store the data
+    // without checking |mDiscontinuity| or calling DropAudioUpToSeekTarget().
+    if (mTask->mTarget.IsVideoOnly()) {
+      mTask->mSeekedAudioData = audio.forget();
+      return;
+    }
+
+    mTask->AdjustFastSeekIfNeeded(audio);
+
+    if (mTask->mTarget.IsFast()) {
+      // Non-precise seek; we can stop the seek at the first sample.
+      mTask->mSeekedAudioData = audio;
+      mTask->mDoneAudioSeeking = true;
+    } else {
+      nsresult rv = mTask->DropAudioUpToSeekTarget(audio);
+      if (NS_FAILED(rv)) {
+        mTask->RejectIfExist(rv, __func__);
+        return;
+      }
+    }
+
+    if (!mTask->mDoneAudioSeeking) {
+      RequestAudioData();
+      return;
+    }
+    mTask->MaybeFinishSeek();
+  }
+
+  void HandleVideoDecoded(MediaData* aVideo, TimeStamp aDecodeStart) override
+  {
+    MOZ_ASSERT(mSeekTaskRequest.Exists(), "Seek shouldn't be finished");
+
+    RefPtr<MediaData> video(aVideo);
+    MOZ_ASSERT(video);
+
+    // The MDSM::mDecodedVideoEndTime will be updated once the whole SeekTask is
+    // resolved.
+
+    SSAMPLELOG("HandleVideoDecoded [%lld,%lld]", video->mTime, video->GetEndTime());
+
+    mTask->AdjustFastSeekIfNeeded(video);
+
+    if (mTask->mTarget.IsFast()) {
+      // Non-precise seek. We can stop the seek at the first sample.
+      mTask->mSeekedVideoData = video;
+      mTask->mDoneVideoSeeking = true;
+    } else {
+      nsresult rv = mTask->DropVideoUpToSeekTarget(video.get());
+      if (NS_FAILED(rv)) {
+        mTask->RejectIfExist(rv, __func__);
+        return;
+      }
+    }
+
+    if (!mTask->mDoneVideoSeeking) {
+      RequestVideoData();
+      return;
+    }
+    mTask->MaybeFinishSeek();
+  }
+
+  void HandleNotDecoded(MediaData::Type aType, const MediaResult& aError) override
+  {
+    MOZ_ASSERT(mSeekTaskRequest.Exists(), "Seek shouldn't be finished");
+
+    SSAMPLELOG("OnNotDecoded type=%d reason=%u", aType, aError.Code());
+
+    // Ignore pending requests from video-only seek.
+    if (aType == MediaData::AUDIO_DATA && mTask->mTarget.IsVideoOnly()) {
+      return;
+    }
+
+    // If the decoder is waiting for data, we tell it to call us back when the
+    // data arrives.
+    if (aError == NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA) {
+      Reader()->WaitForData(aType);
+      return;
+    }
+
+    if (aError == NS_ERROR_DOM_MEDIA_CANCELED) {
+      if (aType == MediaData::AUDIO_DATA) {
+        RequestAudioData();
+      } else {
+        RequestVideoData();
+      }
+      return;
+    }
+
+    if (aError == NS_ERROR_DOM_MEDIA_END_OF_STREAM) {
+      if (aType == MediaData::AUDIO_DATA) {
+        mTask->mIsAudioQueueFinished = true;
+        mTask->mDoneAudioSeeking = true;
+      } else {
+        mTask->mIsVideoQueueFinished = true;
+        mTask->mDoneVideoSeeking = true;
+        if (mTask->mFirstVideoFrameAfterSeek) {
+          // Hit the end of stream. Move mFirstVideoFrameAfterSeek into
+          // mSeekedVideoData so we have something to display after seeking.
+          mTask->mSeekedVideoData = mTask->mFirstVideoFrameAfterSeek.forget();
+        }
+      }
+      mTask->MaybeFinishSeek();
+      return;
+    }
+
+    // This is a decode error, delegate to the generic error path.
+    mTask->RejectIfExist(aError, __func__);
+  }
+
+  void HandleAudioWaited(MediaData::Type aType) override
+  {
+    MOZ_ASSERT(mSeekTaskRequest.Exists(), "Seek shouldn't be finished");
+
+    // Ignore pending requests from video-only seek.
+    if (mTask->mTarget.IsVideoOnly()) {
+      return;
+    }
+    RequestAudioData();
+  }
+
+  void HandleVideoWaited(MediaData::Type aType) override
+  {
+    MOZ_ASSERT(mSeekTaskRequest.Exists(), "Seek shouldn't be finished");
+
+    RequestVideoData();
+  }
+
+  void HandleNotWaited(const WaitForDataRejectValue& aRejection) override
+  {
+    MOZ_ASSERT(mSeekTaskRequest.Exists(), "Seek shouldn't be finished");
+  }
+
 private:
   void CreateSeekTask() override
   {
     mSeekTask = new AccurateSeekTask(
       mMaster->mDecoderID, OwnerThread(), Reader(), mSeekJob.mTarget,
       Info(), mMaster->Duration(), mMaster->GetMediaTime());
 
     mTask = static_cast<AccurateSeekTask*>(mSeekTask.get());