Bug 1155089 - Part 1: Reset |TrackID| for MediaPipelineTransmit::PipelineListener on replaceTrack(). r=bwc
authorAndreas Pehrson <pehrsons@gmail.com>
Wed, 22 Apr 2015 11:59:43 +0800
changeset 240529 43ceb677a8de5a0b1ce6407e2396e1dec06c8be6
parent 240528 f86abf1685905048d0b1d492430c86aa24123637
child 240530 6cd7a42a18db756939c4103372d957b04a8a2f16
push id58850
push userryanvm@gmail.com
push dateWed, 22 Apr 2015 16:12:42 +0000
treeherdermozilla-inbound@d49f149a7c76 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbwc
bugs1155089
milestone40.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 1155089 - Part 1: Reset |TrackID| for MediaPipelineTransmit::PipelineListener on replaceTrack(). r=bwc
media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
media/webrtc/signaling/src/mediapipeline/MediaPipeline.h
media/webrtc/signaling/test/FakeMediaStreams.h
--- a/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
+++ b/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
@@ -683,16 +683,18 @@ nsresult MediaPipelineTransmit::ReplaceT
             << " track " << track_id << " conduit type=" <<
             (conduit_->type() == MediaSessionConduit::AUDIO ?"audio":"video"));
 
   if (domstream_) { // may be excessive paranoia
     DetachMediaStream();
   }
   domstream_ = domstream; // Detach clears it
   stream_ = domstream->GetStream();
+  // Unsets the track id after RemoveListener() takes effect.
+  listener_->UnsetTrackId(stream_->GraphImpl());
   track_id_ = track_id;
   AttachToTrack(track_id);
   return NS_OK;
 }
 
 void MediaPipeline::DisconnectTransport_s(TransportInfo &info) {
   MOZ_ASSERT(info.transport_);
   ASSERT_ON_THREAD(sts_thread_);
@@ -848,16 +850,34 @@ nsresult MediaPipeline::PipelineTranspor
     return res;
 
   MOZ_MTLOG(ML_DEBUG, pipeline_->description_ << " sending RTCP packet.");
   pipeline_->increment_rtcp_packets_sent();
   return pipeline_->SendPacket(pipeline_->rtcp_.transport_, inner_data,
                                out_len);
 }
 
+void MediaPipelineTransmit::PipelineListener::
+UnsetTrackId(MediaStreamGraphImpl* graph) {
+#ifndef USE_FAKE_MEDIA_STREAMS
+  class Message : public ControlMessage {
+  public:
+    Message(PipelineListener* listener) :
+      ControlMessage(nullptr), listener_(listener) {}
+    virtual void Run() override
+    {
+      listener_->UnsetTrackIdImpl();
+    }
+    nsRefPtr<PipelineListener> listener_;
+  };
+  graph->AppendMessage(new Message(this));
+#else
+  UnsetTrackIdImpl();
+#endif
+}
 // Called if we're attached with AddDirectListener()
 void MediaPipelineTransmit::PipelineListener::
 NotifyRealtimeData(MediaStreamGraph* graph, TrackID tid,
                    StreamTime offset,
                    uint32_t events,
                    const MediaSegment& media) {
   MOZ_MTLOG(ML_DEBUG, "MediaPipeline::NotifyRealtimeData()");
 
--- a/media/webrtc/signaling/src/mediapipeline/MediaPipeline.h
+++ b/media/webrtc/signaling/src/mediapipeline/MediaPipeline.h
@@ -461,16 +461,22 @@ public:
       nsresult rv = NS_DispatchToMainThread(new
         ConduitDeleteEvent(conduit_.forget()));
       MOZ_ASSERT(!NS_FAILED(rv),"Could not dispatch conduit shutdown to main");
       if (NS_FAILED(rv)) {
         MOZ_CRASH();
       }
     }
 
+    // Dispatches setting the internal TrackID to TRACK_INVALID to the media
+    // graph thread to keep it in sync with other MediaStreamGraph operations
+    // like RemoveListener() and AddListener(). The TrackID will be updated on
+    // the next NewData() callback.
+    void UnsetTrackId(MediaStreamGraphImpl* graph);
+
     void SetActive(bool active) { active_ = active; }
     void SetEnabled(bool enabled) { enabled_ = enabled; }
     TrackID trackid() {
       MutexAutoLock lock(mMutex);
       return track_id_external_;
     }
 
     // Implement MediaStreamListener
@@ -482,16 +488,21 @@ public:
 
     // Implement MediaStreamDirectListener
     virtual void NotifyRealtimeData(MediaStreamGraph* graph, TrackID tid,
                                     StreamTime offset,
                                     uint32_t events,
                                     const MediaSegment& media) override;
 
    private:
+    void UnsetTrackIdImpl() {
+      MutexAutoLock lock(mMutex);
+      track_id_ = track_id_external_ = TRACK_INVALID;
+    }
+
     void NewData(MediaStreamGraph* graph, TrackID tid,
                  StreamTime offset,
                  uint32_t events,
                  const MediaSegment& media);
 
     virtual void ProcessAudioChunk(AudioSessionConduit *conduit,
                                    TrackRate rate, AudioChunk& chunk);
 #if !defined(MOZILLA_EXTERNAL_LINKAGE)
--- a/media/webrtc/signaling/test/FakeMediaStreams.h
+++ b/media/webrtc/signaling/test/FakeMediaStreams.h
@@ -25,16 +25,17 @@
 #include "nsTArray.h"
 #include "nsIRunnable.h"
 #include "nsISupportsImpl.h"
 
 class nsIDOMWindow;
 
 namespace mozilla {
    class MediaStreamGraph;
+   class MediaStreamGraphImpl;
    class MediaSegment;
 };
 
 class Fake_VideoSink {
 public:
   Fake_VideoSink() {}
   virtual void SegmentReady(mozilla::MediaSegment* aSegment) = 0;
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Fake_VideoSink)
@@ -98,16 +99,17 @@ class Fake_MediaStream {
     std::set<Fake_MediaStreamListener *>::iterator it;
     for (it = mListeners.begin(); it != mListeners.end(); ++it) {
       (*it)->NotifyPull(graph, aDesiredTime);
     }
   }
 
   virtual Fake_SourceMediaStream *AsSourceStream() { return nullptr; }
 
+  virtual mozilla::MediaStreamGraphImpl *GraphImpl() { return nullptr; }
   virtual nsresult Start() { return NS_OK; }
   virtual nsresult Stop() { return NS_OK; }
   virtual void StopStream() {}
 
   virtual void Periodic() {}
 
   double StreamTimeToSeconds(mozilla::StreamTime aTime);
   mozilla::StreamTime