Revert "Update RTCStatsCollector to work with RtpTransceivers"

This reverts commit 56bae8ded39c3fab2635b7d2d1d17a87d5d2818b.

Reason for revert: Speculative revert. This CL is suspect of making Chrome trybots fail the following test, preventing rolls:
 external/wpt/webrtc/RTCPeerConnection-track-stats.https.html

Some failed roll attempts:
https://chromium-review.googlesource.com/c/chromium/src/+/921421
https://chromium-review.googlesource.com/c/chromium/src/+/921422
https://chromium-review.googlesource.com/c/chromium/src/+/921781

Some failed bot runs:
https://ci.chromium.org/buildbot/tryserver.chromium.linux/linux_chromium_rel_ng/647669
https://ci.chromium.org/buildbot/tryserver.chromium.win/win7_chromium_rel_ng/103786


Original change's description:
> Update RTCStatsCollector to work with RtpTransceivers
> 
> Bug: webrtc:8764
> Change-Id: I8b442345869eb6d8b65fd12241ed7cb6e7d7ce3d
> Reviewed-on: https://webrtc-review.googlesource.com/49580
> Commit-Queue: Steve Anton <steveanton@webrtc.org>
> Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org>
> Reviewed-by: Henrik Boström <hbos@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#22026}

TBR=steveanton@webrtc.org,deadbeef@webrtc.org,hbos@webrtc.org,pthatcher@webrtc.org

Change-Id: I21ce2109087d7b2d9470471ee9a6757f904296d2
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: webrtc:8764
Reviewed-on: https://webrtc-review.googlesource.com/54000
Reviewed-by: Guido Urdaneta <guidou@webrtc.org>
Commit-Queue: Guido Urdaneta <guidou@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22036}
diff --git a/api/rtpreceiverinterface.cc b/api/rtpreceiverinterface.cc
index 96815a9..b62f744 100644
--- a/api/rtpreceiverinterface.cc
+++ b/api/rtpreceiverinterface.cc
@@ -41,4 +41,8 @@
   return {};
 }
 
+int RtpReceiverInterface::AttachmentId() const {
+  return 0;
+}
+
 }  // namespace webrtc
diff --git a/api/rtpreceiverinterface.h b/api/rtpreceiverinterface.h
index 0e32eae..017c95a 100644
--- a/api/rtpreceiverinterface.h
+++ b/api/rtpreceiverinterface.h
@@ -120,6 +120,14 @@
   // content::FakeRtpReceiver in Chromium.
   virtual std::vector<RtpSource> GetSources() const;
 
+  // TODO(hta): Remove default implementation or move function to
+  // an internal interface. content::FakeRtpReceiver in Chromium needs this.
+
+  // Returns an ID that changes if the attached track changes, but
+  // otherwise remains constant. Used to generate IDs for stats.
+  // The special value zero means that no track is attached.
+  virtual int AttachmentId() const;
+
  protected:
   ~RtpReceiverInterface() override = default;
 };
@@ -138,6 +146,7 @@
   PROXY_METHOD1(bool, SetParameters, const RtpParameters&)
   PROXY_METHOD1(void, SetObserver, RtpReceiverObserverInterface*);
   PROXY_CONSTMETHOD0(std::vector<RtpSource>, GetSources);
+  PROXY_CONSTMETHOD0(int, AttachmentId);
   END_PROXY_MAP()
 
 }  // namespace webrtc
diff --git a/api/rtpsenderinterface.h b/api/rtpsenderinterface.h
index 2ca2edc..83e135f 100644
--- a/api/rtpsenderinterface.h
+++ b/api/rtpsenderinterface.h
@@ -60,6 +60,13 @@
   // Returns null for a video sender.
   virtual rtc::scoped_refptr<DtmfSenderInterface> GetDtmfSender() const = 0;
 
+  // Returns an ID that changes every time SetTrack() is called, but
+  // otherwise remains constant. Used to generate IDs for stats.
+  // The special value zero means that no track is attached.
+  // TODO(hta): Remove default implementation when callers have updated,
+  // or move function to an internal interface.
+  virtual int AttachmentId() const { return 0; }
+
  protected:
   virtual ~RtpSenderInterface() {}
 };
@@ -78,6 +85,7 @@
   PROXY_CONSTMETHOD0(RtpParameters, GetParameters);
   PROXY_METHOD1(RTCError, SetParameters, const RtpParameters&)
   PROXY_CONSTMETHOD0(rtc::scoped_refptr<DtmfSenderInterface>, GetDtmfSender);
+  PROXY_CONSTMETHOD0(int, AttachmentId);
   END_PROXY_MAP()
 
 }  // namespace webrtc
diff --git a/api/test/mock_rtpreceiver.h b/api/test/mock_rtpreceiver.h
index de69cea..7a61200 100644
--- a/api/test/mock_rtpreceiver.h
+++ b/api/test/mock_rtpreceiver.h
@@ -31,6 +31,7 @@
   MOCK_METHOD1(SetParameters, bool(const RtpParameters&));
   MOCK_METHOD1(SetObserver, void(RtpReceiverObserverInterface*));
   MOCK_CONST_METHOD0(GetSources, std::vector<RtpSource>());
+  MOCK_CONST_METHOD0(AttachmentId, int());
 };
 
 }  // namespace webrtc
diff --git a/api/test/mock_rtpsender.h b/api/test/mock_rtpsender.h
index dda5f45..728ceca 100644
--- a/api/test/mock_rtpsender.h
+++ b/api/test/mock_rtpsender.h
@@ -30,6 +30,7 @@
   MOCK_CONST_METHOD0(GetParameters, RtpParameters());
   MOCK_METHOD1(SetParameters, RTCError(const RtpParameters&));
   MOCK_CONST_METHOD0(GetDtmfSender, rtc::scoped_refptr<DtmfSenderInterface>());
+  MOCK_CONST_METHOD0(AttachmentId, int());
 };
 
 }  // namespace webrtc
diff --git a/ortc/ortcrtpreceiveradapter.cc b/ortc/ortcrtpreceiveradapter.cc
index 8e05a85..16cb248 100644
--- a/ortc/ortcrtpreceiveradapter.cc
+++ b/ortc/ortcrtpreceiveradapter.cc
@@ -156,7 +156,7 @@
                                rtc::CreateRandomUuid(), {});
       auto* voice_channel = rtp_transport_controller_->voice_channel();
       RTC_DCHECK(voice_channel);
-      audio_receiver->SetVoiceMediaChannel(voice_channel->media_channel());
+      audio_receiver->SetMediaChannel(voice_channel->media_channel());
       internal_receiver_ = audio_receiver;
       break;
     }
@@ -166,7 +166,7 @@
                                rtc::CreateRandomUuid(), {});
       auto* video_channel = rtp_transport_controller_->video_channel();
       RTC_DCHECK(video_channel);
-      video_receiver->SetVideoMediaChannel(video_channel->media_channel());
+      video_receiver->SetMediaChannel(video_channel->media_channel());
       internal_receiver_ = video_receiver;
       break;
     }
diff --git a/ortc/ortcrtpsenderadapter.cc b/ortc/ortcrtpsenderadapter.cc
index 283ec35..2b25d46 100644
--- a/ortc/ortcrtpsenderadapter.cc
+++ b/ortc/ortcrtpsenderadapter.cc
@@ -160,7 +160,7 @@
           rtp_transport_controller_->worker_thread(), nullptr);
       auto* voice_channel = rtp_transport_controller_->voice_channel();
       RTC_DCHECK(voice_channel);
-      audio_sender->SetVoiceMediaChannel(voice_channel->media_channel());
+      audio_sender->SetMediaChannel(voice_channel->media_channel());
       internal_sender_ = audio_sender;
       break;
     }
@@ -169,7 +169,7 @@
           new VideoRtpSender(rtp_transport_controller_->worker_thread());
       auto* video_channel = rtp_transport_controller_->video_channel();
       RTC_DCHECK(video_channel);
-      video_sender->SetVideoMediaChannel(video_channel->media_channel());
+      video_sender->SetMediaChannel(video_channel->media_channel());
       internal_sender_ = video_sender;
       break;
     }
diff --git a/pc/BUILD.gn b/pc/BUILD.gn
index 21be857..cf506bf 100644
--- a/pc/BUILD.gn
+++ b/pc/BUILD.gn
@@ -339,8 +339,6 @@
       "test/fakevideotracksource.h",
       "test/mock_datachannel.h",
       "test/mock_peerconnection.h",
-      "test/mock_rtpreceiverinternal.h",
-      "test/mock_rtpsenderinternal.h",
       "test/mockpeerconnectionobservers.h",
       "test/peerconnectiontestwrapper.cc",
       "test/peerconnectiontestwrapper.h",
diff --git a/pc/peerconnection.cc b/pc/peerconnection.cc
index db6cad6..90bb267 100644
--- a/pc/peerconnection.cc
+++ b/pc/peerconnection.cc
@@ -1114,7 +1114,8 @@
            : cricket::MEDIA_TYPE_VIDEO);
   auto new_sender = CreateSender(media_type, track, stream_labels);
   if (track->kind() == MediaStreamTrackInterface::kAudioKind) {
-    new_sender->internal()->SetVoiceMediaChannel(voice_media_channel());
+    static_cast<AudioRtpSender*>(new_sender->internal())
+        ->SetMediaChannel(voice_media_channel());
     GetAudioTransceiver()->internal()->AddSender(new_sender);
     const RtpSenderInfo* sender_info =
         FindSenderInfo(local_audio_sender_infos_,
@@ -1124,7 +1125,8 @@
     }
   } else {
     RTC_DCHECK_EQ(MediaStreamTrackInterface::kVideoKind, track->kind());
-    new_sender->internal()->SetVideoMediaChannel(video_media_channel());
+    static_cast<VideoRtpSender*>(new_sender->internal())
+        ->SetMediaChannel(video_media_channel());
     GetVideoTransceiver()->internal()->AddSender(new_sender);
     const RtpSenderInfo* sender_info =
         FindSenderInfo(local_video_sender_infos_,
@@ -1415,14 +1417,14 @@
   if (kind == MediaStreamTrackInterface::kAudioKind) {
     auto* audio_sender = new AudioRtpSender(worker_thread(), nullptr,
                                             stream_labels, stats_.get());
-    audio_sender->SetVoiceMediaChannel(voice_media_channel());
+    audio_sender->SetMediaChannel(voice_media_channel());
     new_sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
         signaling_thread(), audio_sender);
     GetAudioTransceiver()->internal()->AddSender(new_sender);
   } else if (kind == MediaStreamTrackInterface::kVideoKind) {
     auto* video_sender =
         new VideoRtpSender(worker_thread(), nullptr, stream_labels);
-    video_sender->SetVideoMediaChannel(video_media_channel());
+    video_sender->SetMediaChannel(video_media_channel());
     new_sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
         signaling_thread(), video_sender);
     GetVideoTransceiver()->internal()->AddSender(new_sender);
@@ -3017,7 +3019,7 @@
   streams.push_back(rtc::scoped_refptr<MediaStreamInterface>(stream));
   auto* audio_receiver = new AudioRtpReceiver(
       worker_thread(), remote_sender_info.sender_id, streams);
-  audio_receiver->SetVoiceMediaChannel(voice_media_channel());
+  audio_receiver->SetMediaChannel(voice_media_channel());
   audio_receiver->SetupMediaChannel(remote_sender_info.first_ssrc);
   auto receiver = RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create(
       signaling_thread(), audio_receiver);
@@ -3032,7 +3034,7 @@
   streams.push_back(rtc::scoped_refptr<MediaStreamInterface>(stream));
   auto* video_receiver = new VideoRtpReceiver(
       worker_thread(), remote_sender_info.sender_id, streams);
-  video_receiver->SetVideoMediaChannel(video_media_channel());
+  video_receiver->SetMediaChannel(video_media_channel());
   video_receiver->SetupMediaChannel(remote_sender_info.first_ssrc);
   auto receiver = RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create(
       signaling_thread(), video_receiver);
@@ -3072,7 +3074,8 @@
   // Normal case; we've never seen this track before.
   auto new_sender =
       CreateSender(cricket::MEDIA_TYPE_AUDIO, track, {stream->label()});
-  new_sender->internal()->SetVoiceMediaChannel(voice_media_channel());
+  static_cast<AudioRtpSender*>(new_sender->internal())
+      ->SetMediaChannel(voice_media_channel());
   GetAudioTransceiver()->internal()->AddSender(new_sender);
   // If the sender has already been configured in SDP, we call SetSsrc,
   // which will connect the sender to the underlying transport. This can
@@ -3115,7 +3118,8 @@
   // Normal case; we've never seen this track before.
   auto new_sender =
       CreateSender(cricket::MEDIA_TYPE_VIDEO, track, {stream->label()});
-  new_sender->internal()->SetVideoMediaChannel(video_media_channel());
+  static_cast<VideoRtpSender*>(new_sender->internal())
+      ->SetMediaChannel(video_media_channel());
   GetVideoTransceiver()->internal()->AddSender(new_sender);
   const RtpSenderInfo* sender_info =
       FindSenderInfo(local_video_sender_infos_, stream->label(), track->id());
diff --git a/pc/peerconnectioninterface_unittest.cc b/pc/peerconnectioninterface_unittest.cc
index 8413b79..e496e4e 100644
--- a/pc/peerconnectioninterface_unittest.cc
+++ b/pc/peerconnectioninterface_unittest.cc
@@ -32,7 +32,6 @@
 #include "pc/mediasession.h"
 #include "pc/mediastream.h"
 #include "pc/peerconnection.h"
-#include "pc/rtpsender.h"
 #include "pc/streamcollection.h"
 #include "pc/test/fakeaudiocapturemodule.h"
 #include "pc/test/fakertccertificategenerator.h"
@@ -351,8 +350,6 @@
 using webrtc::RTCErrorType;
 using webrtc::RtpReceiverInterface;
 using webrtc::RtpSenderInterface;
-using webrtc::RtpSenderProxyWithInternal;
-using webrtc::RtpSenderInternal;
 using webrtc::RtpTransceiverDirection;
 using webrtc::SdpParseError;
 using webrtc::SdpType;
@@ -1495,29 +1492,19 @@
                              std::unique_ptr<cricket::VideoCapturer>(
                                  new cricket::FakeVideoCapturer()))));
   auto audio_sender = pc_->AddTrack(audio_track, std::vector<std::string>());
-  ASSERT_TRUE(audio_sender.ok());
-  auto* audio_sender_proxy =
-      static_cast<RtpSenderProxyWithInternal<RtpSenderInternal>*>(
-          audio_sender.value().get());
-  EXPECT_NE(0, audio_sender_proxy->internal()->AttachmentId());
-
   auto video_sender = pc_->AddTrack(video_track, std::vector<std::string>());
-  ASSERT_TRUE(video_sender.ok());
-  auto* video_sender_proxy =
-      static_cast<RtpSenderProxyWithInternal<RtpSenderInternal>*>(
-          video_sender.value().get());
-  EXPECT_NE(0, video_sender_proxy->internal()->AttachmentId());
+  EXPECT_TRUE(audio_sender.ok());
+  EXPECT_TRUE(video_sender.ok());
+  EXPECT_NE(0, video_sender.value()->AttachmentId());
+  EXPECT_NE(0, audio_sender.value()->AttachmentId());
 }
 
 TEST_F(PeerConnectionInterfaceTest, AttachmentIdIsSetOnAddStream) {
   CreatePeerConnectionWithoutDtls();
   AddVideoStream(kStreamLabel1);
   auto senders = pc_->GetSenders();
-  ASSERT_EQ(1u, senders.size());
-  auto* sender_proxy =
-      static_cast<RtpSenderProxyWithInternal<RtpSenderInternal>*>(
-          senders[0].get());
-  EXPECT_NE(0, sender_proxy->internal()->AttachmentId());
+  EXPECT_EQ(1u, senders.size());
+  EXPECT_NE(0, senders[0]->AttachmentId());
 }
 
 TEST_F(PeerConnectionInterfaceTest, CreateOfferReceiveAnswer) {
diff --git a/pc/rtcstatscollector.cc b/pc/rtcstatscollector.cc
index e2be5ff..77dde95 100644
--- a/pc/rtcstatscollector.cc
+++ b/pc/rtcstatscollector.cc
@@ -24,7 +24,6 @@
 #include "p2p/base/port.h"
 #include "pc/peerconnection.h"
 #include "rtc_base/checks.h"
-#include "rtc_base/ptr_util.h"
 #include "rtc_base/stringutils.h"
 #include "rtc_base/timeutils.h"
 #include "rtc_base/trace_event.h"
@@ -37,11 +36,19 @@
   return "RTCCertificate_" + fingerprint;
 }
 
-std::string RTCCodecStatsIDFromMidDirectionAndPayload(const std::string& mid,
-                                                      bool inbound,
-                                                      uint32_t payload_type) {
-  return "RTCCodec_" + mid + "_" + (inbound ? "Inbound" : "Outbound") + "_" +
-         rtc::ToString<>(payload_type);
+std::string RTCCodecStatsIDFromDirectionMediaAndPayload(
+    bool inbound, bool audio, uint32_t payload_type) {
+  // TODO(hbos): The present codec ID assignment is not sufficient to support
+  // Unified Plan or unbundled connections in all cases. When we are able to
+  // handle multiple m= lines of the same media type (and multiple BaseChannels
+  // for the same type is possible?) this needs to be updated to differentiate
+  // the transport being used, and stats need to be collected for all of them.
+  if (inbound) {
+    return audio ? "RTCCodec_InboundAudio_" + rtc::ToString<>(payload_type)
+                 : "RTCCodec_InboundVideo_" + rtc::ToString<>(payload_type);
+  }
+  return audio ? "RTCCodec_OutboundAudio_" + rtc::ToString<>(payload_type)
+               : "RTCCodec_OutboundVideo_" + rtc::ToString<>(payload_type);
 }
 
 std::string RTCIceCandidatePairStatsIDFromConnectionInfo(
@@ -168,16 +175,14 @@
 }
 
 std::unique_ptr<RTCCodecStats> CodecStatsFromRtpCodecParameters(
-    uint64_t timestamp_us,
-    const std::string& mid,
-    bool inbound,
+    uint64_t timestamp_us, bool inbound, bool audio,
     const RtpCodecParameters& codec_params) {
   RTC_DCHECK_GE(codec_params.payload_type, 0);
   RTC_DCHECK_LE(codec_params.payload_type, 127);
   RTC_DCHECK(codec_params.clock_rate);
   uint32_t payload_type = static_cast<uint32_t>(codec_params.payload_type);
   std::unique_ptr<RTCCodecStats> codec_stats(new RTCCodecStats(
-      RTCCodecStatsIDFromMidDirectionAndPayload(mid, inbound, payload_type),
+      RTCCodecStatsIDFromDirectionMediaAndPayload(inbound, audio, payload_type),
       timestamp_us));
   codec_stats->payload_type = payload_type;
   codec_stats->mime_type = codec_params.mime_type();
@@ -213,15 +218,15 @@
 }
 
 void SetInboundRTPStreamStatsFromVoiceReceiverInfo(
-    const std::string& mid,
     const cricket::VoiceReceiverInfo& voice_receiver_info,
     RTCInboundRTPStreamStats* inbound_audio) {
   SetInboundRTPStreamStatsFromMediaReceiverInfo(
       voice_receiver_info, inbound_audio);
   inbound_audio->media_type = "audio";
   if (voice_receiver_info.codec_payload_type) {
-    inbound_audio->codec_id = RTCCodecStatsIDFromMidDirectionAndPayload(
-        mid, true, *voice_receiver_info.codec_payload_type);
+    inbound_audio->codec_id =
+        RTCCodecStatsIDFromDirectionMediaAndPayload(
+            true, true, *voice_receiver_info.codec_payload_type);
   }
   inbound_audio->jitter =
       static_cast<double>(voice_receiver_info.jitter_ms) /
@@ -231,15 +236,15 @@
 }
 
 void SetInboundRTPStreamStatsFromVideoReceiverInfo(
-    const std::string& mid,
     const cricket::VideoReceiverInfo& video_receiver_info,
     RTCInboundRTPStreamStats* inbound_video) {
   SetInboundRTPStreamStatsFromMediaReceiverInfo(
       video_receiver_info, inbound_video);
   inbound_video->media_type = "video";
   if (video_receiver_info.codec_payload_type) {
-    inbound_video->codec_id = RTCCodecStatsIDFromMidDirectionAndPayload(
-        mid, true, *video_receiver_info.codec_payload_type);
+    inbound_video->codec_id =
+        RTCCodecStatsIDFromDirectionMediaAndPayload(
+            true, false, *video_receiver_info.codec_payload_type);
   }
   inbound_video->fir_count =
       static_cast<uint32_t>(video_receiver_info.firs_sent);
@@ -267,30 +272,30 @@
 }
 
 void SetOutboundRTPStreamStatsFromVoiceSenderInfo(
-    const std::string& mid,
     const cricket::VoiceSenderInfo& voice_sender_info,
     RTCOutboundRTPStreamStats* outbound_audio) {
   SetOutboundRTPStreamStatsFromMediaSenderInfo(
       voice_sender_info, outbound_audio);
   outbound_audio->media_type = "audio";
   if (voice_sender_info.codec_payload_type) {
-    outbound_audio->codec_id = RTCCodecStatsIDFromMidDirectionAndPayload(
-        mid, false, *voice_sender_info.codec_payload_type);
+    outbound_audio->codec_id =
+        RTCCodecStatsIDFromDirectionMediaAndPayload(
+            false, true, *voice_sender_info.codec_payload_type);
   }
   // |fir_count|, |pli_count| and |sli_count| are only valid for video and are
   // purposefully left undefined for audio.
 }
 
 void SetOutboundRTPStreamStatsFromVideoSenderInfo(
-    const std::string& mid,
     const cricket::VideoSenderInfo& video_sender_info,
     RTCOutboundRTPStreamStats* outbound_video) {
   SetOutboundRTPStreamStatsFromMediaSenderInfo(
       video_sender_info, outbound_video);
   outbound_video->media_type = "video";
   if (video_sender_info.codec_payload_type) {
-    outbound_video->codec_id = RTCCodecStatsIDFromMidDirectionAndPayload(
-        mid, false, *video_sender_info.codec_payload_type);
+    outbound_video->codec_id =
+        RTCCodecStatsIDFromDirectionMediaAndPayload(
+            false, false, *video_sender_info.codec_payload_type);
   }
   outbound_video->fir_count =
       static_cast<uint32_t>(video_sender_info.firs_rcvd);
@@ -497,14 +502,14 @@
 void ProduceSenderMediaTrackStats(
     int64_t timestamp_us,
     const TrackMediaInfoMap& track_media_info_map,
-    std::vector<rtc::scoped_refptr<RtpSenderInternal>> senders,
+    std::vector<rtc::scoped_refptr<RtpSenderInterface>> senders,
     RTCStatsReport* report) {
   // This function iterates over the senders to generate outgoing track stats.
 
   // TODO(hbos): Return stats of detached tracks. We have to perform stats
   // gathering at the time of detachment to get accurate stats and timestamps.
   // https://crbug.com/659137
-  for (auto sender : senders) {
+  for (auto const sender : senders) {
     if (sender->media_type() == cricket::MEDIA_TYPE_AUDIO) {
       AudioTrackInterface* track =
           static_cast<AudioTrackInterface*>(sender->track().get());
@@ -515,11 +520,11 @@
       // TODO(hta): Checking on ssrc is not proper. There should be a way
       // to see from a sender whether it's connected or not.
       // Related to https://crbug.com/8694 (using ssrc 0 to indicate "none")
-      if (sender->ssrc() != 0) {
+      if (sender->ssrc()) {
         // When pc.close is called, sender info is discarded, so
         // we generate zeroes instead. Bug: It should be retained.
         // https://crbug.com/807174
-        const cricket::VoiceSenderInfo* sender_info =
+        auto sender_info =
             track_media_info_map.GetVoiceSenderInfoBySsrc(sender->ssrc());
         if (sender_info) {
           voice_sender_info = sender_info;
@@ -543,11 +548,11 @@
       // TODO(hta): Check on state not ssrc when state is available
       // Related to https://bugs.webrtc.org/8694 (using ssrc 0 to indicate
       // "none")
-      if (sender->ssrc() != 0) {
+      if (sender->ssrc()) {
         // When pc.close is called, sender info is discarded, so
         // we generate zeroes instead. Bug: It should be retained.
         // https://crbug.com/807174
-        const cricket::VideoSenderInfo* sender_info =
+        auto sender_info =
             track_media_info_map.GetVideoSenderInfoBySsrc(sender->ssrc());
         if (sender_info) {
           video_sender_info = sender_info;
@@ -569,10 +574,10 @@
 void ProduceReceiverMediaTrackStats(
     int64_t timestamp_us,
     const TrackMediaInfoMap& track_media_info_map,
-    std::vector<rtc::scoped_refptr<RtpReceiverInternal>> receivers,
+    std::vector<rtc::scoped_refptr<RtpReceiverInterface>> receivers,
     RTCStatsReport* report) {
   // This function iterates over the receivers to find the remote tracks.
-  for (auto receiver : receivers) {
+  for (auto const receiver : receivers) {
     if (receiver->media_type() == cricket::MEDIA_TYPE_AUDIO) {
       AudioTrackInterface* track =
           static_cast<AudioTrackInterface*>(receiver->track().get());
@@ -605,6 +610,38 @@
   }
 }
 
+void ProduceMediaStreamStats(
+    int64_t timestamp_us,
+    const std::vector<rtc::scoped_refptr<RtpSenderInterface>>& rtp_senders,
+    const std::vector<rtc::scoped_refptr<RtpReceiverInterface>>& rtp_receivers,
+    RTCStatsReport* report) {
+  std::map<std::string, std::vector<std::string>> track_ids;
+
+  for (auto& sender : rtp_senders) {
+    std::string track_id = RTCMediaStreamTrackStatsIDFromDirectionAndAttachment(
+        kSender, sender->AttachmentId());
+    for (auto& stream_id : sender->stream_ids()) {
+      track_ids[stream_id].push_back(track_id);
+    }
+  }
+  for (auto& receiver : rtp_receivers) {
+    std::string track_id = RTCMediaStreamTrackStatsIDFromDirectionAndAttachment(
+        kReceiver, receiver->AttachmentId());
+    for (auto& stream : receiver->streams()) {
+      track_ids[stream->label()].push_back(track_id);
+    }
+  }
+
+  // Build stats for each stream ID known.
+  for (auto& it : track_ids) {
+    std::unique_ptr<RTCMediaStreamStats> stream_stats(
+        new RTCMediaStreamStats("RTCMediaStream_" + it.first, timestamp_us));
+    stream_stats->stream_identifier = it.first;
+    stream_stats->track_ids = it.second;
+    report->AddStats(std::move(stream_stats));
+  }
+}
+
 }  // namespace
 
 rtc::scoped_refptr<RTCStatsCollector> RTCStatsCollector::Create(
@@ -662,10 +699,27 @@
     num_pending_partial_reports_ = 2;
     partial_report_timestamp_us_ = cache_now_us;
 
-    // Prepare |transceiver_stats_infos_| for use in
+    // Prepare |transport_name_by_mid_| for use in
+    // |ProducePartialResultsOnNetworkThread|.
+    transport_names_by_mid_ = pc_->GetTransportNamesByMid();
+    // Prepare |track_media_info_map_| for use in
     // |ProducePartialResultsOnNetworkThread| and
     // |ProducePartialResultsOnSignalingThread|.
-    transceiver_stats_infos_ = PrepareTransceiverStatsInfos_s();
+    track_media_info_map_.reset(PrepareTrackMediaInfoMap_s().release());
+    // Prepare |track_to_id_| for use in |ProducePartialResultsOnNetworkThread|.
+    // This avoids a possible deadlock if |MediaStreamTrackInterface::id| is
+    // implemented to invoke on the signaling thread.
+    track_to_id_ = PrepareTrackToID_s();
+
+    voice_mid_.reset();
+    if (pc_->voice_channel()) {
+      voice_mid_ = pc_->voice_channel()->content_name();
+    }
+
+    video_mid_.reset();
+    if (pc_->video_channel()) {
+      video_mid_ = pc_->video_channel()->content_name();
+    }
 
     // Prepare |call_stats_| here since GetCallStats() will hop to the worker
     // thread.
@@ -704,8 +758,7 @@
       timestamp_us);
 
   ProduceDataChannelStats_s(timestamp_us, report.get());
-  ProduceMediaStreamStats_s(timestamp_us, report.get());
-  ProduceMediaStreamTrackStats_s(timestamp_us, report.get());
+  ProduceMediaStreamAndTrackStats_s(timestamp_us, report.get());
   ProducePeerConnectionStats_s(timestamp_us, report.get());
 
   AddPartialResults(report);
@@ -718,8 +771,8 @@
       timestamp_us);
 
   std::set<std::string> transport_names;
-  for (const auto& stats : transceiver_stats_infos_) {
-    transport_names.insert(stats.transport_name);
+  for (const auto& entry : transport_names_by_mid_) {
+    transport_names.insert(entry.second);
   }
   std::map<std::string, cricket::TransportStats> transport_stats_by_name =
       pc_->GetTransportStatsByNames(transport_names);
@@ -728,10 +781,12 @@
       PrepareTransportCertificateStats_n(transport_stats_by_name);
 
   ProduceCertificateStats_n(timestamp_us, transport_cert_stats, report.get());
-  ProduceCodecStats_n(timestamp_us, transceiver_stats_infos_, report.get());
+  ProduceCodecStats_n(timestamp_us, *track_media_info_map_, report.get());
   ProduceIceCandidateAndPairStats_n(timestamp_us, transport_stats_by_name,
+                                    track_media_info_map_->video_media_info(),
                                     call_stats_, report.get());
-  ProduceRTPStreamStats_n(timestamp_us, transceiver_stats_infos_, report.get());
+  ProduceRTPStreamStats_n(timestamp_us, transport_names_by_mid_,
+                          *track_media_info_map_, report.get());
   ProduceTransportStats_n(timestamp_us, transport_stats_by_name,
                           transport_cert_stats, report.get());
 
@@ -763,7 +818,9 @@
     cache_timestamp_us_ = partial_report_timestamp_us_;
     cached_report_ = partial_report_;
     partial_report_ = nullptr;
-    transceiver_stats_infos_.clear();
+    transport_names_by_mid_.clear();
+    track_media_info_map_.reset();
+    track_to_id_.clear();
     // Trace WebRTC Stats when getStats is called on Javascript.
     // This allows access to WebRTC stats from trace logs. To enable them,
     // select the "webrtc_stats" category when recording traces.
@@ -802,40 +859,37 @@
 }
 
 void RTCStatsCollector::ProduceCodecStats_n(
-    int64_t timestamp_us,
-    const std::vector<RtpTransceiverStatsInfo>& transceiver_stats_infos,
+    int64_t timestamp_us, const TrackMediaInfoMap& track_media_info_map,
     RTCStatsReport* report) const {
   RTC_DCHECK(network_thread_->IsCurrent());
-  for (const auto& stats : transceiver_stats_infos) {
-    const cricket::VoiceMediaInfo* voice_media_info =
-        stats.track_media_info_map->voice_media_info();
-    const cricket::VideoMediaInfo* video_media_info =
-        stats.track_media_info_map->video_media_info();
-    // Audio
-    if (voice_media_info) {
-      // Inbound
-      for (const auto& pair : voice_media_info->receive_codecs) {
-        report->AddStats(CodecStatsFromRtpCodecParameters(
-            timestamp_us, stats.mid, true, pair.second));
-      }
-      // Outbound
-      for (const auto& pair : voice_media_info->send_codecs) {
-        report->AddStats(CodecStatsFromRtpCodecParameters(
-            timestamp_us, stats.mid, false, pair.second));
-      }
+  // Audio
+  if (track_media_info_map.voice_media_info()) {
+    // Inbound
+    for (const auto& pair :
+         track_media_info_map.voice_media_info()->receive_codecs) {
+      report->AddStats(CodecStatsFromRtpCodecParameters(
+          timestamp_us, true, true, pair.second));
     }
-    // Video
-    if (video_media_info) {
-      // Inbound
-      for (const auto& pair : video_media_info->receive_codecs) {
-        report->AddStats(CodecStatsFromRtpCodecParameters(
-            timestamp_us, stats.mid, true, pair.second));
-      }
-      // Outbound
-      for (const auto& pair : video_media_info->send_codecs) {
-        report->AddStats(CodecStatsFromRtpCodecParameters(
-            timestamp_us, stats.mid, false, pair.second));
-      }
+    // Outbound
+    for (const auto& pair :
+         track_media_info_map.voice_media_info()->send_codecs) {
+      report->AddStats(CodecStatsFromRtpCodecParameters(
+          timestamp_us, false, true, pair.second));
+    }
+  }
+  // Video
+  if (track_media_info_map.video_media_info()) {
+    // Inbound
+    for (const auto& pair :
+         track_media_info_map.video_media_info()->receive_codecs) {
+      report->AddStats(CodecStatsFromRtpCodecParameters(
+          timestamp_us, true, false, pair.second));
+    }
+    // Outbound
+    for (const auto& pair :
+         track_media_info_map.video_media_info()->send_codecs) {
+      report->AddStats(CodecStatsFromRtpCodecParameters(
+          timestamp_us, false, false, pair.second));
     }
   }
 }
@@ -866,6 +920,7 @@
     int64_t timestamp_us,
     const std::map<std::string, cricket::TransportStats>&
         transport_stats_by_name,
+    const cricket::VideoMediaInfo* video_media_info,
     const Call::Stats& call_stats,
     RTCStatsReport* report) const {
   RTC_DCHECK(network_thread_->IsCurrent());
@@ -945,61 +1000,16 @@
   }
 }
 
-void RTCStatsCollector::ProduceMediaStreamStats_s(
-    int64_t timestamp_us,
-    RTCStatsReport* report) const {
+void RTCStatsCollector::ProduceMediaStreamAndTrackStats_s(
+    int64_t timestamp_us, RTCStatsReport* report) const {
   RTC_DCHECK(signaling_thread_->IsCurrent());
-
-  std::map<std::string, std::vector<std::string>> track_ids;
-
-  for (const auto& stats : transceiver_stats_infos_) {
-    for (auto sender : stats.transceiver->senders()) {
-      std::string track_id =
-          RTCMediaStreamTrackStatsIDFromDirectionAndAttachment(
-              kSender, sender->internal()->AttachmentId());
-      for (auto& stream_id : sender->stream_ids()) {
-        track_ids[stream_id].push_back(track_id);
-      }
-    }
-    for (auto receiver : stats.transceiver->receivers()) {
-      std::string track_id =
-          RTCMediaStreamTrackStatsIDFromDirectionAndAttachment(
-              kReceiver, receiver->internal()->AttachmentId());
-      for (auto& stream : receiver->streams()) {
-        track_ids[stream->label()].push_back(track_id);
-      }
-    }
-  }
-
-  // Build stats for each stream ID known.
-  for (auto& it : track_ids) {
-    std::unique_ptr<RTCMediaStreamStats> stream_stats(
-        new RTCMediaStreamStats("RTCMediaStream_" + it.first, timestamp_us));
-    stream_stats->stream_identifier = it.first;
-    stream_stats->track_ids = it.second;
-    report->AddStats(std::move(stream_stats));
-  }
-}
-
-void RTCStatsCollector::ProduceMediaStreamTrackStats_s(
-    int64_t timestamp_us,
-    RTCStatsReport* report) const {
-  RTC_DCHECK(signaling_thread_->IsCurrent());
-  for (const RtpTransceiverStatsInfo& stats : transceiver_stats_infos_) {
-    std::vector<rtc::scoped_refptr<RtpSenderInternal>> senders;
-    for (auto sender : stats.transceiver->senders()) {
-      senders.push_back(sender->internal());
-    }
-    ProduceSenderMediaTrackStats(timestamp_us, *stats.track_media_info_map,
-                                 senders, report);
-
-    std::vector<rtc::scoped_refptr<RtpReceiverInternal>> receivers;
-    for (auto receiver : stats.transceiver->receivers()) {
-      receivers.push_back(receiver->internal());
-    }
-    ProduceReceiverMediaTrackStats(timestamp_us, *stats.track_media_info_map,
-                                   receivers, report);
-  }
+  RTC_DCHECK(track_media_info_map_);
+  ProduceMediaStreamStats(timestamp_us, pc_->GetSenders(), pc_->GetReceivers(),
+                          report);
+  ProduceSenderMediaTrackStats(timestamp_us, *track_media_info_map_,
+                               pc_->GetSenders(), report);
+  ProduceReceiverMediaTrackStats(timestamp_us, *track_media_info_map_,
+                                 pc_->GetReceivers(), report);
 }
 
 void RTCStatsCollector::ProducePeerConnectionStats_s(
@@ -1014,125 +1024,122 @@
 
 void RTCStatsCollector::ProduceRTPStreamStats_n(
     int64_t timestamp_us,
-    const std::vector<RtpTransceiverStatsInfo>& transceiver_stats_infos,
+    const std::map<std::string, std::string>& transport_names_by_mid,
+    const TrackMediaInfoMap& track_media_info_map,
     RTCStatsReport* report) const {
   RTC_DCHECK(network_thread_->IsCurrent());
 
-  for (const RtpTransceiverStatsInfo& stats : transceiver_stats_infos) {
-    if (stats.media_type == cricket::MEDIA_TYPE_AUDIO) {
-      ProduceAudioRTPStreamStats_n(timestamp_us, stats, report);
-    } else if (stats.media_type == cricket::MEDIA_TYPE_VIDEO) {
-      ProduceVideoRTPStreamStats_n(timestamp_us, stats, report);
-    } else {
-      RTC_NOTREACHED();
-    }
-  }
-}
+  // Audio
+  if (track_media_info_map.voice_media_info()) {
+    RTC_DCHECK(voice_mid_);
+    const std::string& transport_name = transport_names_by_mid.at(*voice_mid_);
+    std::string transport_id = RTCTransportStatsIDFromTransportChannel(
+        transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
+    // Inbound
+    for (const cricket::VoiceReceiverInfo& voice_receiver_info :
+         track_media_info_map.voice_media_info()->receivers) {
+      if (!voice_receiver_info.connected())
+        continue;
 
-void RTCStatsCollector::ProduceAudioRTPStreamStats_n(
-    int64_t timestamp_us,
-    const RtpTransceiverStatsInfo& stats,
-    RTCStatsReport* report) const {
-  RTC_DCHECK(stats.track_media_info_map);
-  const TrackMediaInfoMap& track_media_info_map = *stats.track_media_info_map;
-  RTC_DCHECK(track_media_info_map.voice_media_info());
-  std::string transport_id = RTCTransportStatsIDFromTransportChannel(
-      stats.transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
-  // Inbound
-  for (const cricket::VoiceReceiverInfo& voice_receiver_info :
-       track_media_info_map.voice_media_info()->receivers) {
-    if (!voice_receiver_info.connected())
-      continue;
-    auto inbound_audio = rtc::MakeUnique<RTCInboundRTPStreamStats>(
-        RTCInboundRTPStreamStatsIDFromSSRC(true, voice_receiver_info.ssrc()),
-        timestamp_us);
-    SetInboundRTPStreamStatsFromVoiceReceiverInfo(
-        stats.mid, voice_receiver_info, inbound_audio.get());
-    // TODO(hta): This lookup should look for the sender, not the track.
-    rtc::scoped_refptr<AudioTrackInterface> audio_track =
-        track_media_info_map.GetAudioTrack(voice_receiver_info);
-    if (audio_track) {
-      inbound_audio->track_id =
-          RTCMediaStreamTrackStatsIDFromDirectionAndAttachment(
-              kReceiver,
-              track_media_info_map.GetAttachmentIdByTrack(audio_track).value());
+      std::unique_ptr<RTCInboundRTPStreamStats> inbound_audio(
+          new RTCInboundRTPStreamStats(RTCInboundRTPStreamStatsIDFromSSRC(
+                                           true, voice_receiver_info.ssrc()),
+                                       timestamp_us));
+      SetInboundRTPStreamStatsFromVoiceReceiverInfo(voice_receiver_info,
+                                                    inbound_audio.get());
+      // TODO(hta): This lookup should look for the sender, not the track.
+      rtc::scoped_refptr<AudioTrackInterface> audio_track =
+          track_media_info_map_->GetAudioTrack(voice_receiver_info);
+      if (audio_track) {
+        RTC_DCHECK(track_to_id_.find(audio_track.get()) != track_to_id_.end());
+        inbound_audio
+            ->track_id = RTCMediaStreamTrackStatsIDFromDirectionAndAttachment(
+            kReceiver,
+            track_media_info_map_->GetAttachmentIdByTrack(audio_track).value());
+      }
+      inbound_audio->transport_id = transport_id;
+      report->AddStats(std::move(inbound_audio));
     }
-    inbound_audio->transport_id = transport_id;
-    report->AddStats(std::move(inbound_audio));
+    // Outbound
+    for (const cricket::VoiceSenderInfo& voice_sender_info :
+         track_media_info_map.voice_media_info()->senders) {
+      if (!voice_sender_info.connected())
+        continue;
+      std::unique_ptr<RTCOutboundRTPStreamStats> outbound_audio(
+          new RTCOutboundRTPStreamStats(
+              RTCOutboundRTPStreamStatsIDFromSSRC(
+                  true, voice_sender_info.ssrc()),
+              timestamp_us));
+      SetOutboundRTPStreamStatsFromVoiceSenderInfo(
+          voice_sender_info, outbound_audio.get());
+      rtc::scoped_refptr<AudioTrackInterface> audio_track =
+          track_media_info_map_->GetAudioTrack(voice_sender_info);
+      if (audio_track) {
+        RTC_DCHECK(track_to_id_.find(audio_track.get()) != track_to_id_.end());
+        outbound_audio
+            ->track_id = RTCMediaStreamTrackStatsIDFromDirectionAndAttachment(
+            kSender,
+            track_media_info_map.GetAttachmentIdByTrack(audio_track).value());
+      }
+      outbound_audio->transport_id = transport_id;
+      report->AddStats(std::move(outbound_audio));
+    }
   }
-  // Outbound
-  for (const cricket::VoiceSenderInfo& voice_sender_info :
-       track_media_info_map.voice_media_info()->senders) {
-    if (!voice_sender_info.connected())
-      continue;
-    auto outbound_audio = rtc::MakeUnique<RTCOutboundRTPStreamStats>(
-        RTCOutboundRTPStreamStatsIDFromSSRC(true, voice_sender_info.ssrc()),
-        timestamp_us);
-    SetOutboundRTPStreamStatsFromVoiceSenderInfo(stats.mid, voice_sender_info,
-                                                 outbound_audio.get());
-    rtc::scoped_refptr<AudioTrackInterface> audio_track =
-        track_media_info_map.GetAudioTrack(voice_sender_info);
-    if (audio_track) {
-      outbound_audio->track_id =
-          RTCMediaStreamTrackStatsIDFromDirectionAndAttachment(
-              kSender,
-              track_media_info_map.GetAttachmentIdByTrack(audio_track).value());
+  // Video
+  if (track_media_info_map.video_media_info()) {
+    RTC_DCHECK(video_mid_);
+    const std::string& transport_name = transport_names_by_mid.at(*video_mid_);
+    std::string transport_id = RTCTransportStatsIDFromTransportChannel(
+        transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
+    // Inbound
+    for (const cricket::VideoReceiverInfo& video_receiver_info :
+         track_media_info_map.video_media_info()->receivers) {
+      // TODO(nisse): SSRC == 0 currently means none. Delete check when that
+      // is fixed.
+      if (!video_receiver_info.connected())
+        continue;
+      std::unique_ptr<RTCInboundRTPStreamStats> inbound_video(
+          new RTCInboundRTPStreamStats(
+              RTCInboundRTPStreamStatsIDFromSSRC(
+                  false, video_receiver_info.ssrc()),
+              timestamp_us));
+      SetInboundRTPStreamStatsFromVideoReceiverInfo(
+          video_receiver_info, inbound_video.get());
+      rtc::scoped_refptr<VideoTrackInterface> video_track =
+          track_media_info_map_->GetVideoTrack(video_receiver_info);
+      if (video_track) {
+        RTC_DCHECK(track_to_id_.find(video_track.get()) != track_to_id_.end());
+        inbound_video
+            ->track_id = RTCMediaStreamTrackStatsIDFromDirectionAndAttachment(
+            kReceiver,
+            track_media_info_map_->GetAttachmentIdByTrack(video_track).value());
+      }
+      inbound_video->transport_id = transport_id;
+      report->AddStats(std::move(inbound_video));
     }
-    outbound_audio->transport_id = transport_id;
-    report->AddStats(std::move(outbound_audio));
-  }
-}
-
-void RTCStatsCollector::ProduceVideoRTPStreamStats_n(
-    int64_t timestamp_us,
-    const RtpTransceiverStatsInfo& stats,
-    RTCStatsReport* report) const {
-  RTC_DCHECK(stats.track_media_info_map);
-  const TrackMediaInfoMap& track_media_info_map = *stats.track_media_info_map;
-  RTC_DCHECK(track_media_info_map.video_media_info());
-  std::string transport_id = RTCTransportStatsIDFromTransportChannel(
-      stats.transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
-  // Inbound
-  for (const cricket::VideoReceiverInfo& video_receiver_info :
-       track_media_info_map.video_media_info()->receivers) {
-    if (!video_receiver_info.connected())
-      continue;
-    auto inbound_video = rtc::MakeUnique<RTCInboundRTPStreamStats>(
-        RTCInboundRTPStreamStatsIDFromSSRC(false, video_receiver_info.ssrc()),
-        timestamp_us);
-    SetInboundRTPStreamStatsFromVideoReceiverInfo(
-        stats.mid, video_receiver_info, inbound_video.get());
-    rtc::scoped_refptr<VideoTrackInterface> video_track =
-        track_media_info_map.GetVideoTrack(video_receiver_info);
-    if (video_track) {
-      inbound_video->track_id =
-          RTCMediaStreamTrackStatsIDFromDirectionAndAttachment(
-              kReceiver,
-              track_media_info_map.GetAttachmentIdByTrack(video_track).value());
+    // Outbound
+    for (const cricket::VideoSenderInfo& video_sender_info :
+         track_media_info_map.video_media_info()->senders) {
+      if (!video_sender_info.connected())
+        continue;
+      std::unique_ptr<RTCOutboundRTPStreamStats> outbound_video(
+          new RTCOutboundRTPStreamStats(RTCOutboundRTPStreamStatsIDFromSSRC(
+                                            false, video_sender_info.ssrc()),
+                                        timestamp_us));
+      SetOutboundRTPStreamStatsFromVideoSenderInfo(
+          video_sender_info, outbound_video.get());
+      rtc::scoped_refptr<VideoTrackInterface> video_track =
+          track_media_info_map_->GetVideoTrack(video_sender_info);
+      if (video_track) {
+        RTC_DCHECK(track_to_id_.find(video_track.get()) != track_to_id_.end());
+        outbound_video
+            ->track_id = RTCMediaStreamTrackStatsIDFromDirectionAndAttachment(
+            kSender,
+            track_media_info_map_->GetAttachmentIdByTrack(video_track).value());
+      }
+      outbound_video->transport_id = transport_id;
+      report->AddStats(std::move(outbound_video));
     }
-    inbound_video->transport_id = transport_id;
-    report->AddStats(std::move(inbound_video));
-  }
-  // Outbound
-  for (const cricket::VideoSenderInfo& video_sender_info :
-       track_media_info_map.video_media_info()->senders) {
-    if (!video_sender_info.connected())
-      continue;
-    auto outbound_video = rtc::MakeUnique<RTCOutboundRTPStreamStats>(
-        RTCOutboundRTPStreamStatsIDFromSSRC(false, video_sender_info.ssrc()),
-        timestamp_us);
-    SetOutboundRTPStreamStatsFromVideoSenderInfo(stats.mid, video_sender_info,
-                                                 outbound_video.get());
-    rtc::scoped_refptr<VideoTrackInterface> video_track =
-        track_media_info_map.GetVideoTrack(video_sender_info);
-    if (video_track) {
-      outbound_video->track_id =
-          RTCMediaStreamTrackStatsIDFromDirectionAndAttachment(
-              kSender,
-              track_media_info_map.GetAttachmentIdByTrack(video_track).value());
-    }
-    outbound_video->transport_id = transport_id;
-    report->AddStats(std::move(outbound_video));
   }
 }
 
@@ -1236,100 +1243,47 @@
   return transport_cert_stats;
 }
 
-std::vector<RTCStatsCollector::RtpTransceiverStatsInfo>
-RTCStatsCollector::PrepareTransceiverStatsInfos_s() const {
-  std::vector<RtpTransceiverStatsInfo> transceiver_stats_infos;
-
-  // These are used to invoke GetStats for all the media channels together in
-  // one worker thread hop.
-  std::map<cricket::VoiceMediaChannel*,
-           std::unique_ptr<cricket::VoiceMediaInfo>>
-      voice_stats;
-  std::map<cricket::VideoMediaChannel*,
-           std::unique_ptr<cricket::VideoMediaInfo>>
-      video_stats;
-
-  for (auto transceiver : pc_->GetTransceiversInternal()) {
-    cricket::MediaType media_type = transceiver->internal()->media_type();
-    cricket::BaseChannel* channel = transceiver->internal()->channel();
-    if (!channel) {
-      // No BaseChannel, no stats to collect.
-      continue;
-    }
-
-    // Prepare stats entry. The TrackMediaInfoMap will be filled in after the
-    // stats have been fetched on the worker thread.
-    transceiver_stats_infos.emplace_back();
-    RtpTransceiverStatsInfo& stats = transceiver_stats_infos.back();
-    stats.transceiver = transceiver->internal();
-    stats.media_type = media_type;
-    stats.mid = channel->content_name();
-    stats.transport_name = channel->transport_name();
-
-    if (media_type == cricket::MEDIA_TYPE_AUDIO) {
-      auto* voice_channel = static_cast<cricket::VoiceChannel*>(channel);
-      RTC_DCHECK(voice_stats.find(voice_channel->media_channel()) ==
-                 voice_stats.end());
-      voice_stats[voice_channel->media_channel()] =
-          rtc::MakeUnique<cricket::VoiceMediaInfo>();
-    } else if (media_type == cricket::MEDIA_TYPE_VIDEO) {
-      auto* video_channel = static_cast<cricket::VideoChannel*>(channel);
-      RTC_DCHECK(video_stats.find(video_channel->media_channel()) ==
-                 video_stats.end());
-      video_stats[video_channel->media_channel()] =
-          rtc::MakeUnique<cricket::VideoMediaInfo>();
-    } else {
-      RTC_NOTREACHED();
+std::unique_ptr<TrackMediaInfoMap>
+RTCStatsCollector::PrepareTrackMediaInfoMap_s() const {
+  RTC_DCHECK(signaling_thread_->IsCurrent());
+  std::unique_ptr<cricket::VoiceMediaInfo> voice_media_info;
+  if (pc_->voice_channel()) {
+    voice_media_info.reset(new cricket::VoiceMediaInfo());
+    if (!pc_->voice_channel()->GetStats(voice_media_info.get())) {
+      voice_media_info.reset();
     }
   }
-
-  // Call GetStats for all media channels together on the worker thread in one
-  // hop.
-  worker_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
-    for (const auto& entry : voice_stats) {
-      if (!entry.first->GetStats(entry.second.get())) {
-        RTC_LOG(LS_WARNING) << "Failed to get voice stats.";
-      }
+  std::unique_ptr<cricket::VideoMediaInfo> video_media_info;
+  if (pc_->video_channel()) {
+    video_media_info.reset(new cricket::VideoMediaInfo());
+    if (!pc_->video_channel()->GetStats(video_media_info.get())) {
+      video_media_info.reset();
     }
-    for (const auto& entry : video_stats) {
-      if (!entry.first->GetStats(entry.second.get())) {
-        RTC_LOG(LS_WARNING) << "Failed to get video stats.";
-      }
-    }
-  });
-
-  // Create the TrackMediaInfoMap for each transceiver stats object.
-  for (auto& stats : transceiver_stats_infos) {
-    auto transceiver = stats.transceiver;
-    RTC_DCHECK(transceiver->channel());
-    std::unique_ptr<cricket::VoiceMediaInfo> voice_media_info;
-    std::unique_ptr<cricket::VideoMediaInfo> video_media_info;
-    cricket::MediaType media_type = transceiver->media_type();
-    if (media_type == cricket::MEDIA_TYPE_AUDIO) {
-      auto* voice_channel =
-          static_cast<cricket::VoiceChannel*>(transceiver->channel());
-      RTC_DCHECK(voice_stats[voice_channel->media_channel()]);
-      voice_media_info = std::move(voice_stats[voice_channel->media_channel()]);
-    } else if (media_type == cricket::MEDIA_TYPE_VIDEO) {
-      auto* video_channel =
-          static_cast<cricket::VideoChannel*>(transceiver->channel());
-      RTC_DCHECK(video_stats[video_channel->media_channel()]);
-      video_media_info = std::move(video_stats[video_channel->media_channel()]);
-    }
-    std::vector<rtc::scoped_refptr<RtpSenderInternal>> senders;
-    for (auto sender : transceiver->senders()) {
-      senders.push_back(sender->internal());
-    }
-    std::vector<rtc::scoped_refptr<RtpReceiverInternal>> receivers;
-    for (auto receiver : transceiver->receivers()) {
-      receivers.push_back(receiver->internal());
-    }
-    stats.track_media_info_map = rtc::MakeUnique<TrackMediaInfoMap>(
-        std::move(voice_media_info), std::move(video_media_info), senders,
-        receivers);
   }
+  std::unique_ptr<TrackMediaInfoMap> track_media_info_map(new TrackMediaInfoMap(
+      std::move(voice_media_info), std::move(video_media_info),
+      pc_->GetSenders(), pc_->GetReceivers()));
+  return track_media_info_map;
+}
 
-  return transceiver_stats_infos;
+std::map<MediaStreamTrackInterface*, std::string>
+RTCStatsCollector::PrepareTrackToID_s() const {
+  // TODO(hta): Remove this method, and vector its callers via
+  // senders / receivers instead.
+  // It ignores tracks that are multiply connected to the PC.
+  RTC_DCHECK(signaling_thread_->IsCurrent());
+  std::map<MediaStreamTrackInterface*, std::string> track_to_id;
+  for (auto sender : pc_->GetSenders()) {
+    auto track = sender->track();
+    if (track)
+      track_to_id[track.get()] = track->id();
+  }
+  for (auto receiver : pc_->GetReceivers()) {
+    auto track = receiver->track();
+    if (track)
+      track_to_id[track.get()] = track->id();
+  }
+  return track_to_id;
 }
 
 void RTCStatsCollector::OnDataChannelCreated(DataChannel* channel) {
diff --git a/pc/rtcstatscollector.h b/pc/rtcstatscollector.h
index f88586a..24a7bb2 100644
--- a/pc/rtcstatscollector.h
+++ b/pc/rtcstatscollector.h
@@ -78,19 +78,6 @@
     std::unique_ptr<rtc::SSLCertificateStats> remote;
   };
 
-  // Structure for tracking stats about each RtpTransceiver managed by the
-  // PeerConnection. This can either by a Plan B style or Unified Plan style
-  // transceiver (i.e., can have 0 or many senders and receivers).
-  // Some fields are copied from the RtpTransceiver/BaseChannel object so that
-  // they can be accessed safely on threads other than the signaling thread.
-  struct RtpTransceiverStatsInfo {
-    rtc::scoped_refptr<RtpTransceiver> transceiver;
-    cricket::MediaType media_type;
-    std::string mid;
-    std::string transport_name;
-    std::unique_ptr<TrackMediaInfoMap> track_media_info_map;
-  };
-
   void AddPartialResults_s(rtc::scoped_refptr<RTCStatsReport> partial_report);
   void DeliverCachedReport();
 
@@ -101,8 +88,7 @@
       RTCStatsReport* report) const;
   // Produces |RTCCodecStats|.
   void ProduceCodecStats_n(
-      int64_t timestamp_us,
-      const std::vector<RtpTransceiverStatsInfo>& transceiver_stats_infos,
+      int64_t timestamp_us, const TrackMediaInfoMap& track_media_info_map,
       RTCStatsReport* report) const;
   // Produces |RTCDataChannelStats|.
   void ProduceDataChannelStats_s(
@@ -112,28 +98,21 @@
       int64_t timestamp_us,
       const std::map<std::string, cricket::TransportStats>&
           transport_stats_by_name,
+      const cricket::VideoMediaInfo* video_media_info,
       const Call::Stats& call_stats,
       RTCStatsReport* report) const;
-  // Produces |RTCMediaStreamStats|.
-  void ProduceMediaStreamStats_s(int64_t timestamp_us,
-                                 RTCStatsReport* report) const;
-  // Produces |RTCMediaStreamTrackStats|.
-  void ProduceMediaStreamTrackStats_s(int64_t timestamp_us,
-                                      RTCStatsReport* report) const;
+  // Produces |RTCMediaStreamStats| and |RTCMediaStreamTrackStats|.
+  void ProduceMediaStreamAndTrackStats_s(
+      int64_t timestamp_us, RTCStatsReport* report) const;
   // Produces |RTCPeerConnectionStats|.
   void ProducePeerConnectionStats_s(
       int64_t timestamp_us, RTCStatsReport* report) const;
   // Produces |RTCInboundRTPStreamStats| and |RTCOutboundRTPStreamStats|.
   void ProduceRTPStreamStats_n(
       int64_t timestamp_us,
-      const std::vector<RtpTransceiverStatsInfo>& transceiver_stats_infos,
+      const std::map<std::string, std::string>& transport_names_by_mid,
+      const TrackMediaInfoMap& track_media_info_map,
       RTCStatsReport* report) const;
-  void ProduceAudioRTPStreamStats_n(int64_t timestamp_us,
-                                    const RtpTransceiverStatsInfo& stats,
-                                    RTCStatsReport* report) const;
-  void ProduceVideoRTPStreamStats_n(int64_t timestamp_us,
-                                    const RtpTransceiverStatsInfo& stats,
-                                    RTCStatsReport* report) const;
   // Produces |RTCTransportStats|.
   void ProduceTransportStats_n(
       int64_t timestamp_us,
@@ -147,7 +126,8 @@
   PrepareTransportCertificateStats_n(
       const std::map<std::string, cricket::TransportStats>&
           transport_stats_by_name) const;
-  std::vector<RtpTransceiverStatsInfo> PrepareTransceiverStatsInfos_s() const;
+  std::unique_ptr<TrackMediaInfoMap> PrepareTrackMediaInfoMap_s() const;
+  std::map<MediaStreamTrackInterface*, std::string> PrepareTrackToID_s() const;
 
   // Slots for signals (sigslot) that are wired up to |pc_|.
   void OnDataChannelCreated(DataChannel* channel);
@@ -170,7 +150,12 @@
   // |ProducePartialResultsOnSignalingThread|, reset after work is complete. Not
   // passed as arguments to avoid copies. This is thread safe - when we
   // set/reset we know there are no pending stats requests in progress.
-  std::vector<RtpTransceiverStatsInfo> transceiver_stats_infos_;
+  std::map<std::string, std::string> transport_names_by_mid_;
+  std::unique_ptr<TrackMediaInfoMap> track_media_info_map_;
+  std::map<MediaStreamTrackInterface*, std::string> track_to_id_;
+
+  rtc::Optional<std::string> voice_mid_;
+  rtc::Optional<std::string> video_mid_;
 
   Call::Stats call_stats_;
 
diff --git a/pc/rtcstatscollector_unittest.cc b/pc/rtcstatscollector_unittest.cc
index a54367d..566d677 100644
--- a/pc/rtcstatscollector_unittest.cc
+++ b/pc/rtcstatscollector_unittest.cc
@@ -18,6 +18,8 @@
 #include "api/rtpparameters.h"
 #include "api/stats/rtcstats_objects.h"
 #include "api/stats/rtcstatsreport.h"
+#include "api/test/mock_rtpreceiver.h"
+#include "api/test/mock_rtpsender.h"
 #include "p2p/base/p2pconstants.h"
 #include "p2p/base/port.h"
 #include "pc/mediastream.h"
@@ -25,8 +27,6 @@
 #include "pc/rtcstatscollector.h"
 #include "pc/test/fakepeerconnectionforstats.h"
 #include "pc/test/mock_datachannel.h"
-#include "pc/test/mock_rtpreceiverinternal.h"
-#include "pc/test/mock_rtpsenderinternal.h"
 #include "pc/test/rtcstatsobtainer.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/fakeclock.h"
@@ -38,7 +38,6 @@
 #include "rtc_base/timedelta.h"
 #include "rtc_base/timeutils.h"
 
-using testing::AtLeast;
 using testing::Invoke;
 using testing::Return;
 
@@ -244,13 +243,13 @@
   }
 }
 
-rtc::scoped_refptr<MockRtpSenderInternal> CreateMockSender(
+rtc::scoped_refptr<MockRtpSender> CreateMockSender(
     const rtc::scoped_refptr<MediaStreamTrackInterface>& track,
     uint32_t ssrc,
     int attachment_id,
     std::vector<std::string> local_stream_ids) {
-  rtc::scoped_refptr<MockRtpSenderInternal> sender(
-      new rtc::RefCountedObject<MockRtpSenderInternal>());
+  rtc::scoped_refptr<MockRtpSender> sender(
+      new rtc::RefCountedObject<MockRtpSender>());
   EXPECT_CALL(*sender, track()).WillRepeatedly(Return(track));
   EXPECT_CALL(*sender, ssrc()).WillRepeatedly(Return(ssrc));
   EXPECT_CALL(*sender, media_type()).WillRepeatedly(Return(
@@ -268,12 +267,12 @@
   return sender;
 }
 
-rtc::scoped_refptr<MockRtpReceiverInternal> CreateMockReceiver(
+rtc::scoped_refptr<MockRtpReceiver> CreateMockReceiver(
     const rtc::scoped_refptr<MediaStreamTrackInterface>& track,
     uint32_t ssrc,
     int attachment_id) {
-  rtc::scoped_refptr<MockRtpReceiverInternal> receiver(
-      new rtc::RefCountedObject<MockRtpReceiverInternal>());
+  rtc::scoped_refptr<MockRtpReceiver> receiver(
+      new rtc::RefCountedObject<MockRtpReceiver>());
   EXPECT_CALL(*receiver, track()).WillRepeatedly(Return(track));
   EXPECT_CALL(*receiver, streams())
       .WillRepeatedly(
@@ -347,7 +346,7 @@
       }
     }
 
-    rtc::scoped_refptr<MockRtpSenderInternal> sender =
+    rtc::scoped_refptr<MockRtpSender> sender =
         CreateMockSender(track, ssrc, 50, {});
     pc_->AddSender(sender);
   }
@@ -370,7 +369,7 @@
       remote_stream->AddTrack(static_cast<VideoTrackInterface*>(track.get()));
     }
 
-    rtc::scoped_refptr<MockRtpReceiverInternal> receiver =
+    rtc::scoped_refptr<MockRtpReceiver> receiver =
         CreateMockReceiver(track, ssrc, 62);
     EXPECT_CALL(*receiver, streams())
         .WillRepeatedly(
@@ -411,7 +410,7 @@
                     MediaStreamTrackInterface::kAudioKind);
 
       voice_media_info.senders.push_back(voice_sender_info);
-      rtc::scoped_refptr<MockRtpSenderInternal> rtp_sender = CreateMockSender(
+      rtc::scoped_refptr<MockRtpSender> rtp_sender = CreateMockSender(
           rtc::scoped_refptr<MediaStreamTrackInterface>(local_audio_track),
           voice_sender_info.local_stats[0].ssrc, attachment_id++,
           local_stream_ids);
@@ -427,10 +426,9 @@
                     MediaStreamTrackInterface::kAudioKind);
 
       voice_media_info.receivers.push_back(voice_receiver_info);
-      rtc::scoped_refptr<MockRtpReceiverInternal> rtp_receiver =
-          CreateMockReceiver(
-              rtc::scoped_refptr<MediaStreamTrackInterface>(remote_audio_track),
-              voice_receiver_info.local_stats[0].ssrc, attachment_id++);
+      rtc::scoped_refptr<MockRtpReceiver> rtp_receiver = CreateMockReceiver(
+          rtc::scoped_refptr<MediaStreamTrackInterface>(remote_audio_track),
+          voice_receiver_info.local_stats[0].ssrc, attachment_id++);
       EXPECT_CALL(*rtp_receiver, streams())
           .WillRepeatedly(Return(remote_streams));
       pc_->AddReceiver(rtp_receiver);
@@ -445,7 +443,7 @@
                     MediaStreamTrackInterface::kVideoKind);
 
       video_media_info.senders.push_back(video_sender_info);
-      rtc::scoped_refptr<MockRtpSenderInternal> rtp_sender = CreateMockSender(
+      rtc::scoped_refptr<MockRtpSender> rtp_sender = CreateMockSender(
           rtc::scoped_refptr<MediaStreamTrackInterface>(local_video_track),
           video_sender_info.local_stats[0].ssrc, attachment_id++,
           local_stream_ids);
@@ -461,10 +459,9 @@
                     MediaStreamTrackInterface::kVideoKind);
 
       video_media_info.receivers.push_back(video_receiver_info);
-      rtc::scoped_refptr<MockRtpReceiverInternal> rtp_receiver =
-          CreateMockReceiver(
-              rtc::scoped_refptr<MediaStreamTrackInterface>(remote_video_track),
-              video_receiver_info.local_stats[0].ssrc, attachment_id++);
+      rtc::scoped_refptr<MockRtpReceiver> rtp_receiver = CreateMockReceiver(
+          rtc::scoped_refptr<MediaStreamTrackInterface>(remote_video_track),
+          video_receiver_info.local_stats[0].ssrc, attachment_id++);
       EXPECT_CALL(*rtp_receiver, streams())
           .WillRepeatedly(Return(remote_streams));
       pc_->AddReceiver(rtp_receiver);
@@ -609,7 +606,7 @@
   voice_media_info.send_codecs.insert(
       std::make_pair(outbound_audio_codec.payload_type, outbound_audio_codec));
 
-  auto* voice_media_channel = pc_->AddVoiceChannel("AudioMid", "TransportName");
+  auto* voice_media_channel = pc_->AddVoiceChannel("audio", "TransportName");
   voice_media_channel->SetStats(voice_media_info);
 
   // Video
@@ -631,31 +628,31 @@
   video_media_info.send_codecs.insert(
       std::make_pair(outbound_video_codec.payload_type, outbound_video_codec));
 
-  auto* video_media_channel = pc_->AddVideoChannel("VideoMid", "TransportName");
+  auto* video_media_channel = pc_->AddVideoChannel("video", "TransportName");
   video_media_channel->SetStats(video_media_info);
 
   rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
 
-  RTCCodecStats expected_inbound_audio_codec("RTCCodec_AudioMid_Inbound_1",
-                                             report->timestamp_us());
+  RTCCodecStats expected_inbound_audio_codec(
+      "RTCCodec_InboundAudio_1", report->timestamp_us());
   expected_inbound_audio_codec.payload_type = 1;
   expected_inbound_audio_codec.mime_type = "audio/opus";
   expected_inbound_audio_codec.clock_rate = 1337;
 
-  RTCCodecStats expected_outbound_audio_codec("RTCCodec_AudioMid_Outbound_2",
-                                              report->timestamp_us());
+  RTCCodecStats expected_outbound_audio_codec(
+      "RTCCodec_OutboundAudio_2", report->timestamp_us());
   expected_outbound_audio_codec.payload_type = 2;
   expected_outbound_audio_codec.mime_type = "audio/isac";
   expected_outbound_audio_codec.clock_rate = 1338;
 
-  RTCCodecStats expected_inbound_video_codec("RTCCodec_VideoMid_Inbound_3",
-                                             report->timestamp_us());
+  RTCCodecStats expected_inbound_video_codec(
+      "RTCCodec_InboundVideo_3", report->timestamp_us());
   expected_inbound_video_codec.payload_type = 3;
   expected_inbound_video_codec.mime_type = "video/H264";
   expected_inbound_video_codec.clock_rate = 1339;
 
-  RTCCodecStats expected_outbound_video_codec("RTCCodec_VideoMid_Outbound_4",
-                                              report->timestamp_us());
+  RTCCodecStats expected_outbound_video_codec(
+      "RTCCodec_OutboundVideo_4", report->timestamp_us());
   expected_outbound_video_codec.payload_type = 4;
   expected_outbound_video_codec.mime_type = "video/VP8";
   expected_outbound_video_codec.clock_rate = 1340;
@@ -1447,6 +1444,8 @@
 }
 
 TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Audio) {
+  const char kTransportName[] = "TransportName";
+
   cricket::VoiceMediaInfo voice_media_info;
 
   voice_media_info.receivers.push_back(cricket::VoiceReceiverInfo());
@@ -1468,7 +1467,7 @@
   voice_media_info.receive_codecs.insert(
       std::make_pair(codec_parameters.payload_type, codec_parameters));
 
-  auto* voice_media_channel = pc_->AddVoiceChannel("AudioMid", "TransportName");
+  auto* voice_media_channel = pc_->AddVoiceChannel("voice", kTransportName);
   voice_media_channel->SetStats(voice_media_info);
   stats_->SetupRemoteTrackAndReceiver(cricket::MEDIA_TYPE_AUDIO,
                                       "RemoteAudioTrackID", 1);
@@ -1484,8 +1483,10 @@
   expected_audio.is_remote = false;
   expected_audio.media_type = "audio";
   expected_audio.track_id = stats_of_track_type[0]->id();
-  expected_audio.transport_id = "RTCTransport_TransportName_1";
-  expected_audio.codec_id = "RTCCodec_AudioMid_Inbound_42";
+  expected_audio.transport_id =
+      "RTCTransport_TransportName_" +
+      rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTP);
+  expected_audio.codec_id = "RTCCodec_InboundAudio_42";
   expected_audio.packets_received = 2;
   expected_audio.bytes_received = 3;
   expected_audio.packets_lost = -1;
@@ -1526,7 +1527,7 @@
   video_media_info.receive_codecs.insert(
       std::make_pair(codec_parameters.payload_type, codec_parameters));
 
-  auto* video_media_channel = pc_->AddVideoChannel("VideoMid", "TransportName");
+  auto* video_media_channel = pc_->AddVideoChannel("video", "TransportName");
   video_media_channel->SetStats(video_media_info);
   stats_->SetupRemoteTrackAndReceiver(cricket::MEDIA_TYPE_VIDEO,
                                       "RemoteVideoTrackID", 1);
@@ -1539,8 +1540,9 @@
   expected_video.is_remote = false;
   expected_video.media_type = "video";
   expected_video.track_id = IdForType<RTCMediaStreamTrackStats>(report);
-  expected_video.transport_id = "RTCTransport_TransportName_1";
-  expected_video.codec_id = "RTCCodec_VideoMid_Inbound_42";
+  expected_video.transport_id = "RTCTransport_TransportName_" +
+      rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTP);
+  expected_video.codec_id = "RTCCodec_InboundVideo_42";
   expected_video.fir_count = 5;
   expected_video.pli_count = 6;
   expected_video.nack_count = 7;
@@ -1590,7 +1592,7 @@
   voice_media_info.send_codecs.insert(
       std::make_pair(codec_parameters.payload_type, codec_parameters));
 
-  auto* voice_media_channel = pc_->AddVoiceChannel("AudioMid", "TransportName");
+  auto* voice_media_channel = pc_->AddVoiceChannel("audio", "TransportName");
   voice_media_channel->SetStats(voice_media_info);
   stats_->SetupLocalTrackAndSender(cricket::MEDIA_TYPE_AUDIO,
                                    "LocalAudioTrackID", 1, true);
@@ -1603,8 +1605,9 @@
   expected_audio.is_remote = false;
   expected_audio.media_type = "audio";
   expected_audio.track_id = IdForType<RTCMediaStreamTrackStats>(report);
-  expected_audio.transport_id = "RTCTransport_TransportName_1";
-  expected_audio.codec_id = "RTCCodec_AudioMid_Outbound_42";
+  expected_audio.transport_id = "RTCTransport_TransportName_" +
+      rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTP);
+  expected_audio.codec_id = "RTCCodec_OutboundAudio_42";
   expected_audio.packets_sent = 2;
   expected_audio.bytes_sent = 3;
 
@@ -1645,7 +1648,7 @@
   video_media_info.send_codecs.insert(
       std::make_pair(codec_parameters.payload_type, codec_parameters));
 
-  auto* video_media_channel = pc_->AddVideoChannel("VideoMid", "TransportName");
+  auto* video_media_channel = pc_->AddVideoChannel("video", "TransportName");
   video_media_channel->SetStats(video_media_info);
   stats_->SetupLocalTrackAndSender(cricket::MEDIA_TYPE_VIDEO,
                                    "LocalVideoTrackID", 1, true);
@@ -1663,8 +1666,9 @@
   expected_video.is_remote = false;
   expected_video.media_type = "video";
   expected_video.track_id = stats_of_track_type[0]->id();
-  expected_video.transport_id = "RTCTransport_TransportName_1";
-  expected_video.codec_id = "RTCCodec_VideoMid_Outbound_42";
+  expected_video.transport_id = "RTCTransport_TransportName_" +
+      rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTP);
+  expected_video.codec_id = "RTCCodec_OutboundVideo_42";
   expected_video.fir_count = 2;
   expected_video.pli_count = 3;
   expected_video.nack_count = 4;
@@ -1850,7 +1854,7 @@
       std::make_pair(codec_parameters.payload_type, codec_parameters));
 
   // Emulates the case where AddTrack is used without an associated MediaStream
-  auto* voice_media_channel = pc_->AddVoiceChannel("AudioMid", "TransportName");
+  auto* voice_media_channel = pc_->AddVoiceChannel("audio", "TransportName");
   voice_media_channel->SetStats(voice_media_info);
   stats_->SetupLocalTrackAndSender(cricket::MEDIA_TYPE_AUDIO,
                                    "LocalAudioTrackID", 1, false);
@@ -1863,8 +1867,10 @@
   expected_audio.is_remote = false;
   expected_audio.media_type = "audio";
   expected_audio.track_id = IdForType<RTCMediaStreamTrackStats>(report);
-  expected_audio.transport_id = "RTCTransport_TransportName_1";
-  expected_audio.codec_id = "RTCCodec_AudioMid_Outbound_42";
+  expected_audio.transport_id =
+      "RTCTransport_TransportName_" +
+      rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTP);
+  expected_audio.codec_id = "RTCCodec_OutboundAudio_42";
   expected_audio.packets_sent = 2;
   expected_audio.bytes_sent = 3;
 
@@ -1881,13 +1887,10 @@
 // SSRC 0, meaning "unconnected".
 // In this state, we report on track stats, but not RTP stats.
 TEST_F(RTCStatsCollectorTest, StatsReportedOnZeroSsrc) {
-  pc_->AddVoiceChannel("audio", "transport");
-
   rtc::scoped_refptr<MediaStreamTrackInterface> track =
       CreateFakeTrack(cricket::MEDIA_TYPE_AUDIO, "audioTrack",
                       MediaStreamTrackInterface::kLive);
-  rtc::scoped_refptr<MockRtpSenderInternal> sender =
-      CreateMockSender(track, 0, 49, {});
+  rtc::scoped_refptr<MockRtpSender> sender = CreateMockSender(track, 0, 49, {});
   pc_->AddSender(sender);
 
   rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
@@ -1902,12 +1905,10 @@
 }
 
 TEST_F(RTCStatsCollectorTest, DoNotCrashOnSsrcChange) {
-  pc_->AddVoiceChannel("audio", "transport");
-
   rtc::scoped_refptr<MediaStreamTrackInterface> track =
       CreateFakeTrack(cricket::MEDIA_TYPE_AUDIO, "audioTrack",
                       MediaStreamTrackInterface::kLive);
-  rtc::scoped_refptr<MockRtpSenderInternal> sender =
+  rtc::scoped_refptr<MockRtpSender> sender =
       CreateMockSender(track, 4711, 49, {});
   pc_->AddSender(sender);
 
diff --git a/pc/rtpreceiver.cc b/pc/rtpreceiver.cc
index bf0b1d6..05990f4 100644
--- a/pc/rtpreceiver.cc
+++ b/pc/rtpreceiver.cc
@@ -202,6 +202,11 @@
   }
 }
 
+void AudioRtpReceiver::SetMediaChannel(
+    cricket::VoiceMediaChannel* media_channel) {
+  media_channel_ = media_channel;
+}
+
 void AudioRtpReceiver::NotifyFirstPacketReceived() {
   if (observer_) {
     observer_->OnFirstPacketReceived(media_type());
@@ -337,6 +342,11 @@
   }
 }
 
+void VideoRtpReceiver::SetMediaChannel(
+    cricket::VideoMediaChannel* media_channel) {
+  media_channel_ = media_channel;
+}
+
 void VideoRtpReceiver::NotifyFirstPacketReceived() {
   if (observer_) {
     observer_->OnFirstPacketReceived(media_type());
diff --git a/pc/rtpreceiver.h b/pc/rtpreceiver.h
index da92298..887f828 100644
--- a/pc/rtpreceiver.h
+++ b/pc/rtpreceiver.h
@@ -34,16 +34,6 @@
  public:
   virtual void Stop() = 0;
 
-  // Sets the underlying MediaEngine channel associated with this RtpSender.
-  // SetVoiceMediaChannel should be used for audio RtpSenders and
-  // SetVideoMediaChannel should be used for video RtpSenders. Must call the
-  // appropriate SetXxxMediaChannel(nullptr) before the media channel is
-  // destroyed.
-  virtual void SetVoiceMediaChannel(
-      cricket::VoiceMediaChannel* voice_media_channel) = 0;
-  virtual void SetVideoMediaChannel(
-      cricket::VideoMediaChannel* video_media_channel) = 0;
-
   // Configures the RtpReceiver with the underlying media channel, with the
   // given SSRC as the stream identifier. If |ssrc| is 0, the receiver will
   // receive packets on unsignaled SSRCs.
@@ -62,11 +52,6 @@
   // any new streams.
   virtual void SetStreams(
       const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) = 0;
-
-  // Returns an ID that changes if the attached track changes, but
-  // otherwise remains constant. Used to generate IDs for stats.
-  // The special value zero means that no track is attached.
-  virtual int AttachmentId() const = 0;
 };
 
 class AudioRtpReceiver : public ObserverInterface,
@@ -117,14 +102,9 @@
 
   void SetObserver(RtpReceiverObserverInterface* observer) override;
 
-  void SetVoiceMediaChannel(
-      cricket::VoiceMediaChannel* voice_media_channel) override {
-    media_channel_ = voice_media_channel;
-  }
-  void SetVideoMediaChannel(
-      cricket::VideoMediaChannel* video_media_channel) override {
-    RTC_NOTREACHED();
-  }
+  // Does not take ownership.
+  // Should call SetMediaChannel(nullptr) before |media_channel| is destroyed.
+  void SetMediaChannel(cricket::VoiceMediaChannel* media_channel);
 
   std::vector<RtpSource> GetSources() const override;
   int AttachmentId() const override { return attachment_id_; }
@@ -191,16 +171,9 @@
 
   void SetObserver(RtpReceiverObserverInterface* observer) override;
 
-  void SetVoiceMediaChannel(
-      cricket::VoiceMediaChannel* voice_media_channel) override {
-    RTC_NOTREACHED();
-  }
-  void SetVideoMediaChannel(
-      cricket::VideoMediaChannel* video_media_channel) override {
-    media_channel_ = video_media_channel;
-  }
-
-  int AttachmentId() const override { return attachment_id_; }
+  // Does not take ownership.
+  // Should call SetMediaChannel(nullptr) before |media_channel| is destroyed.
+  void SetMediaChannel(cricket::VideoMediaChannel* media_channel);
 
  private:
   bool SetSink(rtc::VideoSinkInterface<VideoFrame>* sink);
diff --git a/pc/rtpsender.h b/pc/rtpsender.h
index 000df94..97e32e2 100644
--- a/pc/rtpsender.h
+++ b/pc/rtpsender.h
@@ -34,16 +34,6 @@
 // Internal interface used by PeerConnection.
 class RtpSenderInternal : public RtpSenderInterface {
  public:
-  // Sets the underlying MediaEngine channel associated with this RtpSender.
-  // SetVoiceMediaChannel should be used for audio RtpSenders and
-  // SetVideoMediaChannel should be used for video RtpSenders. Must call the
-  // appropriate SetXxxMediaChannel(nullptr) before the media channel is
-  // destroyed.
-  virtual void SetVoiceMediaChannel(
-      cricket::VoiceMediaChannel* voice_media_channel) = 0;
-  virtual void SetVideoMediaChannel(
-      cricket::VideoMediaChannel* video_media_channel) = 0;
-
   // Used to set the SSRC of the sender, once a local description has been set.
   // If |ssrc| is 0, this indiates that the sender should disconnect from the
   // underlying transport (this occurs if the sender isn't seen in a local
@@ -59,11 +49,6 @@
   virtual void set_stream_ids(const std::vector<std::string>& stream_ids) = 0;
 
   virtual void Stop() = 0;
-
-  // Returns an ID that changes every time SetTrack() is called, but
-  // otherwise remains constant. Used to generate IDs for stats.
-  // The special value zero means that no track is attached.
-  virtual int AttachmentId() const = 0;
 };
 
 // LocalAudioSinkAdapter receives data callback as a sink to the local
@@ -154,13 +139,10 @@
 
   int AttachmentId() const override { return attachment_id_; }
 
-  void SetVoiceMediaChannel(
-      cricket::VoiceMediaChannel* voice_media_channel) override {
-    media_channel_ = voice_media_channel;
-  }
-  void SetVideoMediaChannel(
-      cricket::VideoMediaChannel* video_media_channel) override {
-    RTC_NOTREACHED();
+  // Does not take ownership.
+  // Should call SetMediaChannel(nullptr) before |media_channel| is destroyed.
+  void SetMediaChannel(cricket::VoiceMediaChannel* media_channel) {
+    media_channel_ = media_channel;
   }
 
  private:
@@ -247,13 +229,10 @@
   void Stop() override;
   int AttachmentId() const override { return attachment_id_; }
 
-  void SetVoiceMediaChannel(
-      cricket::VoiceMediaChannel* voice_media_channel) override {
-    RTC_NOTREACHED();
-  }
-  void SetVideoMediaChannel(
-      cricket::VideoMediaChannel* video_media_channel) override {
-    media_channel_ = video_media_channel;
+  // Does not take ownership.
+  // Should call SetMediaChannel(nullptr) before |media_channel| is destroyed.
+  void SetMediaChannel(cricket::VideoMediaChannel* media_channel) {
+    media_channel_ = media_channel;
   }
 
  private:
diff --git a/pc/rtpsenderreceiver_unittest.cc b/pc/rtpsenderreceiver_unittest.cc
index 4223264..40ed368 100644
--- a/pc/rtpsenderreceiver_unittest.cc
+++ b/pc/rtpsenderreceiver_unittest.cc
@@ -139,7 +139,7 @@
     audio_rtp_sender_ =
         new AudioRtpSender(worker_thread_, local_stream_->GetAudioTracks()[0],
                            {local_stream_->label()}, nullptr);
-    audio_rtp_sender_->SetVoiceMediaChannel(voice_media_channel_);
+    audio_rtp_sender_->SetMediaChannel(voice_media_channel_);
     audio_rtp_sender_->SetSsrc(kAudioSsrc);
     audio_rtp_sender_->GetOnDestroyedSignal()->connect(
         this, &RtpSenderReceiverTest::OnAudioSenderDestroyed);
@@ -148,7 +148,7 @@
 
   void CreateAudioRtpSenderWithNoTrack() {
     audio_rtp_sender_ = new AudioRtpSender(worker_thread_, nullptr);
-    audio_rtp_sender_->SetVoiceMediaChannel(voice_media_channel_);
+    audio_rtp_sender_->SetMediaChannel(voice_media_channel_);
   }
 
   void OnAudioSenderDestroyed() { audio_sender_destroyed_signal_fired_ = true; }
@@ -160,14 +160,14 @@
     video_rtp_sender_ =
         new VideoRtpSender(worker_thread_, local_stream_->GetVideoTracks()[0],
                            {local_stream_->label()});
-    video_rtp_sender_->SetVideoMediaChannel(video_media_channel_);
+    video_rtp_sender_->SetMediaChannel(video_media_channel_);
     video_rtp_sender_->SetSsrc(kVideoSsrc);
     VerifyVideoChannelInput();
   }
 
   void CreateVideoRtpSenderWithNoTrack() {
     video_rtp_sender_ = new VideoRtpSender(worker_thread_);
-    video_rtp_sender_->SetVideoMediaChannel(video_media_channel_);
+    video_rtp_sender_->SetMediaChannel(video_media_channel_);
   }
 
   void DestroyAudioRtpSender() {
@@ -184,7 +184,7 @@
       std::vector<rtc::scoped_refptr<MediaStreamInterface>> streams = {}) {
     audio_rtp_receiver_ = new AudioRtpReceiver(
         rtc::Thread::Current(), kAudioTrackId, std::move(streams));
-    audio_rtp_receiver_->SetVoiceMediaChannel(voice_media_channel_);
+    audio_rtp_receiver_->SetMediaChannel(voice_media_channel_);
     audio_rtp_receiver_->SetupMediaChannel(kAudioSsrc);
     audio_track_ = audio_rtp_receiver_->audio_track();
     VerifyVoiceChannelOutput();
@@ -194,7 +194,7 @@
       std::vector<rtc::scoped_refptr<MediaStreamInterface>> streams = {}) {
     video_rtp_receiver_ = new VideoRtpReceiver(
         rtc::Thread::Current(), kVideoTrackId, std::move(streams));
-    video_rtp_receiver_->SetVideoMediaChannel(video_media_channel_);
+    video_rtp_receiver_->SetMediaChannel(video_media_channel_);
     video_rtp_receiver_->SetupMediaChannel(kVideoSsrc);
     video_track_ = video_rtp_receiver_->video_track();
     VerifyVideoChannelOutput();
@@ -783,7 +783,7 @@
   video_rtp_sender_ = new VideoRtpSender(worker_thread_,
                                          local_stream_->GetVideoTracks()[0],
                                          {local_stream_->label()});
-  video_rtp_sender_->SetVideoMediaChannel(video_media_channel_);
+  video_rtp_sender_->SetMediaChannel(video_media_channel_);
   video_track_->set_enabled(true);
 
   // Sender is not ready to send (no SSRC) so no option should have been set.
diff --git a/pc/rtptransceiver.cc b/pc/rtptransceiver.cc
index 1f1a850..310c4c4 100644
--- a/pc/rtptransceiver.cc
+++ b/pc/rtptransceiver.cc
@@ -61,12 +61,14 @@
   for (auto sender : senders_) {
     if (media_type() == cricket::MEDIA_TYPE_AUDIO) {
       auto* voice_channel = static_cast<cricket::VoiceChannel*>(channel);
-      sender->internal()->SetVoiceMediaChannel(
-          voice_channel ? voice_channel->media_channel() : nullptr);
+      static_cast<AudioRtpSender*>(sender->internal())
+          ->SetMediaChannel(voice_channel ? voice_channel->media_channel()
+                                          : nullptr);
     } else {
       auto* video_channel = static_cast<cricket::VideoChannel*>(channel);
-      sender->internal()->SetVideoMediaChannel(
-          video_channel ? video_channel->media_channel() : nullptr);
+      static_cast<VideoRtpSender*>(sender->internal())
+          ->SetMediaChannel(video_channel ? video_channel->media_channel()
+                                          : nullptr);
     }
   }
 
@@ -76,12 +78,14 @@
     }
     if (media_type() == cricket::MEDIA_TYPE_AUDIO) {
       auto* voice_channel = static_cast<cricket::VoiceChannel*>(channel);
-      receiver->internal()->SetVoiceMediaChannel(
-          voice_channel ? voice_channel->media_channel() : nullptr);
+      static_cast<AudioRtpReceiver*>(receiver->internal())
+          ->SetMediaChannel(voice_channel ? voice_channel->media_channel()
+                                          : nullptr);
     } else {
       auto* video_channel = static_cast<cricket::VideoChannel*>(channel);
-      receiver->internal()->SetVideoMediaChannel(
-          video_channel ? video_channel->media_channel() : nullptr);
+      static_cast<VideoRtpReceiver*>(receiver->internal())
+          ->SetMediaChannel(video_channel ? video_channel->media_channel()
+                                          : nullptr);
     }
   }
 }
diff --git a/pc/test/fakepeerconnectionforstats.h b/pc/test/fakepeerconnectionforstats.h
index be8003e..d73e734 100644
--- a/pc/test/fakepeerconnectionforstats.h
+++ b/pc/test/fakepeerconnectionforstats.h
@@ -97,23 +97,12 @@
     return remote_streams_;
   }
 
-  void AddSender(rtc::scoped_refptr<RtpSenderInternal> sender) {
-    // TODO(steveanton): Switch tests to use RtpTransceivers directly.
-    auto sender_proxy = RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
-        signaling_thread_, sender);
-    GetOrCreateFirstTransceiverOfType(sender->media_type())
-        ->internal()
-        ->AddSender(sender_proxy);
+  void AddSender(rtc::scoped_refptr<RtpSenderInterface> sender) {
+    senders_.push_back(sender);
   }
 
-  void AddReceiver(rtc::scoped_refptr<RtpReceiverInternal> receiver) {
-    // TODO(steveanton): Switch tests to use RtpTransceivers directly.
-    auto receiver_proxy =
-        RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create(
-            signaling_thread_, receiver);
-    GetOrCreateFirstTransceiverOfType(receiver->media_type())
-        ->internal()
-        ->AddReceiver(receiver_proxy);
+  void AddReceiver(rtc::scoped_refptr<RtpReceiverInterface> receiver) {
+    receivers_.push_back(receiver);
   }
 
   FakeVoiceMediaChannelForStats* AddVoiceChannel(
@@ -127,9 +116,10 @@
         std::move(voice_media_channel), mid, kDefaultRtcpMuxRequired,
         kDefaultSrtpRequired);
     voice_channel_->set_transport_name_for_testing(transport_name);
-    GetOrCreateFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)
-        ->internal()
-        ->SetChannel(voice_channel_.get());
+    auto transceiver = RtpTransceiverProxyWithInternal<RtpTransceiver>::Create(
+        signaling_thread_, new RtpTransceiver(cricket::MEDIA_TYPE_AUDIO));
+    transceiver->internal()->SetChannel(voice_channel_.get());
+    transceivers_.push_back(transceiver);
     return voice_media_channel_ptr;
   }
 
@@ -144,9 +134,10 @@
         std::move(video_media_channel), mid, kDefaultRtcpMuxRequired,
         kDefaultSrtpRequired);
     video_channel_->set_transport_name_for_testing(transport_name);
-    GetOrCreateFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
-        ->internal()
-        ->SetChannel(video_channel_.get());
+    auto transceiver = RtpTransceiverProxyWithInternal<RtpTransceiver>::Create(
+        signaling_thread_, new RtpTransceiver(cricket::MEDIA_TYPE_VIDEO));
+    transceiver->internal()->SetChannel(video_channel_.get());
+    transceivers_.push_back(transceiver);
     return video_media_channel_ptr;
   }
 
@@ -213,24 +204,12 @@
 
   std::vector<rtc::scoped_refptr<RtpSenderInterface>> GetSenders()
       const override {
-    std::vector<rtc::scoped_refptr<RtpSenderInterface>> senders;
-    for (auto transceiver : transceivers_) {
-      for (auto sender : transceiver->internal()->senders()) {
-        senders.push_back(sender);
-      }
-    }
-    return senders;
+    return senders_;
   }
 
   std::vector<rtc::scoped_refptr<RtpReceiverInterface>> GetReceivers()
       const override {
-    std::vector<rtc::scoped_refptr<RtpReceiverInterface>> receivers;
-    for (auto transceiver : transceivers_) {
-      for (auto receiver : transceiver->internal()->receivers()) {
-        receivers.push_back(receiver);
-      }
-    }
-    return receivers;
+    return receivers_;
   }
 
   // PeerConnectionInternal overrides.
@@ -344,19 +323,6 @@
     return transport_stats;
   }
 
-  rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>
-  GetOrCreateFirstTransceiverOfType(cricket::MediaType media_type) {
-    for (auto transceiver : transceivers_) {
-      if (transceiver->internal()->media_type() == media_type) {
-        return transceiver;
-      }
-    }
-    auto transceiver = RtpTransceiverProxyWithInternal<RtpTransceiver>::Create(
-        signaling_thread_, new RtpTransceiver(media_type));
-    transceivers_.push_back(transceiver);
-    return transceiver;
-  }
-
   rtc::Thread* const network_thread_;
   rtc::Thread* const worker_thread_;
   rtc::Thread* const signaling_thread_;
@@ -367,6 +333,8 @@
   std::vector<
       rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>>
       transceivers_;
+  std::vector<rtc::scoped_refptr<RtpSenderInterface>> senders_;
+  std::vector<rtc::scoped_refptr<RtpReceiverInterface>> receivers_;
 
   FakeDataChannelProvider data_channel_provider_;
 
diff --git a/pc/test/mock_rtpreceiverinternal.h b/pc/test/mock_rtpreceiverinternal.h
deleted file mode 100644
index 8fb93b4..0000000
--- a/pc/test/mock_rtpreceiverinternal.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- *  Copyright 2016 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef PC_TEST_MOCK_RTPRECEIVERINTERNAL_H_
-#define PC_TEST_MOCK_RTPRECEIVERINTERNAL_H_
-
-#include <string>
-#include <vector>
-
-#include "pc/rtpreceiver.h"
-#include "test/gmock.h"
-
-namespace webrtc {
-
-// The definition of MockRtpReceiver is copied in to avoid multiple inheritance.
-class MockRtpReceiverInternal : public RtpReceiverInternal {
- public:
-  // RtpReceiverInterface methods.
-  MOCK_METHOD1(SetTrack, void(MediaStreamTrackInterface*));
-  MOCK_CONST_METHOD0(track, rtc::scoped_refptr<MediaStreamTrackInterface>());
-  MOCK_CONST_METHOD0(streams,
-                     std::vector<rtc::scoped_refptr<MediaStreamInterface>>());
-  MOCK_CONST_METHOD0(media_type, cricket::MediaType());
-  MOCK_CONST_METHOD0(id, std::string());
-  MOCK_CONST_METHOD0(GetParameters, RtpParameters());
-  MOCK_METHOD1(SetParameters, bool(const RtpParameters&));
-  MOCK_METHOD1(SetObserver, void(RtpReceiverObserverInterface*));
-  MOCK_CONST_METHOD0(GetSources, std::vector<RtpSource>());
-
-  // RtpReceiverInternal methods.
-  MOCK_METHOD0(Stop, void());
-  MOCK_METHOD1(SetVoiceMediaChannel, void(cricket::VoiceMediaChannel*));
-  MOCK_METHOD1(SetVideoMediaChannel, void(cricket::VideoMediaChannel*));
-  MOCK_METHOD1(SetupMediaChannel, void(uint32_t));
-  MOCK_CONST_METHOD0(ssrc, uint32_t());
-  MOCK_METHOD0(NotifyFirstPacketReceived, void());
-  MOCK_METHOD1(
-      SetStreams,
-      void(const std::vector<rtc::scoped_refptr<MediaStreamInterface>>&));
-  MOCK_CONST_METHOD0(AttachmentId, int());
-};
-
-}  // namespace webrtc
-
-#endif  // PC_TEST_MOCK_RTPRECEIVERINTERNAL_H_
diff --git a/pc/test/mock_rtpsenderinternal.h b/pc/test/mock_rtpsenderinternal.h
deleted file mode 100644
index b76a9ac..0000000
--- a/pc/test/mock_rtpsenderinternal.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- *  Copyright 2016 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef PC_TEST_MOCK_RTPSENDERINTERNAL_H_
-#define PC_TEST_MOCK_RTPSENDERINTERNAL_H_
-
-#include <string>
-#include <vector>
-
-#include "pc/rtpsender.h"
-#include "test/gmock.h"
-
-namespace webrtc {
-
-// The definition of MockRtpSender is copied in to avoid multiple inheritance.
-class MockRtpSenderInternal : public RtpSenderInternal {
- public:
-  // RtpSenderInterface methods.
-  MOCK_METHOD1(SetTrack, bool(MediaStreamTrackInterface*));
-  MOCK_CONST_METHOD0(track, rtc::scoped_refptr<MediaStreamTrackInterface>());
-  MOCK_CONST_METHOD0(ssrc, uint32_t());
-  MOCK_CONST_METHOD0(media_type, cricket::MediaType());
-  MOCK_CONST_METHOD0(id, std::string());
-  MOCK_CONST_METHOD0(stream_ids, std::vector<std::string>());
-  MOCK_CONST_METHOD0(GetParameters, RtpParameters());
-  MOCK_METHOD1(SetParameters, RTCError(const RtpParameters&));
-  MOCK_CONST_METHOD0(GetDtmfSender, rtc::scoped_refptr<DtmfSenderInterface>());
-
-  // RtpSenderInternal methods.
-  MOCK_METHOD1(SetVoiceMediaChannel, void(cricket::VoiceMediaChannel*));
-  MOCK_METHOD1(SetVideoMediaChannel, void(cricket::VideoMediaChannel*));
-  MOCK_METHOD1(SetSsrc, void(uint32_t));
-  MOCK_METHOD1(set_stream_id, void(const std::string&));
-  MOCK_CONST_METHOD0(stream_id, std::string());
-  MOCK_METHOD1(set_stream_ids, void(const std::vector<std::string>&));
-  MOCK_METHOD0(Stop, void());
-  MOCK_CONST_METHOD0(AttachmentId, int());
-};
-
-}  // namespace webrtc
-
-#endif  // PC_TEST_MOCK_RTPSENDERINTERNAL_H_
diff --git a/pc/trackmediainfomap.cc b/pc/trackmediainfomap.cc
index 5450cee..654db15 100644
--- a/pc/trackmediainfomap.cc
+++ b/pc/trackmediainfomap.cc
@@ -30,8 +30,8 @@
 }
 
 void GetAudioAndVideoTrackBySsrc(
-    const std::vector<rtc::scoped_refptr<RtpSenderInternal>>& rtp_senders,
-    const std::vector<rtc::scoped_refptr<RtpReceiverInternal>>& rtp_receivers,
+    const std::vector<rtc::scoped_refptr<RtpSenderInterface>>& rtp_senders,
+    const std::vector<rtc::scoped_refptr<RtpReceiverInterface>>& rtp_receivers,
     std::map<uint32_t, AudioTrackInterface*>* local_audio_track_by_ssrc,
     std::map<uint32_t, VideoTrackInterface*>* local_video_track_by_ssrc,
     std::map<uint32_t, AudioTrackInterface*>* remote_audio_track_by_ssrc,
@@ -47,7 +47,7 @@
   // means one thread jump if on signaling thread and two thread jumps if on any
   // other threads). Is there a way to avoid thread jump(s) on a per
   // sender/receiver, per method basis?
-  for (auto rtp_sender : rtp_senders) {
+  for (const rtc::scoped_refptr<RtpSenderInterface>& rtp_sender : rtp_senders) {
     cricket::MediaType media_type = rtp_sender->media_type();
     MediaStreamTrackInterface* track = rtp_sender->track();
     if (!track) {
@@ -72,7 +72,8 @@
       }
     }
   }
-  for (auto rtp_receiver : rtp_receivers) {
+  for (const rtc::scoped_refptr<RtpReceiverInterface>& rtp_receiver :
+       rtp_receivers) {
     cricket::MediaType media_type = rtp_receiver->media_type();
     MediaStreamTrackInterface* track = rtp_receiver->track();
     RTC_DCHECK(track);
@@ -110,8 +111,8 @@
 TrackMediaInfoMap::TrackMediaInfoMap(
     std::unique_ptr<cricket::VoiceMediaInfo> voice_media_info,
     std::unique_ptr<cricket::VideoMediaInfo> video_media_info,
-    const std::vector<rtc::scoped_refptr<RtpSenderInternal>>& rtp_senders,
-    const std::vector<rtc::scoped_refptr<RtpReceiverInternal>>& rtp_receivers)
+    const std::vector<rtc::scoped_refptr<RtpSenderInterface>>& rtp_senders,
+    const std::vector<rtc::scoped_refptr<RtpReceiverInterface>>& rtp_receivers)
     : voice_media_info_(std::move(voice_media_info)),
       video_media_info_(std::move(video_media_info)) {
   std::map<uint32_t, AudioTrackInterface*> local_audio_track_by_ssrc;
@@ -126,10 +127,10 @@
       &remote_video_track_by_ssrc, &unsignaled_audio_track,
       &unsignaled_video_track);
 
-  for (auto sender : rtp_senders) {
+  for (auto& sender : rtp_senders) {
     attachment_id_by_track_[sender->track()] = sender->AttachmentId();
   }
-  for (auto receiver : rtp_receivers) {
+  for (auto& receiver : rtp_receivers) {
     attachment_id_by_track_[receiver->track()] = receiver->AttachmentId();
   }
 
diff --git a/pc/trackmediainfomap.h b/pc/trackmediainfomap.h
index d603626..a0f882d 100644
--- a/pc/trackmediainfomap.h
+++ b/pc/trackmediainfomap.h
@@ -17,9 +17,9 @@
 #include <vector>
 
 #include "api/mediastreaminterface.h"
+#include "api/rtpreceiverinterface.h"
+#include "api/rtpsenderinterface.h"
 #include "media/base/mediachannel.h"
-#include "pc/rtpreceiver.h"
-#include "pc/rtpsender.h"
 #include "rtc_base/refcount.h"
 
 namespace webrtc {
@@ -39,8 +39,8 @@
   TrackMediaInfoMap(
       std::unique_ptr<cricket::VoiceMediaInfo> voice_media_info,
       std::unique_ptr<cricket::VideoMediaInfo> video_media_info,
-      const std::vector<rtc::scoped_refptr<RtpSenderInternal>>& rtp_senders,
-      const std::vector<rtc::scoped_refptr<RtpReceiverInternal>>&
+      const std::vector<rtc::scoped_refptr<RtpSenderInterface>>& rtp_senders,
+      const std::vector<rtc::scoped_refptr<RtpReceiverInterface>>&
           rtp_receivers);
 
   const cricket::VoiceMediaInfo* voice_media_info() const {
diff --git a/pc/trackmediainfomap_unittest.cc b/pc/trackmediainfomap_unittest.cc
index c135564..93d6155 100644
--- a/pc/trackmediainfomap_unittest.cc
+++ b/pc/trackmediainfomap_unittest.cc
@@ -18,11 +18,11 @@
 
 #include "api/rtpreceiverinterface.h"
 #include "api/rtpsenderinterface.h"
+#include "api/test/mock_rtpreceiver.h"
+#include "api/test/mock_rtpsender.h"
 #include "media/base/mediachannel.h"
 #include "pc/audiotrack.h"
 #include "pc/test/fakevideotracksource.h"
-#include "pc/test/mock_rtpreceiverinternal.h"
-#include "pc/test/mock_rtpsenderinternal.h"
 #include "pc/videotrack.h"
 #include "rtc_base/refcount.h"
 #include "test/gtest.h"
@@ -42,7 +42,7 @@
   return params;
 }
 
-rtc::scoped_refptr<MockRtpSenderInternal> CreateMockRtpSender(
+rtc::scoped_refptr<MockRtpSender> CreateMockRtpSender(
     cricket::MediaType media_type,
     std::initializer_list<uint32_t> ssrcs,
     rtc::scoped_refptr<MediaStreamTrackInterface> track) {
@@ -52,8 +52,8 @@
   } else {
     first_ssrc = 0;
   }
-  rtc::scoped_refptr<MockRtpSenderInternal> sender(
-      new rtc::RefCountedObject<MockRtpSenderInternal>());
+  rtc::scoped_refptr<MockRtpSender> sender(
+      new rtc::RefCountedObject<MockRtpSender>());
   EXPECT_CALL(*sender, track())
       .WillRepeatedly(testing::Return(std::move(track)));
   EXPECT_CALL(*sender, ssrc()).WillRepeatedly(testing::Return(first_ssrc));
@@ -65,12 +65,12 @@
   return sender;
 }
 
-rtc::scoped_refptr<MockRtpReceiverInternal> CreateMockRtpReceiver(
+rtc::scoped_refptr<MockRtpReceiver> CreateMockRtpReceiver(
     cricket::MediaType media_type,
     std::initializer_list<uint32_t> ssrcs,
     rtc::scoped_refptr<MediaStreamTrackInterface> track) {
-  rtc::scoped_refptr<MockRtpReceiverInternal> receiver(
-      new rtc::RefCountedObject<MockRtpReceiverInternal>());
+  rtc::scoped_refptr<MockRtpReceiver> receiver(
+      new rtc::RefCountedObject<MockRtpReceiver>());
   EXPECT_CALL(*receiver, track())
       .WillRepeatedly(testing::Return(std::move(track)));
   EXPECT_CALL(*receiver, media_type())
@@ -108,7 +108,7 @@
 
   void AddRtpSenderWithSsrcs(std::initializer_list<uint32_t> ssrcs,
                              MediaStreamTrackInterface* local_track) {
-    rtc::scoped_refptr<MockRtpSenderInternal> rtp_sender = CreateMockRtpSender(
+    rtc::scoped_refptr<MockRtpSender> rtp_sender = CreateMockRtpSender(
         local_track->kind() == MediaStreamTrackInterface::kAudioKind
             ? cricket::MEDIA_TYPE_AUDIO
             : cricket::MEDIA_TYPE_VIDEO,
@@ -136,7 +136,7 @@
 
   void AddRtpReceiverWithSsrcs(std::initializer_list<uint32_t> ssrcs,
                                MediaStreamTrackInterface* remote_track) {
-    auto rtp_receiver = CreateMockRtpReceiver(
+    rtc::scoped_refptr<MockRtpReceiver> rtp_receiver = CreateMockRtpReceiver(
         remote_track->kind() == MediaStreamTrackInterface::kAudioKind
             ? cricket::MEDIA_TYPE_AUDIO
             : cricket::MEDIA_TYPE_VIDEO,
@@ -173,8 +173,8 @@
  protected:
   cricket::VoiceMediaInfo* voice_media_info_;
   cricket::VideoMediaInfo* video_media_info_;
-  std::vector<rtc::scoped_refptr<RtpSenderInternal>> rtp_senders_;
-  std::vector<rtc::scoped_refptr<RtpReceiverInternal>> rtp_receivers_;
+  std::vector<rtc::scoped_refptr<RtpSenderInterface>> rtp_senders_;
+  std::vector<rtc::scoped_refptr<RtpReceiverInterface>> rtp_receivers_;
   std::unique_ptr<TrackMediaInfoMap> map_;
   rtc::scoped_refptr<AudioTrack> local_audio_track_;
   rtc::scoped_refptr<AudioTrack> remote_audio_track_;