Bug 1170958 - Refactor DOMMediaStream to contain a 3-stage track chain. r=roc

This lets us separate tracks by ownership like so:
* Input    - Owned by the producer of the DOMMediaStream (gUM etc.)
* Owned    - Contains Input tracks (per above) or tracks cloned tracks
             if this DOMMediaStream is a clone.
* Playback - Contains Owned tracks plus tracks addTrack()ed to this
             DOMMediaStream minus tracks removeTrack()ed from this
             DOMMediaStream.
This commit is contained in:
Andreas Pehrson
2015-09-25 23:23:18 +08:00
parent aa0d330301
commit 4132b4532f
25 changed files with 518 additions and 194 deletions

View File

@@ -561,7 +561,7 @@ HTMLMediaElement::GetMozMediaSourceObject() const
already_AddRefed<DOMMediaStream>
HTMLMediaElement::GetSrcObject() const
{
NS_ASSERTION(!mSrcAttrStream || mSrcAttrStream->GetStream(),
NS_ASSERTION(!mSrcAttrStream || mSrcAttrStream->GetPlaybackStream(),
"MediaStream should have been set up properly");
nsRefPtr<DOMMediaStream> stream = mSrcAttrStream;
return stream.forget();
@@ -585,7 +585,7 @@ HTMLMediaElement::SetSrcObject(DOMMediaStream* aValue)
already_AddRefed<DOMMediaStream>
HTMLMediaElement::GetMozSrcObject() const
{
NS_ASSERTION(!mSrcAttrStream || mSrcAttrStream->GetStream(),
NS_ASSERTION(!mSrcAttrStream || mSrcAttrStream->GetPlaybackStream(),
"MediaStream should have been set up properly");
nsRefPtr<DOMMediaStream> stream = mSrcAttrStream;
return stream.forget();
@@ -1876,17 +1876,17 @@ HTMLMediaElement::CaptureStreamInternal(bool aFinishWhenEnded,
mAudioCaptured = true;
if (mDecoder) {
mDecoder->AddOutputStream(out->mStream->GetStream()->AsProcessedStream(),
mDecoder->AddOutputStream(out->mStream->GetInputStream()->AsProcessedStream(),
aFinishWhenEnded);
if (mReadyState >= HAVE_METADATA) {
// Expose the tracks to JS directly.
if (HasAudio()) {
TrackID audioTrackId = mMediaInfo.mAudio.mTrackId;
out->mStream->CreateDOMTrack(audioTrackId, MediaSegment::AUDIO);
out->mStream->CreateOwnDOMTrack(audioTrackId, MediaSegment::AUDIO);
}
if (HasVideo()) {
TrackID videoTrackId = mMediaInfo.mVideo.mTrackId;
out->mStream->CreateDOMTrack(videoTrackId, MediaSegment::VIDEO);
out->mStream->CreateOwnDOMTrack(videoTrackId, MediaSegment::VIDEO);
}
}
}
@@ -2446,7 +2446,7 @@ bool HTMLMediaElement::ParseAttribute(int32_t aNamespaceID,
mAudioChannel = audioChannel;
if (mSrcStream) {
nsRefPtr<MediaStream> stream = mSrcStream->GetStream();
nsRefPtr<MediaStream> stream = GetSrcMediaStream();
if (stream) {
stream->SetAudioChannelType(mAudioChannel);
}
@@ -2861,7 +2861,7 @@ nsresult HTMLMediaElement::FinishDecoderSetup(MediaDecoder* aDecoder,
for (uint32_t i = 0; i < mOutputStreams.Length(); ++i) {
OutputMediaStream* ms = &mOutputStreams[i];
aDecoder->AddOutputStream(ms->mStream->GetStream()->AsProcessedStream(),
aDecoder->AddOutputStream(ms->mStream->GetInputStream()->AsProcessedStream(),
ms->mFinishWhenEnded);
}
@@ -3105,10 +3105,10 @@ void HTMLMediaElement::UpdateSrcMediaStreamPlaying(uint32_t aFlags)
if (!mSrcStream) {
return;
}
// We might be in cycle collection with mSrcStream->GetStream() already
// We might be in cycle collection with mSrcStream->GetPlaybackStream() already
// returning null due to unlinking.
MediaStream* stream = mSrcStream->GetStream();
MediaStream* stream = GetSrcMediaStream();
bool shouldPlay = !(aFlags & REMOVING_SRC_STREAM) && !mPaused &&
!mPausedForInactiveDocumentOrChannel && stream;
if (shouldPlay == mSrcStreamIsPlaying) {
@@ -3183,7 +3183,7 @@ void HTMLMediaElement::SetupSrcMediaStreamPlayback(DOMMediaStream* aStream)
return;
}
nsRefPtr<MediaStream> stream = mSrcStream->GetStream();
nsRefPtr<MediaStream> stream = GetSrcMediaStream();
if (stream) {
stream->SetAudioChannelType(mAudioChannel);
}
@@ -3282,11 +3282,11 @@ void HTMLMediaElement::MetadataLoaded(const MediaInfo* aInfo,
for (OutputMediaStream& out : mOutputStreams) {
if (aInfo->HasAudio()) {
TrackID audioTrackId = aInfo->mAudio.mTrackId;
out.mStream->CreateDOMTrack(audioTrackId, MediaSegment::AUDIO);
out.mStream->CreateOwnDOMTrack(audioTrackId, MediaSegment::AUDIO);
}
if (aInfo->HasVideo()) {
TrackID videoTrackId = aInfo->mVideo.mTrackId;
out.mStream->CreateDOMTrack(videoTrackId, MediaSegment::VIDEO);
out.mStream->CreateOwnDOMTrack(videoTrackId, MediaSegment::VIDEO);
}
}
@@ -4789,11 +4789,11 @@ NS_IMETHODIMP HTMLMediaElement::WindowAudioCaptureChanged()
MediaStreamGraph::GetInstance(MediaStreamGraph::AUDIO_THREAD_DRIVER,
AudioChannel::Normal);
if (mSrcStream) {
mCaptureStreamPort = msg->ConnectToCaptureStream(id, mSrcStream->GetStream());
if (GetSrcMediaStream()) {
mCaptureStreamPort = msg->ConnectToCaptureStream(id, GetSrcMediaStream());
} else {
nsRefPtr<DOMMediaStream> stream = CaptureStreamInternal(false, msg);
mCaptureStreamPort = msg->ConnectToCaptureStream(id, stream->GetStream());
mCaptureStreamPort = msg->ConnectToCaptureStream(id, stream->GetPlaybackStream());
}
} else {
mAudioCapturedByWindow = false;
@@ -4803,7 +4803,7 @@ NS_IMETHODIMP HTMLMediaElement::WindowAudioCaptureChanged()
MOZ_ASSERT(ps);
for (uint32_t i = 0; i < mOutputStreams.Length(); i++) {
if (mOutputStreams[i].mStream->GetStream() == ps) {
if (mOutputStreams[i].mStream->GetPlaybackStream() == ps) {
mOutputStreams.RemoveElementAt(i);
break;
}