Bug 1208371 - Let FindOwnedDOMTrack operate on input stream. r?roc draft
authorAndreas Pehrson <pehrsons@gmail.com>
Tue, 05 Jan 2016 10:16:22 +0800
changeset 342092 a7a6ae42cc9b4e535f7499fb8996a8576116ae93
parent 342091 673666c006a1d8628fda55e48f6966a9d11fbb57
child 342093 ce58d9df0169e35f7e767eaa99a81268fa4c3cb7
push id13352
push userpehrsons@gmail.com
push dateFri, 18 Mar 2016 13:49:47 +0000
reviewersroc
bugs1208371
milestone47.0a1
Bug 1208371 - Let FindOwnedDOMTrack operate on input stream. r?roc This let's us use FindOwnedDOMTrack before the TrackID in mOwnedStream is known. This is necessary for a stream clone with multiple tracks whose original TrackID is the same. MozReview-Commit-ID: J3OvbiNb8X
dom/media/DOMMediaStream.cpp
dom/media/DOMMediaStream.h
--- a/dom/media/DOMMediaStream.cpp
+++ b/dom/media/DOMMediaStream.cpp
@@ -112,79 +112,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;
 };
@@ -796,17 +798,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);
@@ -825,26 +827,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; }