Bug 1252762 - Decode at most one audio/video sample before finishing seeking. r=cpearce. draft
authorJW Wang <jwwang@mozilla.com>
Thu, 03 Mar 2016 15:13:37 +0800
changeset 336457 1a5d4616693c77f4a54848b8aa0585eaf6b1b213
parent 336395 9ec5ec38ef99ee97ae2ad9013a6c1fe203e41acb
child 336679 7da2c12b2750f94e6088e296eb8dde5643bde773
push id12067
push userjwwang@mozilla.com
push dateThu, 03 Mar 2016 07:17:18 +0000
reviewerscpearce
bugs1252762
milestone47.0a1
Bug 1252762 - Decode at most one audio/video sample before finishing seeking. r=cpearce. The idea is to make NeedToDecode{Audio,Video} return false when mState is DECODER_STATE_SEEKING so DispatchDecodeTasksIfNeeded() basically does nothing during seeking. And we call Ensure{Audio,Video}DecodeTaskQueued instead during seeking to request audio/video samples only when audio/video seeking is not completed. MozReview-Commit-ID: 2n7ehVXAq4H
dom/media/MediaDecoderStateMachine.cpp
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -481,23 +481,21 @@ bool MediaDecoderStateMachine::HaveEnoug
 
   return true;
 }
 
 bool
 MediaDecoderStateMachine::NeedToDecodeVideo()
 {
   MOZ_ASSERT(OnTaskQueue());
-  SAMPLE_LOG("NeedToDecodeVideo() isDec=%d decToTar=%d minPrl=%d seek=%d enufVid=%d",
-             IsVideoDecoding(), mDecodeToSeekTarget, mMinimizePreroll,
-             mState == DECODER_STATE_SEEKING,
-             HaveEnoughDecodedVideo());
+  SAMPLE_LOG("NeedToDecodeVideo() isDec=%d minPrl=%d enufVid=%d",
+             IsVideoDecoding(), mMinimizePreroll, HaveEnoughDecodedVideo());
   return IsVideoDecoding() &&
-         ((mState == DECODER_STATE_SEEKING && mDecodeToSeekTarget) ||
-          (IsDecodingFirstFrame() && VideoQueue().GetSize() == 0) ||
+         mState != DECODER_STATE_SEEKING &&
+         ((IsDecodingFirstFrame() && VideoQueue().GetSize() == 0) ||
           (!mMinimizePreroll && !HaveEnoughDecodedVideo()));
 }
 
 bool
 MediaDecoderStateMachine::NeedToSkipToNextKeyframe()
 {
   MOZ_ASSERT(OnTaskQueue());
   if (IsDecodingFirstFrame()) {
@@ -551,24 +549,23 @@ MediaDecoderStateMachine::NeedToSkipToNe
 
   return false;
 }
 
 bool
 MediaDecoderStateMachine::NeedToDecodeAudio()
 {
   MOZ_ASSERT(OnTaskQueue());
-  SAMPLE_LOG("NeedToDecodeAudio() isDec=%d decToTar=%d minPrl=%d seek=%d enufAud=%d",
-             IsAudioDecoding(), mDecodeToSeekTarget, mMinimizePreroll,
-             mState == DECODER_STATE_SEEKING,
+  SAMPLE_LOG("NeedToDecodeAudio() isDec=%d minPrl=%d enufAud=%d",
+             IsAudioDecoding(), mMinimizePreroll,
              HaveEnoughDecodedAudio(mAmpleAudioThresholdUsecs * mPlaybackRate));
 
   return IsAudioDecoding() &&
-         ((mState == DECODER_STATE_SEEKING && mDecodeToSeekTarget) ||
-          (IsDecodingFirstFrame() && AudioQueue().GetSize() == 0) ||
+         mState != DECODER_STATE_SEEKING &&
+         ((IsDecodingFirstFrame() && AudioQueue().GetSize() == 0) ||
           (!mMinimizePreroll &&
            !HaveEnoughDecodedAudio(mAmpleAudioThresholdUsecs * mPlaybackRate)));
 }
 
 bool
 MediaDecoderStateMachine::IsAudioSeekComplete()
 {
   MOZ_ASSERT(OnTaskQueue());
@@ -1020,16 +1017,18 @@ MediaDecoderStateMachine::CheckIfSeekCom
       DecodeError();
     }
   }
 
   SAMPLE_LOG("CheckIfSeekComplete() audioSeekComplete=%d videoSeekComplete=%d",
              audioSeekComplete, videoSeekComplete);
 
   if (audioSeekComplete && videoSeekComplete) {
+    NS_ASSERTION(AudioQueue().GetSize() <= 1, "Should decode at most one sample");
+    NS_ASSERTION(VideoQueue().GetSize() <= 1, "Should decode at most one sample");
     mDecodeToSeekTarget = false;
     SeekCompleted();
   }
 }
 
 bool
 MediaDecoderStateMachine::IsAudioDecoding()
 {
@@ -1643,17 +1642,18 @@ MediaDecoderStateMachine::InitiateSeek()
                                  &MediaDecoderReader::Seek, seekTarget,
                                  Duration().ToMicroseconds())
     ->Then(OwnerThread(), __func__,
            [self] (media::TimeUnit) -> void {
              self->mSeekRequest.Complete();
              // We must decode the first samples of active streams, so we can determine
              // the new stream time. So dispatch tasks to do that.
              self->mDecodeToSeekTarget = true;
-             self->DispatchDecodeTasksIfNeeded();
+             self->EnsureAudioDecodeTaskQueued();
+             self->EnsureVideoDecodeTaskQueued();
            }, [self] (nsresult aResult) -> void {
              self->mSeekRequest.Complete();
              MOZ_ASSERT(NS_FAILED(aResult), "Cancels should also disconnect mSeekRequest");
              self->DecodeError();
            }));
 }
 
 nsresult