Bug 1183007. Part 2.5 - don't call AudioEndTime() after mAudioSink becomes null. r=kinetik.
authorJW Wang <jwwang@mozilla.com>
Thu, 16 Jul 2015 10:14:42 +0800
changeset 253146 fafc65c08458810737e0f67ca36f60e976d514fc
parent 253145 6db05cc790a9f54b26cc50a0ed9067b420dd10b9
child 253147 f0e5f3f89b912fb3faf3ebf036c54820189bcf79
push id29061
push userryanvm@gmail.com
push dateThu, 16 Jul 2015 18:53:45 +0000
treeherdermozilla-central@a0f4a688433d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskinetik
bugs1183007
milestone42.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 1183007. Part 2.5 - don't call AudioEndTime() after mAudioSink becomes null. r=kinetik.
dom/media/MediaDecoderStateMachine.cpp
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -2417,32 +2417,35 @@ nsresult MediaDecoderStateMachine::RunSt
 
       if (mState != DECODER_STATE_COMPLETED) {
         // While we're presenting a frame we can change state. Whatever changed
         // our state should have scheduled another state machine run.
         NS_ASSERTION(IsStateMachineScheduled(), "Must have timer scheduled");
         return NS_OK;
       }
 
-      StopAudioThread();
-      mDecodedStream->StopPlayback();
-
       if (mPlayState == MediaDecoder::PLAY_STATE_PLAYING &&
           !mSentPlaybackEndedEvent)
       {
         int64_t clockTime = std::max(AudioEndTime(), mVideoFrameEndTime);
         clockTime = std::max(int64_t(0), std::max(clockTime, Duration().ToMicroseconds()));
         UpdatePlaybackPosition(clockTime);
 
         nsCOMPtr<nsIRunnable> event =
           NS_NewRunnableMethod(mDecoder, &MediaDecoder::PlaybackEnded);
         AbstractThread::MainThread()->Dispatch(event.forget());
 
         mSentPlaybackEndedEvent = true;
       }
+
+      // Stop audio sink after call to AudioEndTime() above, otherwise it will
+      // return an incorrect value due to a null mAudioSink.
+      StopAudioThread();
+      mDecodedStream->StopPlayback();
+
       return NS_OK;
     }
   }
 
   return NS_OK;
 }
 
 void
@@ -3073,16 +3076,19 @@ void MediaDecoderStateMachine::QueueMeta
 int64_t
 MediaDecoderStateMachine::AudioEndTime() const
 {
   MOZ_ASSERT(OnTaskQueue());
   AssertCurrentThreadInMonitor();
   if (mAudioSink) {
     return mAudioSink->GetEndTime();
   }
+  // Don't call this after mAudioSink becomes null since we can't distinguish
+  // "before StartAudioThread" and "after StopAudioThread".
+  MOZ_ASSERT(mAudioCaptured || !mAudioCompleted);
   return mAudioEndTime;
 }
 
 void MediaDecoderStateMachine::OnAudioEndTimeUpdate(int64_t aAudioEndTime)
 {
   MOZ_ASSERT(OnTaskQueue());
   ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
   MOZ_ASSERT(aAudioEndTime >= AudioEndTime());