Bug 1285290 move code to choose the next GraphDriver to CheckDriver() r=padenot
authorKarl Tomlinson <karlt+@karlt.net>
Wed, 27 May 2020 10:27:20 +0000
changeset 532353 1823eb201ef68f7f4ba6f250c6449de53230f3f5
parent 532352 806573d7d69a90ea111a3b235f5fa1f45bd70b4f
child 532354 a1dd9afbfdf5deddd0a6b2f1a76d9f83dc0bb66a
push id37454
push userccoroiu@mozilla.com
push dateWed, 27 May 2020 16:14:31 +0000
treeherdermozilla-central@a1dd9afbfdf5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspadenot
bugs1285290
milestone78.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 1285290 move code to choose the next GraphDriver to CheckDriver() r=padenot There is a small logic change here when !audioTrackPresent && audioCallbackDriver && !IsStarted() && graphOutputChannelCount != audioCallbackDriver->OutputChannelCount() Now, no driver change is scheduled in that situation. Differential Revision: https://phabricator.services.mozilla.com/D76803
dom/media/MediaTrackGraph.cpp
dom/media/MediaTrackGraphImpl.h
--- a/dom/media/MediaTrackGraph.cpp
+++ b/dom/media/MediaTrackGraph.cpp
@@ -282,60 +282,66 @@ bool MediaTrackGraphImpl::AudioTrackPres
   if (!audioTrackPresent && mInputDeviceUsers.Count() != 0) {
     NS_WARNING("No audio tracks, but full-duplex audio is enabled!!!!!");
     audioTrackPresent = true;
   }
 
   return audioTrackPresent;
 }
 
-void MediaTrackGraphImpl::UpdateTrackOrder() {
+void MediaTrackGraphImpl::CheckDriver() {
   MOZ_ASSERT(OnGraphThread());
+  // An offline graph has only one driver.
+  // Otherwise, if a switch is already pending, let that happen.
+  if (!mRealtime || Switching()) {
+    return;
+  }
+
+  AudioCallbackDriver* audioCallbackDriver =
+      CurrentDriver()->AsAudioCallbackDriver();
   bool audioTrackPresent = AudioTrackPresent();
-  uint32_t graphOutputChannelCount = AudioOutputChannelCount();
 
   // Note that this looks for any audio tracks, input or output, and switches
-  // to a SystemClockDriver if there are none.  However, if another is already
-  // pending, let that switch happen.
-
-  if (!audioTrackPresent && mRealtime &&
-      CurrentDriver()->AsAudioCallbackDriver()) {
-    if (CurrentDriver()->AsAudioCallbackDriver()->IsStarted() && !Switching()) {
+  // to a SystemClockDriver if there are none.
+  if (!audioTrackPresent) {
+    if (audioCallbackDriver && audioCallbackDriver->IsStarted()) {
       SwitchAtNextIteration(
           new SystemClockDriver(this, CurrentDriver(), mSampleRate));
     }
+    return;
   }
 
-  if (audioTrackPresent && mRealtime &&
-      !CurrentDriver()->AsAudioCallbackDriver() && !Switching() &&
-      graphOutputChannelCount > 0) {
-    AudioCallbackDriver* driver = new AudioCallbackDriver(
-        this, CurrentDriver(), mSampleRate, graphOutputChannelCount,
-        AudioInputChannelCount(), mOutputDeviceID, mInputDeviceID,
-        AudioInputDevicePreference());
-    SwitchAtNextIteration(driver);
+  uint32_t graphOutputChannelCount = AudioOutputChannelCount();
+  if (!audioCallbackDriver) {
+    if (graphOutputChannelCount > 0) {
+      AudioCallbackDriver* driver = new AudioCallbackDriver(
+          this, CurrentDriver(), mSampleRate, graphOutputChannelCount,
+          AudioInputChannelCount(), mOutputDeviceID, mInputDeviceID,
+          AudioInputDevicePreference());
+      SwitchAtNextIteration(driver);
+    }
+    return;
   }
 
   // Check if this graph should switch to a different number of output channels.
   // Generally, a driver switch is explicitly made by an event (e.g., setting
   // the AudioDestinationNode channelCount), but if an HTMLMediaElement is
   // directly playing back via another HTMLMediaElement, the number of channels
   // of the media determines how many channels to output, and it can change
   // dynamically.
-  if (CurrentDriver()->AsAudioCallbackDriver() && !Switching()) {
-    if (graphOutputChannelCount !=
-        CurrentDriver()->AsAudioCallbackDriver()->OutputChannelCount()) {
-      AudioCallbackDriver* driver = new AudioCallbackDriver(
-          this, CurrentDriver(), mSampleRate, graphOutputChannelCount,
-          AudioInputChannelCount(), mOutputDeviceID, mInputDeviceID,
-          AudioInputDevicePreference());
-      SwitchAtNextIteration(driver);
-    }
+  if (graphOutputChannelCount != audioCallbackDriver->OutputChannelCount()) {
+    AudioCallbackDriver* driver = new AudioCallbackDriver(
+        this, CurrentDriver(), mSampleRate, graphOutputChannelCount,
+        AudioInputChannelCount(), mOutputDeviceID, mInputDeviceID,
+        AudioInputDevicePreference());
+    SwitchAtNextIteration(driver);
   }
-
+}
+
+void MediaTrackGraphImpl::UpdateTrackOrder() {
   if (!mTrackOrderDirty) {
     return;
   }
 
   mTrackOrderDirty = false;
 
   // The algorithm for finding cycles is based on Tim Leslie's iterative
   // implementation [1][2] of Pearce's variant [3] of Tarjan's strongly
@@ -1146,16 +1152,17 @@ void MediaTrackGraphImpl::UpdateGraph(Gr
   TRACE();
   MOZ_ASSERT(OnGraphThread());
   MOZ_ASSERT(aEndBlockingDecisions >= mProcessedTime);
   // The next state computed time can be the same as the previous: it
   // means the driver would have been blocking indefinitly, but the graph has
   // been woken up right after having been to sleep.
   MOZ_ASSERT(aEndBlockingDecisions >= mStateComputedTime);
 
+  CheckDriver();
   UpdateTrackOrder();
 
   bool ensureNextIteration = false;
 
   for (MediaTrack* track : mTracks) {
     if (SourceMediaTrack* is = track->AsSourceTrack()) {
       ensureNextIteration |= is->PullNewData(aEndBlockingDecisions);
       is->ExtractPendingInput(mStateComputedTime, aEndBlockingDecisions);
--- a/dom/media/MediaTrackGraphImpl.h
+++ b/dom/media/MediaTrackGraphImpl.h
@@ -337,19 +337,23 @@ class MediaTrackGraphImpl : public Media
                              const nsTArray<MediaTrack*>& aTrackSet);
 
   /**
    * Determine if we have any audio tracks, or are about to add any audiotracks.
    */
   bool AudioTrackPresent();
 
   /**
+   * Schedules a replacement GraphDriver in mNextDriver, if necessary.
+   */
+  void CheckDriver();
+
+  /**
    * Sort mTracks so that every track not in a cycle is after any tracks
    * it depends on, and every track in a cycle is marked as being in a cycle.
-   * Also sets mIsConsumed on every track.
    */
   void UpdateTrackOrder();
 
   /**
    * Returns smallest value of t such that t is a multiple of
    * WEBAUDIO_BLOCK_SIZE and t >= aTime.
    */
   static GraphTime RoundUpToEndOfAudioBlock(GraphTime aTime);