Backed out 5 changesets (bug 1205540) for Assertion Failurs in m2-e10s tests on a CLOSED TREE
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Fri, 18 Sep 2015 16:36:33 +0200
changeset 263246 eb30e5ee32f0a11e3df594b5b3e69d0a5566bb63
parent 263245 504162ed4ed46c511483e97de0b47fa512096332
child 263267 eb5e1be4923e0c282f1dab34a637c29ff7af0b66
child 263281 045b1309490f8d1de44768effd16fe7b997ba19d
push id29392
push userkwierso@gmail.com
push dateFri, 18 Sep 2015 20:48:57 +0000
treeherdermozilla-central@eb30e5ee32f0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1205540
milestone43.0a1
backs oute89d8182d588cdba43a1340b776eafccb964ed89
abace4cdec06e6ab956dfb8c4a8601252450421a
b3f6e1db72332e5d9690529404ee1f9a83906b0f
0d122cb349217abf026e74934883cfe1793ee361
4de5f87180fb7d5b7528db02d8fae3bc0742b7e8
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
Backed out 5 changesets (bug 1205540) for Assertion Failurs in m2-e10s tests on a CLOSED TREE Backed out changeset e89d8182d588 (bug 1205540) Backed out changeset abace4cdec06 (bug 1205540) Backed out changeset b3f6e1db7233 (bug 1205540) Backed out changeset 0d122cb34921 (bug 1205540) Backed out changeset 4de5f87180fb (bug 1205540)
dom/media/MediaStreamGraph.cpp
dom/media/webaudio/AnalyserNode.cpp
dom/media/webaudio/AudioBufferSourceNode.cpp
dom/media/webaudio/AudioDestinationNode.cpp
dom/media/webaudio/AudioNodeEngine.h
dom/media/webaudio/AudioNodeStream.cpp
dom/media/webaudio/AudioNodeStream.h
dom/media/webaudio/BiquadFilterNode.cpp
dom/media/webaudio/ConvolverNode.cpp
dom/media/webaudio/DelayNode.cpp
dom/media/webaudio/OscillatorNode.cpp
dom/media/webaudio/PannerNode.cpp
dom/media/webaudio/ScriptProcessorNode.cpp
--- a/dom/media/MediaStreamGraph.cpp
+++ b/dom/media/MediaStreamGraph.cpp
@@ -2360,18 +2360,18 @@ void
 MediaInputPort::Disconnect()
 {
   NS_ASSERTION(!mSource == !mDest,
                "mSource must either both be null or both non-null");
   if (!mSource)
     return;
 
   mSource->RemoveConsumer(this);
+  mSource = nullptr;
   mDest->RemoveInput(this);
-  mSource = nullptr;
   mDest = nullptr;
 
   GraphImpl()->SetStreamOrderDirty();
 }
 
 MediaInputPort::InputInterval
 MediaInputPort::GetNextInputInterval(GraphTime aTime)
 {
--- a/dom/media/webaudio/AnalyserNode.cpp
+++ b/dom/media/webaudio/AnalyserNode.cpp
@@ -60,49 +60,25 @@ public:
 
   virtual void ProcessBlock(AudioNodeStream* aStream,
                             const AudioBlock& aInput,
                             AudioBlock* aOutput,
                             bool* aFinished) override
   {
     *aOutput = aInput;
 
-    if (aInput.IsNull()) {
-      // If AnalyserNode::mChunks has only null chunks, then there is no need
-      // to send further null chunks.
-      if (mChunksToProcess <= 0) {
-        if (mChunksToProcess != INT32_MIN) {
-          mChunksToProcess = INT32_MIN;
-          aStream->CheckForInactive();
-        }
-        return;
-      }
-
-      --mChunksToProcess;
-    } else {
-      // This many null chunks will be required to empty AnalyserNode::mChunks.
-      mChunksToProcess = CHUNK_COUNT;
-    }
-
     nsRefPtr<TransferBuffer> transfer =
       new TransferBuffer(aStream, aInput.AsAudioChunk());
     NS_DispatchToMainThread(transfer);
   }
 
-  virtual bool IsActive() const override
-  {
-    return mChunksToProcess != INT32_MIN;
-  }
-
   virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override
   {
     return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
   }
-
-  int32_t mChunksToProcess = INT32_MIN;
 };
 
 AnalyserNode::AnalyserNode(AudioContext* aContext)
   : AudioNode(aContext,
               1,
               ChannelCountMode::Max,
               ChannelInterpretation::Speakers)
   , mAnalysisBlock(2048)
--- a/dom/media/webaudio/AudioBufferSourceNode.cpp
+++ b/dom/media/webaudio/AudioBufferSourceNode.cpp
@@ -106,21 +106,17 @@ public:
       break;
     default:
       NS_ERROR("Bad AudioBufferSourceNodeEngine double parameter.");
     };
   }
   virtual void SetInt32Parameter(uint32_t aIndex, int32_t aParam) override
   {
     switch (aIndex) {
-    case AudioBufferSourceNode::SAMPLE_RATE:
-      MOZ_ASSERT(aParam > 0);
-      mBufferSampleRate = aParam;
-      mSource->SetActive();
-      break;
+    case AudioBufferSourceNode::SAMPLE_RATE: mBufferSampleRate = aParam; break;
     case AudioBufferSourceNode::BUFFERSTART:
       MOZ_ASSERT(aParam >= 0);
       if (mBufferPosition == 0) {
         mBufferPosition = aParam;
       }
       break;
     case AudioBufferSourceNode::BUFFEREND:
       MOZ_ASSERT(aParam >= 0);
@@ -465,31 +461,22 @@ public:
                             bool* aFinished) override
   {
     if (mBufferSampleRate == 0) {
       // start() has not yet been called or no buffer has yet been set
       aOutput->SetNull(WEBAUDIO_BLOCK_SIZE);
       return;
     }
 
-    StreamTime streamPosition = aStream->GetCurrentPosition();
-    // We've finished if we've gone past mStop, or if we're past mDuration when
-    // looping is disabled.
-    if (streamPosition >= mStop ||
-        (!mLoop && mBufferPosition >= mBufferEnd && !mRemainingResamplerTail)) {
-      *aFinished = true;
-      aOutput->SetNull(WEBAUDIO_BLOCK_SIZE);
-      return;
-    }
-
     uint32_t channels = mBuffer ? mBuffer->GetChannels() : 0;
 
     UpdateSampleRateIfNeeded(channels);
 
     uint32_t written = 0;
+    StreamTime streamPosition = aStream->GetCurrentPosition();
     while (written < WEBAUDIO_BLOCK_SIZE) {
       if (mStop != STREAM_TIME_MAX &&
           streamPosition >= mStop) {
         FillWithZeroes(aOutput, channels, &written, &streamPosition, STREAM_TIME_MAX);
         continue;
       }
       if (streamPosition < mBeginProcessing) {
         FillWithZeroes(aOutput, channels, &written, &streamPosition,
@@ -507,22 +494,23 @@ public:
       } else {
         if (mBufferPosition < mBufferEnd || mRemainingResamplerTail) {
           CopyFromBuffer(aStream, aOutput, channels, &written, &streamPosition, mBufferEnd);
         } else {
           FillWithZeroes(aOutput, channels, &written, &streamPosition, STREAM_TIME_MAX);
         }
       }
     }
-  }
 
-  virtual bool IsActive() const override
-  {
-    // Whether buffer has been set and start() has been called.
-    return mBufferSampleRate != 0;
+    // We've finished if we've gone past mStop, or if we're past mDuration when
+    // looping is disabled.
+    if (streamPosition >= mStop ||
+        (!mLoop && mBufferPosition >= mBufferEnd && !mRemainingResamplerTail)) {
+      *aFinished = true;
+    }
   }
 
   virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override
   {
     // Not owned:
     // - mBuffer - shared w/ AudioNode
     // - mPlaybackRateTimeline - shared w/ AudioNode
     // - mDetuneTimeline - shared w/ AudioNode
--- a/dom/media/webaudio/AudioDestinationNode.cpp
+++ b/dom/media/webaudio/AudioDestinationNode.cpp
@@ -107,24 +107,16 @@ public:
       NS_ASSERTION(mWriteIndex == mLength, "Overshot length");
       // Go to finished state. When the graph's current time eventually reaches
       // the end of the stream, then the main thread will be notified and we'll
       // shut down the AudioContext.
       *aFinished = true;
     }
   }
 
-  virtual bool IsActive() const override
-  {
-    // Keep processing to track stream time, which is used for all timelines
-    // associated with the same AudioContext.
-    return true;
-  }
-
-
   class OnCompleteTask final : public nsRunnable
   {
   public:
     OnCompleteTask(AudioContext* aAudioContext, AudioBuffer* aRenderedBuffer)
       : mAudioContext(aAudioContext)
       , mRenderedBuffer(aRenderedBuffer)
     {}
 
@@ -258,26 +250,16 @@ public:
 
       nsRefPtr<InputMutedRunnable> runnable =
         new InputMutedRunnable(aStream, newInputMuted);
       aStream->Graph()->
         DispatchToMainThreadAfterStreamStateUpdate(runnable.forget());
     }
   }
 
-  virtual bool IsActive() const override
-  {
-    // Keep processing to track stream time, which is used for all timelines
-    // associated with the same AudioContext.  If there are no other engines
-    // for the AudioContext, then this could return false to suspend the
-    // stream, but the stream is blocked anyway through
-    // AudioDestinationNode::SetIsOnlyNodeForContext().
-    return true;
-  }
-
   virtual void SetDoubleParameter(uint32_t aIndex, double aParam) override
   {
     if (aIndex == VOLUME) {
       mVolume = aParam;
     }
   }
 
   virtual void SetInt32Parameter(uint32_t aIndex, int32_t aParam) override
--- a/dom/media/webaudio/AudioNodeEngine.h
+++ b/dom/media/webaudio/AudioNodeEngine.h
@@ -304,20 +304,18 @@ public:
   }
 
   /**
    * Produce the next block of audio samples, given input samples aInput
    * (the mixed data for input 0).
    * aInput is guaranteed to have float sample format (if it has samples at all)
    * and to have been resampled to the sampling rate for the stream, and to have
    * exactly WEBAUDIO_BLOCK_SIZE samples.
-   * *aFinished is set to false by the caller. The callee must not set this to
-   * true unless silent output is produced. If set to true, we'll finish the
-   * stream, consider this input inactive on any downstream nodes, and not
-   * call this again.
+   * *aFinished is set to false by the caller. If the callee sets it to true,
+   * we'll finish the stream and not call this again.
    */
   virtual void ProcessBlock(AudioNodeStream* aStream,
                             const AudioBlock& aInput,
                             AudioBlock* aOutput,
                             bool* aFinished);
   /**
    * Produce the next block of audio samples, before input is provided.
    * ProcessBlock() will be called later, and it then should not change
@@ -343,22 +341,16 @@ public:
    * corresponding AudioNode, in which case it will be interpreted as a channel
    * of silence.
    */
   virtual void ProcessBlocksOnPorts(AudioNodeStream* aStream,
                                     const OutputChunks& aInput,
                                     OutputChunks& aOutput,
                                     bool* aFinished);
 
-  // IsActive() returns true if the engine needs to continue processing an
-  // unfinished stream even when it has silent or no input connections.  This
-  // includes tail-times and when sources have been scheduled to start.  If
-  // returning false, then the stream can be suspended.
-  virtual bool IsActive() const { return false; }
-
   bool HasNode() const
   {
     MOZ_ASSERT(NS_IsMainThread());
     return !!mNode;
   }
 
   dom::AudioNode* NodeMainThread() const
   {
--- a/dom/media/webaudio/AudioNodeStream.cpp
+++ b/dom/media/webaudio/AudioNodeStream.cpp
@@ -29,33 +29,31 @@ namespace mozilla {
 AudioNodeStream::AudioNodeStream(AudioNodeEngine* aEngine,
                                  Flags aFlags,
                                  TrackRate aSampleRate)
   : ProcessedMediaStream(nullptr),
     mEngine(aEngine),
     mSampleRate(aSampleRate),
     mFlags(aFlags),
     mNumberOfInputChannels(2),
-    mIsActive(aEngine->IsActive()),
     mMarkAsFinishedAfterThisBlock(false),
     mAudioParamStream(false),
     mPassThrough(false)
 {
   MOZ_ASSERT(NS_IsMainThread());
   mChannelCountMode = ChannelCountMode::Max;
   mChannelInterpretation = ChannelInterpretation::Speakers;
   // AudioNodes are always producing data
   mHasCurrentData = true;
   mLastChunks.SetLength(std::max(uint16_t(1), mEngine->OutputCount()));
   MOZ_COUNT_CTOR(AudioNodeStream);
 }
 
 AudioNodeStream::~AudioNodeStream()
 {
-  MOZ_ASSERT(mActiveInputCount == 0);
   MOZ_COUNT_DTOR(AudioNodeStream);
 }
 
 void
 AudioNodeStream::DestroyImpl()
 {
   // These are graph thread objects, so clean up on graph thread.
   mInputChunks.Clear();
@@ -517,24 +515,17 @@ AudioNodeStream::ProcessInput(GraphTime 
     EnsureTrack(AUDIO_TRACK);
   }
   // No more tracks will be coming
   mBuffer.AdvanceKnownTracksTime(STREAM_TIME_MAX);
 
   uint16_t outputCount = mLastChunks.Length();
   MOZ_ASSERT(outputCount == std::max(uint16_t(1), mEngine->OutputCount()));
 
-  if (!mIsActive) {
-    // mLastChunks are already null.
-#ifdef DEBUG
-    for (const auto& chunk : mLastChunks) {
-      MOZ_ASSERT(chunk.IsNull());
-    }
-#endif
-  } else if (InMutedCycle()) {
+  if (mFinished || InMutedCycle()) {
     mInputChunks.Clear();
     for (uint16_t i = 0; i < outputCount; ++i) {
       mLastChunks[i].SetNull(WEBAUDIO_BLOCK_SIZE);
     }
   } else {
     // We need to generate at least one input
     uint16_t maxInputs = std::max(uint16_t(1), mEngine->InputCount());
     mInputChunks.SetLength(maxInputs);
@@ -553,17 +544,16 @@ AudioNodeStream::ProcessInput(GraphTime 
       }
     }
     for (uint16_t i = 0; i < outputCount; ++i) {
       NS_ASSERTION(mLastChunks[i].GetDuration() == WEBAUDIO_BLOCK_SIZE,
                    "Invalid WebAudio chunk size");
     }
     if (finished) {
       mMarkAsFinishedAfterThisBlock = true;
-      CheckForInactive();
     }
 
     if (mDisabledTrackIDs.Contains(static_cast<TrackID>(AUDIO_TRACK))) {
       for (uint32_t i = 0; i < outputCount; ++i) {
         mLastChunks[i].SetNull(WEBAUDIO_BLOCK_SIZE);
       }
     }
   }
@@ -584,17 +574,17 @@ void
 AudioNodeStream::ProduceOutputBeforeInput(GraphTime aFrom)
 {
   MOZ_ASSERT(mEngine->AsDelayNodeEngine());
   MOZ_ASSERT(mEngine->OutputCount() == 1,
              "DelayNodeEngine output count should be 1");
   MOZ_ASSERT(!InMutedCycle(), "DelayNodes should break cycles");
   MOZ_ASSERT(mLastChunks.Length() == 1);
 
-  if (!mIsActive) {
+  if (mFinished) {
     mLastChunks[0].SetNull(WEBAUDIO_BLOCK_SIZE);
   } else {
     mEngine->ProduceBlockBeforeInput(&mLastChunks[0]);
     NS_ASSERTION(mLastChunks[0].GetDuration() == WEBAUDIO_BLOCK_SIZE,
                  "Invalid WebAudio chunk size");
     if (mDisabledTrackIDs.Contains(static_cast<TrackID>(AUDIO_TRACK))) {
       mLastChunks[0].SetNull(WEBAUDIO_BLOCK_SIZE);
     }
@@ -689,93 +679,9 @@ AudioNodeStream::DestinationTimeFromTick
 {
   MOZ_ASSERT(SampleRate() == aDestination->SampleRate());
 
   GraphTime graphTime = StreamTimeToGraphTime(aPosition);
   StreamTime destinationTime = aDestination->GraphTimeToStreamTime(graphTime);
   return StreamTimeToSeconds(destinationTime);
 }
 
-void
-AudioNodeStream::AddInput(MediaInputPort* aPort)
-{
-  ProcessedMediaStream::AddInput(aPort);
-  AudioNodeStream* ns = aPort->GetSource()->AsAudioNodeStream();
-  // Streams that are not AudioNodeStreams are considered active.
-  if (!ns || (ns->mIsActive && !ns->IsAudioParamStream())) {
-    IncrementActiveInputCount();
-  }
-}
-void
-AudioNodeStream::RemoveInput(MediaInputPort* aPort)
-{
-  ProcessedMediaStream::RemoveInput(aPort);
-  AudioNodeStream* ns = aPort->GetSource()->AsAudioNodeStream();
-  // Streams that are not AudioNodeStreams are considered active.
-  if (!ns || (ns->mIsActive && !ns->IsAudioParamStream())) {
-    DecrementActiveInputCount();
-  }
-}
-
-void
-AudioNodeStream::SetActive()
-{
-  if (mIsActive || mMarkAsFinishedAfterThisBlock) {
-    return;
-  }
-
-  mIsActive = true;
-  if (IsAudioParamStream()) {
-    // Consumers merely influence stream order.
-    // They do not read from the stream.
-    return;
-  }
-
-  for (const auto& consumer : mConsumers) {
-    AudioNodeStream* ns = consumer->GetDestination()->AsAudioNodeStream();
-    if (ns) {
-      ns->IncrementActiveInputCount();
-    }
-  }
-}
-
-void
-AudioNodeStream::CheckForInactive()
-{
-  if (((mActiveInputCount > 0 || mEngine->IsActive()) &&
-       !mMarkAsFinishedAfterThisBlock) ||
-      !mIsActive) {
-    return;
-  }
-
-  mIsActive = false;
-  mInputChunks.Clear(); // not required for foreseeable future
-  for (auto& chunk : mLastChunks) {
-    chunk.SetNull(WEBAUDIO_BLOCK_SIZE);
-  }
-  if (IsAudioParamStream()) {
-    return;
-  }
-
-  for (const auto& consumer : mConsumers) {
-    AudioNodeStream* ns = consumer->GetDestination()->AsAudioNodeStream();
-    if (ns) {
-      ns->DecrementActiveInputCount();
-    }
-  }
-}
-
-void
-AudioNodeStream::IncrementActiveInputCount()
-{
-  ++mActiveInputCount;
-  SetActive();
-}
-
-void
-AudioNodeStream::DecrementActiveInputCount()
-{
-  MOZ_ASSERT(mActiveInputCount > 0);
-  --mActiveInputCount;
-  CheckForInactive();
-}
-
 } // namespace mozilla
--- a/dom/media/webaudio/AudioNodeStream.h
+++ b/dom/media/webaudio/AudioNodeStream.h
@@ -101,18 +101,16 @@ public:
 
   void SetAudioParamHelperStream()
   {
     MOZ_ASSERT(!mAudioParamStream, "Can only do this once");
     mAudioParamStream = true;
   }
 
   virtual AudioNodeStream* AsAudioNodeStream() override { return this; }
-  virtual void AddInput(MediaInputPort* aPort) override;
-  virtual void RemoveInput(MediaInputPort* aPort) override;
 
   // Graph thread only
   void SetStreamTimeParameterImpl(uint32_t aIndex, MediaStream* aRelativeToStream,
                                   double aStreamTime);
   void SetChannelMixingParametersImpl(uint32_t aNumberOfChannels,
                                       ChannelCountMode aChannelCountMoe,
                                       ChannelInterpretation aChannelInterpretation);
   virtual void ProcessInput(GraphTime aFrom, GraphTime aTo, uint32_t aFlags) override;
@@ -162,71 +160,48 @@ public:
                                   StreamTime aPosition);
 
   size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
   size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
 
   void SizeOfAudioNodesIncludingThis(MallocSizeOf aMallocSizeOf,
                                      AudioNodeSizes& aUsage) const;
 
-  /*
-   * SetActive() is called when either an active input is added or the engine
-   * for a source node transitions from inactive to active.  This is not
-   * called from engines for processing nodes because they only become active
-   * when there are active input streams, in which case this stream is already
-   * active.
-   */
-  void SetActive();
-  /*
-   * CheckForInactive() is called when the engine transitions from active to
-   * inactive, or an active input is removed, or the stream finishes.  If the
-   * stream is now inactive, then mInputChunks will be cleared and mLastChunks
-   * will be set to null.  ProcessBlock() will not be called on the engine
-   * again until SetActive() is called.
-   */
-  void CheckForInactive();
 
 protected:
   virtual void DestroyImpl() override;
 
   void AdvanceOutputSegment();
   void FinishOutput();
   void AccumulateInputChunk(uint32_t aInputIndex, const AudioBlock& aChunk,
                             AudioBlock* aBlock,
                             nsTArray<float>* aDownmixBuffer);
   void UpMixDownMixChunk(const AudioBlock* aChunk, uint32_t aOutputChannelCount,
                          nsTArray<const float*>& aOutputChannels,
                          nsTArray<float>& aDownmixBuffer);
 
   uint32_t ComputedNumberOfChannels(uint32_t aInputChannelCount);
   void ObtainInputBlock(AudioBlock& aTmpChunk, uint32_t aPortIndex);
-  void IncrementActiveInputCount();
-  void DecrementActiveInputCount();
 
   // The engine that will generate output for this node.
   nsAutoPtr<AudioNodeEngine> mEngine;
   // The mixed input blocks are kept from iteration to iteration to avoid
   // reallocating channel data arrays and any buffers for mixing.
   OutputChunks mInputChunks;
   // The last block produced by this node.
   OutputChunks mLastChunks;
   // The stream's sampling rate
   const TrackRate mSampleRate;
   // Whether this is an internal or external stream
   const Flags mFlags;
-  // The number of input streams that may provide non-silent input.
-  uint32_t mActiveInputCount = 0;
   // The number of input channels that this stream requires. 0 means don't care.
   uint32_t mNumberOfInputChannels;
   // The mixing modes
   ChannelCountMode mChannelCountMode;
   ChannelInterpretation mChannelInterpretation;
-  // Streams are considered active if the stream has not finished and either
-  // the engine is active or there are active input streams.
-  bool mIsActive;
   // Whether the stream should be marked as finished as soon
   // as the current time range has been computed block by block.
   bool mMarkAsFinishedAfterThisBlock;
   // Whether the stream is an AudioParamHelper stream.
   bool mAudioParamStream;
   // Whether the stream just passes its input through.
   bool mPassThrough;
 };
--- a/dom/media/webaudio/BiquadFilterNode.cpp
+++ b/dom/media/webaudio/BiquadFilterNode.cpp
@@ -150,17 +150,16 @@ public:
         if (mBiquads[i].hasTail()) {
           hasTail = true;
           break;
         }
       }
       if (!hasTail) {
         if (!mBiquads.IsEmpty()) {
           mBiquads.Clear();
-          aStream->CheckForInactive();
 
           nsRefPtr<PlayingRefChangeHandler> refchanged =
             new PlayingRefChangeHandler(aStream, PlayingRefChangeHandler::RELEASE);
           aStream->Graph()->
             DispatchToMainThreadAfterStreamStateUpdate(refchanged.forget());
         }
 
         aOutput->SetNull(WEBAUDIO_BLOCK_SIZE);
@@ -207,21 +206,16 @@ public:
       SetParamsOnBiquad(mBiquads[i], aStream->SampleRate(), mType, freq, q, gain, detune);
 
       mBiquads[i].process(input,
                           aOutput->ChannelFloatsForWrite(i),
                           aInput.GetDuration());
     }
   }
 
-  virtual bool IsActive() const override
-  {
-    return !mBiquads.IsEmpty();
-  }
-
   virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override
   {
     // Not owned:
     // - mSource - probably not owned
     // - mDestination - probably not owned
     // - AudioParamTimelines - counted in the AudioNode
     size_t amount = AudioNodeEngine::SizeOfExcludingThis(aMallocSizeOf);
     amount += mBiquads.ShallowSizeOfExcludingThis(aMallocSizeOf);
--- a/dom/media/webaudio/ConvolverNode.cpp
+++ b/dom/media/webaudio/ConvolverNode.cpp
@@ -115,17 +115,16 @@ public:
     if (aInput.IsNull()) {
       if (mLeftOverData > 0) {
         mLeftOverData -= WEBAUDIO_BLOCK_SIZE;
         input.AllocateChannels(1);
         WriteZeroesToAudioBlock(&input, 0, WEBAUDIO_BLOCK_SIZE);
       } else {
         if (mLeftOverData != INT32_MIN) {
           mLeftOverData = INT32_MIN;
-          aStream->CheckForInactive();
           nsRefPtr<PlayingRefChanged> refchanged =
             new PlayingRefChanged(aStream, PlayingRefChanged::RELEASE);
           aStream->Graph()->
             DispatchToMainThreadAfterStreamStateUpdate(refchanged.forget());
         }
         aOutput->SetNull(WEBAUDIO_BLOCK_SIZE);
         return;
       }
@@ -150,21 +149,16 @@ public:
       mLeftOverData = mBufferLength;
       MOZ_ASSERT(mLeftOverData > 0);
     }
     aOutput->AllocateChannels(2);
 
     mReverb->process(&input, aOutput, WEBAUDIO_BLOCK_SIZE);
   }
 
-  virtual bool IsActive() const override
-  {
-    return mLeftOverData != INT32_MIN;
-  }
-
   virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override
   {
     size_t amount = AudioNodeEngine::SizeOfExcludingThis(aMallocSizeOf);
     if (mBuffer && !mBuffer->IsShared()) {
       amount += mBuffer->SizeOfIncludingThis(aMallocSizeOf);
     }
 
     if (mReverb) {
--- a/dom/media/webaudio/DelayNode.cpp
+++ b/dom/media/webaudio/DelayNode.cpp
@@ -91,27 +91,25 @@ public:
           DispatchToMainThreadAfterStreamStateUpdate(refchanged.forget());
       }
       mLeftOverData = mBuffer.MaxDelayTicks();
     } else if (mLeftOverData > 0) {
       mLeftOverData -= WEBAUDIO_BLOCK_SIZE;
     } else {
       if (mLeftOverData != INT32_MIN) {
         mLeftOverData = INT32_MIN;
-        aStream->CheckForInactive();
-
         // Delete our buffered data now we no longer need it
         mBuffer.Reset();
 
         nsRefPtr<PlayingRefChanged> refchanged =
           new PlayingRefChanged(aStream, PlayingRefChanged::RELEASE);
         aStream->Graph()->
           DispatchToMainThreadAfterStreamStateUpdate(refchanged.forget());
       }
-      aOutput->SetNull(WEBAUDIO_BLOCK_SIZE);
+      *aOutput = aInput;
       return;
     }
 
     mBuffer.Write(aInput);
 
     // Skip output update if mLastChunks has already been set by
     // ProduceBlockBeforeInput() when in a cycle.
     if (!mHaveProducedBeforeInput) {
@@ -158,21 +156,16 @@ public:
     if (mLeftOverData <= 0) {
       aOutput->SetNull(WEBAUDIO_BLOCK_SIZE);
     } else {
       UpdateOutputBlock(aOutput, WEBAUDIO_BLOCK_SIZE);
     }
     mHaveProducedBeforeInput = true;
   }
 
-  virtual bool IsActive() const override
-  {
-    return mLeftOverData != INT32_MIN;
-  }
-
   virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override
   {
     size_t amount = AudioNodeEngine::SizeOfExcludingThis(aMallocSizeOf);
     // Not owned:
     // - mSource - probably not owned
     // - mDestination - probably not owned
     // - mDelay - shares ref with AudioNode, don't count
     amount += mBuffer.SizeOfExcludingThis(aMallocSizeOf);
--- a/dom/media/webaudio/OscillatorNode.cpp
+++ b/dom/media/webaudio/OscillatorNode.cpp
@@ -76,20 +76,17 @@ public:
     default:
       NS_ERROR("Bad OscillatorNodeEngine TimelineParameter");
     }
   }
 
   virtual void SetStreamTimeParameter(uint32_t aIndex, StreamTime aParam) override
   {
     switch (aIndex) {
-    case START:
-      mStart = aParam;
-      mSource->SetActive();
-      break;
+    case START: mStart = aParam; break;
     case STOP: mStop = aParam; break;
     default:
       NS_ERROR("Bad OscillatorNodeEngine StreamTimeParameter");
     }
   }
 
   virtual void SetInt32Parameter(uint32_t aIndex, int32_t aParam) override
   {
@@ -328,22 +325,16 @@ public:
         ComputeCustom(output, ticks, start, end);
         break;
       default:
         ComputeSilence(aOutput);
     };
 
   }
 
-  virtual bool IsActive() const override
-  {
-    // start() has been called.
-    return mStart != -1;
-  }
-
   virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override
   {
     size_t amount = AudioNodeEngine::SizeOfExcludingThis(aMallocSizeOf);
 
     // Not owned:
     // - mSource
     // - mDestination
     // - mFrequency (internal ref owned by node)
--- a/dom/media/webaudio/PannerNode.cpp
+++ b/dom/media/webaudio/PannerNode.cpp
@@ -144,45 +144,39 @@ public:
       // tail-time reference was added.  Even if the model is now equalpower,
       // the reference will need to be removed.
       if (mLeftOverData > 0 &&
           mPanningModelFunction == &PannerNodeEngine::HRTFPanningFunction) {
         mLeftOverData -= WEBAUDIO_BLOCK_SIZE;
       } else {
         if (mLeftOverData != INT_MIN) {
           mLeftOverData = INT_MIN;
-          aStream->CheckForInactive();
           mHRTFPanner->reset();
 
           nsRefPtr<PlayingRefChangeHandler> refchanged =
             new PlayingRefChangeHandler(aStream, PlayingRefChangeHandler::RELEASE);
           aStream->Graph()->
             DispatchToMainThreadAfterStreamStateUpdate(refchanged.forget());
         }
-        aOutput->SetNull(WEBAUDIO_BLOCK_SIZE);
+        *aOutput = aInput;
         return;
       }
     } else if (mPanningModelFunction == &PannerNodeEngine::HRTFPanningFunction) {
       if (mLeftOverData == INT_MIN) {
         nsRefPtr<PlayingRefChangeHandler> refchanged =
           new PlayingRefChangeHandler(aStream, PlayingRefChangeHandler::ADDREF);
         aStream->Graph()->
           DispatchToMainThreadAfterStreamStateUpdate(refchanged.forget());
       }
       mLeftOverData = mHRTFPanner->maxTailFrames();
     }
 
     (this->*mPanningModelFunction)(aInput, aOutput);
   }
 
-  virtual bool IsActive() const override
-  {
-    return mLeftOverData != INT_MIN;
-  }
-
   void ComputeAzimuthAndElevation(float& aAzimuth, float& aElevation);
   float ComputeConeGain();
   // Compute how much the distance contributes to the gain reduction.
   float ComputeDistanceGain();
 
   void EqualPowerPanningFunction(const AudioBlock& aInput, AudioBlock* aOutput);
   void HRTFPanningFunction(const AudioBlock& aInput, AudioBlock* aOutput);
 
--- a/dom/media/webaudio/ScriptProcessorNode.cpp
+++ b/dom/media/webaudio/ScriptProcessorNode.cpp
@@ -328,24 +328,16 @@ public:
     *aOutput = mSharedBuffers->GetOutputBuffer();
 
     if (mInputWriteIndex >= mBufferSize) {
       SendBuffersToMainThread(aStream);
       mInputWriteIndex -= mBufferSize;
     }
   }
 
-  virtual bool IsActive() const override
-  {
-    // Could return false when !mIsConnected after all output chunks produced
-    // by main thread events calling
-    // SharedBuffers::FinishProducingOutputBuffer() have been processed.
-    return true;
-  }
-
   virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override
   {
     // Not owned:
     // - mSource (probably)
     // - mDestination (probably)
     size_t amount = AudioNodeEngine::SizeOfExcludingThis(aMallocSizeOf);
     amount += mSharedBuffers->SizeOfIncludingThis(aMallocSizeOf);
     amount += mInputBuffer->SizeOfIncludingThis(aMallocSizeOf);