Bug 1201363 - Register MediaStreamVideoSink into SourceMediaStream. r=jesup
authorctai <ctai@mozilla.com>
Mon, 30 May 2016 11:32:23 +0800
changeset 308254 8248c1bc1b17f0ab1b3090bd61493410f81cc546
parent 308253 94a4304e69df741186ec14a9994bfa8adee62261
child 308255 8ec3f1abad0a0773d924f95c2053b855fe4cfd54
push id31092
push usercbook@mozilla.com
push dateFri, 05 Aug 2016 10:16:59 +0000
treeherderautoland@b97dd7dd3cb9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjesup
bugs1201363
milestone51.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 1201363 - Register MediaStreamVideoSink into SourceMediaStream. r=jesup MozReview-Commit-ID: 7X546VXVLJT
dom/media/MediaStreamGraph.cpp
dom/media/MediaStreamListener.h
dom/media/MediaStreamVideoSink.h
--- a/dom/media/MediaStreamGraph.cpp
+++ b/dom/media/MediaStreamGraph.cpp
@@ -18,16 +18,17 @@
 #include "mozilla/Attributes.h"
 #include "TrackUnionStream.h"
 #include "ImageContainer.h"
 #include "AudioCaptureStream.h"
 #include "AudioChannelService.h"
 #include "AudioNodeStream.h"
 #include "AudioNodeExternalInputStream.h"
 #include "MediaStreamListener.h"
+#include "MediaStreamVideoSink.h"
 #include "mozilla/dom/AudioContextBinding.h"
 #include "mozilla/media/MediaUtils.h"
 #include <algorithm>
 #include "GeckoProfiler.h"
 #include "VideoFrameContainer.h"
 #include "mozilla/unused.h"
 #include "mozilla/media/MediaUtils.h"
 #ifdef MOZ_WEBRTC
@@ -2282,16 +2283,18 @@ MediaStream::AddVideoOutputImpl(already_
      if (entry.mListener == sink &&
          (entry.mTrackID == TRACK_ANY || entry.mTrackID == aID)) {
        return;
      }
    }
    TrackBound<MediaStreamVideoSink>* l = mVideoOutputs.AppendElement();
    l->mListener = sink;
    l->mTrackID = aID;
+
+   AddDirectTrackListenerImpl(sink.forget(), aID);
 }
 
 void
 MediaStream::RemoveVideoOutputImpl(MediaStreamVideoSink* aSink,
                                    TrackID aID)
 {
   STREAM_LOG(LogLevel::Info, ("MediaStream %p Removing MediaStreamVideoSink %p as output",
                               this, aSink));
@@ -2302,16 +2305,18 @@ MediaStream::RemoveVideoOutputImpl(Media
   aSink->ClearFrames();
   for (size_t i = 0; i < mVideoOutputs.Length(); ++i) {
     if (mVideoOutputs[i].mListener == aSink &&
         (mVideoOutputs[i].mTrackID == TRACK_ANY ||
          mVideoOutputs[i].mTrackID == aID)) {
       mVideoOutputs.RemoveElementAt(i);
     }
   }
+
+  RemoveDirectTrackListenerImpl(aSink, aID);
 }
 
 void
 MediaStream::AddVideoOutput(MediaStreamVideoSink* aSink, TrackID aID)
 {
   class Message : public ControlMessage {
   public:
     Message(MediaStream* aStream, MediaStreamVideoSink* aSink, TrackID aID) :
@@ -2964,16 +2969,25 @@ SourceMediaStream::AddDirectTrackListene
     MutexAutoLock lock(mMutex);
     data = FindDataForTrack(aTrackID);
     found = !!data;
     if (found) {
       isAudio = data->mData->GetType() == MediaSegment::AUDIO;
       isVideo = data->mData->GetType() == MediaSegment::VIDEO;
     }
     if (found && (isAudio || isVideo)) {
+      for (auto entry : mDirectTrackListeners) {
+        if (entry.mListener == listener &&
+            (entry.mTrackID == TRACK_ANY || entry.mTrackID == aTrackID)) {
+          listener->NotifyDirectListenerInstalled(
+            DirectMediaStreamTrackListener::InstallationResult::ALREADY_EXISTS);
+          return;
+        }
+      }
+
       TrackBound<DirectMediaStreamTrackListener>* sourceListener =
         mDirectTrackListeners.AppendElement();
       sourceListener->mListener = listener;
       sourceListener->mTrackID = aTrackID;
     }
   }
   if (!found) {
     STREAM_LOG(LogLevel::Warning, ("Couldn't find source track for direct track listener %p",
--- a/dom/media/MediaStreamListener.h
+++ b/dom/media/MediaStreamListener.h
@@ -9,16 +9,17 @@
 
 #include "StreamTracks.h"
 
 namespace mozilla {
 
 class AudioSegment;
 class MediaStream;
 class MediaStreamGraph;
+class MediaStreamVideoSink;
 class VideoSegment;
 
 enum MediaStreamGraphEvent : uint32_t {
   EVENT_FINISHED,
   EVENT_REMOVED,
   EVENT_HAS_DIRECT_LISTENERS, // transition from no direct listeners
   EVENT_HAS_NO_DIRECT_LISTENERS,  // transition to no direct listeners
 };
@@ -240,29 +241,35 @@ public:
    * successful or not. The results of this installation are the following:
    * TRACK_NOT_FOUND_AT_SOURCE
    *    We found the source stream of media data for this track, but the track
    *    didn't exist. This should only happen if you try to install the listener
    *    directly to a SourceMediaStream that doesn't contain the given TrackID.
    * STREAM_NOT_SUPPORTED
    *    While looking for the data source of this track, we found a MediaStream
    *    that is not a SourceMediaStream or a TrackUnionStream.
+   * ALREADY_EXIST
+   *    This DirectMediaStreamTrackListener already exists in the
+   *    SourceMediaStream.
    * SUCCESS
    *    Installation was successful and this listener will start receiving
    *    NotifyRealtimeData on the next AppendToTrack().
    */
   enum class InstallationResult {
     TRACK_NOT_FOUND_AT_SOURCE,
     TRACK_TYPE_NOT_SUPPORTED,
     STREAM_NOT_SUPPORTED,
+    ALREADY_EXISTS,
     SUCCESS
   };
   virtual void NotifyDirectListenerInstalled(InstallationResult aResult) {}
   virtual void NotifyDirectListenerUninstalled() {}
 
+  virtual MediaStreamVideoSink* AsMediaStreamVideoSink() { return nullptr; }
+
 protected:
   virtual ~DirectMediaStreamTrackListener() {}
 
   void MirrorAndDisableSegment(AudioSegment& aFrom, AudioSegment& aTo);
   void MirrorAndDisableSegment(VideoSegment& aFrom, VideoSegment& aTo);
   void NotifyRealtimeTrackDataAndApplyTrackDisabling(MediaStreamGraph* aGraph,
                                                      StreamTime aTrackOffset,
                                                      MediaSegment& aMedia);
--- a/dom/media/MediaStreamVideoSink.h
+++ b/dom/media/MediaStreamVideoSink.h
@@ -28,15 +28,17 @@ public:
 
   // Call on any thread
   virtual void SetCurrentFrames(const VideoSegment& aSegment) = 0;
   virtual void ClearFrames() = 0;
 
   virtual VideoFrameContainer* AsVideoFrameContainer() { return nullptr; }
   virtual void Invalidate() {}
 
+  virtual MediaStreamVideoSink* AsMediaStreamVideoSink() override { return this; }
+
 protected:
   virtual ~MediaStreamVideoSink() {};
 };
 
 } // namespace mozilla
 
 #endif /* MEDIASTREAMVIDEOSINK_H_ */