Bug 1213897 - Extract DelayedScheduler out of MDSM to a common class. r=jwwang

--HG--
extra : rebase_source : 5408c282a678fe060d24138eccbe34cf99c8c929
This commit is contained in:
Kilik Kuo 2015-10-13 15:39:01 +08:00
parent 208c875629
commit 3b7a3980ff
3 changed files with 62 additions and 47 deletions

View File

@ -204,7 +204,7 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
mProducerID(ImageContainer::AllocateProducerID()),
mRealTime(aRealTime),
mDispatchedStateMachine(false),
mDelayedScheduler(this),
mDelayedScheduler(mTaskQueue),
mState(DECODER_STATE_DECODING_NONE, "MediaDecoderStateMachine::mState"),
mCurrentFrameID(0),
mObservedDuration(TimeUnit(), "MediaDecoderStateMachine::mObservedDuration"),
@ -2855,7 +2855,13 @@ MediaDecoderStateMachine::ScheduleStateMachineIn(int64_t aMicroseconds)
TimeStamp target = now + TimeDuration::FromMicroseconds(aMicroseconds);
SAMPLE_LOG("Scheduling state machine for %lf ms from now", (target - now).ToMilliseconds());
mDelayedScheduler.Ensure(target);
nsRefPtr<MediaDecoderStateMachine> self = this;
mDelayedScheduler.Ensure(target, [self] () {
self->OnDelayedSchedule();
}, [self] () {
self->NotReached();
});
}
bool MediaDecoderStateMachine::OnTaskQueue() const

View File

@ -679,51 +679,8 @@ private:
// yet to run.
bool mDispatchedStateMachine;
// Class for managing delayed dispatches of the state machine.
class DelayedScheduler {
public:
explicit DelayedScheduler(MediaDecoderStateMachine* aSelf)
: mSelf(aSelf), mMediaTimer(new MediaTimer()) {}
bool IsScheduled() const { return !mTarget.IsNull(); }
void Reset()
{
MOZ_ASSERT(mSelf->OnTaskQueue(), "Must be on state machine queue to disconnect");
if (IsScheduled()) {
mRequest.Disconnect();
mTarget = TimeStamp();
}
}
void Ensure(mozilla::TimeStamp& aTarget)
{
MOZ_ASSERT(mSelf->OnTaskQueue());
if (IsScheduled() && mTarget <= aTarget) {
return;
}
Reset();
mTarget = aTarget;
mRequest.Begin(mMediaTimer->WaitUntil(mTarget, __func__)->Then(
mSelf->OwnerThread(), __func__, mSelf,
&MediaDecoderStateMachine::OnDelayedSchedule,
&MediaDecoderStateMachine::NotReached));
}
void CompleteRequest()
{
MOZ_ASSERT(mSelf->OnTaskQueue());
mRequest.Complete();
mTarget = TimeStamp();
}
private:
MediaDecoderStateMachine* mSelf;
nsRefPtr<MediaTimer> mMediaTimer;
MozPromiseRequestHolder<mozilla::MediaTimerPromise> mRequest;
TimeStamp mTarget;
} mDelayedScheduler;
// Used to dispatch another round schedule with specific target time.
DelayedScheduler mDelayedScheduler;
// StartTimeRendezvous is a helper class that quarantines the first sample
// until it gets a sample from both channels, such that we can be guaranteed

View File

@ -113,6 +113,58 @@ private:
bool mUpdateScheduled;
};
// Class for managing delayed dispatches on target thread.
class DelayedScheduler {
public:
explicit DelayedScheduler(AbstractThread* aTargetThread)
: mTargetThread(aTargetThread), mMediaTimer(new MediaTimer())
{
MOZ_ASSERT(mTargetThread);
}
bool IsScheduled() const { return !mTarget.IsNull(); }
void Reset()
{
MOZ_ASSERT(mTargetThread->IsCurrentThreadIn(),
"Must be on target thread to disconnect");
if (IsScheduled()) {
mRequest.Disconnect();
mTarget = TimeStamp();
}
}
template <typename ResolveFunc, typename RejectFunc>
void Ensure(mozilla::TimeStamp& aTarget,
ResolveFunc&& aResolver,
RejectFunc&& aRejector)
{
MOZ_ASSERT(mTargetThread->IsCurrentThreadIn());
if (IsScheduled() && mTarget <= aTarget) {
return;
}
Reset();
mTarget = aTarget;
mRequest.Begin(mMediaTimer->WaitUntil(mTarget, __func__)->Then(
mTargetThread, __func__,
Forward<ResolveFunc>(aResolver),
Forward<RejectFunc>(aRejector)));
}
void CompleteRequest()
{
MOZ_ASSERT(mTargetThread->IsCurrentThreadIn());
mRequest.Complete();
mTarget = TimeStamp();
}
private:
nsRefPtr<AbstractThread> mTargetThread;
nsRefPtr<MediaTimer> mMediaTimer;
MozPromiseRequestHolder<mozilla::MediaTimerPromise> mRequest;
TimeStamp mTarget;
};
} // namespace mozilla
#endif