diff --git a/content/html/content/src/HTMLMediaElement.cpp b/content/html/content/src/HTMLMediaElement.cpp index 0beaa9bfed36..4d210a7bb35d 100755 --- a/content/html/content/src/HTMLMediaElement.cpp +++ b/content/html/content/src/HTMLMediaElement.cpp @@ -2843,6 +2843,8 @@ void HTMLMediaElement::SetupSrcMediaStreamPlayback(DOMMediaStream* aStream) GetSrcMediaStream()->AddVideoOutput(container); } + // Note: we must call DisconnectTrackListListeners(...) before dropping + // mSrcStream mSrcStream->ConstructMediaTracks(AudioTracks(), VideoTracks()); ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_METADATA); @@ -2859,6 +2861,8 @@ void HTMLMediaElement::EndSrcMediaStreamPlayback() if (stream) { stream->RemoveListener(mSrcStreamListener); } + mSrcStream->DisconnectTrackListListeners(AudioTracks(), VideoTracks()); + // Kill its reference to this element mSrcStreamListener->Forget(); mSrcStreamListener = nullptr; diff --git a/content/media/DOMMediaStream.cpp b/content/media/DOMMediaStream.cpp index b6fcace53396..206859df9407 100644 --- a/content/media/DOMMediaStream.cpp +++ b/content/media/DOMMediaStream.cpp @@ -452,6 +452,19 @@ DOMMediaStream::ConstructMediaTracks(AudioTrackList* aAudioTrackList, } } +void +DOMMediaStream::DisconnectTrackListListeners(const AudioTrackList* aAudioTrackList, + const VideoTrackList* aVideoTrackList) +{ + for (auto i = mMediaTrackListListeners.Length(); i > 0; ) { // unsigned! + --i; // 0 ... Length()-1 range + if (mMediaTrackListListeners[i].mMediaTrackList == aAudioTrackList || + mMediaTrackListListeners[i].mMediaTrackList == aVideoTrackList) { + mMediaTrackListListeners.RemoveElementAt(i); + } + } +} + void DOMMediaStream::NotifyMediaStreamTrackCreated(MediaStreamTrack* aTrack) { diff --git a/content/media/DOMMediaStream.h b/content/media/DOMMediaStream.h index 07aa74379cc2..8160746d157e 100644 --- a/content/media/DOMMediaStream.h +++ b/content/media/DOMMediaStream.h @@ -242,6 +242,12 @@ public: void ConstructMediaTracks(AudioTrackList* aAudioTrackList, VideoTrackList* aVideoTrackList); + /** + * MUST call this before the AudioTrackList or VideoTrackList go away + */ + void DisconnectTrackListListeners(const AudioTrackList* aAudioTrackList, + const VideoTrackList* aVideoTrackList); + virtual void NotifyMediaStreamTrackCreated(MediaStreamTrack* aTrack); virtual void NotifyMediaStreamTrackEnded(MediaStreamTrack* aTrack); diff --git a/content/media/MediaTrackList.h b/content/media/MediaTrackList.h index 1ee16e01a54c..ba2c2411567f 100644 --- a/content/media/MediaTrackList.h +++ b/content/media/MediaTrackList.h @@ -10,6 +10,8 @@ #include "mozilla/DOMEventTargetHelper.h" namespace mozilla { +class DOMMediaStream; + namespace dom { class HTMLMediaElement; @@ -28,6 +30,8 @@ class MediaTrackList; class MediaTrackListListener { public: + friend class mozilla::DOMMediaStream; + explicit MediaTrackListListener(MediaTrackList* aMediaTrackList) : mMediaTrackList(aMediaTrackList) {};