зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1157797 - Use state-watching machinery for UpdateNextFrameStatus. r=jww
The ergonomics here aren't ideal. I'm going to file a bug to improve them.
This commit is contained in:
Родитель
7a1c7f2705
Коммит
23925f4fdc
|
@ -205,11 +205,12 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
|
|||
mRealTime(aRealTime),
|
||||
mDispatchedStateMachine(false),
|
||||
mDelayedScheduler(this),
|
||||
mState(DECODER_STATE_DECODING_NONE),
|
||||
mState(DECODER_STATE_DECODING_NONE, "MediaDecoderStateMachine::mState"),
|
||||
mPlayDuration(0),
|
||||
mStartTime(-1),
|
||||
mEndTime(-1),
|
||||
mDurationSet(false),
|
||||
mNextFrameStatusUpdater("MediaDecoderStateMachine::mNextFrameStatusUpdater"),
|
||||
mFragmentEndTime(-1),
|
||||
mReader(aReader),
|
||||
mCurrentFrameTime(0),
|
||||
|
@ -228,7 +229,7 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
|
|||
mIsVideoPrerolling(false),
|
||||
mAudioCaptured(false),
|
||||
mPositionChangeQueued(false),
|
||||
mAudioCompleted(false),
|
||||
mAudioCompleted(false, "MediaDecoderStateMachine::mAudioCompleted"),
|
||||
mGotDurationFromMetaData(false),
|
||||
mDispatchedEventToDecode(false),
|
||||
mStopAudioThread(true),
|
||||
|
@ -257,6 +258,12 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
|
|||
mNextFrameStatus.Init(mTaskQueue, MediaDecoderOwner::NEXT_FRAME_UNINITIALIZED,
|
||||
"MediaDecoderStateMachine::mNextFrameStatus (Canonical)");
|
||||
|
||||
// Skip the initial notification we get when we Watch the value, since we're
|
||||
// not on the right thread yet.
|
||||
mNextFrameStatusUpdater->Watch(mState, /* aSkipInitialNotify = */ true);
|
||||
mNextFrameStatusUpdater->Watch(mAudioCompleted, /* aSkipInitialNotify = */ true);
|
||||
mNextFrameStatusUpdater->AddWeakCallback(this, &MediaDecoderStateMachine::UpdateNextFrameStatus);
|
||||
|
||||
static bool sPrefCacheInit = false;
|
||||
if (!sPrefCacheInit) {
|
||||
sPrefCacheInit = true;
|
||||
|
@ -1321,8 +1328,6 @@ void MediaDecoderStateMachine::SetState(State aState)
|
|||
|
||||
mState = aState;
|
||||
|
||||
UpdateNextFrameStatus();
|
||||
|
||||
// Clear state-scoped state.
|
||||
mSentPlaybackEndedEvent = false;
|
||||
}
|
||||
|
@ -3182,7 +3187,7 @@ void MediaDecoderStateMachine::SetStartTime(int64_t aStartTimeUsecs)
|
|||
|
||||
void MediaDecoderStateMachine::UpdateNextFrameStatus() {
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
AssertCurrentThreadInMonitor();
|
||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||
|
||||
MediaDecoderOwner::NextFrameStatus status;
|
||||
const char* statusString;
|
||||
|
@ -3424,7 +3429,6 @@ void MediaDecoderStateMachine::OnAudioSinkComplete()
|
|||
}
|
||||
ResyncAudioClock();
|
||||
mAudioCompleted = true;
|
||||
UpdateNextFrameStatus();
|
||||
// Kick the decode thread; it may be sleeping waiting for this to finish.
|
||||
mDecoder->GetReentrantMonitor().NotifyAll();
|
||||
}
|
||||
|
|
|
@ -844,7 +844,7 @@ public:
|
|||
// NotifyAll on the monitor must be called when the state is changed so
|
||||
// that interested threads can wake up and alter behaviour if appropriate
|
||||
// Accessed on state machine, audio, main, and AV thread.
|
||||
State mState;
|
||||
Watchable<State> mState;
|
||||
|
||||
// The task queue in which we run decode tasks. This is referred to as
|
||||
// the "decode thread", though in practise tasks can run on a different
|
||||
|
@ -887,6 +887,7 @@ public:
|
|||
|
||||
// The status of our next frame. Mirrored on the main thread and used to
|
||||
// compute ready state.
|
||||
WatcherHolder mNextFrameStatusUpdater;
|
||||
Canonical<NextFrameStatus>::Holder mNextFrameStatus;
|
||||
public:
|
||||
AbstractCanonical<NextFrameStatus>* CanonicalNextFrameStatus() { return &mNextFrameStatus; }
|
||||
|
@ -1155,7 +1156,7 @@ protected:
|
|||
// the state machine thread. Synchronised via decoder monitor.
|
||||
// When data is being sent to a MediaStream, this is true when all data has
|
||||
// been written to the MediaStream.
|
||||
bool mAudioCompleted;
|
||||
Watchable<bool> mAudioCompleted;
|
||||
|
||||
// True if mDuration has a value obtained from an HTTP header, or from
|
||||
// the media index/metadata. Accessed on the state machine thread.
|
||||
|
|
|
@ -70,7 +70,7 @@ void EnsureStateWatchingLog();
|
|||
class AbstractWatcher
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(AbstractWatcher)
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AbstractWatcher)
|
||||
AbstractWatcher() : mDestroyed(false) {}
|
||||
bool IsDestroyed() { return mDestroyed; }
|
||||
virtual void Notify() = 0;
|
||||
|
@ -104,12 +104,14 @@ class WatchTarget
|
|||
public:
|
||||
explicit WatchTarget(const char* aName) : mName(aName) {}
|
||||
|
||||
void AddWatcher(AbstractWatcher* aWatcher)
|
||||
void AddWatcher(AbstractWatcher* aWatcher, bool aSkipInitialNotify)
|
||||
{
|
||||
MOZ_ASSERT(!mWatchers.Contains(aWatcher));
|
||||
mWatchers.AppendElement(aWatcher);
|
||||
if (!aSkipInitialNotify) {
|
||||
aWatcher->Notify();
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveWatcher(AbstractWatcher* aWatcher)
|
||||
{
|
||||
|
@ -204,7 +206,7 @@ public:
|
|||
AbstractThread::GetCurrent()->TailDispatcher().AddDirectTask(r.forget());
|
||||
}
|
||||
|
||||
void Watch(WatchTarget& aTarget) { aTarget.AddWatcher(this); }
|
||||
void Watch(WatchTarget& aTarget, bool aSkipInitialNotify = false) { aTarget.AddWatcher(this, aSkipInitialNotify); }
|
||||
void Unwatch(WatchTarget& aTarget) { aTarget.RemoveWatcher(this); }
|
||||
|
||||
template<typename ThisType>
|
||||
|
|
Загрузка…
Ссылка в новой задаче