Bug 1592287 - Remove ended captureStream tracks and fire "removetrack" on MediaStream. r=jib

Differential Revision: https://phabricator.services.mozilla.com/D52816

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Andreas Pehrson 2019-11-20 15:24:10 +00:00
Родитель 483606f0fa
Коммит 67229e8a27
4 изменённых файлов: 47 добавлений и 0 удалений

Просмотреть файл

@ -897,6 +897,8 @@ void ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
HTMLMediaElement::OutputMediaStream& aField,
const char* aName, uint32_t aFlags) {
ImplCycleCollectionTraverse(aCallback, aField.mStream, "mStream", aFlags);
ImplCycleCollectionTraverse(aCallback, aField.mLiveTracks, "mLiveTracks",
aFlags);
ImplCycleCollectionTraverse(aCallback, aField.mFinishWhenEndedLoadingSrc,
"mFinishWhenEndedLoadingSrc", aFlags);
ImplCycleCollectionTraverse(aCallback, aField.mFinishWhenEndedAttrStream,
@ -905,6 +907,7 @@ void ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
void ImplCycleCollectionUnlink(HTMLMediaElement::OutputMediaStream& aField) {
ImplCycleCollectionUnlink(aField.mStream);
ImplCycleCollectionUnlink(aField.mLiveTracks);
ImplCycleCollectionUnlink(aField.mFinishWhenEndedLoadingSrc);
ImplCycleCollectionUnlink(aField.mFinishWhenEndedAttrStream);
}
@ -3326,6 +3329,8 @@ void HTMLMediaElement::AddOutputTrackSourceToOutputStream(
aSource->Track(), aSource);
}
aOutputStream.mLiveTracks.AppendElement(domTrack);
switch (aMode) {
case AddTrackMode::ASYNC:
mMainThreadEventTarget->Dispatch(
@ -3413,6 +3418,27 @@ void HTMLMediaElement::UpdateOutputTrackSources() {
NewRunnableMethod("MediaElementTrackSource::OverrideEnded", source,
&MediaElementTrackSource::OverrideEnded));
// Remove the track from the MediaStream after it ended.
for (OutputMediaStream& ms : mOutputStreams) {
if (source->Track()->mType == MediaSegment::VIDEO &&
ms.mCapturingAudioOnly) {
continue;
}
DebugOnly<size_t> length = ms.mLiveTracks.Length();
ms.mLiveTracks.RemoveElementsBy(
[&](const RefPtr<MediaStreamTrack>& aTrack) {
if (&aTrack->GetSource() != source) {
return false;
}
mMainThreadEventTarget->Dispatch(
NewRunnableMethod<RefPtr<MediaStreamTrack>>(
"DOMMediaStream::RemoveTrackInternal", ms.mStream,
&DOMMediaStream::RemoveTrackInternal, aTrack));
return true;
});
MOZ_ASSERT(ms.mLiveTracks.Length() == length - 1);
}
mOutputTrackSources.Remove(id);
}

Просмотреть файл

@ -123,6 +123,7 @@ class HTMLMediaElement : public nsGenericHTMLElement,
~OutputMediaStream();
RefPtr<DOMMediaStream> mStream;
nsTArray<RefPtr<MediaStreamTrack>> mLiveTracks;
const bool mCapturingAudioOnly;
const bool mFinishWhenEnded;
// If mFinishWhenEnded is true, this is the URI of the first resource

Просмотреть файл

@ -397,6 +397,16 @@ void DOMMediaStream::AddTrackInternal(MediaStreamTrack* aTrack) {
DispatchTrackEvent(NS_LITERAL_STRING("addtrack"), aTrack);
}
void DOMMediaStream::RemoveTrackInternal(MediaStreamTrack* aTrack) {
LOG(LogLevel::Debug,
("DOMMediaStream %p Removing owned track %p", this, aTrack));
if (!HasTrack(*aTrack)) {
return;
}
RemoveTrack(*aTrack);
DispatchTrackEvent(NS_LITERAL_STRING("removetrack"), aTrack);
}
already_AddRefed<nsIPrincipal> DOMMediaStream::GetPrincipal() {
nsCOMPtr<nsIPrincipal> principal =
nsGlobalWindowInner::Cast(mWindow)->GetPrincipal();

Просмотреть файл

@ -171,6 +171,16 @@ class DOMMediaStream : public DOMEventTargetHelper,
*/
void AddTrackInternal(MediaStreamTrack* aTrack);
/**
* Removes a MediaStreamTrack from mTracks and fires "removetrack" if it
* was removed.
*
* Note that "removetrack" is raised synchronously and only has an effect if
* this MediaStream is already exposed to script. For spec compliance this is
* to be called from an async task.
*/
void RemoveTrackInternal(MediaStreamTrack* aTrack);
/**
* Add an nsISupports object that this stream will keep alive as long as
* the stream itself is alive.