Bug 1284399. Part 6 - store a copy of SeekTarget instead of its reference in SeekTask so it's life cycle can be independent from the client. r=kaku
MozReview-Commit-ID: BWrutqvsj29
--- a/dom/media/AccurateSeekTask.cpp
+++ b/dom/media/AccurateSeekTask.cpp
@@ -33,24 +33,24 @@ extern LazyLogModule gMediaSampleLog;
// when __VA_ARGS__ expands to nothing. This is a workaround for it.
#define DECODER_WARN_HELPER(a, b) NS_WARNING b
#define DECODER_WARN(x, ...) \
DECODER_WARN_HELPER(0, (nsPrintfCString("Decoder=%p " x, mDecoderID, ##__VA_ARGS__).get()))
AccurateSeekTask::AccurateSeekTask(const void* aDecoderID,
AbstractThread* aThread,
MediaDecoderReaderWrapper* aReader,
- SeekJob& aSeekJob,
+ const SeekTarget& aTarget,
const MediaInfo& aInfo,
const media::TimeUnit& aEnd,
int64_t aCurrentMediaTime)
- : SeekTask(aDecoderID, aThread, aReader, aSeekJob)
+ : SeekTask(aDecoderID, aThread, aReader, aTarget)
, mCurrentTimeBeforeSeek(media::TimeUnit::FromMicroseconds(aCurrentMediaTime))
, mAudioRate(aInfo.mAudio.mRate)
- , mDoneAudioSeeking(!aInfo.HasAudio() || mTarget.IsVideoOnly())
+ , mDoneAudioSeeking(!aInfo.HasAudio() || aTarget.IsVideoOnly())
, mDoneVideoSeeking(!aInfo.HasVideo())
{
AssertOwnerThread();
// Bound the seek time to be inside the media range.
NS_ASSERTION(aEnd.ToMicroseconds() != -1, "Should know end time by now");
mTarget.SetTime(std::max(media::TimeUnit(), std::min(mTarget.GetTime(), aEnd)));
--- a/dom/media/AccurateSeekTask.h
+++ b/dom/media/AccurateSeekTask.h
@@ -14,17 +14,17 @@
namespace mozilla {
class AccurateSeekTask final : public SeekTask {
public:
AccurateSeekTask(const void* aDecoderID,
AbstractThread* aThread,
MediaDecoderReaderWrapper* aReader,
- SeekJob& aSeekJob,
+ const SeekTarget& aTarget,
const MediaInfo& aInfo,
const media::TimeUnit& aEnd,
int64_t aCurrentMediaTime);
void Discard() override;
RefPtr<SeekTaskPromise> Seek(const media::TimeUnit& aDuration) override;
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -1437,17 +1437,17 @@ void MediaDecoderStateMachine::InitiateD
// SeekTask will register its callbacks to MediaDecoderReaderWrapper.
CancelMediaDecoderReaderWrapperCallback();
MOZ_ASSERT(!mCurrentSeek.Exists());
mCurrentSeek = Move(seekJob);
// Create a new SeekTask instance for the incoming seek task.
mSeekTask = new AccurateSeekTask(mDecoderID, OwnerThread(),
- mReader.get(), mCurrentSeek,
+ mReader.get(), mCurrentSeek.mTarget,
mInfo, Duration(), GetMediaTime());
mOnSeekingStart.Notify(MediaDecoderEventVisibility::Suppressed);
// Reset our state machine and decoding pipeline before seeking.
if (mSeekTask->NeedToResetMDSM()) {
Reset(aTracks);
}
@@ -1642,33 +1642,38 @@ MediaDecoderStateMachine::InitiateSeek(S
// SeekTask will register its callbacks to MediaDecoderReaderWrapper.
CancelMediaDecoderReaderWrapperCallback();
// Create a new SeekTask instance for the incoming seek task.
MOZ_ASSERT(!mCurrentSeek.Exists());
mCurrentSeek = Move(aSeekJob);
if (mCurrentSeek.mTarget.IsAccurate() || mCurrentSeek.mTarget.IsFast()) {
mSeekTask = new AccurateSeekTask(mDecoderID, OwnerThread(),
- mReader.get(), mCurrentSeek,
+ mReader.get(), mCurrentSeek.mTarget,
mInfo, Duration(), GetMediaTime());
} else if (mCurrentSeek.mTarget.IsNextFrame()) {
mSeekTask = new NextFrameSeekTask(mDecoderID, OwnerThread(), mReader.get(),
- mCurrentSeek, mInfo, Duration(),
+ mCurrentSeek.mTarget, mInfo, Duration(),
GetMediaTime(), AudioQueue(), VideoQueue());
} else {
MOZ_DIAGNOSTIC_ASSERT(false, "Cannot handle this seek task.");
}
// Stop playback now to ensure that while we're outside the monitor
// dispatching SeekingStarted, playback doesn't advance and mess with
// mCurrentPosition that we've setting to seekTime here.
StopPlayback();
+
+ // mCurrentSeek.mTarget.mTime might be different from
+ // mSeekTask->GetSeekTarget().mTime because the seek task might clamp the seek
+ // target to [0, duration]. We want to update the playback position to the
+ // clamped value.
UpdatePlaybackPositionInternal(mSeekTask->GetSeekTarget().GetTime().ToMicroseconds());
- mOnSeekingStart.Notify(mSeekTask->GetSeekTarget().mEventVisibility);
+ mOnSeekingStart.Notify(mCurrentSeek.mTarget.mEventVisibility);
// Reset our state machine and decoding pipeline before seeking.
if (mSeekTask->NeedToResetMDSM()) { Reset(); }
// Do the seek.
mSeekTaskRequest.Begin(mSeekTask->Seek(Duration())
->Then(OwnerThread(), __func__, this,
&MediaDecoderStateMachine::OnSeekTaskResolved,
--- a/dom/media/NextFrameSeekTask.cpp
+++ b/dom/media/NextFrameSeekTask.cpp
@@ -17,23 +17,23 @@ extern LazyLogModule gMediaSampleLog;
#define SAMPLE_LOG(x, ...) MOZ_LOG(gMediaSampleLog, LogLevel::Debug, \
("[NextFrameSeekTask] Decoder=%p " x, mDecoderID, ##__VA_ARGS__))
namespace media {
NextFrameSeekTask::NextFrameSeekTask(const void* aDecoderID,
AbstractThread* aThread,
MediaDecoderReaderWrapper* aReader,
- SeekJob& aSeekJob,
+ const SeekTarget& aTarget,
const MediaInfo& aInfo,
const media::TimeUnit& aDuration,
int64_t aCurrentTime,
MediaQueue<MediaData>& aAudioQueue,
MediaQueue<MediaData>& aVideoQueue)
- : SeekTask(aDecoderID, aThread, aReader, aSeekJob)
+ : SeekTask(aDecoderID, aThread, aReader, aTarget)
, mAudioQueue(aAudioQueue)
, mVideoQueue(aVideoQueue)
, mCurrentTime(aCurrentTime)
, mDuration(aDuration)
{
AssertOwnerThread();
MOZ_ASSERT(aInfo.HasVideo());
--- a/dom/media/NextFrameSeekTask.h
+++ b/dom/media/NextFrameSeekTask.h
@@ -22,17 +22,17 @@ namespace media {
* so that the MDSM will be able to update the media element's position.
*/
class NextFrameSeekTask final : public SeekTask {
public:
NextFrameSeekTask(const void* aDecoderID,
AbstractThread* aThread,
MediaDecoderReaderWrapper* aReader,
- SeekJob& aSeekJob,
+ const SeekTarget& aTarget,
const MediaInfo& aInfo,
const media::TimeUnit& aDuration,
int64_t aCurrentTime,
MediaQueue<MediaData>& aAudioQueue,
MediaQueue<MediaData>& aVideoQueue);
void Discard() override;
--- a/dom/media/SeekTask.cpp
+++ b/dom/media/SeekTask.cpp
@@ -8,21 +8,21 @@
#include "MediaDecoderReaderWrapper.h"
#include "mozilla/AbstractThread.h"
namespace mozilla {
SeekTask::SeekTask(const void* aDecoderID,
AbstractThread* aThread,
MediaDecoderReaderWrapper* aReader,
- SeekJob& aSeekJob)
+ const SeekTarget& aTarget)
: mDecoderID(aDecoderID)
, mOwnerThread(aThread)
, mReader(aReader)
- , mTarget(aSeekJob.mTarget)
+ , mTarget(aTarget)
, mIsDiscarded(false)
, mIsAudioQueueFinished(false)
, mIsVideoQueueFinished(false)
, mNeedToStopPrerollingAudio(false)
, mNeedToStopPrerollingVideo(false)
{
AssertOwnerThread();
}
@@ -71,16 +71,16 @@ SeekTask::AssertOwnerThread() const
AbstractThread*
SeekTask::OwnerThread() const
{
AssertOwnerThread();
return mOwnerThread;
}
-SeekTarget&
+const SeekTarget&
SeekTask::GetSeekTarget()
{
AssertOwnerThread();
return mTarget;
}
} // namespace mozilla
--- a/dom/media/SeekTask.h
+++ b/dom/media/SeekTask.h
@@ -51,23 +51,23 @@ public:
MozPromise<SeekTaskResolveValue, SeekTaskRejectValue, IsExclusive>;
virtual void Discard() = 0;
virtual RefPtr<SeekTaskPromise> Seek(const media::TimeUnit& aDuration) = 0;
virtual bool NeedToResetMDSM() const = 0;
- SeekTarget& GetSeekTarget();
+ const SeekTarget& GetSeekTarget();
protected:
SeekTask(const void* aDecoderID,
AbstractThread* aThread,
MediaDecoderReaderWrapper* aReader,
- SeekJob& aSeekJob);
+ const SeekTarget& aTarget);
virtual ~SeekTask();
void Resolve(const char* aCallSite);
void RejectIfExist(const char* aCallSite);
void AssertOwnerThread() const;
@@ -79,17 +79,17 @@ protected:
*/
const void* mDecoderID; // For logging.
const RefPtr<AbstractThread> mOwnerThread;
const RefPtr<MediaDecoderReaderWrapper> mReader;
/*
* Internal state.
*/
- SeekTarget& mTarget;
+ SeekTarget mTarget;
MozPromiseHolder<SeekTaskPromise> mSeekTaskPromise;
bool mIsDiscarded;
/*
* Information which are going to be returned to MDSM.
*/
RefPtr<MediaData> mSeekedAudioData;
RefPtr<MediaData> mSeekedVideoData;