Bug 1576938 - Allow a live MediaStreamTrack to be created with a destroyed input stream. r=karlt
authorAndreas Pehrson <apehrson@mozilla.com>
Thu, 29 Aug 2019 23:45:04 +0000
changeset 551371 2f4ccf9252b971b8dc165ea86848d91a5d274acf
parent 551370 e830fea4c442f23ee56f4c33ddb42666df0f6e7a
child 551372 087b063910da4bb4d7d346e4a75404bf55de6da7
push id11865
push userbtara@mozilla.com
push dateMon, 02 Sep 2019 08:54:37 +0000
treeherdermozilla-beta@37f59c4671b3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskarlt
bugs1576938
milestone70.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1576938 - Allow a live MediaStreamTrack to be created with a destroyed input stream. r=karlt This is a valid use case when cloning a MediaStreamTrack, if the source track of the clone has had its input stream destroyed out-of-band and that change hasn't been asynchronously communicated to the source track yet, i.e., it's still live. Depends on D44019 Differential Revision: https://phabricator.services.mozilla.com/D44020
dom/media/MediaStreamTrack.cpp
dom/media/MediaStreamTrack.h
--- a/dom/media/MediaStreamTrack.cpp
+++ b/dom/media/MediaStreamTrack.cpp
@@ -183,32 +183,42 @@ class MediaStreamTrack::TrackSink : publ
 
 MediaStreamTrack::MediaStreamTrack(nsPIDOMWindowInner* aWindow,
                                    MediaStream* aInputStream, TrackID aTrackID,
                                    MediaStreamTrackSource* aSource,
                                    MediaStreamTrackState aReadyState,
                                    const MediaTrackConstraints& aConstraints)
     : mWindow(aWindow),
       mInputStream(aInputStream),
-      mStream(aReadyState == MediaStreamTrackState::Live
-                  ? mInputStream->Graph()->CreateTrackUnionStream()
-                  : nullptr),
-      mPort(mStream ? mStream->AllocateInputPort(mInputStream) : nullptr),
       mTrackID(aTrackID),
       mSource(aSource),
       mSink(MakeUnique<TrackSink>(this)),
       mPrincipal(aSource->GetPrincipal()),
       mReadyState(aReadyState),
       mEnabled(true),
       mMuted(false),
       mConstraints(aConstraints) {
   if (!Ended()) {
-    MOZ_DIAGNOSTIC_ASSERT(!mInputStream->IsDestroyed());
     GetSource().RegisterSink(mSink.get());
 
+    // Even if the input stream is destroyed we need mStream so that methods
+    // like AddListener still work. Keeping the number of paths to a minimum
+    // also helps prevent bugs elsewhere. We'll be ended through the
+    // MediaStreamTrackSource soon enough.
+    auto graph = mInputStream->IsDestroyed()
+                     ? MediaStreamGraph::GetInstanceIfExists(
+                           mWindow, mInputStream->GraphRate())
+                     : mInputStream->Graph();
+    MOZ_DIAGNOSTIC_ASSERT(graph,
+                          "A destroyed input stream is only expected when "
+                          "cloning, but since we're live there must be another "
+                          "live track that is keeping the graph alive");
+
+    mStream = graph->CreateTrackUnionStream();
+    mPort = mStream->AllocateInputPort(mInputStream);
     mMSGListener = new MSGListener(this);
     AddListener(mMSGListener);
   }
 
   nsresult rv;
   nsCOMPtr<nsIUUIDGenerator> uuidgen =
       do_GetService("@mozilla.org/uuid-generator;1", &rv);
 
--- a/dom/media/MediaStreamTrack.h
+++ b/dom/media/MediaStreamTrack.h
@@ -616,20 +616,21 @@ class MediaStreamTrack : public DOMEvent
 
   // We need this to track our parent object.
   nsCOMPtr<nsPIDOMWindowInner> mWindow;
 
   // The input MediaStream assigned us by the data producer.
   // Owned by the producer.
   const RefPtr<MediaStream> mInputStream;
   // The MediaStream representing this MediaStreamTrack in the MediaStreamGraph.
-  // Valid until we end. Owned by us.
+  // Set on construction if we're live. Valid until we end. Owned by us.
   RefPtr<ProcessedMediaStream> mStream;
-  // The MediaInputPort connecting mInputStream to mStream. Valid until we end.
-  // Owned by us.
+  // The MediaInputPort connecting mInputStream to mStream. Set on construction
+  // if mInputStream is non-destroyed and we're live. Valid until we end. Owned
+  // by us.
   RefPtr<MediaInputPort> mPort;
   // The TrackID of this track in mInputStream and mStream.
   const TrackID mTrackID;
   RefPtr<MediaStreamTrackSource> mSource;
   const UniquePtr<TrackSink> mSink;
   nsCOMPtr<nsIPrincipal> mPrincipal;
   nsCOMPtr<nsIPrincipal> mPendingPrincipal;
   RefPtr<MSGListener> mMSGListener;