diff --git a/dom/media/mediasink/DecodedAudioDataSink.cpp b/dom/media/mediasink/DecodedAudioDataSink.cpp index b5891e11b321..766dfe93ba3b 100644 --- a/dom/media/mediasink/DecodedAudioDataSink.cpp +++ b/dom/media/mediasink/DecodedAudioDataSink.cpp @@ -38,6 +38,7 @@ DecodedAudioDataSink::DecodedAudioDataSink(MediaQueue& aAudioQueue, , mInfo(aInfo) , mChannel(aChannel) , mPlaying(true) + , mPlaybackComplete(false) { } @@ -119,7 +120,7 @@ DecodedAudioDataSink::SetPreservesPitch(bool aPreservesPitch) void DecodedAudioDataSink::SetPlaying(bool aPlaying) { - if (!mAudioStream || mPlaying == aPlaying) { + if (!mAudioStream || mPlaying == aPlaying || mPlaybackComplete) { return; } // pause/resume AudioStream as necessary. @@ -291,9 +292,7 @@ void DecodedAudioDataSink::Drained() { SINK_LOG("Drained"); - // FIXME : In OSX, the audio backend could trigger Drained() twice, then it - // cause the crash because the promise had already been resolve and free. - // You can fix it on the bug 1246108. + mPlaybackComplete = true; mEndPromise.ResolveIfExists(true, __func__); } diff --git a/dom/media/mediasink/DecodedAudioDataSink.h b/dom/media/mediasink/DecodedAudioDataSink.h index 1134068e1474..1411681d434b 100644 --- a/dom/media/mediasink/DecodedAudioDataSink.h +++ b/dom/media/mediasink/DecodedAudioDataSink.h @@ -101,6 +101,9 @@ private: UniquePtr mCursor; // True if there is any error in processing audio data like overflow. bool mErrored = false; + + // Set on the callback thread of cubeb once the stream has drained. + Atomic mPlaybackComplete; }; } // namespace media