void SeekTask::OnAudioDecoded(MediaData* aAudioSample) { AssertOwnerThread(); RefPtr<MediaData> audio(aAudioSample); MOZ_ASSERT(audio); // The MDSM::mDecodedAudioEndTime will be updated once the whole SeekTask is // resolved. SAMPLE_LOG("OnAudioDecoded [%lld,%lld] disc=%d", (audio ? audio->mTime : -1), (audio ? audio->GetEndTime() : -1), (audio ? audio->mDiscontinuity : 0)); if (!Exists()) { // We've received a sample from a previous decode. Discard it. return; } if (audio->mDiscontinuity) { mDropAudioUntilNextDiscontinuity = false; } if (!mDropAudioUntilNextDiscontinuity) { // 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 && audio->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. mSeekedAudioData = audio; } else { // We're doing an accurate seek. We must discard // MediaData up to the one containing exact seek target. if (NS_FAILED(DropAudioUpToSeekTarget(audio.get()))) { RejectIfExist(__func__); return; } } } CheckIfSeekComplete(); }
void AccurateSeekTask::OnAudioDecoded(MediaData* aAudioSample) { AssertOwnerThread(); MOZ_ASSERT(!mSeekTaskPromise.IsEmpty(), "Seek shouldn't be finished"); RefPtr<MediaData> audio(aAudioSample); MOZ_ASSERT(audio); // The MDSM::mDecodedAudioEndTime will be updated once the whole SeekTask is // resolved. SAMPLE_LOG("OnAudioDecoded [%lld,%lld] disc=%d", audio->mTime, audio->GetEndTime(), audio->mDiscontinuity); // Video-only seek doesn't reset audio decoder. There might be pending audio // requests when AccurateSeekTask::Seek() begins. We will just store the data // without checking |mDiscontinuity| or calling DropAudioUpToSeekTarget(). if (mTarget.IsVideoOnly()) { mSeekedAudioData = audio.forget(); return; } if (mFirstAudioSample) { mFirstAudioSample = false; MOZ_ASSERT(audio->mDiscontinuity); } AdjustFastSeekIfNeeded(audio); if (mTarget.IsFast()) { // Non-precise seek; we can stop the seek at the first sample. mSeekedAudioData = audio; mDoneAudioSeeking = true; } else if (NS_FAILED(DropAudioUpToSeekTarget(audio))) { CancelCallbacks(); RejectIfExist(__func__); return; } if (!mDoneAudioSeeking) { RequestAudioData(); return; } MaybeFinishSeek(); }