Bug 1175510 - Update the AudioBufferSourceNode <=> PannerNode mapping when destroying AudioNodeStream. r=karlt, a=ritu
authorPaul Adenot <paul@paul.cx>
Thu, 02 Jul 2015 05:43:52 +0200
changeset 281426 c41b3fd3ff67b482d93cab4b97ace968eba0c037
parent 281425 73463a63b2996bcf46bcd6a081c688c5f7e979cc
child 281427 68f8a8129260f0a95d82c6fbee7d8fa64ce7db98
push id4932
push userjlund@mozilla.com
push dateMon, 10 Aug 2015 18:23:06 +0000
treeherdermozilla-beta@6dd5a4f5f745 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskarlt, ritu
bugs1175510
milestone41.0a2
Bug 1175510 - Update the AudioBufferSourceNode <=> PannerNode mapping when destroying AudioNodeStream. r=karlt, a=ritu
dom/media/webaudio/AudioBufferSourceNode.cpp
dom/media/webaudio/AudioBufferSourceNode.h
dom/media/webaudio/PannerNode.cpp
--- a/dom/media/webaudio/AudioBufferSourceNode.cpp
+++ b/dom/media/webaudio/AudioBufferSourceNode.cpp
@@ -21,22 +21,17 @@ namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(AudioBufferSourceNode)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(AudioBufferSourceNode)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mBuffer)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mPlaybackRate)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mDetune)
   if (tmp->Context()) {
-    // AudioNode's Unlink implementation disconnects us from the graph
-    // too, but we need to do this right here to make sure that
-    // UnregisterAudioBufferSourceNode can properly untangle us from
-    // the possibly connected PannerNodes.
     tmp->DisconnectFromGraph();
-    tmp->Context()->UnregisterAudioBufferSourceNode(tmp);
   }
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END_INHERITED(AudioNode)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(AudioBufferSourceNode, AudioNode)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBuffer)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPlaybackRate)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDetune)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
@@ -566,19 +561,16 @@ AudioBufferSourceNode::AudioBufferSource
   AudioBufferSourceNodeEngine* engine = new AudioBufferSourceNodeEngine(this, aContext->Destination());
   mStream = aContext->Graph()->CreateAudioNodeStream(engine, MediaStreamGraph::SOURCE_STREAM);
   engine->SetSourceStream(static_cast<AudioNodeStream*>(mStream.get()));
   mStream->AddMainThreadListener(this);
 }
 
 AudioBufferSourceNode::~AudioBufferSourceNode()
 {
-  if (Context()) {
-    Context()->UnregisterAudioBufferSourceNode(this);
-  }
 }
 
 size_t
 AudioBufferSourceNode::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
 {
   size_t amount = AudioNode::SizeOfExcludingThis(aMallocSizeOf);
   if (mBuffer) {
     amount += mBuffer->SizeOfIncludingThis(aMallocSizeOf);
@@ -753,16 +745,19 @@ AudioBufferSourceNode::SendPlaybackRateT
   }
   SendTimelineParameterToStream(This, PLAYBACKRATE, *This->mPlaybackRate);
 }
 
 void
 AudioBufferSourceNode::SendDetuneToStream(AudioNode* aNode)
 {
   AudioBufferSourceNode* This = static_cast<AudioBufferSourceNode*>(aNode);
+  if (!This->mStream) {
+    return;
+  }
   SendTimelineParameterToStream(This, DETUNE, *This->mDetune);
 }
 
 void
 AudioBufferSourceNode::SendDopplerShiftToStream(double aDopplerShift)
 {
   MOZ_ASSERT(mStream, "Should have disconnected panner if no stream");
   SendDoubleParameterToStream(DOPPLERSHIFT, aDopplerShift);
--- a/dom/media/webaudio/AudioBufferSourceNode.h
+++ b/dom/media/webaudio/AudioBufferSourceNode.h
@@ -22,16 +22,19 @@ public:
   explicit AudioBufferSourceNode(AudioContext* aContext);
 
   virtual void DestroyMediaStream() override
   {
     if (mStream) {
       mStream->RemoveMainThreadListener(this);
     }
     AudioNode::DestroyMediaStream();
+    if (Context()) {
+      Context()->UnregisterAudioBufferSourceNode(this);
+    }
   }
   virtual uint16_t NumberOfInputs() const final override
   {
     return 0;
   }
   virtual AudioBufferSourceNode* AsAudioBufferSourceNode() override
   {
     return this;
--- a/dom/media/webaudio/PannerNode.cpp
+++ b/dom/media/webaudio/PannerNode.cpp
@@ -535,19 +535,20 @@ PannerNode::FindConnectedSources(AudioNo
     // Return if we find a node that we have seen already.
     if (aNodesSeen.find(inputNodes[i].mInputNode) != aNodesSeen.end()) {
       return;
     }
     aNodesSeen.insert(inputNodes[i].mInputNode);
     // Recurse
     FindConnectedSources(inputNodes[i].mInputNode, aSources, aNodesSeen);
 
-    // Check if this node is an AudioBufferSourceNode
+    // Check if this node is an AudioBufferSourceNode that still have a stream,
+    // which means it has not finished playing.
     AudioBufferSourceNode* node = inputNodes[i].mInputNode->AsAudioBufferSourceNode();
-    if (node) {
+    if (node && node->Stream()) {
       aSources.AppendElement(node);
     }
   }
 }
 
 void
 PannerNode::SendDopplerToSourcesIfNeeded()
 {