diff --git a/content/media/AudioStream.cpp b/content/media/AudioStream.cpp index 9e02f77cb2df..0955272938a7 100644 --- a/content/media/AudioStream.cpp +++ b/content/media/AudioStream.cpp @@ -76,6 +76,15 @@ bool AudioStream::sCubebLatencyPrefSet; return GetCubebContextUnlocked(); } +/*static*/ void AudioStream::InitPreferredSampleRate() +{ + StaticMutexAutoLock lock(sMutex); + if (sPreferredSampleRate != 0 || + cubeb_get_preferred_sample_rate(GetCubebContextUnlocked(), &sPreferredSampleRate) != CUBEB_OK) { + sPreferredSampleRate = 44100; + } +} + /*static*/ cubeb* AudioStream::GetCubebContextUnlocked() { sMutex.AssertCurrentThreadOwns(); @@ -266,25 +275,8 @@ int64_t AudioStream::GetWritten() /*static*/ int AudioStream::PreferredSampleRate() { - const int fallbackSampleRate = 44100; - StaticMutexAutoLock lock(sMutex); - if (sPreferredSampleRate != 0) { - return sPreferredSampleRate; - } - - cubeb* cubebContext = GetCubebContextUnlocked(); - if (!cubebContext) { - sPreferredSampleRate = fallbackSampleRate; - } - // Get the preferred samplerate for this platform, or fallback to something - // sensible if we fail. We cache the value, because this might be accessed - // often, and the complexity of the function call below depends on the - // backend used. - if (cubeb_get_preferred_sample_rate(cubebContext, - &sPreferredSampleRate) != CUBEB_OK) { - sPreferredSampleRate = fallbackSampleRate; - } - + MOZ_ASSERT(sPreferredSampleRate, + "sPreferredSampleRate has not been initialized!"); return sPreferredSampleRate; } diff --git a/content/media/AudioStream.h b/content/media/AudioStream.h index fc040020c32a..2739de44082c 100644 --- a/content/media/AudioStream.h +++ b/content/media/AudioStream.h @@ -179,8 +179,11 @@ public: // Returns the maximum number of channels supported by the audio hardware. static int MaxNumberOfChannels(); - // Returns the samplerate the systems prefer, because it is the - // samplerate the hardware/mixer supports. + // Queries the samplerate the hardware/mixer runs at, and stores it. + // Can be called on any thread. When this returns, it is safe to call + // PreferredSampleRate without locking. + static void InitPreferredSampleRate(); + // Get the aformentionned sample rate. Does not lock. static int PreferredSampleRate(); AudioStream(); diff --git a/content/media/MediaStreamGraph.cpp b/content/media/MediaStreamGraph.cpp index 671db6eeaf2f..db8fd8c577c3 100644 --- a/content/media/MediaStreamGraph.cpp +++ b/content/media/MediaStreamGraph.cpp @@ -1328,6 +1328,12 @@ MediaStreamGraphImpl::ForceShutDown() } } +void +MediaStreamGraphImpl::Init() +{ + AudioStream::InitPreferredSampleRate(); +} + namespace { class MediaStreamGraphInitThreadRunnable : public nsRunnable { @@ -1340,6 +1346,7 @@ public: { char aLocal; profiler_register_thread("MediaStreamGraph", &aLocal); + mGraph->Init(); mGraph->RunThread(); return NS_OK; } diff --git a/content/media/MediaStreamGraphImpl.h b/content/media/MediaStreamGraphImpl.h index c8cd27a8b1be..76b036e1c4df 100644 --- a/content/media/MediaStreamGraphImpl.h +++ b/content/media/MediaStreamGraphImpl.h @@ -150,6 +150,10 @@ public: */ void ShutdownThreads(); + /** + * Called before the thread runs. + */ + void Init(); // The following methods run on the graph thread (or possibly the main thread if // mLifecycleState > LIFECYCLE_RUNNING) /** diff --git a/content/media/webaudio/AudioContext.cpp b/content/media/webaudio/AudioContext.cpp index c757d574a6b4..f269163652f7 100644 --- a/content/media/webaudio/AudioContext.cpp +++ b/content/media/webaudio/AudioContext.cpp @@ -34,6 +34,7 @@ #include "ConvolverNode.h" #include "OscillatorNode.h" #include "nsNetUtil.h" +#include "AudioStream.h" namespace mozilla { namespace dom { @@ -65,12 +66,22 @@ NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper) static uint8_t gWebAudioOutputKey; +float GetSampleRateForAudioContext(bool aIsOffline, float aSampleRate) +{ + if (aIsOffline) { + return aSampleRate; + } else { + AudioStream::InitPreferredSampleRate(); + return static_cast(AudioStream::PreferredSampleRate()); + } +} + AudioContext::AudioContext(nsPIDOMWindow* aWindow, bool aIsOffline, uint32_t aNumberOfChannels, uint32_t aLength, float aSampleRate) - : mSampleRate(aIsOffline ? aSampleRate : IdealAudioRate()) + : mSampleRate(GetSampleRateForAudioContext(aIsOffline, aSampleRate)) , mNumberOfChannels(aNumberOfChannels) , mIsOffline(aIsOffline) , mIsStarted(!aIsOffline)