Bug 1322800 part 1 - move NextFrameSeekTask::Seek(); r?jwwang draft
authorKaku Kuo <kaku@mozilla.com>
Wed, 14 Dec 2016 10:49:24 +0800
changeset 450256 c0342b640b46a7f974b356f8daf760a291cda85b
parent 450250 c6953db2fe3db049be977f78710845bf7f98c896
child 450257 b1452ec4c110156f519e964e15cc84bbfb07ecd7
push id38817
push userbmo:kaku@mozilla.com
push dateFri, 16 Dec 2016 08:40:33 +0000
reviewersjwwang
bugs1322800
milestone53.0a1
Bug 1322800 part 1 - move NextFrameSeekTask::Seek(); r?jwwang MozReview-Commit-ID: IOai99XSetN
dom/media/MediaDecoderStateMachine.cpp
dom/media/NextFrameSeekTask.cpp
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -1327,16 +1327,33 @@ private:
    * Information which are going to be returned to MDSM.
    */
   RefPtr<MediaData> mSeekedAudioData;
   RefPtr<MediaData> mSeekedVideoData;
   bool mIsAudioQueueFinished = false;
   bool mIsVideoQueueFinished = false;
 };
 
+/*
+ * Remove samples from the queue until aCompare() returns false.
+ * aCompare A function object with the signature bool(int64_t) which returns
+ *          true for samples that should be removed.
+ */
+template <typename Function> static void
+DiscardFrames(MediaQueue<MediaData>& aQueue, const Function& aCompare)
+{
+  while(aQueue.GetSize() > 0) {
+    if (aCompare(aQueue.PeekFront()->mTime)) {
+      RefPtr<MediaData> releaseMe = aQueue.PopFront();
+      continue;
+    }
+    break;
+  }
+}
+
 class MediaDecoderStateMachine::NextFrameSeekingState
   : public MediaDecoderStateMachine::SeekingState
 {
 public:
   explicit NextFrameSeekingState(Master* aPtr) : SeekingState(aPtr)
   {
   }
 
@@ -1349,33 +1366,45 @@ public:
 
 private:
   void CreateSeekTask() override
   {
     mSeekTask = new NextFrameSeekTask(
       mMaster->mDecoderID, OwnerThread(), Reader(), mSeekJob.mTarget,
       Info(), mMaster->Duration(),mMaster->GetMediaTime(),
       AudioQueue(), VideoQueue());
+
+    mTask = static_cast<NextFrameSeekTask*>(mSeekTask.get());
   }
 
   void ResetMDSM() override
   {
     // Do nothing.
   }
 
   void DoSeek() override
   {
+    auto currentTime = mTask->mCurrentTime;
+    DiscardFrames(mTask->mVideoQueue, [currentTime] (int64_t aSampleTime) {
+      return aSampleTime <= currentTime;
+    });
+
     mSeekTaskRequest.Begin(mSeekTask->Seek(mMaster->Duration())
       ->Then(OwnerThread(), __func__,
              [this] (const SeekTaskResolveValue& aValue) {
                OnSeekTaskResolved(aValue);
              },
              [this] (const SeekTaskRejectValue& aValue) {
                OnSeekTaskRejected(aValue);
              }));
+
+    if (!mTask->IsVideoRequestPending() && mTask->NeedMoreVideo()) {
+      mTask->RequestVideoData();
+    }
+    mTask->MaybeFinishSeek(); // Might resolve mSeekTaskPromise and modify audio queue.
   }
 
   int64_t CalculateNewCurrentTime() const override
   {
     return mSeekTask->CalculateNewCurrentTime();
   }
 
   void OnSeekTaskResolved(const SeekTaskResolveValue& aValue)
@@ -1415,16 +1444,19 @@ private:
 
     if (aValue.mIsVideoQueueFinished) {
       VideoQueue().Finish();
     }
 
     mMaster->DecodeError(aValue.mError);
   }
 
+  // For refactoring only, will be removed later.
+  RefPtr<NextFrameSeekTask> mTask;
+
 };
 
 /**
  * Purpose: stop playback until enough data is decoded to continue playback.
  *
  * Transition to:
  *   SEEKING if any seek request.
  *   SHUTDOWN if any decode error.
--- a/dom/media/NextFrameSeekTask.cpp
+++ b/dom/media/NextFrameSeekTask.cpp
@@ -230,26 +230,18 @@ DiscardFrames(MediaQueue<MediaData>& aQu
   }
 }
 
 RefPtr<NextFrameSeekTask::SeekTaskPromise>
 NextFrameSeekTask::Seek(const media::TimeUnit&)
 {
   AssertOwnerThread();
 
-  auto currentTime = mCurrentTime;
-  DiscardFrames(mVideoQueue, [currentTime] (int64_t aSampleTime) {
-    return aSampleTime <= currentTime;
-  });
+  RefPtr<SeekTaskPromise> promise = mSeekTaskPromise.Ensure(__func__);
 
-  RefPtr<SeekTaskPromise> promise = mSeekTaskPromise.Ensure(__func__);
-  if (!IsVideoRequestPending() && NeedMoreVideo()) {
-    RequestVideoData();
-  }
-  MaybeFinishSeek(); // Might resolve mSeekTaskPromise and modify audio queue.
   return promise;
 }
 
 void
 NextFrameSeekTask::RequestVideoData()
 {
   AssertOwnerThread();
   mReader->RequestVideoData(false, media::TimeUnit());