Bug 1521577 - Don't block a MediaStream where at least one track is pulled. r=achronop
authorAndreas Pehrson <pehrsons@mozilla.com>
Mon, 28 Jan 2019 07:26:03 +0000
changeset 455600 a21454f433a1c9dfd88e75db4a3ea08fe8f2c560
parent 455599 5d9c5aa981a5b824e6132c923c2f201b3fa49397
child 455601 ee85b1ccaa18e47a0c56b5b0fe8408cfc4a20181
push id76876
push userpehrsons@gmail.com
push dateMon, 28 Jan 2019 07:29:51 +0000
treeherderautoland@a21454f433a1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersachronop
bugs1521577
milestone66.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 1521577 - Don't block a MediaStream where at least one track is pulled. r=achronop With the per-track pulling settings we have today it is clearly the intention of the producer to start consuming a track that has pulling enabled, even if there are other tracks where pulling is disabled. This patch fixes that, so that when a stream has at least one pulled track it will append null data to other tracks (commonly video) if they are lacking data. This means that we still block an entire stream if all tracks have pulling disabled - to maintain the status quo for media element capture, which is the only push-only producer of data. Differential Revision: https://phabricator.services.mozilla.com/D17611
dom/media/MediaStreamGraph.cpp
--- a/dom/media/MediaStreamGraph.cpp
+++ b/dom/media/MediaStreamGraph.cpp
@@ -2534,31 +2534,48 @@ void SourceMediaStream::SetPullingEnable
 }
 
 bool SourceMediaStream::PullNewData(GraphTime aDesiredUpToTime) {
   TRACE_AUDIO_CALLBACK_COMMENT("SourceMediaStream %p", this);
   MutexAutoLock lock(mMutex);
   if (mFinished) {
     return false;
   }
+  bool streamPullingEnabled = false;
+  for (const TrackData& track : mUpdateTracks) {
+    if (!(track.mCommands & TrackEventCommand::TRACK_EVENT_ENDED) &&
+        track.mPullingEnabled) {
+      // At least one track in this stream is pulled. We want to consume it in
+      // real-time (i.e., not block the stream).
+      streamPullingEnabled = true;
+      break;
+    }
+  }
   // Compute how much stream time we'll need assuming we don't block
   // the stream at all.
   StreamTime t = GraphTimeToStreamTime(aDesiredUpToTime);
-  StreamTime current = mTracks.GetEarliestTrackEnd();
   for (const TrackData& track : mUpdateTracks) {
-    if (!track.mPullingEnabled) {
-      continue;
-    }
     if (track.mCommands & TrackEventCommand::TRACK_EVENT_ENDED) {
       continue;
     }
-    current = track.mEndOfFlushedData + track.mData->GetDuration();
+    StreamTime current = track.mEndOfFlushedData + track.mData->GetDuration();
     if (t <= current) {
       continue;
     }
+    if (!track.mPullingEnabled) {
+      if (streamPullingEnabled) {
+        LOG(LogLevel::Verbose,
+            ("%p: Pulling disabled for track but enabled for stream, append "
+             "null data; stream=%p track=%d t=%f current end=%f",
+             GraphImpl(), this, track.mID, GraphImpl()->MediaTimeToSeconds(t),
+             GraphImpl()->MediaTimeToSeconds(current)));
+        track.mData->AppendNullData(t - current);
+      }
+      continue;
+    }
     LOG(LogLevel::Verbose,
         ("%p: Calling NotifyPull stream=%p track=%d t=%f current end=%f",
          GraphImpl(), this, track.mID, GraphImpl()->MediaTimeToSeconds(t),
          GraphImpl()->MediaTimeToSeconds(current)));
     MutexAutoUnlock unlock(mMutex);
     for (TrackBound<MediaStreamTrackListener>& l : mTrackListeners) {
       if (l.mTrackID == track.mID) {
         l.mListener->NotifyPull(Graph(), current, t);