Bug 1322799 part 2 - let AccurateSeekingState request demuxer seeking; r?jwwang draft
authorKaku Kuo <kaku@mozilla.com>
Thu, 08 Dec 2016 17:40:03 -1000
changeset 449364 f7b19adf25c056550fa3b918bd864aaab69d5d4a
parent 449363 430f3ed9bef9d636aa036abb6136695d0c8cc687
child 449365 5776c735204bed3ac4dfdd6f79f491b21576ff1d
push id38552
push userbmo:kaku@mozilla.com
push dateWed, 14 Dec 2016 02:51:42 +0000
reviewersjwwang
bugs1322799
milestone53.0a1
Bug 1322799 part 2 - let AccurateSeekingState request demuxer seeking; r?jwwang MozReview-Commit-ID: ERUCjllzBRx
dom/media/AccurateSeekTask.cpp
dom/media/AccurateSeekTask.h
dom/media/MediaDecoderStateMachine.cpp
--- a/dom/media/AccurateSeekTask.cpp
+++ b/dom/media/AccurateSeekTask.cpp
@@ -51,19 +51,16 @@ AccurateSeekTask::~AccurateSeekTask()
 void
 AccurateSeekTask::Discard()
 {
   AssertOwnerThread();
 
   // Disconnect MDSM.
   RejectIfExist(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
 
-  // Disconnect MediaDecoderReaderWrapper.
-  mSeekRequest.DisconnectIfExists();
-
   mIsDiscarded = true;
 }
 
 int64_t
 AccurateSeekTask::CalculateNewCurrentTime() const
 {
   AssertOwnerThread();
 
@@ -250,21 +247,16 @@ AccurateSeekTask::HandleNotWaited(const 
   AssertOwnerThread();
 }
 
 RefPtr<AccurateSeekTask::SeekTaskPromise>
 AccurateSeekTask::Seek(const media::TimeUnit& aDuration)
 {
   AssertOwnerThread();
 
-  // Do the seek.
-  mSeekRequest.Begin(mReader->Seek(mTarget, aDuration)
-    ->Then(OwnerThread(), __func__, this,
-           &AccurateSeekTask::OnSeekResolved, &AccurateSeekTask::OnSeekRejected));
-
   return mSeekTaskPromise.Ensure(__func__);
 }
 
 void
 AccurateSeekTask::RequestAudioData()
 {
   AssertOwnerThread();
   MOZ_ASSERT(!mDoneAudioSeeking);
@@ -410,33 +402,31 @@ AccurateSeekTask::MaybeFinishSeek()
   }
 }
 
 void
 AccurateSeekTask::OnSeekResolved(media::TimeUnit)
 {
   AssertOwnerThread();
 
-  mSeekRequest.Complete();
   // We must decode the first samples of active streams, so we can determine
   // the new stream time. So dispatch tasks to do that.
   if (!mDoneVideoSeeking) {
     RequestVideoData();
   }
   if (!mDoneAudioSeeking) {
     RequestAudioData();
   }
 }
 
 void
 AccurateSeekTask::OnSeekRejected(nsresult aResult)
 {
   AssertOwnerThread();
 
-  mSeekRequest.Complete();
   MOZ_ASSERT(NS_FAILED(aResult), "Cancels should also disconnect mSeekRequest");
   RejectIfExist(aResult, __func__);
 }
 
 void
 AccurateSeekTask::AdjustFastSeekIfNeeded(MediaData* aSample)
 {
   AssertOwnerThread();
--- a/dom/media/AccurateSeekTask.h
+++ b/dom/media/AccurateSeekTask.h
@@ -67,18 +67,13 @@ public:
   bool mDoneAudioSeeking;
   bool mDoneVideoSeeking;
 
   // This temporarily stores the first frame we decode after we seek.
   // This is so that if we hit end of stream while we're decoding to reach
   // the seek target, we will still have a frame that we can display as the
   // last frame in the media.
   RefPtr<MediaData> mFirstVideoFrameAfterSeek;
-
-  /*
-   * Track the current seek promise made by the reader.
-   */
-  MozPromiseRequestHolder<MediaDecoderReader::SeekPromise> mSeekRequest;
 };
 
 } // namespace mozilla
 
 #endif /* ACCURATE_SEEK_TASK_H */
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -791,17 +791,17 @@ public:
 
     ResetMDSM();
 
     DoSeek();
 
     return mSeekJob.mPromise.Ensure(__func__);
   }
 
-  void Exit() override
+  virtual void Exit() override
   {
     mSeekTaskRequest.DisconnectIfExists();
     mSeekJob.RejectIfExists(__func__);
     mSeekTask->Discard();
   }
 
   State GetState() const override
   {
@@ -876,35 +876,58 @@ public:
 
   RefPtr<MediaDecoder::SeekPromise> Enter(SeekJob aSeekJob,
                                           EventVisibility aVisibility)
   {
     MOZ_ASSERT(aSeekJob.mTarget.IsAccurate() || aSeekJob.mTarget.IsFast());
     return SeekingState::Enter(Move(aSeekJob), aVisibility);
   }
 
+  void Exit() override
+  {
+    SeekingState::Exit();
+
+    // Disconnect MediaDecoderReaderWrapper.
+    mSeekRequest.DisconnectIfExists();
+  }
+
 private:
   void CreateSeekTask() override
   {
     mSeekTask = new AccurateSeekTask(
       mMaster->mDecoderID, OwnerThread(), Reader(), mSeekJob.mTarget,
       Info(), mMaster->Duration(), mMaster->GetMediaTime());
+
+    mTask = static_cast<AccurateSeekTask*>(mSeekTask.get());
   }
 
   void ResetMDSM() override
   {
     if (mSeekJob.mTarget.IsVideoOnly()) {
       mMaster->Reset(TrackInfo::kVideoTrack);
     } else {
       mMaster->Reset();
     }
   }
 
   void DoSeek() override
   {
+    // Request the demuxer to perform seek.
+    mSeekRequest.Begin(Reader()->Seek(mTask->mTarget, mMaster->Duration())
+      ->Then(OwnerThread(), __func__,
+             [this] (media::TimeUnit aUnit) {
+               mSeekRequest.Complete();
+               mTask->OnSeekResolved(aUnit);
+             },
+             [this] (nsresult aResult) {
+               mSeekRequest.Complete();
+               mTask->OnSeekRejected(aResult);
+             }));
+
+    // Let SeekTask handle the following operations once the demuxer seeking is done.
     mSeekTaskRequest.Begin(mSeekTask->Seek(mMaster->Duration())
       ->Then(OwnerThread(), __func__,
              [this] (const SeekTaskResolveValue& aValue) {
                OnSeekTaskResolved(aValue);
              },
              [this] (const SeekTaskRejectValue& aValue) {
                OnSeekTaskRejected(aValue);
              }));
@@ -952,16 +975,24 @@ private:
 
     if (aValue.mIsVideoQueueFinished) {
       VideoQueue().Finish();
     }
 
     mMaster->DecodeError(aValue.mError);
   }
 
+  /*
+   * Track the current seek promise made by the reader.
+   */
+  MozPromiseRequestHolder<MediaDecoderReader::SeekPromise> mSeekRequest;
+
+  // For refactoring only, will be removed later.
+  RefPtr<AccurateSeekTask> mTask;
+
 };
 
 class MediaDecoderStateMachine::NextFrameSeekingState
   : public MediaDecoderStateMachine::SeekingState
 {
 public:
   explicit NextFrameSeekingState(Master* aPtr) : SeekingState(aPtr)
   {