diff --git a/content/media/MediaStreamGraph.cpp b/content/media/MediaStreamGraph.cpp index 38a7ea050fd..e1e42a8409c 100644 --- a/content/media/MediaStreamGraph.cpp +++ b/content/media/MediaStreamGraph.cpp @@ -2352,9 +2352,12 @@ void MediaStreamGraph::DestroyNonRealtimeInstance(MediaStreamGraph* aGraph) { NS_ASSERTION(NS_IsMainThread(), "Main thread only"); - MOZ_ASSERT(aGraph != gGraph, "Should not destroy the global graph here"); + MOZ_ASSERT(aGraph->IsNonRealtime(), "Should not destroy the global graph here"); MediaStreamGraphImpl* graph = static_cast(aGraph); + if (graph->mForceShutDown) + return; // already done + if (!graph->mNonRealtimeProcessing) { // Start the graph, but don't produce anything graph->StartNonRealtimeProcessing(0); @@ -2421,6 +2424,12 @@ MediaStreamGraph::CreateAudioNodeStream(AudioNodeEngine* aEngine, return stream; } +bool +MediaStreamGraph::IsNonRealtime() const +{ + return this != gGraph; +} + void MediaStreamGraph::StartNonRealtimeProcessing(uint32_t aTicksToProcess) { diff --git a/content/media/MediaStreamGraph.h b/content/media/MediaStreamGraph.h index fb2d810266b..4a05e493a8c 100644 --- a/content/media/MediaStreamGraph.h +++ b/content/media/MediaStreamGraph.h @@ -975,6 +975,7 @@ public: // Main thread only static MediaStreamGraph* GetInstance(); static MediaStreamGraph* CreateNonRealtimeInstance(); + // Idempotent static void DestroyNonRealtimeInstance(MediaStreamGraph* aGraph); // Control API. @@ -1022,6 +1023,8 @@ public: * in main-thread stream state. */ int64_t GetCurrentGraphUpdateIndex() { return mGraphUpdatesSent; } + + bool IsNonRealtime() const; /** * Start processing non-realtime for a specific number of ticks. */ diff --git a/content/media/webaudio/AudioContext.h b/content/media/webaudio/AudioContext.h index a3e518c10f8..19759604e33 100644 --- a/content/media/webaudio/AudioContext.h +++ b/content/media/webaudio/AudioContext.h @@ -79,7 +79,7 @@ public: return GetOwner(); } - void Shutdown(); + void Shutdown(); // idempotent void Suspend(); void Resume(); diff --git a/content/media/webaudio/AudioDestinationNode.cpp b/content/media/webaudio/AudioDestinationNode.cpp index c5aea724e3a..ff6ccad106f 100644 --- a/content/media/webaudio/AudioDestinationNode.cpp +++ b/content/media/webaudio/AudioDestinationNode.cpp @@ -235,6 +235,19 @@ AudioDestinationNode::AudioDestinationNode(AudioContext* aContext, mStream = graph->CreateAudioNodeStream(engine, MediaStreamGraph::EXTERNAL_STREAM); } +void +AudioDestinationNode::DestroyMediaStream() +{ + if (!mStream) + return; + + MediaStreamGraph* graph = mStream->Graph(); + if (graph->IsNonRealtime()) { + MediaStreamGraph::DestroyNonRealtimeInstance(graph); + } + AudioNode::DestroyMediaStream(); +} + uint32_t AudioDestinationNode::MaxChannelCount() const { diff --git a/content/media/webaudio/AudioDestinationNode.h b/content/media/webaudio/AudioDestinationNode.h index 68f891d3d9b..1d239a463d0 100644 --- a/content/media/webaudio/AudioDestinationNode.h +++ b/content/media/webaudio/AudioDestinationNode.h @@ -25,6 +25,8 @@ public: uint32_t aLength = 0, float aSampleRate = 0.0f); + virtual void DestroyMediaStream() MOZ_OVERRIDE; + NS_DECL_ISUPPORTS_INHERITED virtual JSObject* WrapObject(JSContext* aCx,