Bug 1259788 - Implement disabled track modes for direct track listeners. r?jesup draft
authorAndreas Pehrson <pehrsons@gmail.com>
Tue, 23 Aug 2016 18:05:51 +0200
changeset 404934 42c3a58cc00e3891391d0f247d0c736e97d6ad44
parent 404933 991e26a8f8273a7d6ad8286d3ddc60113265b2c4
child 404935 4775534563abc8c5a1476d88e38ca698eec77608
push id27359
push userpehrsons@gmail.com
push dateWed, 24 Aug 2016 14:53:56 +0000
reviewersjesup
bugs1259788
milestone51.0a1
Bug 1259788 - Implement disabled track modes for direct track listeners. r?jesup MozReview-Commit-ID: H8TygONnCiv
dom/media/MediaStreamGraph.cpp
dom/media/MediaStreamListener.cpp
dom/media/MediaStreamListener.h
dom/media/TrackUnionStream.cpp
--- a/dom/media/MediaStreamGraph.cpp
+++ b/dom/media/MediaStreamGraph.cpp
@@ -2925,31 +2925,31 @@ SourceMediaStream::FinishWithLockHeld()
 }
 
 void
 SourceMediaStream::SetTrackEnabledImpl(TrackID aTrackID, DisabledTrackMode aMode)
 {
   {
     MutexAutoLock lock(mMutex);
     for (TrackBound<DirectMediaStreamTrackListener>& l: mDirectTrackListeners) {
-      if (l.mTrackID == aTrackID) {
-        MOZ_ASSERT(l.mListener->mMedia->GetType() == MediaSegment::AUDIO,
-                   "Must implement DisabledTrackMode support for MediaStreamTrackDirectListener for video");
-        bool oldEnabled = GetDisabledTrackMode(aTrackID) == DisabledTrackMode::ENABLED;
-        if (!oldEnabled && aMode == DisabledTrackMode::ENABLED) {
-          STREAM_LOG(LogLevel::Debug, ("SourceMediaStream %p track %d setting "
-                                       "direct listener enabled",
-                                       this, aTrackID));
-          l.mListener->DecreaseDisabled();
-        } else if (oldEnabled && aMode != DisabledTrackMode::ENABLED) {
-          STREAM_LOG(LogLevel::Debug, ("SourceMediaStream %p track %d setting "
-                                       "direct listener disabled",
-                                       this, aTrackID));
-          l.mListener->IncreaseDisabled();
-        }
+      if (l.mTrackID != aTrackID) {
+        continue;
+      }
+      DisabledTrackMode oldMode = GetDisabledTrackMode(aTrackID);
+      bool oldEnabled = oldMode == DisabledTrackMode::ENABLED;
+      if (!oldEnabled && aMode == DisabledTrackMode::ENABLED) {
+        STREAM_LOG(LogLevel::Debug, ("SourceMediaStream %p track %d setting "
+                                     "direct listener enabled",
+                                     this, aTrackID));
+        l.mListener->DecreaseDisabled(oldMode);
+      } else if (oldEnabled && aMode != DisabledTrackMode::ENABLED) {
+        STREAM_LOG(LogLevel::Debug, ("SourceMediaStream %p track %d setting "
+                                     "direct listener disabled",
+                                     this, aTrackID));
+        l.mListener->IncreaseDisabled(aMode);
       }
     }
   }
   MediaStream::SetTrackEnabledImpl(aTrackID, aMode);
 }
 
 void
 SourceMediaStream::EndAllTrackAndFinish()
--- a/dom/media/MediaStreamListener.cpp
+++ b/dom/media/MediaStreamListener.cpp
@@ -6,53 +6,111 @@
 #include "MediaStreamListener.h"
 
 #include "AudioSegment.h"
 #include "VideoSegment.h"
 #include "StreamTracks.h"
 
 namespace mozilla {
 
+#ifdef LOG
+#undef LOG
+#endif
+
+#define LOG(type, msg) MOZ_LOG(gMediaStreamGraphLog, type, msg)
+
 void
 DirectMediaStreamTrackListener::MirrorAndDisableSegment(AudioSegment& aFrom,
-                                                       AudioSegment& aTo)
+                                                        AudioSegment& aTo)
 {
   aTo.Clear();
   aTo.AppendNullData(aFrom.GetDuration());
 }
 
 void
 DirectMediaStreamTrackListener::MirrorAndDisableSegment(VideoSegment& aFrom,
-                                                       VideoSegment& aTo)
+                                                        VideoSegment& aTo,
+                                                        DisabledTrackMode aMode)
 {
   aTo.Clear();
-  for (VideoSegment::ChunkIterator it(aFrom); !it.IsEnded(); it.Next()) {
-    aTo.AppendFrame(do_AddRef(it->mFrame.GetImage()), it->GetDuration(),
-                    it->mFrame.GetIntrinsicSize(), it->GetPrincipalHandle(), true);
+  if (aMode == DisabledTrackMode::SILENCE_BLACK) {
+    for (VideoSegment::ChunkIterator it(aFrom); !it.IsEnded(); it.Next()) {
+      aTo.AppendFrame(do_AddRef(it->mFrame.GetImage()),
+                      it->GetDuration(),
+                      it->mFrame.GetIntrinsicSize(),
+                      it->GetPrincipalHandle(),
+                      true);
+    }
+  } else if (aMode == DisabledTrackMode::SILENCE_FREEZE) {
+    aTo.AppendNullData(aFrom.GetDuration());
   }
 }
 
 void
 DirectMediaStreamTrackListener::NotifyRealtimeTrackDataAndApplyTrackDisabling(MediaStreamGraph* aGraph,
                                                                              StreamTime aTrackOffset,
                                                                              MediaSegment& aMedia)
 {
-  if (mDisabledCount == 0) {
+  if (mDisabledFreezeCount == 0 && mDisabledBlackCount == 0) {
     NotifyRealtimeTrackData(aGraph, aTrackOffset, aMedia);
     return;
   }
 
+  DisabledTrackMode mode = mDisabledBlackCount > 0
+                         ? DisabledTrackMode::SILENCE_BLACK
+                         : DisabledTrackMode::SILENCE_FREEZE;
   if (!mMedia) {
     mMedia = aMedia.CreateEmptyClone();
   }
   if (aMedia.GetType() == MediaSegment::AUDIO) {
     MirrorAndDisableSegment(static_cast<AudioSegment&>(aMedia),
                             static_cast<AudioSegment&>(*mMedia));
   } else if (aMedia.GetType() == MediaSegment::VIDEO) {
     MirrorAndDisableSegment(static_cast<VideoSegment&>(aMedia),
-                            static_cast<VideoSegment&>(*mMedia));
+                            static_cast<VideoSegment&>(*mMedia),
+                            mode);
   } else {
     MOZ_CRASH("Unsupported media type");
   }
   NotifyRealtimeTrackData(aGraph, aTrackOffset, *mMedia);
 }
 
+void
+DirectMediaStreamTrackListener::IncreaseDisabled(DisabledTrackMode aMode)
+{
+  if (aMode == DisabledTrackMode::SILENCE_FREEZE) {
+    ++mDisabledFreezeCount;
+  } else if (aMode == DisabledTrackMode::SILENCE_BLACK) {
+    ++mDisabledBlackCount;
+  } else {
+    MOZ_ASSERT(false, "Unknown disabled mode");
+  }
+
+  LOG(LogLevel::Debug, ("DirectMediaStreamTrackListener %p increased disabled "
+                        "mode %s. Current counts are: freeze=%d, black=%d",
+                        this,
+                        aMode == DisabledTrackMode::SILENCE_FREEZE ? "freeze" : "black",
+                        int32_t(mDisabledFreezeCount),
+                        int32_t(mDisabledBlackCount)));
+}
+
+void
+DirectMediaStreamTrackListener::DecreaseDisabled(DisabledTrackMode aMode)
+{
+  if (aMode == DisabledTrackMode::SILENCE_FREEZE) {
+    --mDisabledFreezeCount;
+    MOZ_ASSERT(mDisabledFreezeCount >= 0, "Double decrease");
+  } else if (aMode == DisabledTrackMode::SILENCE_BLACK) {
+    --mDisabledBlackCount;
+    MOZ_ASSERT(mDisabledBlackCount >= 0, "Double decrease");
+  } else {
+    MOZ_ASSERT(false, "Unknown disabled mode");
+  }
+
+  LOG(LogLevel::Debug, ("DirectMediaStreamTrackListener %p decreased disabled "
+                        "mode %s. Current counts are: freeze=%d, black=%d",
+                        this,
+                        aMode == DisabledTrackMode::SILENCE_FREEZE ? "freeze" : "black",
+                        int32_t(mDisabledFreezeCount),
+                        int32_t(mDisabledBlackCount)));
+}
+
 } // namespace mozilla
--- a/dom/media/MediaStreamListener.h
+++ b/dom/media/MediaStreamListener.h
@@ -264,34 +264,30 @@ public:
   virtual void NotifyDirectListenerUninstalled() {}
 
   virtual MediaStreamVideoSink* AsMediaStreamVideoSink() { return nullptr; }
 
 protected:
   virtual ~DirectMediaStreamTrackListener() {}
 
   void MirrorAndDisableSegment(AudioSegment& aFrom, AudioSegment& aTo);
-  void MirrorAndDisableSegment(VideoSegment& aFrom, VideoSegment& aTo);
+  void MirrorAndDisableSegment(VideoSegment& aFrom,
+                               VideoSegment& aTo,
+                               DisabledTrackMode aMode);
   void NotifyRealtimeTrackDataAndApplyTrackDisabling(MediaStreamGraph* aGraph,
                                                      StreamTime aTrackOffset,
                                                      MediaSegment& aMedia);
 
-  void IncreaseDisabled()
-  {
-    ++mDisabledCount;
-  }
-  void DecreaseDisabled()
-  {
-    --mDisabledCount;
-    MOZ_ASSERT(mDisabledCount >= 0, "Double decrease");
-  }
+  void IncreaseDisabled(DisabledTrackMode aMode);
+  void DecreaseDisabled(DisabledTrackMode aMode);
 
   // Matches the number of disabled streams to which this listener is attached.
   // The number of streams are those between the stream the listener was added
   // and the SourceMediaStream that is the input of the data.
-  Atomic<int32_t> mDisabledCount;
+  Atomic<int32_t> mDisabledFreezeCount;
+  Atomic<int32_t> mDisabledBlackCount;
 
   nsAutoPtr<MediaSegment> mMedia;
 };
 
 } // namespace mozilla
 
 #endif // MOZILLA_MEDIASTREAMLISTENER_h_
--- a/dom/media/TrackUnionStream.cpp
+++ b/dom/media/TrackUnionStream.cpp
@@ -224,18 +224,19 @@ TrackUnionStream::TrackUnionStream() :
     for (int32_t i = mPendingDirectTrackListeners.Length() - 1; i >= 0; --i) {
       TrackBound<DirectMediaStreamTrackListener>& bound =
         mPendingDirectTrackListeners[i];
       if (bound.mTrackID != map->mOutputTrackID) {
         continue;
       }
       MediaStream* source = map->mInputPort->GetSource();
       map->mOwnedDirectListeners.AppendElement(bound.mListener);
-      if (GetDisabledTrackMode(bound.mTrackID) != DisabledTrackMode::ENABLED) {
-        bound.mListener->IncreaseDisabled();
+      DisabledTrackMode currentMode = GetDisabledTrackMode(bound.mTrackID);
+      if (currentMode != DisabledTrackMode::ENABLED) {
+        bound.mListener->IncreaseDisabled(currentMode);
       }
       STREAM_LOG(LogLevel::Debug, ("TrackUnionStream %p adding direct listener "
                                    "%p for track %d. Forwarding to input "
                                    "stream %p track %d.",
                                    this, bound.mListener.get(), bound.mTrackID,
                                    source, map->mInputTrackID));
       source->AddDirectTrackListenerImpl(bound.mListener.forget(),
                                          map->mInputTrackID);
@@ -347,27 +348,28 @@ TrackUnionStream::TrackUnionStream() :
 void
 TrackUnionStream::SetTrackEnabledImpl(TrackID aTrackID, DisabledTrackMode aMode) {
   bool enabled = aMode == DisabledTrackMode::ENABLED;
   for (TrackMapEntry& entry : mTrackMap) {
     if (entry.mOutputTrackID == aTrackID) {
       STREAM_LOG(LogLevel::Info, ("TrackUnionStream %p track %d was explicitly %s",
                                    this, aTrackID, enabled ? "enabled" : "disabled"));
       for (DirectMediaStreamTrackListener* listener : entry.mOwnedDirectListeners) {
-        bool oldEnabled = GetDisabledTrackMode(aTrackID) == DisabledTrackMode::ENABLED;
+        DisabledTrackMode oldMode = GetDisabledTrackMode(aTrackID);
+        bool oldEnabled = oldMode == DisabledTrackMode::ENABLED;
         if (!oldEnabled && enabled) {
           STREAM_LOG(LogLevel::Debug, ("TrackUnionStream %p track %d setting "
                                        "direct listener enabled",
                                        this, aTrackID));
-          listener->DecreaseDisabled();
+          listener->DecreaseDisabled(oldMode);
         } else if (oldEnabled && !enabled) {
           STREAM_LOG(LogLevel::Debug, ("TrackUnionStream %p track %d setting "
                                        "direct listener disabled",
                                        this, aTrackID));
-          listener->IncreaseDisabled();
+          listener->IncreaseDisabled(aMode);
         }
       }
     }
   }
   MediaStream::SetTrackEnabledImpl(aTrackID, aMode);
 }
 
 MediaStream*
@@ -404,18 +406,19 @@ TrackUnionStream::AddDirectTrackListener
     if (entry.mOutputTrackID == aTrackID) {
       MediaStream* source = entry.mInputPort->GetSource();
       STREAM_LOG(LogLevel::Debug, ("TrackUnionStream %p adding direct listener "
                                    "%p for track %d. Forwarding to input "
                                    "stream %p track %d.",
                                    this, listener.get(), aTrackID, source,
                                    entry.mInputTrackID));
       entry.mOwnedDirectListeners.AppendElement(listener);
-      if (GetDisabledTrackMode(aTrackID) != DisabledTrackMode::ENABLED) {
-        listener->IncreaseDisabled();
+      DisabledTrackMode currentMode = GetDisabledTrackMode(aTrackID);
+      if (currentMode != DisabledTrackMode::ENABLED) {
+        listener->IncreaseDisabled(currentMode);
       }
       source->AddDirectTrackListenerImpl(listener.forget(),
                                          entry.mInputTrackID);
       return;
     }
   }
 
   TrackBound<DirectMediaStreamTrackListener>* bound =
@@ -436,19 +439,20 @@ TrackUnionStream::RemoveDirectTrackListe
     for (size_t i = 0; i < entry.mOwnedDirectListeners.Length(); ++i) {
       if (entry.mOwnedDirectListeners[i] == aListener) {
         STREAM_LOG(LogLevel::Debug, ("TrackUnionStream %p removing direct "
                                      "listener %p for track %d, forwarding "
                                      "to input stream %p track %d",
                                      this, aListener, aTrackID,
                                      entry.mInputPort->GetSource(),
                                      entry.mInputTrackID));
-        if (GetDisabledTrackMode(aTrackID) != DisabledTrackMode::ENABLED) {
+        DisabledTrackMode currentMode = GetDisabledTrackMode(aTrackID);
+        if (currentMode != DisabledTrackMode::ENABLED) {
           // Reset the listener's state.
-          aListener->DecreaseDisabled();
+          aListener->DecreaseDisabled(currentMode);
         }
         entry.mOwnedDirectListeners.RemoveElementAt(i);
         break;
       }
     }
     // Forward to the input
     MediaStream* source = entry.mInputPort->GetSource();
     source->RemoveDirectTrackListenerImpl(aListener, entry.mInputTrackID);