Bug 1283718. Part 6 - always check NeedMoreVideo() before requesting new video. r=kaku
We still have a chance to finish seeking even when video promises are rejected
provided we already have video samples in the queue.
MozReview-Commit-ID: 5cIbryiLMYt
--- a/dom/media/NextFrameSeekTask.cpp
+++ b/dom/media/NextFrameSeekTask.cpp
@@ -319,49 +319,41 @@ NextFrameSeekTask::OnVideoDecoded(MediaD
void
NextFrameSeekTask::OnVideoNotDecoded(MediaDecoderReader::NotDecodedReason aReason)
{
AssertOwnerThread();
MOZ_ASSERT(!mSeekTaskPromise.IsEmpty(), "Seek shouldn't be finished");
SAMPLE_LOG("OnVideoNotDecoded (aReason=%u)", aReason);
- if (aReason == MediaDecoderReader::DECODE_ERROR) {
- if (mVideoQueue.GetSize() > 0) {
- // The video decoding request might be filed by MDSM not the
- // NextFrameSeekTask itself. So, the NextFrameSeekTask might has already
- // found its target in the VideoQueue but still waits the video decoding
- // request (which is filed by the MDSM) to be resolved. In this case, we
- // already have the target of this seek task, try to resolve this task.
- MaybeFinishSeek();
- return;
+ if (aReason == MediaDecoderReader::END_OF_STREAM) {
+ mIsVideoQueueFinished = true;
+ }
+
+ // Video seek not finished.
+ if (NeedMoreVideo()) {
+ switch (aReason) {
+ case MediaDecoderReader::DECODE_ERROR:
+ // Reject the promise since we can't finish video seek anyway.
+ RejectIfExist(__func__);
+ break;
+ case MediaDecoderReader::WAITING_FOR_DATA:
+ mReader->WaitForData(MediaData::VIDEO_DATA);
+ break;
+ case MediaDecoderReader::CANCELED:
+ EnsureVideoDecodeTaskQueued();
+ break;
+ case MediaDecoderReader::END_OF_STREAM:
+ MOZ_ASSERT(false, "Shouldn't want more data for ended video.");
+ break;
}
-
- // Otherwise, we cannot get the target video frame of this seek task,
- // delegate the decode error to the generic error path.
- RejectIfExist(__func__);
return;
}
- // If the decoder is waiting for data, we tell it to call us back when the
- // data arrives.
- if (aReason == MediaDecoderReader::WAITING_FOR_DATA) {
- mReader->WaitForData(MediaData::VIDEO_DATA);
- return;
- }
-
- if (aReason == MediaDecoderReader::CANCELED) {
- EnsureVideoDecodeTaskQueued();
- return;
- }
-
- if (aReason == MediaDecoderReader::END_OF_STREAM) {
- mIsVideoQueueFinished = true;
- MaybeFinishSeek();
- }
+ MaybeFinishSeek();
}
void
NextFrameSeekTask::SetCallbacks()
{
AssertOwnerThread();
// Register dummy callbcak for audio decoding since we don't need to handle
@@ -389,19 +381,26 @@ NextFrameSeekTask::SetCallbacks()
OwnerThread(), [this] (WaitCallbackData aData) {
// We don't make an audio decode request here, instead, let MDSM to
// trigger further audio decode tasks if MDSM itself needs to play audio.
MaybeFinishSeek();
});
mVideoWaitCallback = mReader->VideoWaitCallback().Connect(
OwnerThread(), [this] (WaitCallbackData aData) {
- if (aData.is<MediaData::Type>()) {
- EnsureVideoDecodeTaskQueued();
+ if (NeedMoreVideo()) {
+ if (aData.is<MediaData::Type>()) {
+ EnsureVideoDecodeTaskQueued();
+ } else {
+ // Reject if we can't finish video seeking.
+ RejectIfExist(__func__);
+ }
+ return;
}
+ MaybeFinishSeek();
});
}
void
NextFrameSeekTask::CancelCallbacks()
{
AssertOwnerThread();
mAudioCallback.Disconnect();