Bug 693021 - Bail from AdvanceFrame early if no longer playing. r=cpearce
authorMatthew Gregan <kinetik@flim.org>
Mon, 05 Mar 2012 15:27:49 +1300
changeset 89759 8706180542ed9fafd252757ea63c10fcafadb278
parent 89758 71995d5b92a111a7e2d42abc8299f2e664050cee
child 89760 a708e1611e60ee3e0a95b0c8b9feb5632edb3311
push idunknown
push userunknown
push dateunknown
reviewerscpearce
bugs693021
milestone13.0a1
Bug 693021 - Bail from AdvanceFrame early if no longer playing. r=cpearce
content/media/nsBuiltinDecoder.cpp
content/media/nsBuiltinDecoderStateMachine.cpp
--- a/content/media/nsBuiltinDecoder.cpp
+++ b/content/media/nsBuiltinDecoder.cpp
@@ -857,26 +857,17 @@ void nsBuiltinDecoder::PlaybackPositionC
 
   double lastTime = mCurrentTime;
 
   // Control the scope of the monitor so it is not
   // held while the timeupdate and the invalidate is run.
   {
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     if (mDecoderStateMachine) {
-      if (!IsSeeking()) {
-        // Only update the current playback position if we're not seeking.
-        // If we are seeking, the update could have been scheduled on the
-        // state machine thread while we were playing but after the seek
-        // algorithm set the current playback position on the main thread,
-        // and we don't want to override the seek algorithm and change the
-        // current time after the seek has started but before it has
-        // completed.
-        mCurrentTime = mDecoderStateMachine->GetCurrentTime();
-      }
+      mCurrentTime = mDecoderStateMachine->GetCurrentTime();
       mDecoderStateMachine->ClearPositionChangeFlag();
     }
   }
 
   // Invalidate the frame so any video data is displayed.
   // Do this before the timeupdate event so that if that
   // event runs JavaScript that queries the media size, the
   // frame has reflowed and the size updated beforehand.
--- a/content/media/nsBuiltinDecoderStateMachine.cpp
+++ b/content/media/nsBuiltinDecoderStateMachine.cpp
@@ -2014,16 +2014,23 @@ void nsBuiltinDecoderStateMachine::Advan
                           UsecsToDuration(currentFrame->mTime - mStartTime);
     NS_ASSERTION(currentFrame->mTime >= mStartTime, "Should have positive frame time");
     {
       ReentrantMonitorAutoExit exitMon(mDecoder->GetReentrantMonitor());
       // If we have video, we want to increment the clock in steps of the frame
       // duration.
       RenderVideoFrame(currentFrame, presTime);
     }
+    // If we're no longer playing after dropping and reacquiring the lock,
+    // playback must've been stopped on the decode thread (by a seek, for
+    // example).  In that case, the current frame is probably out of date.
+    if (!IsPlaying()) {
+      ScheduleStateMachine();
+      return;
+    }
     mDecoder->GetFrameStatistics().NotifyPresentedFrame();
     PRInt64 now = DurationToUsecs(TimeStamp::Now() - mPlayStartTime) + mPlayDuration;
     remainingTime = currentFrame->mEndTime - mStartTime - now;
     currentFrame = nsnull;
   }
 
   // Cap the current time to the larger of the audio and video end time.
   // This ensures that if we're running off the system clock, we don't