diff --git a/dom/media/AudioStream.cpp b/dom/media/AudioStream.cpp index 8aa2cc0e5bfd..6a39d3d33556 100644 --- a/dom/media/AudioStream.cpp +++ b/dom/media/AudioStream.cpp @@ -148,7 +148,9 @@ AudioStream::AudioStream(DataSource& aSource, uint32_t aInRate, mSandboxed(CubebUtils::SandboxEnabled()), mPlaybackComplete(false), mPlaybackRate(1.0f), - mPreservesPitch(true) {} + mPreservesPitch(true), + mCallbacksStarted(false) + {} AudioStream::~AudioStream() { LOG("deleted, state %d", mState.load()); @@ -231,8 +233,8 @@ nsresult AudioStream::Init(AudioDeviceInfo* aSinkInfo) auto startTime = TimeStamp::Now(); TRACE("AudioStream::Init"); - LOG("%s channels: %d, rate: %d", __FUNCTION__, mOutChannels, - mAudioClock.GetInputRate()); + LOG("%s channels: %d, rate: %d", __FUNCTION__, mOutChannels, mAudioClock.GetInputRate()); + mSinkInfo = aSinkInfo; cubeb_stream_params params; @@ -595,6 +597,9 @@ long AudioStream::DataCallback(void* aBuffer, long aFrames) { CubebUtils::GetAudioThreadRegistry()->Register(mAudioThreadId); } WebCore::DenormalDisabler disabler; + if (!mCallbacksStarted) { + mCallbacksStarted = true; + } TRACE_AUDIO_CALLBACK_BUDGET(aFrames, mAudioClock.GetInputRate()); TRACE("AudioStream::DataCallback"); diff --git a/dom/media/AudioStream.h b/dom/media/AudioStream.h index 04ed62493dcc..86975c6a7124 100644 --- a/dom/media/AudioStream.h +++ b/dom/media/AudioStream.h @@ -297,6 +297,9 @@ class AudioStream final { bool IsPlaybackCompleted() const; + // Returns true if at least one DataCallback has been called. + bool CallbackStarted() const { return mCallbacksStarted; } + protected: friend class AudioClock; @@ -386,6 +389,7 @@ class AudioStream final { std::atomic mPreservesPitch; // Audio thread only bool mAudioThreadChanged = false; + Atomic mCallbacksStarted; }; } // namespace mozilla diff --git a/dom/media/mediasink/AudioSink.h b/dom/media/mediasink/AudioSink.h index 74cc793da14d..2877d7aed322 100644 --- a/dom/media/mediasink/AudioSink.h +++ b/dom/media/mediasink/AudioSink.h @@ -77,6 +77,12 @@ class AudioSink : private AudioStream::DataSource { const RefPtr& AudioDevice() { return mAudioDevice; } + // This returns true if the audio callbacks are being called, and so the + // audio stream-based clock is moving forward. + bool AudioStreamCallbackStarted() { + return mAudioStream && mAudioStream->CallbackStarted(); + } + private: // Allocate and initialize mAudioStream. Returns NS_OK on success. nsresult InitializeAudioStream(const PlaybackParams& aParams); diff --git a/dom/media/mediasink/AudioSinkWrapper.cpp b/dom/media/mediasink/AudioSinkWrapper.cpp index 21ec7d3b4eed..24eeb9f06376 100644 --- a/dom/media/mediasink/AudioSinkWrapper.cpp +++ b/dom/media/mediasink/AudioSinkWrapper.cpp @@ -77,8 +77,7 @@ TimeUnit AudioSinkWrapper::GetPosition(TimeStamp* aTimeStamp) { TimeUnit pos; TimeStamp t = TimeStamp::Now(); - if (!mAudioEnded && !IsMuted()) { - MOZ_ASSERT(mAudioSink); + if (!mAudioEnded && !IsMuted() && mAudioSink && mAudioSink->AudioStreamCallbackStarted()) { // Rely on the audio sink to report playback position when it is not ended. pos = mAudioSink->GetPosition(); LOGV("%p: Getting position from the Audio Sink %lf", this, pos.ToSeconds());