Bug 1306186. Part 2 - reset prerolling flags in MaybeStartPlayback(). r=kikuo
authorJW Wang <jwwang@mozilla.com>
Thu, 29 Sep 2016 11:34:54 +0800
changeset 316174 613397fea462b15878742bcba882e1af4242a5a3
parent 316173 d5cc0a54f8b8162f0a5ca70faa773f544164b049
child 316175 31b07a151f535250ed50e5ab91e79cf06aa84c30
push id30765
push userphilringnalda@gmail.com
push dateTue, 04 Oct 2016 03:06:46 +0000
treeherdermozilla-central@adb484f84dec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskikuo
bugs1306186
milestone52.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 1306186. Part 2 - reset prerolling flags in MaybeStartPlayback(). r=kikuo MozReview-Commit-ID: 8cVfjRAsPk2
dom/media/MediaDecoderStateMachine.cpp
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -432,34 +432,33 @@ public:
 
     if (mMaster->CheckIfDecodeComplete()) {
       SetState(DECODER_STATE_COMPLETED);
       return;
     }
 
     mDecodeStartTime = TimeStamp::Now();
 
-    // Reset other state to pristine values before starting decode.
-    mMaster->mIsAudioPrerolling = !mMaster->DonePrerollingAudio() &&
-                                  !Reader()->IsWaitingAudioData();
-    mMaster->mIsVideoPrerolling = !mMaster->DonePrerollingVideo() &&
-                                  !Reader()->IsWaitingVideoData();
+    mMaster->mIsAudioPrerolling = true;
+    mMaster->mIsVideoPrerolling = true;
 
     // Ensure that we've got tasks enqueued to decode data if we need to.
     mMaster->DispatchDecodeTasksIfNeeded();
 
     mMaster->ScheduleStateMachine();
   }
 
   void Exit() override
   {
     if (!mDecodeStartTime.IsNull()) {
       TimeDuration decodeDuration = TimeStamp::Now() - mDecodeStartTime;
       SLOG("Exiting DECODING, decoded for %.3lfs", decodeDuration.ToSeconds());
     }
+    mMaster->mIsAudioPrerolling = false;
+    mMaster->mIsVideoPrerolling = false;
   }
 
   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!
@@ -1044,18 +1043,19 @@ MediaDecoderStateMachine::OnAudioDecoded
     case DECODER_STATE_DECODING_FIRSTFRAME: {
       Push(audio, MediaData::AUDIO_DATA);
       MaybeFinishDecodeFirstFrame();
       return;
     }
 
     case DECODER_STATE_DECODING: {
       Push(audio, MediaData::AUDIO_DATA);
-      if (mIsAudioPrerolling && DonePrerollingAudio()) {
-        StopPrerollingAudio();
+      if (mIsAudioPrerolling) {
+        // Schedule next cycle to check if we can stop prerolling.
+        ScheduleStateMachine();
       }
       return;
     }
 
     default: {
       // Ignore other cases.
       return;
     }
@@ -1232,18 +1232,19 @@ MediaDecoderStateMachine::OnVideoDecoded
     case DECODER_STATE_DECODING_FIRSTFRAME: {
       Push(video, MediaData::VIDEO_DATA);
       MaybeFinishDecodeFirstFrame();
       return;
     }
 
     case DECODER_STATE_DECODING: {
       Push(video, MediaData::VIDEO_DATA);
-      if (mIsVideoPrerolling && DonePrerollingVideo()) {
-        StopPrerollingVideo();
+      if (mIsVideoPrerolling) {
+        // Schedule next cycle to check if we can stop prerolling.
+        ScheduleStateMachine();
       }
 
       // For non async readers, if the requested video sample was slow to
       // arrive, increase the amount of audio we buffer to ensure that we
       // don't run out of audio. This is unnecessary for async readers,
       // since they decode audio and video on different threads so they
       // are unlikely to run out of decoded audio.
       if (mReader->IsAsync()) {
@@ -1407,16 +1408,26 @@ void MediaDecoderStateMachine::MaybeStar
   MOZ_ASSERT(mState == DECODER_STATE_DECODING ||
              mState == DECODER_STATE_COMPLETED);
 
   if (IsPlaying()) {
     // Logging this case is really spammy - don't do it.
     return;
   }
 
+  if (mIsAudioPrerolling &&
+      (DonePrerollingAudio() || mReader->IsWaitingAudioData())) {
+    mIsAudioPrerolling = false;
+  }
+
+  if (mIsVideoPrerolling &&
+      (DonePrerollingVideo() || mReader->IsWaitingVideoData())) {
+    mIsVideoPrerolling = false;
+  }
+
   bool playStatePermits = mPlayState == MediaDecoder::PLAY_STATE_PLAYING;
   if (!playStatePermits || mIsAudioPrerolling ||
       mIsVideoPrerolling || mAudioOffloading) {
     DECODER_LOG("Not starting playback [playStatePermits: %d, "
                 "mIsAudioPrerolling: %d, mIsVideoPrerolling: %d, "
                 "mAudioOffloading: %d]",
                 (int)playStatePermits, (int)mIsAudioPrerolling,
                 (int)mIsVideoPrerolling, (int)mAudioOffloading);
@@ -2759,23 +2770,17 @@ void
 MediaDecoderStateMachine::SetPlaybackRate(double aPlaybackRate)
 {
   MOZ_ASSERT(OnTaskQueue());
   MOZ_ASSERT(aPlaybackRate != 0, "Should be handled by MediaDecoder::Pause()");
 
   mPlaybackRate = aPlaybackRate;
   mMediaSink->SetPlaybackRate(mPlaybackRate);
 
-  if (mIsAudioPrerolling && DonePrerollingAudio()) {
-    StopPrerollingAudio();
-  }
-  if (mIsVideoPrerolling && DonePrerollingVideo()) {
-    StopPrerollingVideo();
-  }
-
+  // Schedule next cycle to check if we can stop prerolling.
   ScheduleStateMachine();
 }
 
 void MediaDecoderStateMachine::PreservesPitchChanged()
 {
   MOZ_ASSERT(OnTaskQueue());
   mMediaSink->SetPreservesPitch(mPreservesPitch);
 }
@@ -2927,18 +2932,20 @@ MediaDecoderStateMachine::SetAudioCaptur
   mAudioCaptured = aCaptured;
   ScheduleStateMachine();
 
   // Don't buffer as much when audio is captured because we don't need to worry
   // about high latency audio devices.
   mAmpleAudioThresholdUsecs = mAudioCaptured ?
                               detail::AMPLE_AUDIO_USECS / 2 :
                               detail::AMPLE_AUDIO_USECS;
-  if (mIsAudioPrerolling && DonePrerollingAudio()) {
-    StopPrerollingAudio();
+
+  if (mIsAudioPrerolling) {
+    // Schedule next cycle to check if we can stop prerolling.
+    ScheduleStateMachine();
   }
 }
 
 uint32_t MediaDecoderStateMachine::GetAmpleVideoFrames() const
 {
   MOZ_ASSERT(OnTaskQueue());
   return (mReader->IsAsync() && mReader->VideoIsHardwareAccelerated())
     ? std::max<uint32_t>(sVideoQueueHWAccelSize, MIN_VIDEO_QUEUE_SIZE)