Bug 1329110. Part 5 - split Split StateObject::HandleVideoNotDecoded into small functions. draft
authorJW Wang <jwwang@mozilla.com>
Mon, 09 Jan 2017 12:59:32 +0800
changeset 458395 c53970e1f83b83e90ad1efb4c081c83def5c3368
parent 458394 d1466f6ddb0b8b8069a96d9e9f3be9ac388c2a9b
child 458396 06f59c551e95e929c9e8c667b4082fecfeee8f3b
push id40941
push userjwwang@mozilla.com
push dateTue, 10 Jan 2017 07:42:53 +0000
bugs1329110
milestone53.0a1
Bug 1329110. Part 5 - split Split StateObject::HandleVideoNotDecoded into small functions. MozReview-Commit-ID: Bfyekr4I6OX
dom/media/MediaDecoderStateMachine.cpp
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -189,17 +189,16 @@ public:
   virtual void Exit() {};  // Exit action.
   virtual void Step() {}   // Perform a 'cycle' of this state object.
   virtual State GetState() const = 0;
 
   // Event handlers for various events.
   virtual void HandleCDMProxyReady() {}
   virtual void HandleAudioDecoded(MediaData* aAudio) {}
   virtual void HandleVideoDecoded(MediaData* aVideo, TimeStamp aDecodeStart) {}
-  virtual void HandleVideoNotDecoded(const MediaResult& aError);
   virtual void HandleAudioWaited(MediaData::Type aType);
   virtual void HandleVideoWaited(MediaData::Type aType);
   virtual void HandleNotWaited(const WaitForDataRejectValue& aRejection);
   virtual void HandleEndOfStream() {}
   virtual void HandleWaitingForData() {}
   virtual void HandleAudioCaptured() {}
 
   virtual void HandleWaitingForAudio()
@@ -214,16 +213,33 @@ public:
   }
 
   virtual void HandleEndOfAudio()
   {
     AudioQueue().Finish();
     HandleEndOfStream();
   }
 
+  virtual void HandleWaitingForVideo()
+  {
+    mMaster->WaitForData(MediaData::VIDEO_DATA);
+    HandleWaitingForData();
+  }
+
+  virtual void HandleVideoCanceled()
+  {
+    mMaster->EnsureVideoDecodeTaskQueued();
+  }
+
+  virtual void HandleEndOfVideo()
+  {
+    VideoQueue().Finish();
+    HandleEndOfStream();
+  }
+
   virtual RefPtr<MediaDecoder::SeekPromise> HandleSeek(SeekTarget aTarget);
 
   virtual RefPtr<ShutdownPromise> HandleShutdown();
 
   virtual void HandleVideoSuspendTimeout() = 0;
 
   virtual void HandleResumeVideoDecoding();
 
@@ -525,17 +541,31 @@ public:
   }
 
   void HandleEndOfAudio() override
   {
     AudioQueue().Finish();
     MaybeFinishDecodeFirstFrame();
   }
 
-  void HandleVideoNotDecoded(const MediaResult& aError) override;
+  void HandleWaitingForVideo() override
+  {
+    mMaster->WaitForData(MediaData::VIDEO_DATA);
+  }
+
+  void HandleVideoCanceled() override
+  {
+    mMaster->RequestVideoData(false, media::TimeUnit());
+  }
+
+  void HandleEndOfVideo() override
+  {
+    VideoQueue().Finish();
+    MaybeFinishDecodeFirstFrame();
+  }
 
   void HandleAudioWaited(MediaData::Type aType) override
   {
     mMaster->RequestAudioData();
   }
 
   void HandleVideoWaited(MediaData::Type aType) override
   {
@@ -845,17 +875,16 @@ public:
 
   State GetState() const override
   {
     return DECODER_STATE_SEEKING;
   }
 
   void HandleAudioDecoded(MediaData* aAudio) override = 0;
   void HandleVideoDecoded(MediaData* aVideo, TimeStamp aDecodeStart) override = 0;
-  void HandleVideoNotDecoded(const MediaResult& aError) override = 0;
   void HandleAudioWaited(MediaData::Type aType) override = 0;
   void HandleVideoWaited(MediaData::Type aType) override = 0;
   void HandleNotWaited(const WaitForDataRejectValue& aRejection) override = 0;
 
   void HandleVideoSuspendTimeout() override
   {
     // Do nothing since we want a valid video frame to show when seek is done.
   }
@@ -985,17 +1014,40 @@ public:
     if (!mSeekJob.mTarget->IsVideoOnly()) {
       MOZ_ASSERT(!mDoneAudioSeeking);
       AudioQueue().Finish();
       mDoneAudioSeeking = true;
       MaybeFinishSeek();
     }
   }
 
-  void HandleVideoNotDecoded(const MediaResult& aError) override;
+  void HandleWaitingForVideo() override
+  {
+    MOZ_ASSERT(!mDoneVideoSeeking);
+    mMaster->WaitForData(MediaData::VIDEO_DATA);
+  }
+
+  void HandleVideoCanceled() override
+  {
+    MOZ_ASSERT(!mDoneVideoSeeking);
+    RequestVideoData();
+  }
+
+  void HandleEndOfVideo() override
+  {
+    MOZ_ASSERT(!mDoneVideoSeeking);
+    if (mFirstVideoFrameAfterSeek) {
+      // Hit the end of stream. Move mFirstVideoFrameAfterSeek into
+      // mSeekedVideoData so we have something to display after seeking.
+      mMaster->PushVideo(mFirstVideoFrameAfterSeek);
+    }
+    VideoQueue().Finish();
+    mDoneVideoSeeking = true;
+    MaybeFinishSeek();
+  }
 
   void HandleAudioWaited(MediaData::Type aType) override
   {
     MOZ_ASSERT(!mDoneAudioSeeking || !mDoneVideoSeeking, "Seek shouldn't be finished");
 
     // Ignore pending requests from video-only seek.
     if (mSeekJob.mTarget->IsVideoOnly()) {
       return;
@@ -1422,17 +1474,37 @@ private:
   void HandleEndOfAudio() override
   {
     MOZ_ASSERT(!mSeekJob.mPromise.IsEmpty(), "Seek shouldn't be finished");
     MOZ_ASSERT(NeedMoreVideo());
     // We don't care about audio decode errors in this state which will be
     // handled by other states after seeking.
   }
 
-  void HandleVideoNotDecoded(const MediaResult& aError) override;
+  void HandleWaitingForVideo() override
+  {
+    MOZ_ASSERT(!mSeekJob.mPromise.IsEmpty(), "Seek shouldn't be finished");
+    MOZ_ASSERT(NeedMoreVideo());
+    mMaster->WaitForData(MediaData::VIDEO_DATA);
+  }
+
+  void HandleVideoCanceled() override
+  {
+    MOZ_ASSERT(!mSeekJob.mPromise.IsEmpty(), "Seek shouldn't be finished");
+    MOZ_ASSERT(NeedMoreVideo());
+    RequestVideoData();
+  }
+
+  void HandleEndOfVideo() override
+  {
+    MOZ_ASSERT(!mSeekJob.mPromise.IsEmpty(), "Seek shouldn't be finished");
+    MOZ_ASSERT(NeedMoreVideo());
+    VideoQueue().Finish();
+    FinishSeek();
+  }
 
   void HandleAudioWaited(MediaData::Type aType) override
   {
     // We don't care about audio in this state.
   }
 
   void HandleVideoWaited(MediaData::Type aType) override
   {
@@ -1715,18 +1787,16 @@ public:
     MOZ_DIAGNOSTIC_ASSERT(false, "Shouldn't escape the SHUTDOWN state.");
   }
 
   State GetState() const override
   {
     return DECODER_STATE_SHUTDOWN;
   }
 
-  void HandleVideoNotDecoded(const MediaResult& aError) override {}
-
   RefPtr<MediaDecoder::SeekPromise> HandleSeek(SeekTarget aTarget) override
   {
     MOZ_DIAGNOSTIC_ASSERT(false, "Can't seek in shutdown state.");
     return MediaDecoder::SeekPromise::CreateAndReject(true, __func__);
   }
 
   RefPtr<ShutdownPromise> HandleShutdown() override
   {
@@ -1761,37 +1831,16 @@ StateObject::HandleVideoWaited(MediaData
 
 void
 MediaDecoderStateMachine::
 StateObject::HandleNotWaited(const WaitForDataRejectValue& aRejection)
 {
 
 }
 
-void
-MediaDecoderStateMachine::
-StateObject::HandleVideoNotDecoded(const MediaResult& aError)
-{
-  switch (aError.Code()) {
-    case NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA:
-      mMaster->WaitForData(MediaData::VIDEO_DATA);
-      HandleWaitingForData();
-      break;
-    case NS_ERROR_DOM_MEDIA_CANCELED:
-      mMaster->EnsureVideoDecodeTaskQueued();
-      break;
-    case NS_ERROR_DOM_MEDIA_END_OF_STREAM:
-      VideoQueue().Finish();
-      HandleEndOfStream();
-      break;
-    default:
-      mMaster->DecodeError(aError);
-  }
-}
-
 RefPtr<MediaDecoder::SeekPromise>
 MediaDecoderStateMachine::
 StateObject::HandleSeek(SeekTarget aTarget)
 {
   SLOG("Changed state to SEEKING (to %lld)", aTarget.GetTime().ToMicroseconds());
   SeekJob seekJob;
   seekJob.mTarget = Some(aTarget);
   return SetSeekingState(Move(seekJob), EventVisibility::Observable);
@@ -1980,36 +2029,16 @@ DecodingFirstFrameState::Enter()
   }
   if (mMaster->HasVideo()) {
     mMaster->RequestVideoData(false, media::TimeUnit());
   }
 }
 
 void
 MediaDecoderStateMachine::
-DecodingFirstFrameState::HandleVideoNotDecoded(const MediaResult& aError)
-{
-  switch (aError.Code()) {
-    case NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA:
-      mMaster->WaitForData(MediaData::VIDEO_DATA);
-      break;
-    case NS_ERROR_DOM_MEDIA_CANCELED:
-      mMaster->RequestVideoData(false, media::TimeUnit());
-      break;
-    case NS_ERROR_DOM_MEDIA_END_OF_STREAM:
-      VideoQueue().Finish();
-      MaybeFinishDecodeFirstFrame();
-      break;
-    default:
-      mMaster->DecodeError(aError);
-  }
-}
-
-void
-MediaDecoderStateMachine::
 DecodingFirstFrameState::MaybeFinishDecodeFirstFrame()
 {
   MOZ_ASSERT(!mMaster->mSentFirstFrameLoadedEvent);
 
   if ((mMaster->IsAudioDecoding() && AudioQueue().GetSize() == 0) ||
       (mMaster->IsVideoDecoding() && VideoQueue().GetSize() == 0)) {
     return;
   }
@@ -2179,67 +2208,16 @@ SeekingState::SeekCompleted()
     mMaster->mOnPlaybackEvent.Notify(MediaEventType::Invalidate);
   }
 
   SetState<DecodingState>();
 }
 
 void
 MediaDecoderStateMachine::
-AccurateSeekingState::HandleVideoNotDecoded(const MediaResult& aError)
-{
-  MOZ_ASSERT(!mDoneVideoSeeking);
-  switch (aError.Code()) {
-    case NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA:
-      mMaster->WaitForData(MediaData::VIDEO_DATA);
-      break;
-    case NS_ERROR_DOM_MEDIA_CANCELED:
-      RequestVideoData();
-      break;
-    case NS_ERROR_DOM_MEDIA_END_OF_STREAM:
-      if (mFirstVideoFrameAfterSeek) {
-        // Hit the end of stream. Move mFirstVideoFrameAfterSeek into
-        // mSeekedVideoData so we have something to display after seeking.
-        mMaster->PushVideo(mFirstVideoFrameAfterSeek);
-      }
-      VideoQueue().Finish();
-      mDoneVideoSeeking = true;
-      MaybeFinishSeek();
-      break;
-    default:
-      mMaster->DecodeError(aError);
-  }
-}
-
-void
-MediaDecoderStateMachine::
-NextFrameSeekingState::HandleVideoNotDecoded(const MediaResult& aError)
-{
-  MOZ_ASSERT(!mSeekJob.mPromise.IsEmpty(), "Seek shouldn't be finished");
-  MOZ_ASSERT(NeedMoreVideo());
-  // Video seek not finished.
-  switch (aError.Code()) {
-    case NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA:
-      mMaster->WaitForData(MediaData::VIDEO_DATA);
-      break;
-    case NS_ERROR_DOM_MEDIA_CANCELED:
-      RequestVideoData();
-      break;
-    case NS_ERROR_DOM_MEDIA_END_OF_STREAM:
-      VideoQueue().Finish();
-      FinishSeek();
-      break;
-    default:
-      // Raise an error since we can't finish video seek anyway.
-      mMaster->DecodeError(aError);
-  }
-}
-
-void
-MediaDecoderStateMachine::
 BufferingState::DispatchDecodeTasksIfNeeded()
 {
   if (mMaster->IsAudioDecoding() &&
       !mMaster->HaveEnoughDecodedAudio()) {
     mMaster->EnsureAudioDecodeTaskQueued();
   }
 
   if (mMaster->IsVideoDecoding() &&
@@ -3076,17 +3054,29 @@ MediaDecoderStateMachine::RequestVideoDa
         // Handle abnormal or negative timestamps.
         mDecodedVideoEndTime = std::max(mDecodedVideoEndTime, aVideo->GetEndTime());
         SAMPLE_LOG("OnVideoDecoded [%lld,%lld]", aVideo->mTime, aVideo->GetEndTime());
         mStateObj->HandleVideoDecoded(aVideo, videoDecodeStartTime);
       },
       [this] (const MediaResult& aError) {
         SAMPLE_LOG("OnVideoNotDecoded aError=%u", aError.Code());
         mVideoDataRequest.Complete();
-        mStateObj->HandleVideoNotDecoded(aError);
+        switch (aError.Code()) {
+          case NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA:
+            mStateObj->HandleWaitingForVideo();
+            break;
+          case NS_ERROR_DOM_MEDIA_CANCELED:
+            mStateObj->HandleVideoCanceled();
+            break;
+          case NS_ERROR_DOM_MEDIA_END_OF_STREAM:
+            mStateObj->HandleEndOfVideo();
+            break;
+          default:
+            DecodeError(aError);
+        }
       })
   );
 }
 
 void
 MediaDecoderStateMachine::WaitForData(MediaData::Type aType)
 {
   MOZ_ASSERT(OnTaskQueue());