From 4bc48d01347b9b80a19734f86e86f73e334e1261 Mon Sep 17 00:00:00 2001 From: Paul Adenot Date: Fri, 24 Jul 2015 14:28:16 +0200 Subject: [PATCH] Bug 1156472 - Part 4 - Add a new MediaStreamGraph API to connect a MediaStream to a capture stream. r=jesup,roc --- dom/media/MediaStreamGraph.cpp | 73 ++++++++++++++++++++++++++++++++ dom/media/MediaStreamGraph.h | 10 +++++ dom/media/MediaStreamGraphImpl.h | 17 ++++++++ 3 files changed, 100 insertions(+) diff --git a/dom/media/MediaStreamGraph.cpp b/dom/media/MediaStreamGraph.cpp index 53144c054893..a23fba28f998 100644 --- a/dom/media/MediaStreamGraph.cpp +++ b/dom/media/MediaStreamGraph.cpp @@ -18,6 +18,7 @@ #include "mozilla/Attributes.h" #include "TrackUnionStream.h" #include "ImageContainer.h" +#include "AudioCaptureStream.h" #include "AudioChannelService.h" #include "AudioNodeEngine.h" #include "AudioNodeStream.h" @@ -3192,6 +3193,17 @@ MediaStreamGraph::CreateTrackUnionStream(DOMMediaStream* aWrapper) return stream; } +ProcessedMediaStream* +MediaStreamGraph::CreateAudioCaptureStream(DOMMediaStream* aWrapper) +{ + AudioCaptureStream* stream = new AudioCaptureStream(aWrapper); + NS_ADDREF(stream); + MediaStreamGraphImpl* graph = static_cast(this); + stream->SetGraphImpl(graph); + graph->AppendMessage(new CreateMessage(stream)); + return stream; +} + AudioNodeExternalInputStream* MediaStreamGraph::CreateAudioNodeExternalInputStream(AudioNodeEngine* aEngine, TrackRate aSampleRate) { @@ -3556,4 +3568,65 @@ ProcessedMediaStream::AddInput(MediaInputPort* aPort) GraphImpl()->SetStreamOrderDirty(); } +void +MediaStreamGraph::RegisterCaptureStreamForWindow( + uint64_t aWindowId, ProcessedMediaStream* aCaptureStream) +{ + MOZ_ASSERT(NS_IsMainThread()); + MediaStreamGraphImpl* graphImpl = static_cast(this); + graphImpl->RegisterCaptureStreamForWindow(aWindowId, aCaptureStream); +} + +void +MediaStreamGraphImpl::RegisterCaptureStreamForWindow( + uint64_t aWindowId, ProcessedMediaStream* aCaptureStream) +{ + MOZ_ASSERT(NS_IsMainThread()); + WindowAndStream winAndStream; + winAndStream.mWindowId = aWindowId; + winAndStream.mCaptureStreamSink = aCaptureStream; + mWindowCaptureStreams.AppendElement(winAndStream); +} + +void +MediaStreamGraph::UnregisterCaptureStreamForWindow(uint64_t aWindowId) +{ + MOZ_ASSERT(NS_IsMainThread()); + MediaStreamGraphImpl* graphImpl = static_cast(this); + graphImpl->UnregisterCaptureStreamForWindow(aWindowId); +} + +void +MediaStreamGraphImpl::UnregisterCaptureStreamForWindow(uint64_t aWindowId) +{ + MOZ_ASSERT(NS_IsMainThread()); + for (uint32_t i = 0; i < mWindowCaptureStreams.Length(); i++) { + if (mWindowCaptureStreams[i].mWindowId == aWindowId) { + mWindowCaptureStreams.RemoveElementAt(i); + } + } +} + +already_AddRefed +MediaStreamGraph::ConnectToCaptureStream(uint64_t aWindowId, + MediaStream* aMediaStream) +{ + return aMediaStream->GraphImpl()->ConnectToCaptureStream(aWindowId, + aMediaStream); +} + +already_AddRefed +MediaStreamGraphImpl::ConnectToCaptureStream(uint64_t aWindowId, + MediaStream* aMediaStream) +{ + MOZ_ASSERT(NS_IsMainThread()); + for (uint32_t i = 0; i < mWindowCaptureStreams.Length(); i++) { + if (mWindowCaptureStreams[i].mWindowId == aWindowId) { + ProcessedMediaStream* sink = mWindowCaptureStreams[i].mCaptureStreamSink; + return sink->AllocateInputPort(aMediaStream, 0); + } + } + return nullptr; +} + } // namespace mozilla diff --git a/dom/media/MediaStreamGraph.h b/dom/media/MediaStreamGraph.h index 312aad706052..ac770fe1396a 100644 --- a/dom/media/MediaStreamGraph.h +++ b/dom/media/MediaStreamGraph.h @@ -1262,6 +1262,10 @@ public: * particular tracks of each input stream. */ ProcessedMediaStream* CreateTrackUnionStream(DOMMediaStream* aWrapper); + /** + * Create a stream that will mix all its audio input. + */ + ProcessedMediaStream* CreateAudioCaptureStream(DOMMediaStream* aWrapper); // Internal AudioNodeStreams can only pass their output to another // AudioNode, whereas external AudioNodeStreams can pass their output // to an nsAudioStream for playback. @@ -1318,6 +1322,12 @@ public: */ TrackRate GraphRate() const { return mSampleRate; } + void RegisterCaptureStreamForWindow(uint64_t aWindowId, + ProcessedMediaStream* aCaptureStream); + void UnregisterCaptureStreamForWindow(uint64_t aWindowId); + already_AddRefed ConnectToCaptureStream( + uint64_t aWindowId, MediaStream* aMediaStream); + protected: explicit MediaStreamGraph(TrackRate aSampleRate) : mNextGraphUpdateIndex(1) diff --git a/dom/media/MediaStreamGraphImpl.h b/dom/media/MediaStreamGraphImpl.h index 262cae526c2e..15ded10c470c 100644 --- a/dom/media/MediaStreamGraphImpl.h +++ b/dom/media/MediaStreamGraphImpl.h @@ -532,6 +532,13 @@ public: } } + // Capture Stream API. This allows to get a mixed-down output for a window. + void RegisterCaptureStreamForWindow(uint64_t aWindowId, + ProcessedMediaStream* aCaptureStream); + void UnregisterCaptureStreamForWindow(uint64_t aWindowId); + already_AddRefed + ConnectToCaptureStream(uint64_t aWindowId, MediaStream* aMediaStream); + // Data members // /** @@ -755,6 +762,16 @@ private: * Used to pass memory report information across threads. */ nsTArray mAudioStreamSizes; + + struct WindowAndStream + { + uint64_t mWindowId; + nsRefPtr mCaptureStreamSink; + }; + /** + * Stream for window audio capture. + */ + nsTArray mWindowCaptureStreams; /** * Indicates that the MSG thread should gather data for a memory report. */