diff --git a/content/media/AudioStream.cpp b/content/media/AudioStream.cpp index c3c24b5b4c0..39b60a2b895 100644 --- a/content/media/AudioStream.cpp +++ b/content/media/AudioStream.cpp @@ -604,6 +604,10 @@ class BufferedAudioStream : public AudioStream int64_t GetPositionInFramesInternal(); bool IsPaused(); int32_t GetMinWriteSize(); + // This method acquires the monitor and forward the call to the base + // class, to prevent a race on |mTimeStretcher|, in + // |AudioStream::EnsureTimeStretcherInitialized|. + void EnsureTimeStretcherInitialized(); private: static long DataCallback_S(cubeb_stream*, void* aThis, void* aBuffer, long aFrames) @@ -702,6 +706,13 @@ BufferedAudioStream::~BufferedAudioStream() Shutdown(); } +void +BufferedAudioStream::EnsureTimeStretcherInitialized() +{ + MonitorAutoLock mon(mMonitor); + AudioStream::EnsureTimeStretcherInitialized(); +} + nsresult BufferedAudioStream::Init(int32_t aNumChannels, int32_t aRate, const dom::AudioChannelType aAudioChannelType) @@ -962,7 +973,8 @@ BufferedAudioStream::GetTimeStretched(void* aBuffer, long aFrames) { long processedFrames = 0; - EnsureTimeStretcherInitialized(); + // We need to call the non-locking version, because we already have the lock. + AudioStream::EnsureTimeStretcherInitialized(); uint8_t* wpos = reinterpret_cast(aBuffer); double playbackRate = static_cast(mInRate) / mOutRate; diff --git a/content/media/AudioStream.h b/content/media/AudioStream.h index 03ee4a8191e..ae73be00117 100644 --- a/content/media/AudioStream.h +++ b/content/media/AudioStream.h @@ -160,7 +160,7 @@ public: int GetChannels() { return mChannels; } // This should be called before attempting to use the time stretcher. - void EnsureTimeStretcherInitialized(); + virtual void EnsureTimeStretcherInitialized(); // Set playback rate as a multiple of the intrinsic playback rate. This is to // be called only with aPlaybackRate > 0.0. virtual nsresult SetPlaybackRate(double aPlaybackRate);