Bug 1392930 - Part 3: Make AudioCallbackDriver inherit from DeviceChangeListener. r=padenot, a=gchang
authorChun-Min Chang <chun.m.chang@gmail.com>
Tue, 29 Aug 2017 17:45:44 +0800
changeset 421664 a566b0235ef9ead152b01156d4e9ddd4ff65bfef
parent 421663 4302ede51ff60c8779a7a1fe77215a8f351412ee
child 421665 df29a08ea4310d0de72c3b6bd721356191c7f40b
push id7736
push userryanvm@gmail.com
push dateMon, 11 Sep 2017 15:47:51 +0000
treeherdermozilla-beta@94cf7f1ee06b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspadenot, gchang
bugs1392930
milestone56.0
Bug 1392930 - Part 3: Make AudioCallbackDriver inherit from DeviceChangeListener. r=padenot, a=gchang
dom/media/GraphDriver.cpp
dom/media/GraphDriver.h
--- a/dom/media/GraphDriver.cpp
+++ b/dom/media/GraphDriver.cpp
@@ -575,21 +575,31 @@ AudioCallbackDriver::AudioCallbackDriver
   , mAudioInput(nullptr)
   , mAudioChannel(aGraphImpl->AudioChannel())
   , mAddedMixer(false)
   , mInCallback(false)
   , mMicrophoneActive(false)
   , mFromFallback(false)
 {
   LOG(LogLevel::Debug, ("AudioCallbackDriver ctor for graph %p", aGraphImpl));
+#if defined(XP_WIN)
+  if (XRE_IsContentProcess()) {
+    audio::AudioNotificationReceiver::Register(this);
+  }
+#endif
 }
 
 AudioCallbackDriver::~AudioCallbackDriver()
 {
   MOZ_ASSERT(mPromisesForOperation.IsEmpty());
+#if defined(XP_WIN)
+  if (XRE_IsContentProcess()) {
+    audio::AudioNotificationReceiver::Unregister(this);
+  }
+#endif
 }
 
 bool IsMacbookOrMacbookAir()
 {
 #ifdef XP_MACOSX
   size_t len = 0;
   sysctlbyname("hw.model", NULL, &len, NULL, 0);
   if (len) {
@@ -874,16 +884,26 @@ AudioCallbackDriver::WaitForNextIteratio
 
 void
 AudioCallbackDriver::WakeUp()
 {
   mGraphImpl->GetMonitor().AssertCurrentThreadOwns();
   mGraphImpl->GetMonitor().Notify();
 }
 
+#if defined(XP_WIN)
+void
+AudioCallbackDriver::ResetDefaultDevice()
+{
+  if (cubeb_stream_reset_default_device(mAudioStream) != CUBEB_OK) {
+    NS_WARNING("Could not reset cubeb stream to default output device.");
+  }
+}
+#endif
+
 /* static */ long
 AudioCallbackDriver::DataCallback_s(cubeb_stream* aStream,
                                     void* aUser,
                                     const void* aInputBuffer,
                                     void* aOutputBuffer,
                                     long aFrames)
 {
   AudioCallbackDriver* driver = reinterpret_cast<AudioCallbackDriver*>(aUser);
--- a/dom/media/GraphDriver.h
+++ b/dom/media/GraphDriver.h
@@ -10,16 +10,20 @@
 #include "AudioBufferUtils.h"
 #include "AudioMixer.h"
 #include "AudioSegment.h"
 #include "SelfRef.h"
 #include "mozilla/Atomics.h"
 #include "mozilla/SharedThreadPool.h"
 #include "mozilla/StaticPtr.h"
 
+#if defined(XP_WIN)
+#include "mozilla/audio/AudioNotificationReceiver.h"
+#endif
+
 struct cubeb_stream;
 
 template <>
 class nsAutoRefTraits<cubeb_stream> : public nsPointerRefTraits<cubeb_stream>
 {
 public:
   static void Release(cubeb_stream* aStream) { cubeb_stream_destroy(aStream); }
 };
@@ -377,29 +381,35 @@ enum AsyncCubebOperation {
  *   sometimes hardware components are involved and need to be warmed up)
  * - We have no control on how much audio we generate, we have to return exactly
  *   the number of frames asked for by the callback. Since for the Web Audio
  *   API, we have to do block processing at 128 frames per block, we need to
  *   keep a little spill buffer to store the extra frames.
  */
 class AudioCallbackDriver : public GraphDriver,
                             public MixerCallbackReceiver
+#if defined(XP_WIN)
+                            , public audio::DeviceChangeListener
+#endif
 {
 public:
   explicit AudioCallbackDriver(MediaStreamGraphImpl* aGraphImpl);
   virtual ~AudioCallbackDriver();
 
   void Destroy() override;
   void Start() override;
   void Stop() override;
   void Resume() override;
   void Revive() override;
   void RemoveCallback() override;
   void WaitForNextIteration() override;
   void WakeUp() override;
+#if defined(XP_WIN)
+  void ResetDefaultDevice() override;
+#endif
 
   /* Static wrapper function cubeb calls back. */
   static long DataCallback_s(cubeb_stream * aStream,
                              void * aUser,
                              const void * aInputBuffer,
                              void * aOutputBuffer,
                              long aFrames);
   static void StateCallback_s(cubeb_stream* aStream, void * aUser,