diff --git a/dom/media/NextFrameSeekTask.cpp b/dom/media/NextFrameSeekTask.cpp index c018105cb8f0..348b11e76b1d 100644 --- a/dom/media/NextFrameSeekTask.cpp +++ b/dom/media/NextFrameSeekTask.cpp @@ -43,13 +43,13 @@ NextFrameSeekTask::NextFrameSeekTask(const void* aDecoderID, SeekJob&& aSeekJob, const MediaInfo& aInfo, const media::TimeUnit& aDuration, - int64_t aCurrentMediaTime, + int64_t aCurrentTime, MediaQueue& aAudioQueue, MediaQueue& aVideoQueue) : SeekTask(aDecoderID, aThread, aReader, Move(aSeekJob)) , mAudioQueue(aAudioQueue) , mVideoQueue(aVideoQueue) - , mCurrentTimeBeforeSeek(aCurrentMediaTime) + , mCurrentTime(aCurrentTime) , mDuration(aDuration) { AssertOwnerThread(); @@ -89,23 +89,16 @@ NextFrameSeekTask::NeedToResetMDSM() const return false; } -static int64_t -FindNextFrame(MediaQueue& aQueue, int64_t aTime) +/* + * Remove samples from the queue until aCompare() returns false. + * aCompare A function object with the signature bool(int64_t) which returns + * true for samples that should be removed. + */ +template static void +DiscardFrames(MediaQueue& aQueue, const Function& aCompare) { - AutoTArray, 16> frames; - aQueue.GetFirstElements(aQueue.GetSize(), &frames); - for (auto&& frame : frames) { - if (frame->mTime > aTime) { - return frame->mTime; - } - } - return -1; -} - -static void -DropFramesUntil(MediaQueue& aQueue, int64_t aTime) { - while (aQueue.GetSize() > 0) { - if (aQueue.PeekFront()->mTime < aTime) { + while(aQueue.GetSize() > 0) { + if (aCompare(aQueue.PeekFront()->mTime)) { RefPtr releaseMe = aQueue.PopFront(); continue; } @@ -113,53 +106,22 @@ DropFramesUntil(MediaQueue& aQueue, int64_t aTime) { } } -static void -DropAllFrames(MediaQueue& aQueue) { - while(aQueue.GetSize() > 0) { - RefPtr releaseMe = aQueue.PopFront(); - } -} - -static void -DropAllMediaDataBeforeCurrentPosition(MediaQueue& aAudioQueue, - MediaQueue& aVideoQueue, - int64_t const aCurrentTimeBeforeSeek) -{ - // Drop all audio/video data before GetMediaTime(); - int64_t newPos = FindNextFrame(aVideoQueue, aCurrentTimeBeforeSeek); - if (newPos < 0) { - // In this case, we cannot find the next frame in the video queue, so - // the NextFrameSeekTask needs to decode video data. - DropAllFrames(aVideoQueue); - if (aVideoQueue.IsFinished()) { - DropAllFrames(aAudioQueue); - } - } else { - DropFramesUntil(aVideoQueue, newPos); - DropFramesUntil(aAudioQueue, newPos); - // So now, the 1st data in the video queue should be the target of the - // NextFrameSeekTask. - } -} - RefPtr NextFrameSeekTask::Seek(const media::TimeUnit&) { AssertOwnerThread(); - DropAllMediaDataBeforeCurrentPosition(mAudioQueue, mVideoQueue, - mCurrentTimeBeforeSeek); + auto currentTime = mCurrentTime; + DiscardFrames(mVideoQueue, [currentTime] (int64_t aSampleTime) { + return aSampleTime <= currentTime; + }); + RefPtr promise = mSeekTaskPromise.Ensure(__func__); if (NeedMoreVideo()) { EnsureVideoDecodeTaskQueued(); } - if (!IsAudioSeekComplete() || !IsVideoSeekComplete()) { - return mSeekTaskPromise.Ensure(__func__); - } - - UpdateSeekTargetTime(); - SeekTaskResolveValue val = {}; // Zero-initialize data members. - return SeekTask::SeekTaskPromise::CreateAndResolve(val, __func__); + MaybeFinishSeek(); // Might resolve mSeekTaskPromise and modify audio queue. + return promise; } bool @@ -249,6 +211,12 @@ NextFrameSeekTask::MaybeFinishSeek() AssertOwnerThread(); if (IsAudioSeekComplete() && IsVideoSeekComplete()) { UpdateSeekTargetTime(); + + auto time = mSeekJob.mTarget.GetTime().ToMicroseconds(); + DiscardFrames(mAudioQueue, [time] (int64_t aSampleTime) { + return aSampleTime < time; + }); + Resolve(__func__); // Call to MDSM::SeekCompleted(); } } @@ -304,7 +272,7 @@ NextFrameSeekTask::OnVideoDecoded(MediaData* aVideoSample) aVideoSample->GetEndTime(), aVideoSample->mDiscontinuity); - if (aVideoSample->mTime > mCurrentTimeBeforeSeek) { + if (aVideoSample->mTime > mCurrentTime) { mSeekedVideoData = aVideoSample; } diff --git a/dom/media/NextFrameSeekTask.h b/dom/media/NextFrameSeekTask.h index 702b08a14291..171783964d90 100644 --- a/dom/media/NextFrameSeekTask.h +++ b/dom/media/NextFrameSeekTask.h @@ -30,7 +30,7 @@ public: SeekJob&& aSeekJob, const MediaInfo& aInfo, const media::TimeUnit& aDuration, - int64_t aCurrentMediaTime, + int64_t aCurrentTime, MediaQueue& aAudioQueue, MediaQueue& aVideoQueue); @@ -86,7 +86,7 @@ private: /* * Internal state. */ - const int64_t mCurrentTimeBeforeSeek; + const int64_t mCurrentTime; media::TimeUnit mDuration; MediaEventListener mAudioCallback;