Bug 1073406 - Part 2. Add playback stream as output to mSrcStream for individual media element blocking. r=roc

This commit is contained in:
Andreas Pehrson 2014-12-05 00:07:00 +01:00
parent f4813a0d21
commit c685aaf155
2 changed files with 34 additions and 2 deletions

View File

@ -434,6 +434,7 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLMediaElement)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLMediaElement, nsGenericHTMLElement)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMediaSource)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSrcStream)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPlaybackStream)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSrcAttrStream)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSourcePointer)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLoadBlockedDoc)
@ -2887,6 +2888,25 @@ void HTMLMediaElement::SetupSrcMediaStreamPlayback(DOMMediaStream* aStream)
mSrcStream = aStream;
nsIDOMWindow* window = OwnerDoc()->GetInnerWindow();
if (!window) {
return;
}
// Now that we have access to |mSrcStream| we can pipe it to our shadow
// version |mPlaybackStream|. If two media elements are playing the
// same realtime DOMMediaStream, this allows them to pause playback
// independently of each other.
mPlaybackStream = DOMMediaStream::CreateTrackUnionStream(window);
mPlaybackStreamInputPort = mPlaybackStream->GetStream()->AsProcessedStream()->
AllocateInputPort(mSrcStream->GetStream(), MediaInputPort::FLAG_BLOCK_OUTPUT);
nsRefPtr<nsIPrincipal> principal = GetCurrentPrincipal();
mPlaybackStream->CombineWithPrincipal(principal);
// Let |mSrcStream| decide when the stream has finished.
GetSrcMediaStream()->AsProcessedStream()->SetAutofinish(true);
nsRefPtr<MediaStream> stream = mSrcStream->GetStream();
if (stream) {
stream->SetAudioChannelType(mAudioChannel);
@ -2933,6 +2953,8 @@ void HTMLMediaElement::EndSrcMediaStreamPlayback()
}
mSrcStream->DisconnectTrackListListeners(AudioTracks(), VideoTracks());
mPlaybackStreamInputPort->Destroy();
// Kill its reference to this element
mSrcStreamListener->Forget();
mSrcStreamListener = nullptr;
@ -2953,6 +2975,8 @@ void HTMLMediaElement::EndSrcMediaStreamPlayback()
stream->ChangeExplicitBlockerCount(-1);
}
mSrcStream = nullptr;
mPlaybackStreamInputPort = nullptr;
mPlaybackStream = nullptr;
}
void HTMLMediaElement::ProcessMediaFragmentURI()

View File

@ -338,8 +338,8 @@ public:
MediaStream* GetSrcMediaStream() const
{
NS_ASSERTION(mSrcStream, "Don't call this when not playing a stream");
return mSrcStream->GetStream();
NS_ASSERTION(mPlaybackStream, "Don't call this when not playing a stream");
return mPlaybackStream->GetStream();
}
// WebIDL
@ -997,6 +997,14 @@ protected:
// At most one of mDecoder and mSrcStream can be non-null.
nsRefPtr<DOMMediaStream> mSrcStream;
// Holds a reference to a MediaInputPort connecting mSrcStream to mPlaybackStream.
nsRefPtr<MediaInputPort> mPlaybackStreamInputPort;
// Holds a reference to a stream with mSrcStream as input but intended for
// playback. Used so we don't block playback of other video elements
// playing the same mSrcStream.
nsRefPtr<DOMMediaStream> mPlaybackStream;
// Holds references to the DOM wrappers for the MediaStreams that we're
// writing to.
struct OutputMediaStream {