Bug 607838 - Allow audio drains to be interrupted - r=cpearce a=blocking2.0:final
authorChris Double <chris.double@double.co.nz>
Wed, 02 Feb 2011 14:31:53 +1300
changeset 61820 ee00364d30927ea8981eaac56dcb6e14a343bb77
parent 61819 5212ab4ae8082122ad57b5e8bc8015fb25814f68
child 61821 59bcb91cc3489dde592d03e7e7a4968998166243
push id1
push userroot
push dateTue, 10 Dec 2013 15:46:25 +0000
reviewerscpearce, blocking2
bugs607838
milestone2.0b12pre
Bug 607838 - Allow audio drains to be interrupted - r=cpearce a=blocking2.0:final
content/media/nsBuiltinDecoderStateMachine.cpp
--- a/content/media/nsBuiltinDecoderStateMachine.cpp
+++ b/content/media/nsBuiltinDecoderStateMachine.cpp
@@ -505,19 +505,44 @@ void nsBuiltinDecoderStateMachine::Audio
   if (mReader->mAudioQueue.AtEndOfStream() &&
       mState != DECODER_STATE_SHUTDOWN &&
       !mStopDecodeThreads)
   {
     // Last sample pushed to audio hardware, wait for the audio to finish,
     // before the audio thread terminates.
     MonitorAutoEnter audioMon(mAudioMonitor);
     if (mAudioStream) {
-      mAudioStream->Drain();
-      // Fire one last event for any extra samples that didn't fill a framebuffer.
-      mEventManager.Drain(mAudioEndTime);
+      PRBool seeking = PR_FALSE;
+      PRInt64 oldPosition = -1;
+
+      {
+        MonitorAutoExit audioExit(mAudioMonitor);
+        MonitorAutoEnter mon(mDecoder->GetMonitor());
+        PRInt64 position = GetMediaTime();
+        while (oldPosition != position &&
+               mAudioEndTime - position > 0 &&
+               mState != DECODER_STATE_SEEKING &&
+               mState != DECODER_STATE_SHUTDOWN)
+        {
+          const PRInt64 DRAIN_BLOCK_MS = 100;
+          Wait(NS_MIN(mAudioEndTime - position, DRAIN_BLOCK_MS));
+          oldPosition = position;
+          position = GetMediaTime();
+        }
+        if (mState == DECODER_STATE_SEEKING) {
+          seeking = PR_TRUE;
+        }
+      }
+
+      if (!seeking && mAudioStream) {
+        mAudioStream->Drain();
+
+        // Fire one last event for any extra samples that didn't fill a framebuffer.
+        mEventManager.Drain(mAudioEndTime);
+      }
     }
     LOG(PR_LOG_DEBUG, ("%p Reached audio stream end.", mDecoder));
   }
   {
     MonitorAutoEnter mon(mDecoder->GetMonitor());
     mAudioCompleted = PR_TRUE;
     UpdateReadyState();
     // Kick the decode and state machine threads; they may be sleeping waiting