Bug 1289678 - Don't count audio stream creation failures when retrying on Telemetry. r=kinetik
authorPaul Adenot <paul@paul.cx>
Wed, 27 Jul 2016 15:18:17 +0200
changeset 349132 58f01ab6d8560966453ee42d2f1f07c02c99b1e3
parent 349131 d8b267ae7f69ade6abc6e2e446e46a8e629143c8
child 349133 0b81459b4802fc968d47e6f551224416231d3b5e
push id1230
push userjlund@mozilla.com
push dateMon, 31 Oct 2016 18:13:35 +0000
treeherdermozilla-release@5e06e3766db2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskinetik
bugs1289678
milestone50.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 1289678 - Don't count audio stream creation failures when retrying on Telemetry. r=kinetik When failing to create an audio stream, we fallback to a SystemClockDriver marked as being a "fallback driver". When failing again to open an audio stream after re-trying, we can check whether we came from a fallback driver, and not report the failure again to telemetry. MozReview-Commit-ID: FAdQ0pCtC3m
dom/media/GraphDriver.cpp
dom/media/GraphDriver.h
--- a/dom/media/GraphDriver.cpp
+++ b/dom/media/GraphDriver.cpp
@@ -289,23 +289,36 @@ ThreadedDriver::Stop()
     mThread->Shutdown();
     mThread = nullptr;
   }
 }
 
 SystemClockDriver::SystemClockDriver(MediaStreamGraphImpl* aGraphImpl)
   : ThreadedDriver(aGraphImpl),
     mInitialTimeStamp(TimeStamp::Now()),
-    mLastTimeStamp(TimeStamp::Now())
+    mLastTimeStamp(TimeStamp::Now()),
+    mIsFallback(false)
 {}
 
 SystemClockDriver::~SystemClockDriver()
 { }
 
 void
+SystemClockDriver::MarkAsFallback()
+{
+  mIsFallback = true;
+}
+
+bool
+SystemClockDriver::IsFallback()
+{
+  return mIsFallback;
+}
+
+void
 ThreadedDriver::RunThread()
 {
   AutoProfilerUnregisterThread autoUnregister;
 
   bool stillProcessing = true;
   while (stillProcessing) {
     mIterationStart = IterationEnd();
     mIterationEnd += GetIntervalForIteration();
@@ -540,16 +553,17 @@ AudioCallbackDriver::AudioCallbackDriver
   , mInputChannels(1)
   , mIterationDurationMS(MEDIA_GRAPH_TARGET_PERIOD_MS)
   , mStarted(false)
   , mAudioInput(nullptr)
   , mAudioChannel(aGraphImpl->AudioChannel())
   , mAddedMixer(false)
   , mInCallback(false)
   , mMicrophoneActive(false)
+  , mFromFallback(false)
 {
   STREAM_LOG(LogLevel::Debug, ("AudioCallbackDriver ctor for graph %p", aGraphImpl));
 }
 
 AudioCallbackDriver::~AudioCallbackDriver()
 {
   MOZ_ASSERT(mPromisesForOperation.IsEmpty());
 }
@@ -631,23 +645,30 @@ AudioCallbackDriver::Init()
       NS_WARN_IF_FALSE(rv == CUBEB_OK,
           "Could not set the audio stream volume in GraphDriver.cpp");
       CubebUtils::ReportCubebBackendUsed();
     } else {
 #ifdef MOZ_WEBRTC
       StaticMutexAutoUnlock unlock(AudioInputCubeb::Mutex());
 #endif
       NS_WARNING("Could not create a cubeb stream for MediaStreamGraph, falling back to a SystemClockDriver");
-      CubebUtils::ReportCubebStreamInitFailure(firstStream);
+      // Only report failures when we're not coming from a driver that was
+      // created itself as a fallback driver because of a previous audio driver
+      // failure.
+      if (!mFromFallback) {
+        CubebUtils::ReportCubebStreamInitFailure(firstStream);
+      }
       // Fall back to a driver using a normal thread.
       MonitorAutoLock lock(GraphImpl()->GetMonitor());
-      SetNextDriver(new SystemClockDriver(GraphImpl()));
-      NextDriver()->SetGraphTime(this, mIterationStart, mIterationEnd);
-      mGraphImpl->SetCurrentDriver(NextDriver());
-      NextDriver()->Start();
+      SystemClockDriver* nextDriver = new SystemClockDriver(GraphImpl());
+      SetNextDriver(nextDriver);
+      nextDriver->MarkAsFallback();
+      nextDriver->SetGraphTime(this, mIterationStart, mIterationEnd);
+      mGraphImpl->SetCurrentDriver(nextDriver);
+      nextDriver->Start();
       return;
     }
   }
   bool aec;
   Unused << mGraphImpl->AudioTrackPresent(aec);
   SetMicrophoneActive(aec);
 
   cubeb_stream_register_device_changed_callback(mAudioStream,
@@ -684,16 +705,18 @@ AudioCallbackDriver::Start()
       LIFECYCLE_LOG("Releasing audio driver off main thread.");
       RefPtr<AsyncCubebTask> releaseEvent =
         new AsyncCubebTask(mPreviousDriver->AsAudioCallbackDriver(),
                            AsyncCubebOperation::SHUTDOWN);
       releaseEvent->Dispatch();
       mPreviousDriver = nullptr;
     } else {
       LIFECYCLE_LOG("Dropping driver reference for SystemClockDriver.");
+      MOZ_ASSERT(mPreviousDriver->AsSystemClockDriver());
+      mFromFallback = mPreviousDriver->AsSystemClockDriver()->IsFallback();
       mPreviousDriver = nullptr;
     }
   }
 
   LIFECYCLE_LOG("Starting new audio driver off main thread, "
                 "to ensure it runs after previous shutdown.");
   RefPtr<AsyncCubebTask> initEvent =
     new AsyncCubebTask(AsAudioCallbackDriver(), AsyncCubebOperation::INIT);
--- a/dom/media/GraphDriver.h
+++ b/dom/media/GraphDriver.h
@@ -49,16 +49,17 @@ static const int SCHEDULE_SAFETY_MARGIN_
  */
 static const int AUDIO_TARGET_MS = 2*MEDIA_GRAPH_TARGET_PERIOD_MS +
     SCHEDULE_SAFETY_MARGIN_MS;
 
 class MediaStreamGraphImpl;
 
 class AudioCallbackDriver;
 class OfflineClockDriver;
+class SystemClockDriver;
 
 /**
  * A driver is responsible for the scheduling of the processing, the thread
  * management, and give the different clocks to a MediaStreamGraph. This is an
  * abstract base class. A MediaStreamGraph can be driven by an
  * OfflineClockDriver, if the graph is offline, or a SystemClockDriver, if the
  * graph is real time.
  * A MediaStreamGraph holds an owning reference to its driver.
@@ -160,16 +161,20 @@ public:
   virtual AudioCallbackDriver* AsAudioCallbackDriver() {
     return nullptr;
   }
 
   virtual OfflineClockDriver* AsOfflineClockDriver() {
     return nullptr;
   }
 
+  virtual SystemClockDriver* AsSystemClockDriver() {
+    return nullptr;
+  }
+
   /**
    * Tell the driver it has to stop and return the current time of the graph, so
    * another driver can start from the right point in time.
    */
   virtual void SwitchAtNextIteration(GraphDriver* aDriver);
 
   /**
    * Set the time for a graph, on a driver. This is used so a new driver just
@@ -291,23 +296,30 @@ protected:
 class SystemClockDriver : public ThreadedDriver
 {
 public:
   explicit SystemClockDriver(MediaStreamGraphImpl* aGraphImpl);
   virtual ~SystemClockDriver();
   MediaTime GetIntervalForIteration() override;
   void WaitForNextIteration() override;
   void WakeUp() override;
-
+  void MarkAsFallback();
+  bool IsFallback();
+  SystemClockDriver* AsSystemClockDriver() {
+    return this;
+  }
 
 private:
   // Those are only modified (after initialization) on the graph thread. The
   // graph thread does not run during the initialization.
   TimeStamp mInitialTimeStamp;
   TimeStamp mLastTimeStamp;
+  // This is true if this SystemClockDriver runs the graph because we could not
+  // open an audio stream.
+  bool mIsFallback;
 };
 
 /**
  * An OfflineClockDriver runs the graph as fast as possible, without waiting
  * between iteration.
  */
 class OfflineClockDriver : public ThreadedDriver
 {
@@ -520,16 +532,19 @@ private:
 
   /* This is atomic and is set by the audio callback thread. It can be read by
    * any thread safely. */
   Atomic<bool> mInCallback;
   /**
    * True if microphone is being used by this process. This is synchronized by
    * the graph's monitor. */
   bool mMicrophoneActive;
+  /* True if this driver was created from a driver created because of a previous
+   * AudioCallbackDriver failure. */
+  bool mFromFallback;
 };
 
 class AsyncCubebTask : public Runnable
 {
 public:
 
   AsyncCubebTask(AudioCallbackDriver* aDriver, AsyncCubebOperation aOperation);