void SeekTask::OnVideoDecoded(MediaData* aVideoSample) { AssertOwnerThread(); RefPtr<MediaData> video(aVideoSample); MOZ_ASSERT(video); // The MDSM::mDecodedVideoEndTime will be updated once the whole SeekTask is // resolved. SAMPLE_LOG("OnVideoDecoded [%lld,%lld] disc=%d", (video ? video->mTime : -1), (video ? video->GetEndTime() : -1), (video ? video->mDiscontinuity : 0)); if (!Exists()) { // We've received a sample from a previous decode. Discard it. return; } if (mDropVideoUntilNextDiscontinuity) { if (video->mDiscontinuity) { mDropVideoUntilNextDiscontinuity = false; } } if (!mDropVideoUntilNextDiscontinuity) { // We must be after the discontinuity; we're receiving samples // at or after the seek target. if (mSeekJob.mTarget.IsFast() && mSeekJob.mTarget.GetTime().ToMicroseconds() > mCurrentTimeBeforeSeek && video->mTime < mCurrentTimeBeforeSeek) { // We are doing a fastSeek, but we ended up *before* the previous // playback position. This is surprising UX, so switch to an accurate // seek and decode to the seek target. This is not conformant to the // spec, fastSeek should always be fast, but until we get the time to // change all Readers to seek to the keyframe after the currentTime // in this case, we'll just decode forward. Bug 1026330. mSeekJob.mTarget.SetType(SeekTarget::Accurate); } if (mSeekJob.mTarget.IsFast()) { // Non-precise seek. We can stop the seek at the first sample. mSeekedVideoData = video; } else { // We're doing an accurate seek. We still need to discard // MediaData up to the one containing exact seek target. if (NS_FAILED(DropVideoUpToSeekTarget(video.get()))) { RejectIfExist(__func__); return; } } } CheckIfSeekComplete(); }
void AccurateSeekTask::OnVideoDecoded(MediaData* aVideoSample) { AssertOwnerThread(); MOZ_ASSERT(!mSeekTaskPromise.IsEmpty(), "Seek shouldn't be finished"); RefPtr<MediaData> video(aVideoSample); MOZ_ASSERT(video); // The MDSM::mDecodedVideoEndTime will be updated once the whole SeekTask is // resolved. SAMPLE_LOG("OnVideoDecoded [%lld,%lld] disc=%d", video->mTime, video->GetEndTime(), video->mDiscontinuity); if (mFirstVideoSample) { mFirstVideoSample = false; MOZ_ASSERT(video->mDiscontinuity); } AdjustFastSeekIfNeeded(video); if (mTarget.IsFast()) { // Non-precise seek. We can stop the seek at the first sample. mSeekedVideoData = video; mDoneVideoSeeking = true; } else if (NS_FAILED(DropVideoUpToSeekTarget(video.get()))) { CancelCallbacks(); RejectIfExist(__func__); return; } if (!mDoneVideoSeeking) { RequestVideoData(); return; } MaybeFinishSeek(); }