From 08fd4e2d721446f818c00e5309cc3ff1f1008563 Mon Sep 17 00:00:00 2001 From: Randell Jesup Date: Sun, 6 Jan 2013 21:31:30 -0500 Subject: [PATCH] Bug 827007: Implement Stop for UserMediaStreams; add NotifyRemoved for MediaStream listeners r=roc --- content/media/MediaStreamGraph.cpp | 21 +++++++++++++++++++++ content/media/MediaStreamGraph.h | 13 +++++++++---- dom/media/MediaManager.cpp | 10 ++++++++++ 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/content/media/MediaStreamGraph.cpp b/content/media/MediaStreamGraph.cpp index e1b543f9400a..329cfbad5ae7 100644 --- a/content/media/MediaStreamGraph.cpp +++ b/content/media/MediaStreamGraph.cpp @@ -1776,9 +1776,21 @@ MediaStream::FinishOnGraphThread() GraphImpl()->FinishStream(this); } +void +MediaStream::RemoveAllListenersImpl() +{ + for (int32_t i = mListeners.Length() - 1; i >= 0; --i) { + nsRefPtr listener = mListeners[i].forget(); + listener->NotifyRemoved(GraphImpl()); + } + mListeners.Clear(); +} + void MediaStream::DestroyImpl() { + RemoveAllListenersImpl(); + for (int32_t i = mConsumers.Length() - 1; i >= 0; --i) { mConsumers[i]->Disconnect(); } @@ -1961,6 +1973,15 @@ MediaStream::AddListener(MediaStreamListener* aListener) GraphImpl()->AppendMessage(new Message(this, aListener)); } +void +MediaStream::RemoveListenerImpl(MediaStreamListener* aListener) +{ + // wouldn't need this if we could do it in the opposite order + nsRefPtr listener(aListener); + mListeners.RemoveElement(aListener); + listener->NotifyRemoved(GraphImpl()); +} + void MediaStream::RemoveListener(MediaStreamListener* aListener) { diff --git a/content/media/MediaStreamGraph.h b/content/media/MediaStreamGraph.h index 7093a7239d12..b3039b6b85c6 100644 --- a/content/media/MediaStreamGraph.h +++ b/content/media/MediaStreamGraph.h @@ -143,6 +143,12 @@ public: */ virtual void NotifyFinished(MediaStreamGraph* aGraph) {} + /** + * Notify that your listener has been removed, either due to RemoveListener(), + * or due to the stream being destroyed. You will get no further notifications. + */ + virtual void NotifyRemoved(MediaStreamGraph* aGraph) {} + enum { TRACK_EVENT_CREATED = 0x01, TRACK_EVENT_ENDED = 0x02 @@ -363,10 +369,9 @@ public: mExplicitBlockerCount.SetAtAndAfter(aTime, mExplicitBlockerCount.GetAt(aTime) + aDelta); } void AddListenerImpl(already_AddRefed aListener); - void RemoveListenerImpl(MediaStreamListener* aListener) - { - mListeners.RemoveElement(aListener); - } + void RemoveListenerImpl(MediaStreamListener* aListener); + void RemoveAllListenersImpl(); + void AddConsumer(MediaInputPort* aPort) { mConsumers.AppendElement(aPort); diff --git a/dom/media/MediaManager.cpp b/dom/media/MediaManager.cpp index d35d3d0adf45..bd79518115fc 100644 --- a/dom/media/MediaManager.cpp +++ b/dom/media/MediaManager.cpp @@ -241,6 +241,8 @@ public: virtual ~nsDOMUserMediaStream() { + Stop(); + if (mPort) { mPort->Destroy(); } @@ -249,6 +251,14 @@ public: } } + NS_IMETHODIMP Stop() + { + if (mSourceStream) { + mSourceStream->EndAllTrackAndFinish(); + } + return NS_OK; + } + // The actual MediaStream is a TrackUnionStream. But these resources need to be // explicitly destroyed too. nsRefPtr mSourceStream;