Exposing RtpSenders and RtpReceivers from PeerConnection.

This CL essentially converts [Local|Remote]TrackHandler to
Rtp[Sender|Receiver], and adds a "SetTrack" method for RtpSender.

It also gets rid of MediaStreamHandler and MediaStreamHandlerContainer,
since these classes weren't really anything more than containers.
PeerConnection now manages the RtpSenders and RtpReceivers directly.

Review URL: https://codereview.webrtc.org/1351803002

Cr-Commit-Position: refs/heads/master@{#10100}
diff --git a/talk/app/webrtc/peerconnection.cc b/talk/app/webrtc/peerconnection.cc
index f934b61..961ba26 100644
--- a/talk/app/webrtc/peerconnection.cc
+++ b/talk/app/webrtc/peerconnection.cc
@@ -33,7 +33,8 @@
 #include "talk/app/webrtc/jsepicecandidate.h"
 #include "talk/app/webrtc/jsepsessiondescription.h"
 #include "talk/app/webrtc/mediaconstraintsinterface.h"
-#include "talk/app/webrtc/mediastreamhandler.h"
+#include "talk/app/webrtc/rtpreceiver.h"
+#include "talk/app/webrtc/rtpsender.h"
 #include "talk/app/webrtc/streamcollection.h"
 #include "webrtc/p2p/client/basicportallocator.h"
 #include "talk/session/media/channelmanager.h"
@@ -339,10 +340,17 @@
 
 PeerConnection::~PeerConnection() {
   ASSERT(signaling_thread()->IsCurrent());
-  if (mediastream_signaling_)
+  if (mediastream_signaling_) {
     mediastream_signaling_->TearDown();
-  if (stream_handler_container_)
-    stream_handler_container_->TearDown();
+  }
+  // Need to detach RTP senders/receivers from WebRtcSession,
+  // since it's about to be destroyed.
+  for (const auto& sender : senders_) {
+    sender->Stop();
+  }
+  for (const auto& receiver : receivers_) {
+    receiver->Stop();
+  }
 }
 
 bool PeerConnection::Initialize(
@@ -398,8 +406,6 @@
                                    factory_->worker_thread(),
                                    port_allocator_.get(),
                                    mediastream_signaling_.get()));
-  stream_handler_container_.reset(new MediaStreamHandlerContainer(
-      session_.get(), session_.get()));
   stats_.reset(new StatsCollector(session_.get()));
 
   // Initialize the WebRtcSession. It creates transport channels etc.
@@ -424,6 +430,8 @@
   return mediastream_signaling_->remote_streams();
 }
 
+// TODO(deadbeef): Create RtpSenders immediately here, even if local
+// description hasn't yet been set.
 bool PeerConnection::AddStream(MediaStreamInterface* local_stream) {
   if (IsClosed()) {
     return false;
@@ -468,6 +476,25 @@
   return DtmfSenderProxy::Create(signaling_thread(), sender.get());
 }
 
+std::vector<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::GetSenders()
+    const {
+  std::vector<rtc::scoped_refptr<RtpSenderInterface>> senders;
+  for (const auto& sender : senders_) {
+    senders.push_back(RtpSenderProxy::Create(signaling_thread(), sender.get()));
+  }
+  return senders;
+}
+
+std::vector<rtc::scoped_refptr<RtpReceiverInterface>>
+PeerConnection::GetReceivers() const {
+  std::vector<rtc::scoped_refptr<RtpReceiverInterface>> receivers;
+  for (const auto& receiver : receivers_) {
+    receivers.push_back(
+        RtpReceiverProxy::Create(signaling_thread(), receiver.get()));
+  }
+  return receivers;
+}
+
 bool PeerConnection::GetStats(StatsObserver* observer,
                               MediaStreamTrackInterface* track,
                               StatsOutputLevel level) {
@@ -808,7 +835,6 @@
 }
 
 void PeerConnection::OnRemoveRemoteStream(MediaStreamInterface* stream) {
-  stream_handler_container_->RemoveRemoteStream(stream);
   observer_->OnRemoveStream(stream);
 }
 
@@ -820,52 +846,87 @@
 void PeerConnection::OnAddRemoteAudioTrack(MediaStreamInterface* stream,
                                            AudioTrackInterface* audio_track,
                                            uint32 ssrc) {
-  stream_handler_container_->AddRemoteAudioTrack(stream, audio_track, ssrc);
+  receivers_.push_back(new AudioRtpReceiver(audio_track, ssrc, session_.get()));
 }
 
 void PeerConnection::OnAddRemoteVideoTrack(MediaStreamInterface* stream,
                                            VideoTrackInterface* video_track,
                                            uint32 ssrc) {
-  stream_handler_container_->AddRemoteVideoTrack(stream, video_track, ssrc);
+  receivers_.push_back(new VideoRtpReceiver(video_track, ssrc, session_.get()));
 }
 
+// TODO(deadbeef): Keep RtpReceivers around even if track goes away in remote
+// description.
 void PeerConnection::OnRemoveRemoteAudioTrack(
     MediaStreamInterface* stream,
     AudioTrackInterface* audio_track) {
-  stream_handler_container_->RemoveRemoteTrack(stream, audio_track);
+  auto it = FindReceiverForTrack(audio_track);
+  if (it == receivers_.end()) {
+    LOG(LS_WARNING) << "RtpReceiver for track with id " << audio_track->id()
+                    << " doesn't exist.";
+  } else {
+    (*it)->Stop();
+    receivers_.erase(it);
+  }
 }
 
 void PeerConnection::OnRemoveRemoteVideoTrack(
     MediaStreamInterface* stream,
     VideoTrackInterface* video_track) {
-  stream_handler_container_->RemoveRemoteTrack(stream, video_track);
+  auto it = FindReceiverForTrack(video_track);
+  if (it == receivers_.end()) {
+    LOG(LS_WARNING) << "RtpReceiver for track with id " << video_track->id()
+                    << " doesn't exist.";
+  } else {
+    (*it)->Stop();
+    receivers_.erase(it);
+  }
 }
+
 void PeerConnection::OnAddLocalAudioTrack(MediaStreamInterface* stream,
                                           AudioTrackInterface* audio_track,
                                           uint32 ssrc) {
-  stream_handler_container_->AddLocalAudioTrack(stream, audio_track, ssrc);
+  senders_.push_back(new AudioRtpSender(audio_track, ssrc, session_.get()));
   stats_->AddLocalAudioTrack(audio_track, ssrc);
 }
+
 void PeerConnection::OnAddLocalVideoTrack(MediaStreamInterface* stream,
                                           VideoTrackInterface* video_track,
                                           uint32 ssrc) {
-  stream_handler_container_->AddLocalVideoTrack(stream, video_track, ssrc);
+  senders_.push_back(new VideoRtpSender(video_track, ssrc, session_.get()));
 }
 
+// TODO(deadbeef): Keep RtpSenders around even if track goes away in local
+// description.
 void PeerConnection::OnRemoveLocalAudioTrack(MediaStreamInterface* stream,
                                              AudioTrackInterface* audio_track,
                                              uint32 ssrc) {
-  stream_handler_container_->RemoveLocalTrack(stream, audio_track);
+  auto it = FindSenderForTrack(audio_track);
+  if (it == senders_.end()) {
+    LOG(LS_WARNING) << "RtpSender for track with id " << audio_track->id()
+                    << " doesn't exist.";
+    return;
+  } else {
+    (*it)->Stop();
+    senders_.erase(it);
+  }
   stats_->RemoveLocalAudioTrack(audio_track, ssrc);
 }
 
 void PeerConnection::OnRemoveLocalVideoTrack(MediaStreamInterface* stream,
                                              VideoTrackInterface* video_track) {
-  stream_handler_container_->RemoveLocalTrack(stream, video_track);
+  auto it = FindSenderForTrack(video_track);
+  if (it == senders_.end()) {
+    LOG(LS_WARNING) << "RtpSender for track with id " << video_track->id()
+                    << " doesn't exist.";
+    return;
+  } else {
+    (*it)->Stop();
+    senders_.erase(it);
+  }
 }
 
 void PeerConnection::OnRemoveLocalStream(MediaStreamInterface* stream) {
-  stream_handler_container_->RemoveLocalStream(stream);
 }
 
 void PeerConnection::OnIceConnectionChange(
@@ -920,4 +981,22 @@
   observer_->OnStateChange(PeerConnectionObserver::kSignalingState);
 }
 
+std::vector<rtc::scoped_refptr<RtpSenderInterface>>::iterator
+PeerConnection::FindSenderForTrack(MediaStreamTrackInterface* track) {
+  return std::find_if(
+      senders_.begin(), senders_.end(),
+      [track](const rtc::scoped_refptr<RtpSenderInterface>& sender) {
+        return sender->track() == track;
+      });
+}
+
+std::vector<rtc::scoped_refptr<RtpReceiverInterface>>::iterator
+PeerConnection::FindReceiverForTrack(MediaStreamTrackInterface* track) {
+  return std::find_if(
+      receivers_.begin(), receivers_.end(),
+      [track](const rtc::scoped_refptr<RtpReceiverInterface>& receiver) {
+        return receiver->track() == track;
+      });
+}
+
 }  // namespace webrtc