From 6cbe994f89664a09aae192cf034a7de3ecfaf744 Mon Sep 17 00:00:00 2001 From: Randell Jesup Date: Tue, 8 Mar 2016 12:11:08 -0500 Subject: [PATCH] Bug 1250934: Factor out AudioTracksPresent() in MediaStreamGraph, and add checks of 'pending' tracks r=padenot MozReview-Commit-ID: KLWleRaAjx3 --- dom/media/MediaStreamGraph.cpp | 63 ++++++++++++++++---------------- dom/media/MediaStreamGraphImpl.h | 6 +++ 2 files changed, 38 insertions(+), 31 deletions(-) diff --git a/dom/media/MediaStreamGraph.cpp b/dom/media/MediaStreamGraph.cpp index ecb1f43ca5d2..95147a40ccc8 100644 --- a/dom/media/MediaStreamGraph.cpp +++ b/dom/media/MediaStreamGraph.cpp @@ -336,19 +336,19 @@ namespace { const uint32_t IN_MUTED_CYCLE = 1; } // namespace -void -MediaStreamGraphImpl::UpdateStreamOrder() +bool +MediaStreamGraphImpl::AudioTrackPresent(bool& aNeedsAEC) { #ifdef MOZ_WEBRTC bool shouldAEC = false; #endif bool audioTrackPresent = false; - for (uint32_t i = 0; i < mStreams.Length(); ++i) { + for (uint32_t i = 0; i < mStreams.Length() && audioTrackPresent == false; ++i) { MediaStream* stream = mStreams[i]; + SourceMediaStream* source = stream->AsSourceStream(); #ifdef MOZ_WEBRTC - if (stream->AsSourceStream() && - stream->AsSourceStream()->NeedsMixing()) { - shouldAEC = true; + if (source && source->NeedsMixing()) { + aNeedsAEC = true; } #endif // If this is a AudioNodeStream, force a AudioCallbackDriver. @@ -360,7 +360,28 @@ MediaStreamGraphImpl::UpdateStreamOrder() audioTrackPresent = true; } } + if (source) { + for (auto& data : source->mPendingTracks) { + if (data.mData->GetType() == MediaSegment::AUDIO) { + audioTrackPresent = true; + break; + } + } + } } + +#ifdef MOZ_WEBRTC + aNeedsAEC = shouldAEC; +#endif + return audioTrackPresent; +} + +void +MediaStreamGraphImpl::UpdateStreamOrder() +{ + bool shouldAEC = false; + bool audioTrackPresent = AudioTrackPresent(shouldAEC); + // Note that this looks for any audio streams, input or output, and switches to a // SystemClockDriver if there are none. However, if another is already pending, let that // switch happen. @@ -1026,20 +1047,8 @@ MediaStreamGraphImpl::CloseAudioInputImpl(AudioDataListener *aListener) mAudioInputs.RemoveElement(aListener); // Switch Drivers since we're adding or removing an input (to nothing/system or output only) - bool audioTrackPresent = false; - for (uint32_t i = 0; i < mStreams.Length(); ++i) { - MediaStream* stream = mStreams[i]; - // If this is a AudioNodeStream, force a AudioCallbackDriver. - if (stream->AsAudioNodeStream()) { - audioTrackPresent = true; - } else if (CurrentDriver()->AsAudioCallbackDriver()) { - // only if there's a real switch! - for (StreamBuffer::TrackIter tracks(stream->GetStreamBuffer(), MediaSegment::AUDIO); - !tracks.IsEnded(); tracks.Next()) { - audioTrackPresent = true; - } - } - } + bool shouldAEC = false; + bool audioTrackPresent = AudioTrackPresent(shouldAEC); MonitorAutoLock mon(mMonitor); if (mLifecycleState == LIFECYCLE_RUNNING) { @@ -3273,17 +3282,9 @@ MediaStreamGraphImpl::ApplyAudioContextOperationImpl( // This is the same logic as in UpdateStreamOrder, but it's simpler to have it // here as well so we don't have to store the Promise(s) on the Graph. if (aOperation != AudioContextOperation::Resume) { - bool audioTrackPresent = false; - for (uint32_t i = 0; i < mStreams.Length(); ++i) { - MediaStream* stream = mStreams[i]; - if (stream->AsAudioNodeStream()) { - audioTrackPresent = true; - } - for (StreamBuffer::TrackIter tracks(stream->GetStreamBuffer(), MediaSegment::AUDIO); - !tracks.IsEnded(); tracks.Next()) { - audioTrackPresent = true; - } - } + bool shouldAEC = false; + bool audioTrackPresent = AudioTrackPresent(shouldAEC); + if (!audioTrackPresent && CurrentDriver()->AsAudioCallbackDriver()) { CurrentDriver()->AsAudioCallbackDriver()-> EnqueueStreamAndPromiseForOperation(aDestinationStream, aPromise, diff --git a/dom/media/MediaStreamGraphImpl.h b/dom/media/MediaStreamGraphImpl.h index 5076daddcd6f..fe4c7e4a1d0d 100644 --- a/dom/media/MediaStreamGraphImpl.h +++ b/dom/media/MediaStreamGraphImpl.h @@ -333,6 +333,12 @@ public: void SuspendOrResumeStreams(dom::AudioContextOperation aAudioContextOperation, const nsTArray& aStreamSet); + /** + * Determine if we have any audio tracks, or are about to add any audiotracks. + * Also checks if we'll need the AEC running (i.e. microphone input tracks) + */ + bool AudioTrackPresent(bool& aNeedsAEC); + /** * Sort mStreams so that every stream not in a cycle is after any streams * it depends on, and every stream in a cycle is marked as being in a cycle.