diff --git a/dom/media/AudioSink.cpp b/dom/media/AudioSink.cpp index b1465d20ff31..7e4f2bc2d831 100644 --- a/dom/media/AudioSink.cpp +++ b/dom/media/AudioSink.cpp @@ -25,6 +25,38 @@ extern PRLogModuleInfo* gMediaDecoderLog; #define SINK_LOG_V(msg, ...) #endif +AudioSink::OnAudioEndTimeUpdateTask::OnAudioEndTimeUpdateTask( + MediaDecoderStateMachine* aStateMachine) + : mMutex("OnAudioEndTimeUpdateTask") + , mEndTime(0) + , mStateMachine(aStateMachine) +{ +} + +NS_IMETHODIMP +AudioSink::OnAudioEndTimeUpdateTask::Run() { + MutexAutoLock lock(mMutex); + if (mStateMachine) { + mStateMachine->OnAudioEndTimeUpdate(mEndTime); + } + return NS_OK; +} + +void +AudioSink::OnAudioEndTimeUpdateTask::Dispatch(int64_t aEndTime) { + MutexAutoLock lock(mMutex); + if (mStateMachine) { + mEndTime = aEndTime; + mStateMachine->TaskQueue()->Dispatch(this); + } +} + +void +AudioSink::OnAudioEndTimeUpdateTask::Cancel() { + MutexAutoLock lock(mMutex); + mStateMachine = nullptr; +} + // The amount of audio frames that is used to fuzz rounding errors. static const int64_t AUDIO_FUZZ_FRAMES = 1; @@ -46,6 +78,7 @@ AudioSink::AudioSink(MediaDecoderStateMachine* aStateMachine, , mPlaying(true) { NS_ASSERTION(mStartTime != -1, "Should have audio start time by now"); + mOnAudioEndTimeUpdateTask = new OnAudioEndTimeUpdateTask(aStateMachine); } nsresult @@ -108,6 +141,7 @@ AudioSink::PrepareToShutdown() void AudioSink::Shutdown() { + mOnAudioEndTimeUpdateTask->Cancel(); mThread->Shutdown(); mThread = nullptr; MOZ_ASSERT(!mAudioStream); @@ -202,7 +236,7 @@ AudioSink::AudioLoop() } int64_t endTime = GetEndTime(); if (endTime != -1) { - mStateMachine->DispatchOnAudioEndTimeUpdate(endTime); + mOnAudioEndTimeUpdateTask->Dispatch(endTime); } } ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); diff --git a/dom/media/AudioSink.h b/dom/media/AudioSink.h index 8863bcaa92fc..3b8877c0a75c 100644 --- a/dom/media/AudioSink.h +++ b/dom/media/AudioSink.h @@ -139,6 +139,23 @@ private: bool mSetPreservesPitch; bool mPlaying; + + class OnAudioEndTimeUpdateTask : public nsRunnable { + public: + explicit OnAudioEndTimeUpdateTask(MediaDecoderStateMachine* aStateMachine); + + NS_IMETHOD Run() override; + + void Dispatch(int64_t aEndTime); + void Cancel(); + + private: + Mutex mMutex; + int64_t mEndTime; + nsRefPtr mStateMachine; + }; + + nsRefPtr mOnAudioEndTimeUpdateTask; }; } // namespace mozilla diff --git a/dom/media/MediaDecoderStateMachine.h b/dom/media/MediaDecoderStateMachine.h index 9e21e6ebea64..e486c2673412 100644 --- a/dom/media/MediaDecoderStateMachine.h +++ b/dom/media/MediaDecoderStateMachine.h @@ -713,16 +713,9 @@ protected: // Can only be called on the state machine thread. void SetPlayStartTime(const TimeStamp& aTimeStamp); -private: +public: // Update mAudioEndTime. void OnAudioEndTimeUpdate(int64_t aAudioEndTime); -public: - void DispatchOnAudioEndTimeUpdate(int64_t aAudioEndTime) - { - RefPtr r = - NS_NewRunnableMethodWithArg(this, &MediaDecoderStateMachine::OnAudioEndTimeUpdate, aAudioEndTime); - TaskQueue()->Dispatch(r.forget()); - } private: // Update mDecoder's playback offset.