Bug 1498440 - part2 : implement state transition. r=jya
authoralwu <alwu@mozilla.com>
Mon, 05 Nov 2018 22:02:58 +0000
changeset 444493 f47b8fef7cc7f1c4c21bb7ebea49b02e9a92ce10
parent 444492 8937fe137441b2a6bc2c9ad149449e44e1796b3b
child 444494 c67e483b4ab49df78d2bae3b889275284d919a44
push id34996
push userrgurzau@mozilla.com
push dateTue, 06 Nov 2018 09:53:23 +0000
treeherdermozilla-central@e160f0a60e4f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjya
bugs1498440
milestone65.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 1498440 - part2 : implement state transition. r=jya If looping is on, decoding state will be 'loopingDecoding' state. Differential Revision: https://phabricator.services.mozilla.com/D9187
dom/media/MediaDecoderStateMachine.cpp
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -220,16 +220,18 @@ public:
   virtual void HandleVideoSuspendTimeout() = 0;
 
   virtual void HandleResumeVideoDecoding(const TimeUnit& aTarget);
 
   virtual void HandlePlayStateChanged(MediaDecoder::PlayState aPlayState) { }
 
   virtual nsCString GetDebugInfo() { return nsCString(); }
 
+  virtual void HandleLoopingChanged() {}
+
 private:
   template <class S, typename R, typename... As>
   auto ReturnTypeHelper(R(S::*)(As...)) -> R;
 
   void Crash(const char* aReason, const char* aSite)
   {
     char buf[1024];
     SprintfLiteral(buf, "%s state=%s callsite=%s", aReason,
@@ -300,16 +302,18 @@ protected:
     master->mStateObj.reset(s);
     return CallEnterMemberFunction(s, copiedArgs,
                                    std::index_sequence_for<Ts...>{});
   }
 
   RefPtr<MediaDecoder::SeekPromise>
   SetSeekingState(SeekJob&& aSeekJob, EventVisibility aVisibility);
 
+  void SetDecodingState();
+
   // Take a raw pointer in order not to change the life cycle of MDSM.
   // It is guaranteed to be valid by MDSM.
   Master* mMaster;
 };
 
 /**
  * Purpose: decode metadata like duration and dimensions of the media resource.
  *
@@ -701,16 +705,21 @@ public:
     }
   }
 
   nsCString GetDebugInfo() override
   {
     return nsPrintfCString("mIsPrerolling=%d", mIsPrerolling);
   }
 
+  void HandleLoopingChanged() override
+  {
+    SetDecodingState();
+  }
+
 protected:
   virtual void EnsureAudioDecodeTaskQueued();
 
 private:
   void DispatchDecodeTasksIfNeeded();
   void EnsureVideoDecodeTaskQueued();
   void MaybeStartBuffering();
 
@@ -823,17 +832,19 @@ private:
  *   DECODING when media stop seamless looping
  */
 class MediaDecoderStateMachine::LoopingDecodingState
   : public MediaDecoderStateMachine::DecodingState
 {
 public:
   explicit LoopingDecodingState(Master* aPtr)
     : DecodingState(aPtr)
-  {}
+  {
+    MOZ_ASSERT(mMaster->mLooping);
+  }
 
   void Exit() override
   {
     mAudioDataRequest.DisconnectIfExists();
     mAudioSeekRequest.DisconnectIfExists();
     DecodingState::Exit();
   }
 
@@ -1013,17 +1024,17 @@ public:
   }
 
 protected:
   SeekJob mSeekJob;
   EventVisibility mVisibility;
 
   virtual void DoSeek() = 0;
   // Transition to the next state (defined by the subclass) when seek is completed.
-  virtual void GoToNextState() { SetState<DecodingState>(); }
+  virtual void GoToNextState() { SetDecodingState(); }
   void SeekCompleted();
   virtual TimeUnit CalculateNewCurrentTime() const = 0;
 };
 
 class MediaDecoderStateMachine::AccurateSeekingState
   : public MediaDecoderStateMachine::SeekingState
 {
 public:
@@ -2293,16 +2304,26 @@ StateObject::SetSeekingState(SeekJob&& a
     return SetState<NextFrameSeekingState>(std::move(aSeekJob), aVisibility);
   }
 
   MOZ_ASSERT_UNREACHABLE("Unknown SeekTarget::Type.");
   return nullptr;
 }
 
 void
+MediaDecoderStateMachine::StateObject::SetDecodingState()
+{
+  if (mMaster->mLooping) {
+    SetState<LoopingDecodingState>();
+    return;
+  }
+  SetState<DecodingState>();
+}
+
+void
 MediaDecoderStateMachine::
 DecodeMetadataState::OnMetadataRead(MetadataHolder&& aMetadata)
 {
   mMetadataRequest.Complete();
 
   mMaster->mInfo.emplace(*aMetadata.mInfo);
   mMaster->mMediaSeekable = Info().mMediaSeekable;
   mMaster->mMediaSeekableOnlyInBufferedRanges =
@@ -2362,17 +2383,17 @@ DormantState::HandlePlayStateChanged(Med
 }
 
 void
 MediaDecoderStateMachine::
 DecodingFirstFrameState::Enter()
 {
   // Transition to DECODING if we've decoded first frames.
   if (mMaster->mSentFirstFrameLoadedEvent) {
-    SetState<DecodingState>();
+    SetDecodingState();
     return;
   }
 
   MOZ_ASSERT(!mMaster->mVideoDecodeSuspended);
 
   // Dispatch tasks to decode first frames.
   if (mMaster->HasAudio()) {
     mMaster->RequestAudioData();
@@ -2392,17 +2413,17 @@ DecodingFirstFrameState::MaybeFinishDeco
       (mMaster->IsVideoDecoding() && VideoQueue().GetSize() == 0)) {
     return;
   }
 
   mMaster->FinishDecodeFirstFrame();
   if (mPendingSeek.Exists()) {
     SetSeekingState(std::move(mPendingSeek), EventVisibility::Observable);
   } else {
-    SetState<DecodingState>();
+    SetDecodingState();
   }
 }
 
 void
 MediaDecoderStateMachine::
 DecodingState::Enter()
 {
   MOZ_ASSERT(mMaster->mSentFirstFrameLoadedEvent);
@@ -2708,17 +2729,17 @@ BufferingState::Step()
          mMaster->OutOfDecodedAudio(),
          mMaster->AudioRequestStatus(),
          mMaster->OutOfDecodedVideo(),
          mMaster->VideoRequestStatus());
     return;
   }
 
   SLOG("Buffered for %.3lfs", (now - mBufferingStart).ToSeconds());
-  SetState<DecodingState>();
+  SetDecodingState();
 }
 
 void
 MediaDecoderStateMachine::
 BufferingState::HandleEndOfAudio()
 {
   AudioQueue().Finish();
   if (!mMaster->IsVideoDecoding()) {
@@ -3781,19 +3802,17 @@ void MediaDecoderStateMachine::Preserves
   MOZ_ASSERT(OnTaskQueue());
   mMediaSink->SetPreservesPitch(mPreservesPitch);
 }
 
 void
 MediaDecoderStateMachine::LoopingChanged()
 {
   MOZ_ASSERT(OnTaskQueue());
-  if (mSeamlessLoopingAllowed) {
-    mReader->SetSeamlessLoopingEnabled(mLooping);
-  }
+  mStateObj->HandleLoopingChanged();
 }
 
 RefPtr<GenericPromise>
 MediaDecoderStateMachine::InvokeSetSink(RefPtr<AudioDeviceInfo> aSink)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aSink);