Bug 1521577 - Don't block a MediaStream where at least one track is pulled. r=achronop a=lizzard
authorAndreas Pehrson <pehrsons@mozilla.com>
Mon, 28 Jan 2019 07:26:03 +0000
changeset 512758 a7206b7354fbdfba4c7f5b0d6f3909bee7f1ab36
parent 512757 63b51834cc1d92c8feb2885a613b55497e2f1b63
child 512759 97295735ed424b3a791e98cae8a34e48ad14a727
push id10587
push userarchaeopteryx@coole-files.de
push dateThu, 31 Jan 2019 10:03:18 +0000
treeherdermozilla-beta@34bde0c12172 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersachronop, lizzard
bugs1521577
milestone66.0
Bug 1521577 - Don't block a MediaStream where at least one track is pulled. r=achronop a=lizzard 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);