Bug 1325321 - let DecodingState handle audio/video pop events. draft
authorJW Wang <jwwang@mozilla.com>
Thu, 22 Dec 2016 17:28:14 +0800
changeset 454733 34cd181ff0f6a8b27dce37deef37ebb228f4ad2f
parent 454732 9741ab34673455b69e59bda28bd24d1f3e9ba8b7
child 454734 66dda2dc6f45972db5360c5c3a85855b20e23191
push id40012
push userjwwang@mozilla.com
push dateFri, 30 Dec 2016 02:18:00 +0000
bugs1325321
milestone53.0a1
Bug 1325321 - let DecodingState handle audio/video pop events. MozReview-Commit-ID: 9EjeOfn1vBU
dom/media/MediaDecoderStateMachine.cpp
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -551,16 +551,18 @@ public:
 
   void Exit() override
   {
     if (!mDecodeStartTime.IsNull()) {
       TimeDuration decodeDuration = TimeStamp::Now() - mDecodeStartTime;
       SLOG("Exiting DECODING, decoded for %.3lfs", decodeDuration.ToSeconds());
     }
     mDormantTimer.Reset();
+    mOnAudioPopped.DisconnectIfExists();
+    mOnVideoPopped.DisconnectIfExists();
   }
 
   void Step() override
   {
     if (mMaster->mPlayState != MediaDecoder::PLAY_STATE_PLAYING &&
         mMaster->IsPlaying()) {
       // We're playing, but the element/decoder is in paused state. Stop
       // playing!
@@ -746,16 +748,19 @@ private:
   // can't keep up with the decode, and cause us to pause playback. So we
   // have a "preroll" stage, where we ignore the results of our "low data"
   // logic during the first few frames of our decode. This occurs during
   // playback.
   bool mIsPrerolling = true;
 
   // Fired when playback is paused for a while to enter dormant.
   DelayedScheduler mDormantTimer;
+
+  MediaEventListener mOnAudioPopped;
+  MediaEventListener mOnVideoPopped;
 };
 
 /**
  * Purpose: seek to a particular new playback position.
  *
  * Transition to:
  *   SEEKING if any new seek request.
  *   SHUTDOWN if seek failed.
@@ -1984,16 +1989,25 @@ DecodingState::Enter()
     HandleVideoSuspendTimeout();
   }
 
   if (mMaster->CheckIfDecodeComplete()) {
     SetState<CompletedState>();
     return;
   }
 
+  mOnAudioPopped = AudioQueue().PopEvent().Connect(
+    OwnerThread(), [this] () {
+    mMaster->DispatchAudioDecodeTaskIfNeeded();
+  });
+  mOnVideoPopped = VideoQueue().PopEvent().Connect(
+    OwnerThread(), [this] () {
+    mMaster->DispatchVideoDecodeTaskIfNeeded();
+  });
+
   mMaster->UpdateNextFrameStatus(MediaDecoderOwner::NEXT_FRAME_AVAILABLE);
 
   mDecodeStartTime = TimeStamp::Now();
 
   MaybeStopPrerolling();
 
   // Ensure that we've got tasks enqueued to decode data if we need to.
   mMaster->DispatchDecodeTasksIfNeeded();
@@ -2610,27 +2624,24 @@ MediaDecoderStateMachine::PushVideo(Medi
   aSample->As<VideoData>()->mFrameID = ++mCurrentFrameID;
   VideoQueue().Push(aSample);
 }
 
 void
 MediaDecoderStateMachine::OnAudioPopped(const RefPtr<MediaData>& aSample)
 {
   MOZ_ASSERT(OnTaskQueue());
-
   mPlaybackOffset = std::max(mPlaybackOffset.Ref(), aSample->mOffset);
-  DispatchAudioDecodeTaskIfNeeded();
 }
 
 void
 MediaDecoderStateMachine::OnVideoPopped(const RefPtr<MediaData>& aSample)
 {
   MOZ_ASSERT(OnTaskQueue());
   mPlaybackOffset = std::max(mPlaybackOffset.Ref(), aSample->mOffset);
-  DispatchVideoDecodeTaskIfNeeded();
 }
 
 bool
 MediaDecoderStateMachine::IsAudioDecoding()
 {
   MOZ_ASSERT(OnTaskQueue());
   return HasAudio() && !AudioQueue().IsFinished();
 }