Bug 1447563 - Clear direct track listeners from TrackUnionStream during shutdown. r?padenot
MozReview-Commit-ID: 9PbpQpOaIIh
--- a/dom/media/MediaStreamGraph.cpp
+++ b/dom/media/MediaStreamGraph.cpp
@@ -2042,19 +2042,17 @@ MediaStream::RemoveAllListenersImpl()
mListeners.Clear();
auto trackListeners(mTrackListeners);
for (auto& l : trackListeners) {
l.mListener->NotifyRemoved();
}
mTrackListeners.Clear();
- if (SourceMediaStream* source = AsSourceStream()) {
- source->RemoveAllDirectListeners();
- }
+ RemoveAllDirectListenersImpl();
auto videoOutputs(mVideoOutputs);
for (auto& l : videoOutputs) {
l.mListener->NotifyRemoved();
}
mVideoOutputs.Clear();
}
@@ -3267,17 +3265,17 @@ SourceMediaStream::EndAllTrackAndFinish(
data->mCommands |= TrackEventCommand::TRACK_EVENT_ENDED;
}
mPendingTracks.Clear();
FinishPendingWithLockHeld();
// we will call NotifyEvent() to let GetUserMedia know
}
void
-SourceMediaStream::RemoveAllDirectListeners()
+SourceMediaStream::RemoveAllDirectListenersImpl()
{
GraphImpl()->AssertOnGraphThreadOrNotRunning();
auto directListeners(mDirectTrackListeners);
for (auto& l : directListeners) {
l.mListener->NotifyDirectListenerUninstalled();
}
mDirectTrackListeners.Clear();
--- a/dom/media/MediaStreamGraph.h
+++ b/dom/media/MediaStreamGraph.h
@@ -423,16 +423,22 @@ public:
return !mAudioOutputs.IsEmpty();
}
void RemoveAudioOutputImpl(void* aKey);
void AddVideoOutputImpl(already_AddRefed<MediaStreamVideoSink> aSink,
TrackID aID);
void RemoveVideoOutputImpl(MediaStreamVideoSink* aSink, TrackID aID);
void AddListenerImpl(already_AddRefed<MediaStreamListener> aListener);
void RemoveListenerImpl(MediaStreamListener* aListener);
+
+ /**
+ * Removes all direct listeners and signals to them that they have been
+ * uninstalled.
+ */
+ virtual void RemoveAllDirectListenersImpl() {}
void RemoveAllListenersImpl();
virtual void AddTrackListenerImpl(already_AddRefed<MediaStreamTrackListener> aListener,
TrackID aTrackID);
virtual void RemoveTrackListenerImpl(MediaStreamTrackListener* aListener,
TrackID aTrackID);
virtual void AddDirectTrackListenerImpl(already_AddRefed<DirectMediaStreamTrackListener> aListener,
TrackID aTrackID);
virtual void RemoveDirectTrackListenerImpl(DirectMediaStreamTrackListener* aListener,
@@ -796,28 +802,24 @@ public:
// Overriding allows us to ensure mMutex is locked while changing the track enable status
void
ApplyTrackDisabling(TrackID aTrackID, MediaSegment* aSegment,
MediaSegment* aRawSegment = nullptr) override {
mMutex.AssertCurrentThreadOwns();
MediaStream::ApplyTrackDisabling(aTrackID, aSegment, aRawSegment);
}
+ void RemoveAllDirectListenersImpl() override;
+
/**
* End all tracks and Finish() this stream. Used to voluntarily revoke access
* to a LocalMediaStream.
*/
void EndAllTrackAndFinish();
- /**
- * Removes all direct listeners and signals to them that they have been
- * uninstalled.
- */
- void RemoveAllDirectListeners();
-
void RegisterForAudioMixing();
/**
* Returns true if this SourceMediaStream contains at least one audio track
* that is in pending state.
* This is thread safe, and takes the SourceMediaStream mutex.
*/
bool HasPendingAudioTrack();
--- a/dom/media/TrackUnionStream.cpp
+++ b/dom/media/TrackUnionStream.cpp
@@ -476,9 +476,29 @@ TrackUnionStream::RemoveDirectTrackListe
TrackBound<DirectMediaStreamTrackListener>& bound =
mPendingDirectTrackListeners[i];
if (bound.mListener == aListener && bound.mTrackID == aTrackID) {
mPendingDirectTrackListeners.RemoveElementAt(i);
return;
}
}
}
+
+void TrackUnionStream::RemoveAllDirectListenersImpl()
+{
+ for (TrackMapEntry& entry : mTrackMap) {
+ nsTArray<RefPtr<DirectMediaStreamTrackListener>>
+ listeners(entry.mOwnedDirectListeners);
+ for (const auto& listener : listeners) {
+ RemoveDirectTrackListenerImpl(listener, entry.mOutputTrackID);
+ }
+ MOZ_DIAGNOSTIC_ASSERT(entry.mOwnedDirectListeners.IsEmpty());
+ }
+
+ nsTArray<TrackBound<DirectMediaStreamTrackListener>>
+ boundListeners(mPendingDirectTrackListeners);
+ for (const auto& binding : boundListeners) {
+ RemoveDirectTrackListenerImpl(binding.mListener, binding.mTrackID);
+ }
+ MOZ_DIAGNOSTIC_ASSERT(mPendingDirectTrackListeners.IsEmpty());
+}
+
} // namespace mozilla
--- a/dom/media/TrackUnionStream.h
+++ b/dom/media/TrackUnionStream.h
@@ -69,16 +69,17 @@ protected:
void CopyTrackData(StreamTracks::Track* aInputTrack,
uint32_t aMapIndex, GraphTime aFrom, GraphTime aTo,
bool* aOutputTrackFinished);
void AddDirectTrackListenerImpl(already_AddRefed<DirectMediaStreamTrackListener> aListener,
TrackID aTrackID) override;
void RemoveDirectTrackListenerImpl(DirectMediaStreamTrackListener* aListener,
TrackID aTrackID) override;
+ void RemoveAllDirectListenersImpl() override;
nsTArray<TrackMapEntry> mTrackMap;
// The next available TrackID, starting at 1 and progressing upwards.
// All TrackIDs in [1, mNextAvailableTrackID) have implicitly been used.
TrackID mNextAvailableTrackID;
// Sorted array of used TrackIDs that require manual tracking.