Backed out changeset eaa2b716ce89 (bug 921622) for mochitest-1 asserts.
authorRyan VanderMeulen <ryanvm@gmail.com>
Wed, 21 May 2014 21:59:06 -0400
changeset 192354 b7913b826440
parent 192353 eaa2b716ce89
child 192355 b19932497b46
push id3581
push userryanvm@gmail.com
push date2014-05-22 01:59 +0000
Treeherderresults
bugs921622
milestone30.0
backs outeaa2b716ce89
Backed out changeset eaa2b716ce89 (bug 921622) for mochitest-1 asserts.
content/media/AudioStream.cpp
content/media/AudioStream.h
--- a/content/media/AudioStream.cpp
+++ b/content/media/AudioStream.cpp
@@ -180,16 +180,22 @@ AudioStream::~AudioStream()
 
   StaticMutexAutoLock lock(sMutex);
   if (sCubebContext) {
     cubeb_destroy(sCubebContext);
     sCubebContext = nullptr;
   }
 }
 
+nsresult AudioStream::EnsureTimeStretcherInitialized()
+{
+  MonitorAutoLock mon(mMonitor);
+  return EnsureTimeStretcherInitializedUnlocked();
+}
+
 nsresult AudioStream::EnsureTimeStretcherInitializedUnlocked()
 {
   mMonitor.AssertCurrentThreadOwns();
   if (!mTimeStretcher) {
     // SoundTouch does not support a number of channels > 2
     if (mOutChannels > 2) {
       return NS_ERROR_FAILURE;
     }
@@ -201,29 +207,25 @@ nsresult AudioStream::EnsureTimeStretche
   return NS_OK;
 }
 
 nsresult AudioStream::SetPlaybackRate(double aPlaybackRate)
 {
   NS_ASSERTION(aPlaybackRate > 0.0,
                "Can't handle negative or null playbackrate in the AudioStream.");
   // Avoid instantiating the resampler if we are not changing the playback rate.
-  // GetPreservesPitch/SetPreservesPitch don't need locking before calling
   if (aPlaybackRate == mAudioClock.GetPlaybackRate()) {
     return NS_OK;
   }
 
-  // MUST lock since the rate transposer is used from the cubeb callback,
-  // and rate changes can cause the buffer to be reallocated
-  MonitorAutoLock mon(mMonitor);
-  if (EnsureTimeStretcherInitializedUnlocked() != NS_OK) {
+  if (EnsureTimeStretcherInitialized() != NS_OK) {
     return NS_ERROR_FAILURE;
   }
 
-  mAudioClock.SetPlaybackRateUnlocked(aPlaybackRate);
+  mAudioClock.SetPlaybackRate(aPlaybackRate);
   mOutRate = mInRate / aPlaybackRate;
 
   if (mAudioClock.GetPreservesPitch()) {
     mTimeStretcher->setTempo(aPlaybackRate);
     mTimeStretcher->setRate(1.0f);
   } else {
     mTimeStretcher->setTempo(1.0f);
     mTimeStretcher->setRate(aPlaybackRate);
@@ -233,20 +235,17 @@ nsresult AudioStream::SetPlaybackRate(do
 
 nsresult AudioStream::SetPreservesPitch(bool aPreservesPitch)
 {
   // Avoid instantiating the timestretcher instance if not needed.
   if (aPreservesPitch == mAudioClock.GetPreservesPitch()) {
     return NS_OK;
   }
 
-  // MUST lock since the rate transposer is used from the cubeb callback,
-  // and rate changes can cause the buffer to be reallocated
-  MonitorAutoLock mon(mMonitor);
-  if (EnsureTimeStretcherInitializedUnlocked() != NS_OK) {
+  if (EnsureTimeStretcherInitialized() != NS_OK) {
     return NS_ERROR_FAILURE;
   }
 
   if (aPreservesPitch == true) {
     mTimeStretcher->setTempo(mAudioClock.GetPlaybackRate());
     mTimeStretcher->setRate(1.0f);
   } else {
     mTimeStretcher->setTempo(1.0f);
@@ -601,18 +600,17 @@ AudioStream::Resume()
   if (mState != ERRORED && r == CUBEB_OK) {
     mState = STARTED;
   }
 }
 
 int64_t
 AudioStream::GetPosition()
 {
-  MonitorAutoLock mon(mMonitor);
-  return mAudioClock.GetPositionUnlocked();
+  return mAudioClock.GetPosition();
 }
 
 // This function is miscompiled by PGO with MSVC 2010.  See bug 768333.
 #ifdef _MSC_VER
 #pragma optimize("", off)
 #endif
 int64_t
 AudioStream::GetPositionInFrames()
@@ -892,20 +890,19 @@ void AudioClock::Init()
   mOldOutRate = mOutRate;
 }
 
 void AudioClock::UpdateWritePosition(uint32_t aCount)
 {
   mWritten += aCount;
 }
 
-uint64_t AudioClock::GetPositionUnlocked()
+uint64_t AudioClock::GetPosition()
 {
-  // GetPositionInFramesUnlocked() asserts it owns the monitor
-  int64_t position = mAudioStream->GetPositionInFramesUnlocked();
+  int64_t position = mAudioStream->GetPositionInFramesInternal();
   int64_t diffOffset;
   NS_ASSERTION(position < 0 || (mInRate != 0 && mOutRate != 0), "AudioClock not initialized.");
   if (position >= 0) {
     if (position < mPlaybackRateChangeOffset) {
       // See if we are still playing frames pushed with the old playback rate in
       // the backend. If we are, use the old output rate to compute the
       // position.
       mCompensatingLatency = true;
@@ -927,36 +924,35 @@ uint64_t AudioClock::GetPositionUnlocked
       (static_cast<float>(USECS_PER_S * diffOffset) / mOutRate));
     return position;
   }
   return UINT64_MAX;
 }
 
 uint64_t AudioClock::GetPositionInFrames()
 {
-  return (GetPositionUnlocked() * mOutRate) / USECS_PER_S;
+  return (GetPosition() * mOutRate) / USECS_PER_S;
 }
 
-void AudioClock::SetPlaybackRateUnlocked(double aPlaybackRate)
+void AudioClock::SetPlaybackRate(double aPlaybackRate)
 {
-  // GetPositionInFramesUnlocked() asserts it owns the monitor
-  int64_t position = mAudioStream->GetPositionInFramesUnlocked();
+  int64_t position = mAudioStream->GetPositionInFramesInternal();
   if (position > mPlaybackRateChangeOffset) {
     mOldBasePosition = mBasePosition;
-    mBasePosition = GetPositionUnlocked();
+    mBasePosition = GetPosition();
     mOldBaseOffset = mPlaybackRateChangeOffset;
     mBaseOffset = position;
     mPlaybackRateChangeOffset = mWritten;
     mOldOutRate = mOutRate;
     mOutRate = static_cast<int>(mInRate / aPlaybackRate);
   } else {
     // The playbackRate has been changed before the end of the latency
     // compensation phase. We don't update the mOld* variable. That way, the
     // last playbackRate set is taken into account.
-    mBasePosition = GetPositionUnlocked();
+    mBasePosition = GetPosition();
     mBaseOffset = position;
     mPlaybackRateChangeOffset = mWritten;
     mOutRate = static_cast<int>(mInRate / aPlaybackRate);
   }
 }
 
 double AudioClock::GetPlaybackRate()
 {
--- a/content/media/AudioStream.h
+++ b/content/media/AudioStream.h
@@ -38,27 +38,23 @@ public:
   // Initialize the clock with the current AudioStream. Need to be called
   // before querying the clock. Called on the audio thread.
   void Init();
   // Update the number of samples that has been written in the audio backend.
   // Called on the state machine thread.
   void UpdateWritePosition(uint32_t aCount);
   // Get the read position of the stream, in microseconds.
   // Called on the state machine thead.
-  // Assumes the AudioStream lock is held and thus calls Unlocked versions
-  // of AudioStream funcs.
-  uint64_t GetPositionUnlocked();
+  uint64_t GetPosition();
   // Get the read position of the stream, in frames.
   // Called on the state machine thead.
   uint64_t GetPositionInFrames();
   // Set the playback rate.
   // Called on the audio thread.
-  // Assumes the AudioStream lock is held and thus calls Unlocked versions
-  // of AudioStream funcs.
-  void SetPlaybackRateUnlocked(double aPlaybackRate);
+  void SetPlaybackRate(double aPlaybackRate);
   // Get the current playback rate.
   // Called on the audio thread.
   double GetPlaybackRate();
   // Set if we are preserving the pitch.
   // Called on the audio thread.
   void SetPreservesPitch(bool aPreservesPitch);
   // Get the current pitch preservation state.
   // Called on the audio thread.
@@ -253,29 +249,24 @@ public:
 
   // Returns true when the audio stream is paused.
   bool IsPaused();
 
   int GetRate() { return mOutRate; }
   int GetChannels() { return mChannels; }
   int GetOutChannels() { return mOutChannels; }
 
+  // This should be called before attempting to use the time stretcher.
+  nsresult EnsureTimeStretcherInitialized();
   // Set playback rate as a multiple of the intrinsic playback rate. This is to
   // be called only with aPlaybackRate > 0.0.
   nsresult SetPlaybackRate(double aPlaybackRate);
   // Switch between resampling (if false) and time stretching (if true, default).
   nsresult SetPreservesPitch(bool aPreservesPitch);
 
-protected:
-  friend class AudioClock;
-
-  // Shared implementation of underflow adjusted position calculation.
-  // Caller must own the monitor.
-  int64_t GetPositionInFramesUnlocked();
-
 private:
   static void PrefChanged(const char* aPref, void* aClosure);
   static double GetVolumeScale();
   static cubeb* GetCubebContext();
   static cubeb* GetCubebContextUnlocked();
   static uint32_t GetCubebLatency();
   static bool CubebLatencyPrefSet();
 
@@ -294,16 +285,20 @@ private:
 
   nsresult EnsureTimeStretcherInitializedUnlocked();
 
   // aTime is the time in ms the samples were inserted into MediaStreamGraph
   long GetUnprocessed(void* aBuffer, long aFrames, int64_t &aTime);
   long GetTimeStretched(void* aBuffer, long aFrames, int64_t &aTime);
   long GetUnprocessedWithSilencePadding(void* aBuffer, long aFrames, int64_t &aTime);
 
+  // Shared implementation of underflow adjusted position calculation.
+  // Caller must own the monitor.
+  int64_t GetPositionInFramesUnlocked();
+
   int64_t GetLatencyInFrames();
   void GetBufferInsertTime(int64_t &aTimeMs);
 
   void StartUnlocked();
 
   // The monitor is held to protect all access to member variables.  Write()
   // waits while mBuffer is full; DataCallback() notifies as it consumes
   // data from mBuffer.  Drain() waits while mState is DRAINING;