Bug 1055141 - use a UniquePtr for AudioStream's mCubebStream member; r=kinetik
authorNathan Froyd <froydnj@mozilla.com>
Mon, 18 Aug 2014 13:12:08 -0400
changeset 200675 5650d84919fc9cc1d88e8b53bcf65d4db00ba19e
parent 200655 57310a010b9ed3894cd0e7902fc7a53d8e4498d8
child 200676 a36f190b9ad1ee6954e6eb9926dc3c5267590dab
push id27353
push useremorley@mozilla.com
push dateThu, 21 Aug 2014 12:33:28 +0000
treeherdermozilla-central@479ec85d9e6f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskinetik
bugs1055141
milestone34.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1055141 - use a UniquePtr for AudioStream's mCubebStream member; r=kinetik
content/media/AudioStream.cpp
content/media/AudioStream.h
--- a/content/media/AudioStream.cpp
+++ b/content/media/AudioStream.cpp
@@ -570,58 +570,58 @@ void AudioStream::PanOutputIfNeeded(bool
   bool panCenter = false;
 
   rv = sysctlbyname("hw.model", name, &length, NULL, 0);
   if (rv) {
     return;
   }
 
   if (!strncmp(name, "MacBookPro", 10)) {
-    if (cubeb_stream_get_current_device(mCubebStream, &device) == CUBEB_OK) {
+    if (cubeb_stream_get_current_device(mCubebStream.get(), &device) == CUBEB_OK) {
       // Check if we are currently outputing sound on external speakers.
       if (!strcmp(device->output_name, "ispk")) {
         // Pan everything to the right speaker.
         if (aMicrophoneActive) {
           LOG(("%p Panning audio output to the right.", this));
-          if (cubeb_stream_set_panning(mCubebStream, 1.0) != CUBEB_OK) {
+          if (cubeb_stream_set_panning(mCubebStream.get(), 1.0) != CUBEB_OK) {
             NS_WARNING("Could not pan audio output to the right.");
           }
         } else {
           panCenter = true;
         }
       } else {
         panCenter = true;
       }
       if (panCenter) {
         LOG(("%p Panning audio output to the center.", this));
-        if (cubeb_stream_set_panning(mCubebStream, 0.0) != CUBEB_OK) {
+        if (cubeb_stream_set_panning(mCubebStream.get(), 0.0) != CUBEB_OK) {
           NS_WARNING("Could not pan audio output to the center.");
         }
       }
-      cubeb_stream_device_destroy(mCubebStream, device);
+      cubeb_stream_device_destroy(mCubebStream.get(), device);
     }
   }
 #endif
 }
 
 void AudioStream::ResetStreamIfNeeded()
 {
   cubeb_device * device;
   // Only reset a device if a mic is active, and this is a low latency stream.
   if (!mMicrophoneActive || mLatencyRequest != LowLatency) {
     return;
   }
-  if (cubeb_stream_get_current_device(mCubebStream, &device) == CUBEB_OK) {
+  if (cubeb_stream_get_current_device(mCubebStream.get(), &device) == CUBEB_OK) {
     // This a microphone that goes through the headphone plug, reset the
     // output to prevent echo building up.
     if (strcmp(device->input_name, "emic") == 0) {
       LOG(("Resetting audio output"));
       Reset();
     }
-    cubeb_stream_device_destroy(mCubebStream, device);
+    cubeb_stream_device_destroy(mCubebStream.get(), device);
   }
 }
 
 void AudioStream::DeviceChangedCallback()
 {
   MonitorAutoLock mon(mMonitor);
   PanOutputIfNeeded(mMicrophoneActive);
   mShouldDropFrames = true;
@@ -655,29 +655,29 @@ AudioStream::OpenCubeb(cubeb_stream_para
   }
 
   {
     cubeb_stream* stream;
     if (cubeb_stream_init(cubebContext, &stream, "AudioStream", aParams,
                           latency, DataCallback_S, StateCallback_S, this) == CUBEB_OK) {
       MonitorAutoLock mon(mMonitor);
       MOZ_ASSERT(mState != SHUTDOWN);
-      mCubebStream.own(stream);
+      mCubebStream.reset(stream);
       // We can't cubeb_stream_start() the thread from a transient thread due to
       // cubeb API requirements (init can be called from another thread, but
       // not start/stop/destroy/etc)
     } else {
       MonitorAutoLock mon(mMonitor);
       mState = ERRORED;
       NS_WARNING(nsPrintfCString("AudioStream::OpenCubeb() %p failed to init cubeb", this).get());
       return NS_ERROR_FAILURE;
     }
   }
 
-  cubeb_stream_register_device_changed_callback(mCubebStream,
+  cubeb_stream_register_device_changed_callback(mCubebStream.get(),
                                                 AudioStream::DeviceChangedCallback_s);
 
   mState = INITIALIZED;
 
   if (!mStartTime.IsNull()) {
     TimeDuration timeDelta = TimeStamp::Now() - mStartTime;
     LOG(("AudioStream creation time %sfirst: %u ms", mIsFirst ? "" : "not ",
           (uint32_t) timeDelta.ToMilliseconds()));
@@ -839,17 +839,17 @@ AudioStream::Available()
   return BytesToFrames(mBuffer.Available());
 }
 
 void
 AudioStream::SetVolume(double aVolume)
 {
   NS_ABORT_IF_FALSE(aVolume >= 0.0 && aVolume <= 1.0, "Invalid volume");
 
-  if (cubeb_stream_set_volume(mCubebStream, aVolume * GetVolumeScale()) != CUBEB_OK) {
+  if (cubeb_stream_set_volume(mCubebStream.get(), aVolume * GetVolumeScale()) != CUBEB_OK) {
     NS_WARNING("Could not change volume on cubeb stream.");
   }
 }
 
 void
 AudioStream::SetMicrophoneActive(bool aActive)
 {
   MonitorAutoLock mon(mMonitor);
@@ -897,17 +897,17 @@ AudioStream::StartUnlocked()
     mNeedsStart = true;
     return;
   }
 
   if (mState == INITIALIZED) {
     int r;
     {
       MonitorAutoUnlock mon(mMonitor);
-      r = cubeb_stream_start(mCubebStream);
+      r = cubeb_stream_start(mCubebStream.get());
 
       PanOutputIfNeeded(mMicrophoneActive);
     }
     mState = r == CUBEB_OK ? STARTED : ERRORED;
     LOG(("AudioStream: started %p, state %s", this, mState == STARTED ? "STARTED" : "ERRORED"));
   }
 }
 
@@ -919,17 +919,17 @@ AudioStream::Pause()
     mNeedsStart = false;
     mState = STOPPED; // which also tells async OpenCubeb not to start, just init
     return;
   }
 
   int r;
   {
     MonitorAutoUnlock mon(mMonitor);
-    r = cubeb_stream_stop(mCubebStream);
+    r = cubeb_stream_stop(mCubebStream.get());
   }
   if (mState != ERRORED && r == CUBEB_OK) {
     mState = STOPPED;
   }
 }
 
 void
 AudioStream::Resume()
@@ -937,17 +937,17 @@ AudioStream::Resume()
   MonitorAutoLock mon(mMonitor);
   if (!mCubebStream || mState != STOPPED) {
     return;
   }
 
   int r;
   {
     MonitorAutoUnlock mon(mMonitor);
-    r = cubeb_stream_start(mCubebStream);
+    r = cubeb_stream_start(mCubebStream.get());
   }
   if (mState != ERRORED && r == CUBEB_OK) {
     mState = STARTED;
   }
 }
 
 void
 AudioStream::Shutdown()
@@ -957,17 +957,17 @@ AudioStream::Shutdown()
 
   while (mPendingAudioInitTask) {
     mon.Wait();
   }
 
   if (mCubebStream) {
     MonitorAutoUnlock mon(mMonitor);
     // Force stop to put the cubeb stream in a stable state before deletion.
-    cubeb_stream_stop(mCubebStream);
+    cubeb_stream_stop(mCubebStream.get());
     // Must not try to shut down cubeb from within the lock!  wasapi may still
     // call our callback after Pause()/stop()!?! Bug 996162
     mCubebStream.reset();
   }
 
   mState = SHUTDOWN;
 }
 
@@ -999,29 +999,29 @@ AudioStream::GetPositionInFramesUnlocked
 
   if (!mCubebStream || mState == ERRORED) {
     return -1;
   }
 
   uint64_t position = 0;
   {
     MonitorAutoUnlock mon(mMonitor);
-    if (cubeb_stream_get_position(mCubebStream, &position) != CUBEB_OK) {
+    if (cubeb_stream_get_position(mCubebStream.get(), &position) != CUBEB_OK) {
       return -1;
     }
   }
 
   return std::min<uint64_t>(position, INT64_MAX);
 }
 
 int64_t
 AudioStream::GetLatencyInFrames()
 {
   uint32_t latency;
-  if (cubeb_stream_get_latency(mCubebStream, &latency)) {
+  if (cubeb_stream_get_latency(mCubebStream.get(), &latency)) {
     NS_WARNING("Could not get cubeb latency.");
     return 0;
   }
   return static_cast<int64_t>(latency);
 }
 
 bool
 AudioStream::IsPaused()
@@ -1286,17 +1286,17 @@ AudioStream::DataCallback(void* aBuffer,
   }
 
   WriteDumpFile(mDumpFile, this, aFrames, aBuffer);
   // Don't log if we're not interested or if the stream is inactive
   if (PR_LOG_TEST(GetLatencyLog(), PR_LOG_DEBUG) &&
       mState != SHUTDOWN &&
       insertTime != INT64_MAX && servicedFrames > underrunFrames) {
     uint32_t latency = UINT32_MAX;
-    if (cubeb_stream_get_latency(mCubebStream, &latency)) {
+    if (cubeb_stream_get_latency(mCubebStream.get(), &latency)) {
       NS_WARNING("Could not get latency from cubeb.");
     }
     TimeStamp now = TimeStamp::Now();
 
     mLatencyLog->Log(AsyncLatencyLogger::AudioStream, reinterpret_cast<uint64_t>(this),
                      insertTime, now);
     mLatencyLog->Log(AsyncLatencyLogger::Cubeb, reinterpret_cast<uint64_t>(mCubebStream.get()),
                      (latency * 1000) / mOutRate, now);
--- a/content/media/AudioStream.h
+++ b/content/media/AudioStream.h
@@ -3,39 +3,41 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #if !defined(AudioStream_h_)
 #define AudioStream_h_
 
 #include "AudioSampleFormat.h"
 #include "nsAutoPtr.h"
-#include "nsAutoRef.h"
 #include "nsCOMPtr.h"
 #include "nsThreadUtils.h"
 #include "Latency.h"
 #include "mozilla/dom/AudioChannelBinding.h"
+#include "mozilla/RefPtr.h"
 #include "mozilla/StaticMutex.h"
-#include "mozilla/RefPtr.h"
+#include "mozilla/UniquePtr.h"
 
 #include "cubeb/cubeb.h"
 
-template <>
-class nsAutoRefTraits<cubeb_stream> : public nsPointerRefTraits<cubeb_stream>
-{
-public:
-  static void Release(cubeb_stream* aStream) { cubeb_stream_destroy(aStream); }
-};
-
 namespace soundtouch {
 class SoundTouch;
 }
 
 namespace mozilla {
 
+template<>
+struct DefaultDelete<cubeb_stream>
+{
+  void operator()(cubeb_stream* aStream) const
+  {
+    cubeb_stream_destroy(aStream);
+  }
+};
+
 class AudioStream;
 class FrameHistory;
 
 class AudioClock
 {
 public:
   AudioClock(AudioStream* aStream);
   // Initialize the clock with the current AudioStream. Need to be called
@@ -382,19 +384,18 @@ private:
   FILE* mDumpFile;
 
   // Temporary audio buffer.  Filled by Write() and consumed by
   // DataCallback().  Once mBuffer is full, Write() blocks until sufficient
   // space becomes available in mBuffer.  mBuffer is sized in bytes, not
   // frames.
   CircularByteBuffer mBuffer;
 
-  // Owning reference to a cubeb_stream.  cubeb_stream_destroy is called by
-  // nsAutoRef's destructor.
-  nsAutoRef<cubeb_stream> mCubebStream;
+  // Owning reference to a cubeb_stream.
+  UniquePtr<cubeb_stream> mCubebStream;
 
   uint32_t mBytesPerFrame;
 
   uint32_t BytesToFrames(uint32_t aBytes) {
     NS_ASSERTION(aBytes % mBytesPerFrame == 0,
                  "Byte count not aligned on frames size.");
     return aBytes / mBytesPerFrame;
   }