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
--- 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