--- a/dom/media/DOMMediaStream.cpp
+++ b/dom/media/DOMMediaStream.cpp
@@ -119,79 +119,81 @@ NS_IMPL_CYCLE_COLLECTION_0(MediaStreamTr
class DOMMediaStream::OwnedStreamListener : public MediaStreamListener {
public:
explicit OwnedStreamListener(DOMMediaStream* aStream)
: mStream(aStream)
{}
void Forget() { mStream = nullptr; }
- void DoNotifyTrackCreated(TrackID aTrackId, MediaSegment::Type aType)
+ void DoNotifyTrackCreated(TrackID aTrackID, MediaSegment::Type aType,
+ MediaStream* aInputStream, TrackID aInputTrackID)
{
MOZ_ASSERT(NS_IsMainThread());
if (!mStream) {
return;
}
- MediaStreamTrack* track = mStream->FindOwnedDOMTrack(
- mStream->GetOwnedStream(), aTrackId);
+ MediaStreamTrack* track =
+ mStream->FindOwnedDOMTrack(aInputStream, aInputTrackID);
if (!track) {
// Track had not been created on main thread before, create it now.
NS_WARN_IF_FALSE(!mStream->mTracks.IsEmpty(),
"A new track was detected on the input stream; creating "
"a corresponding MediaStreamTrack. Initial tracks "
"should be added manually to immediately and "
"synchronously be available to JS.");
RefPtr<MediaStreamTrackSource> source;
if (mStream->mTrackSourceGetter) {
- source = mStream->mTrackSourceGetter->GetMediaStreamTrackSource(aTrackId);
+ source = mStream->mTrackSourceGetter->GetMediaStreamTrackSource(aTrackID);
}
if (!source) {
NS_ASSERTION(false, "Dynamic track created without an explicit TrackSource");
source = new BasicUnstoppableTrackSource();
}
- track = mStream->CreateOwnDOMTrack(aTrackId, aType, nsString(), source);
+ track = mStream->CreateOwnDOMTrack(aTrackID, aType, nsString(), source);
}
}
- void DoNotifyTrackEnded(TrackID aTrackId)
+ void DoNotifyTrackEnded(MediaStream* aInputStream, TrackID aInputTrackID)
{
MOZ_ASSERT(NS_IsMainThread());
if (!mStream) {
return;
}
RefPtr<MediaStreamTrack> track =
- mStream->FindOwnedDOMTrack(mStream->GetOwnedStream(), aTrackId);
+ mStream->FindOwnedDOMTrack(aInputStream, aInputTrackID);
NS_ASSERTION(track, "Owned MediaStreamTracks must be known by the DOMMediaStream");
if (track) {
LOG(LogLevel::Debug, ("DOMMediaStream %p MediaStreamTrack %p ended at the source. Marking it ended.",
mStream, track.get()));
track->NotifyEnded();
}
}
void NotifyQueuedTrackChanges(MediaStreamGraph* aGraph, TrackID aID,
StreamTime aTrackOffset, uint32_t aTrackEvents,
const MediaSegment& aQueuedMedia,
MediaStream* aInputStream,
TrackID aInputTrackID) override
{
if (aTrackEvents & TRACK_EVENT_CREATED) {
nsCOMPtr<nsIRunnable> runnable =
- NS_NewRunnableMethodWithArgs<TrackID, MediaSegment::Type>(
+ NS_NewRunnableMethodWithArgs<TrackID, MediaSegment::Type, MediaStream*, TrackID>(
this, &OwnedStreamListener::DoNotifyTrackCreated,
- aID, aQueuedMedia.GetType());
+ aID, aQueuedMedia.GetType(), aInputStream, aInputTrackID);
aGraph->DispatchToMainThreadAfterStreamStateUpdate(runnable.forget());
} else if (aTrackEvents & TRACK_EVENT_ENDED) {
nsCOMPtr<nsIRunnable> runnable =
- NS_NewRunnableMethodWithArgs<TrackID>(
- this, &OwnedStreamListener::DoNotifyTrackEnded, aID);
+ NS_NewRunnableMethodWithArgs<MediaStream*, TrackID>(
+ this, &OwnedStreamListener::DoNotifyTrackEnded,
+ aInputStream, aInputTrackID);
aGraph->DispatchToMainThreadAfterStreamStateUpdate(runnable.forget());
}
}
private:
// These fields may only be accessed on the main thread
DOMMediaStream* mStream;
};
@@ -803,17 +805,17 @@ DOMMediaStream::RemovePrincipalChangeObs
MediaStreamTrack*
DOMMediaStream::CreateOwnDOMTrack(TrackID aTrackID, MediaSegment::Type aType,
const nsString& aLabel,
MediaStreamTrackSource* aSource)
{
MOZ_RELEASE_ASSERT(mInputStream);
MOZ_RELEASE_ASSERT(mOwnedStream);
- MOZ_ASSERT(FindOwnedDOMTrack(GetOwnedStream(), aTrackID) == nullptr);
+ MOZ_ASSERT(FindOwnedDOMTrack(GetInputStream(), aTrackID) == nullptr);
MediaStreamTrack* track;
switch (aType) {
case MediaSegment::AUDIO:
track = new AudioStreamTrack(this, aTrackID, aTrackID, aLabel, aSource);
break;
case MediaSegment::VIDEO:
track = new VideoStreamTrack(this, aTrackID, aTrackID, aLabel, aSource);
@@ -832,26 +834,26 @@ DOMMediaStream::CreateOwnDOMTrack(TrackI
new TrackPort(mPlaybackPort, track, TrackPort::InputPortOwnership::EXTERNAL);
mTracks.AppendElement(playbackTrackPort.forget());
NotifyTrackAdded(track);
return track;
}
MediaStreamTrack*
-DOMMediaStream::FindOwnedDOMTrack(MediaStream* aOwningStream, TrackID aTrackID) const
+DOMMediaStream::FindOwnedDOMTrack(MediaStream* aInputStream,
+ TrackID aInputTrackID) const
{
MOZ_RELEASE_ASSERT(mOwnedStream);
- if (aOwningStream != mOwnedStream) {
- return nullptr;
- }
-
for (const RefPtr<TrackPort>& info : mOwnedTracks) {
- if (info->GetTrack()->GetTrackID() == aTrackID) {
+ if (info->GetInputPort() &&
+ info->GetInputPort()->GetSource() == aInputStream &&
+ info->GetTrack()->GetInputTrackID() == aInputTrackID) {
+ // This track is owned externally but in our playback stream.
return info->GetTrack();
}
}
return nullptr;
}
MediaStreamTrack*
DOMMediaStream::FindPlaybackDOMTrack(MediaStream* aInputStream, TrackID aInputTrackID) const
--- a/dom/media/DOMMediaStream.h
+++ b/dom/media/DOMMediaStream.h
@@ -369,23 +369,27 @@ public:
/**
* Returns true if this DOMMediaStream owns aTrack.
*/
bool OwnsTrack(const MediaStreamTrack& aTrack) const;
/**
* Returns the corresponding MediaStreamTrack if it's in our mOwnedStream.
+ * aInputTrackID should match the track's TrackID in its input stream.
*/
- MediaStreamTrack* FindOwnedDOMTrack(MediaStream* aOwningStream, TrackID aTrackID) const;
+ MediaStreamTrack* FindOwnedDOMTrack(MediaStream* aOwningStream,
+ TrackID aInputTrackID) const;
/**
* Returns the corresponding MediaStreamTrack if it's in our mPlaybackStream.
+ * aInputTrackID should match the track's TrackID in its owned stream.
*/
- MediaStreamTrack* FindPlaybackDOMTrack(MediaStream* aOwningStream, TrackID aTrackID) const;
+ MediaStreamTrack* FindPlaybackDOMTrack(MediaStream* aOwningStream,
+ TrackID aInputTrackID) const;
/**
* Returns the TrackPort connecting mOwnedStream to mPlaybackStream for aTrack.
*/
TrackPort* FindPlaybackTrackPort(const MediaStreamTrack& aTrack) const;
MediaStream* GetInputStream() const { return mInputStream; }
ProcessedMediaStream* GetOwnedStream() const { return mOwnedStream; }