diff --git a/content/media/AudioNodeStream.cpp b/content/media/AudioNodeStream.cpp index 1c3f5018138f..8bc89902d4dc 100644 --- a/content/media/AudioNodeStream.cpp +++ b/content/media/AudioNodeStream.cpp @@ -189,7 +189,7 @@ AudioNodeStream::ObtainInputBlock(AudioChunk* aTmpChunk) if (a->IsFinishedOnGraphThread()) { continue; } - AudioChunk* chunk = a->mLastChunk; + AudioChunk* chunk = &a->mLastChunk; // XXX when we implement DelayNode, this will no longer be true and we'll // need to treat a null chunk (when the DelayNode hasn't had a chance // to produce data yet) as silence here. @@ -268,11 +268,16 @@ AudioNodeStream::ProduceOutput(GraphTime aFrom, GraphTime aTo) } } - mLastChunk = segment->AppendAndConsumeChunk(&outputChunk); + mLastChunk = outputChunk; + if (mKind == MediaStreamGraph::EXTERNAL_STREAM) { + segment->AppendAndConsumeChunk(&outputChunk); + } else { + segment->AppendNullData(outputChunk.GetDuration()); + } for (uint32_t j = 0; j < mListeners.Length(); ++j) { MediaStreamListener* l = mListeners[j]; - AudioChunk copyChunk = *mLastChunk; + AudioChunk copyChunk = outputChunk; AudioSegment tmpSegment; tmpSegment.AppendAndConsumeChunk(©Chunk); l->NotifyQueuedTrackChanges(Graph(), AUDIO_NODE_STREAM_TRACK_ID, diff --git a/content/media/AudioNodeStream.h b/content/media/AudioNodeStream.h index c9ad0c279bed..3595041dc64a 100644 --- a/content/media/AudioNodeStream.h +++ b/content/media/AudioNodeStream.h @@ -42,8 +42,11 @@ public: /** * Transfers ownership of aEngine to the new AudioNodeStream. */ - explicit AudioNodeStream(AudioNodeEngine* aEngine) - : ProcessedMediaStream(nullptr), mEngine(aEngine), mLastChunk(nullptr) + AudioNodeStream(AudioNodeEngine* aEngine, + MediaStreamGraph::AudioNodeStreamKind aKind) + : ProcessedMediaStream(nullptr), + mEngine(aEngine), + mKind(aKind) { } ~AudioNodeStream(); @@ -81,7 +84,9 @@ protected: // The engine that will generate output for this node. nsAutoPtr mEngine; // The last block produced by this node. - AudioChunk* mLastChunk; + AudioChunk mLastChunk; + // Whether this is an internal or external stream + MediaStreamGraph::AudioNodeStreamKind mKind; }; } diff --git a/content/media/MediaStreamGraph.cpp b/content/media/MediaStreamGraph.cpp index 96bcbb95df04..6703e20769f3 100644 --- a/content/media/MediaStreamGraph.cpp +++ b/content/media/MediaStreamGraph.cpp @@ -2002,9 +2002,10 @@ MediaStreamGraph::CreateTrackUnionStream(DOMMediaStream* aWrapper) } AudioNodeStream* -MediaStreamGraph::CreateAudioNodeStream(AudioNodeEngine* aEngine) +MediaStreamGraph::CreateAudioNodeStream(AudioNodeEngine* aEngine, + AudioNodeStreamKind aKind) { - AudioNodeStream* stream = new AudioNodeStream(aEngine); + AudioNodeStream* stream = new AudioNodeStream(aEngine, aKind); NS_ADDREF(stream); MediaStreamGraphImpl* graph = static_cast(this); stream->SetGraphImpl(graph); diff --git a/content/media/MediaStreamGraph.h b/content/media/MediaStreamGraph.h index c0a35526c3cc..4e3ef0e2e73f 100644 --- a/content/media/MediaStreamGraph.h +++ b/content/media/MediaStreamGraph.h @@ -883,11 +883,16 @@ public: * particular tracks of each input stream. */ ProcessedMediaStream* CreateTrackUnionStream(DOMMediaStream* aWrapper); + // Internal AudioNodeStreams can only pass their output to another + // AudioNode, whereas external AudioNodeStreams can pass their output + // to an nsAudioStream for playback. + enum AudioNodeStreamKind { INTERNAL_STREAM, EXTERNAL_STREAM }; /** * Create a stream that will process audio for an AudioNode. * Takes ownership of aEngine. */ - AudioNodeStream* CreateAudioNodeStream(AudioNodeEngine* aEngine); + AudioNodeStream* CreateAudioNodeStream(AudioNodeEngine* aEngine, + AudioNodeStreamKind aKind); /** * Returns the number of graph updates sent. This can be used to track * whether a given update has been processed by the graph thread and reflected diff --git a/content/media/webaudio/AudioBufferSourceNode.cpp b/content/media/webaudio/AudioBufferSourceNode.cpp index b63eccbf95ea..eb2d9f02b0b0 100644 --- a/content/media/webaudio/AudioBufferSourceNode.cpp +++ b/content/media/webaudio/AudioBufferSourceNode.cpp @@ -227,7 +227,8 @@ AudioBufferSourceNode::AudioBufferSourceNode(AudioContext* aContext) , mStartCalled(false) { SetProduceOwnOutput(true); - mStream = aContext->Graph()->CreateAudioNodeStream(new AudioBufferSourceNodeEngine()); + mStream = aContext->Graph()->CreateAudioNodeStream(new AudioBufferSourceNodeEngine(), + MediaStreamGraph::INTERNAL_STREAM); mStream->AddMainThreadListener(this); } diff --git a/content/media/webaudio/AudioDestinationNode.cpp b/content/media/webaudio/AudioDestinationNode.cpp index 07467d955ba8..e1ee3d258f33 100644 --- a/content/media/webaudio/AudioDestinationNode.cpp +++ b/content/media/webaudio/AudioDestinationNode.cpp @@ -31,7 +31,8 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(AudioDestinationNode) AudioDestinationNode::AudioDestinationNode(AudioContext* aContext, MediaStreamGraph* aGraph) : AudioNode(aContext) { - mStream = aGraph->CreateAudioNodeStream(new AudioNodeEngine()); + mStream = aGraph->CreateAudioNodeStream(new AudioNodeEngine(), + MediaStreamGraph::EXTERNAL_STREAM); SetIsDOMBinding(); } diff --git a/content/media/webaudio/GainNode.cpp b/content/media/webaudio/GainNode.cpp index 2cf83972d674..cc1d368b6fb8 100644 --- a/content/media/webaudio/GainNode.cpp +++ b/content/media/webaudio/GainNode.cpp @@ -118,7 +118,7 @@ GainNode::GainNode(AudioContext* aContext) , mGain(new AudioParam(this, SendGainToStream, 1.0f, 0.0f, 1.0f)) { GainNodeEngine* engine = new GainNodeEngine(aContext->Destination()); - mStream = aContext->Graph()->CreateAudioNodeStream(engine); + mStream = aContext->Graph()->CreateAudioNodeStream(engine, MediaStreamGraph::INTERNAL_STREAM); engine->SetSourceStream(static_cast (mStream.get())); } diff --git a/content/media/webaudio/PannerNode.cpp b/content/media/webaudio/PannerNode.cpp index cac8ce819b89..fa6efb28e7a1 100644 --- a/content/media/webaudio/PannerNode.cpp +++ b/content/media/webaudio/PannerNode.cpp @@ -121,7 +121,8 @@ PannerNode::PannerNode(AudioContext* aContext) , mConeOuterAngle(360.) , mConeOuterGain(0.) { - mStream = aContext->Graph()->CreateAudioNodeStream(new PannerNodeEngine()); + mStream = aContext->Graph()->CreateAudioNodeStream(new PannerNodeEngine(), + MediaStreamGraph::INTERNAL_STREAM); // We should register once we have set up our stream and engine. Context()->Listener()->RegisterPannerNode(this); }