Define RtpTransportControllerSendInterface.

Implementation owned by call, and passed to VideoSendStream and
AudioSendStream.

BUG=webrtc:6847, webrtc:7135

Review-Url: https://codereview.webrtc.org/2685673003
Cr-Commit-Position: refs/heads/master@{#17389}
diff --git a/webrtc/audio/audio_send_stream.cc b/webrtc/audio/audio_send_stream.cc
index d16ae18..6f72998 100644
--- a/webrtc/audio/audio_send_stream.cc
+++ b/webrtc/audio/audio_send_stream.cc
@@ -20,6 +20,7 @@
 #include "webrtc/base/logging.h"
 #include "webrtc/base/task_queue.h"
 #include "webrtc/base/timeutils.h"
+#include "webrtc/call/rtp_transport_controller_send.h"
 #include "webrtc/modules/bitrate_controller/include/bitrate_controller.h"
 #include "webrtc/modules/congestion_controller/include/send_side_congestion_controller.h"
 #include "webrtc/modules/pacing/paced_sender.h"
@@ -50,8 +51,7 @@
     const webrtc::AudioSendStream::Config& config,
     const rtc::scoped_refptr<webrtc::AudioState>& audio_state,
     rtc::TaskQueue* worker_queue,
-    PacketRouter* packet_router,
-    SendSideCongestionController* send_side_cc,
+    RtpTransportControllerSendInterface* transport,
     BitrateAllocator* bitrate_allocator,
     RtcEventLog* event_log,
     RtcpRttStats* rtcp_rtt_stats)
@@ -59,14 +59,15 @@
       config_(config),
       audio_state_(audio_state),
       bitrate_allocator_(bitrate_allocator),
-      send_side_cc_(send_side_cc),
+      transport_(transport),
       packet_loss_tracker_(kPacketLossTrackerMaxWindowSizeMs,
                            kPacketLossRateMinNumAckedPackets,
                            kRecoverablePacketLossRateMinNumAckedPairs) {
   LOG(LS_INFO) << "AudioSendStream: " << config_.ToString();
   RTC_DCHECK_NE(config_.voe_channel_id, -1);
   RTC_DCHECK(audio_state_.get());
-  RTC_DCHECK(send_side_cc);
+  RTC_DCHECK(transport);
+  RTC_DCHECK(transport->send_side_cc());
 
   VoiceEngineImpl* voe_impl = static_cast<VoiceEngineImpl*>(voice_engine());
   channel_proxy_ = voe_impl->GetChannelProxy(config_.voe_channel_id);
@@ -81,23 +82,23 @@
                                 config_.rtp.nack.rtp_history_ms / 20);
 
   channel_proxy_->RegisterExternalTransport(config.send_transport);
-  send_side_cc_->RegisterPacketFeedbackObserver(this);
+  transport_->send_side_cc()->RegisterPacketFeedbackObserver(this);
 
   for (const auto& extension : config.rtp.extensions) {
     if (extension.uri == RtpExtension::kAudioLevelUri) {
       channel_proxy_->SetSendAudioLevelIndicationStatus(true, extension.id);
     } else if (extension.uri == RtpExtension::kTransportSequenceNumberUri) {
       channel_proxy_->EnableSendTransportSequenceNumber(extension.id);
-      send_side_cc->EnablePeriodicAlrProbing(true);
-      bandwidth_observer_.reset(
-          send_side_cc->GetBitrateController()->CreateRtcpBandwidthObserver());
+      transport->send_side_cc()->EnablePeriodicAlrProbing(true);
+      bandwidth_observer_.reset(transport->send_side_cc()
+                                    ->GetBitrateController()
+                                    ->CreateRtcpBandwidthObserver());
     } else {
       RTC_NOTREACHED() << "Registering unsupported RTP extension.";
     }
   }
   channel_proxy_->RegisterSenderCongestionControlObjects(
-      send_side_cc->pacer(), send_side_cc, packet_router,
-      bandwidth_observer_.get());
+      transport, bandwidth_observer_.get());
   if (!SetupSendCodec()) {
     LOG(LS_ERROR) << "Failed to set up send codec state.";
   }
@@ -108,7 +109,7 @@
 AudioSendStream::~AudioSendStream() {
   RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
   LOG(LS_INFO) << "~AudioSendStream: " << config_.ToString();
-  send_side_cc_->DeRegisterPacketFeedbackObserver(this);
+  transport_->send_side_cc()->DeRegisterPacketFeedbackObserver(this);
   channel_proxy_->DeRegisterExternalTransport();
   channel_proxy_->ResetCongestionControlObjects();
   channel_proxy_->SetRtcEventLog(nullptr);
@@ -302,7 +303,8 @@
 
 void AudioSendStream::SetTransportOverhead(int transport_overhead_per_packet) {
   RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
-  send_side_cc_->SetTransportOverhead(transport_overhead_per_packet);
+  transport_->send_side_cc()->SetTransportOverhead(
+      transport_overhead_per_packet);
   channel_proxy_->SetTransportOverhead(transport_overhead_per_packet);
 }
 
diff --git a/webrtc/audio/audio_send_stream.h b/webrtc/audio/audio_send_stream.h
index f50f7c4..567799c 100644
--- a/webrtc/audio/audio_send_stream.h
+++ b/webrtc/audio/audio_send_stream.h
@@ -23,12 +23,11 @@
 #include "webrtc/voice_engine/transport_feedback_packet_loss_tracker.h"
 
 namespace webrtc {
-class SendSideCongestionController;
 class VoiceEngine;
 class RtcEventLog;
 class RtcpBandwidthObserver;
 class RtcpRttStats;
-class PacketRouter;
+class RtpTransportControllerSendInterface;
 
 namespace voe {
 class ChannelProxy;
@@ -42,8 +41,7 @@
   AudioSendStream(const webrtc::AudioSendStream::Config& config,
                   const rtc::scoped_refptr<webrtc::AudioState>& audio_state,
                   rtc::TaskQueue* worker_queue,
-                  PacketRouter* packet_router,
-                  SendSideCongestionController* send_side_cc,
+                  RtpTransportControllerSendInterface* transport,
                   BitrateAllocator* bitrate_allocator,
                   RtcEventLog* event_log,
                   RtcpRttStats* rtcp_rtt_stats);
@@ -87,7 +85,7 @@
   std::unique_ptr<voe::ChannelProxy> channel_proxy_;
 
   BitrateAllocator* const bitrate_allocator_;
-  SendSideCongestionController* const send_side_cc_;
+  RtpTransportControllerSendInterface* const transport_;
   std::unique_ptr<RtcpBandwidthObserver> bandwidth_observer_;
 
   rtc::CriticalSection packet_loss_tracker_cs_;
diff --git a/webrtc/audio/audio_send_stream_unittest.cc b/webrtc/audio/audio_send_stream_unittest.cc
index 74a18bc..5cd8baf 100644
--- a/webrtc/audio/audio_send_stream_unittest.cc
+++ b/webrtc/audio/audio_send_stream_unittest.cc
@@ -15,6 +15,7 @@
 #include "webrtc/audio/audio_state.h"
 #include "webrtc/audio/conversion.h"
 #include "webrtc/base/task_queue.h"
+#include "webrtc/call/rtp_transport_controller_send.h"
 #include "webrtc/logging/rtc_event_log/mock/mock_rtc_event_log.h"
 #include "webrtc/modules/audio_mixer/audio_mixer_impl.h"
 #include "webrtc/modules/audio_processing/include/mock_audio_processing.h"
@@ -69,13 +70,36 @@
 };
 
 struct ConfigHelper {
+  class FakeRtpTransportController
+      : public RtpTransportControllerSendInterface {
+   public:
+    explicit FakeRtpTransportController(RtcEventLog* event_log)
+        : simulated_clock_(123456),
+          send_side_cc_(&simulated_clock_,
+                        &bitrate_observer_,
+                        event_log,
+                        &packet_router_) {}
+    PacketRouter* packet_router() override { return &packet_router_; }
+
+    SendSideCongestionController* send_side_cc() override {
+      return &send_side_cc_;
+    }
+    TransportFeedbackObserver* transport_feedback_observer() override {
+      return &send_side_cc_;
+    }
+
+    RtpPacketSender* packet_sender() override { return send_side_cc_.pacer(); }
+
+   private:
+    SimulatedClock simulated_clock_;
+    testing::NiceMock<MockCongestionObserver> bitrate_observer_;
+    PacketRouter packet_router_;
+    SendSideCongestionController send_side_cc_;
+  };
+
   explicit ConfigHelper(bool audio_bwe_enabled)
-      : simulated_clock_(123456),
-        stream_config_(nullptr),
-        send_side_cc_(&simulated_clock_,
-                      &bitrate_observer_,
-                      &event_log_,
-                      &packet_router_),
+      : stream_config_(nullptr),
+        fake_transport_(&event_log_),
         bitrate_allocator_(&limit_observer_),
         worker_queue_("ConfigHelper_worker_queue") {
     using testing::Invoke;
@@ -124,8 +148,7 @@
   AudioSendStream::Config& config() { return stream_config_; }
   rtc::scoped_refptr<AudioState> audio_state() { return audio_state_; }
   MockVoEChannelProxy* channel_proxy() { return channel_proxy_; }
-  PacketRouter* packet_router() { return &packet_router_; }
-  SendSideCongestionController* send_side_cc() { return &send_side_cc_; }
+  RtpTransportControllerSendInterface* transport() { return &fake_transport_; }
   BitrateAllocator* bitrate_allocator() { return &bitrate_allocator_; }
   rtc::TaskQueue* worker_queue() { return &worker_queue_; }
   RtcEventLog* event_log() { return &event_log_; }
@@ -141,19 +164,16 @@
     EXPECT_CALL(*channel_proxy_,
                 SetSendAudioLevelIndicationStatus(true, kAudioLevelId))
         .Times(1);
-
     if (audio_bwe_enabled) {
       EXPECT_CALL(*channel_proxy_,
                   EnableSendTransportSequenceNumber(kTransportSequenceNumberId))
           .Times(1);
       EXPECT_CALL(*channel_proxy_, RegisterSenderCongestionControlObjects(
-                                       send_side_cc_.pacer(), &send_side_cc_,
-                                       packet_router(), Ne(nullptr)))
+                                       &fake_transport_, Ne(nullptr)))
           .Times(1);
     } else {
       EXPECT_CALL(*channel_proxy_, RegisterSenderCongestionControlObjects(
-                                       send_side_cc_.pacer(), &send_side_cc_,
-                                       packet_router(), Eq(nullptr)))
+                                       &fake_transport_, Eq(nullptr)))
           .Times(1);
     }
     EXPECT_CALL(*channel_proxy_, ResetCongestionControlObjects()).Times(1);
@@ -234,7 +254,6 @@
   }
 
  private:
-  SimulatedClock simulated_clock_;
   testing::StrictMock<MockVoiceEngine> voice_engine_;
   rtc::scoped_refptr<AudioState> audio_state_;
   AudioSendStream::Config stream_config_;
@@ -243,8 +262,7 @@
   MockAudioProcessing audio_processing_;
   MockTransmitMixer transmit_mixer_;
   AudioProcessing::AudioProcessingStatistics audio_processing_stats_;
-  PacketRouter packet_router_;
-  SendSideCongestionController send_side_cc_;
+  FakeRtpTransportController fake_transport_;
   MockRtcEventLog event_log_;
   MockRtcpRttStats rtcp_rtt_stats_;
   testing::NiceMock<MockLimitObserver> limit_observer_;
@@ -291,16 +309,16 @@
   ConfigHelper helper(false);
   internal::AudioSendStream send_stream(
       helper.config(), helper.audio_state(), helper.worker_queue(),
-      helper.packet_router(), helper.send_side_cc(), helper.bitrate_allocator(),
-      helper.event_log(), helper.rtcp_rtt_stats());
+      helper.transport(), helper.bitrate_allocator(), helper.event_log(),
+      helper.rtcp_rtt_stats());
 }
 
 TEST(AudioSendStreamTest, SendTelephoneEvent) {
   ConfigHelper helper(false);
   internal::AudioSendStream send_stream(
       helper.config(), helper.audio_state(), helper.worker_queue(),
-      helper.packet_router(), helper.send_side_cc(), helper.bitrate_allocator(),
-      helper.event_log(), helper.rtcp_rtt_stats());
+      helper.transport(), helper.bitrate_allocator(), helper.event_log(),
+      helper.rtcp_rtt_stats());
   helper.SetupMockForSendTelephoneEvent();
   EXPECT_TRUE(send_stream.SendTelephoneEvent(kTelephoneEventPayloadType,
       kTelephoneEventPayloadFrequency, kTelephoneEventCode,
@@ -311,8 +329,8 @@
   ConfigHelper helper(false);
   internal::AudioSendStream send_stream(
       helper.config(), helper.audio_state(), helper.worker_queue(),
-      helper.packet_router(), helper.send_side_cc(), helper.bitrate_allocator(),
-      helper.event_log(), helper.rtcp_rtt_stats());
+      helper.transport(), helper.bitrate_allocator(), helper.event_log(),
+      helper.rtcp_rtt_stats());
   EXPECT_CALL(*helper.channel_proxy(), SetInputMute(true));
   send_stream.SetMuted(true);
 }
@@ -321,24 +339,24 @@
   ConfigHelper helper(true);
   internal::AudioSendStream send_stream(
       helper.config(), helper.audio_state(), helper.worker_queue(),
-      helper.packet_router(), helper.send_side_cc(), helper.bitrate_allocator(),
-      helper.event_log(), helper.rtcp_rtt_stats());
+      helper.transport(), helper.bitrate_allocator(), helper.event_log(),
+      helper.rtcp_rtt_stats());
 }
 
 TEST(AudioSendStreamTest, NoAudioBweCorrectObjectsOnChannelProxy) {
   ConfigHelper helper(false);
   internal::AudioSendStream send_stream(
       helper.config(), helper.audio_state(), helper.worker_queue(),
-      helper.packet_router(), helper.send_side_cc(), helper.bitrate_allocator(),
-      helper.event_log(), helper.rtcp_rtt_stats());
+      helper.transport(), helper.bitrate_allocator(), helper.event_log(),
+      helper.rtcp_rtt_stats());
 }
 
 TEST(AudioSendStreamTest, GetStats) {
   ConfigHelper helper(false);
   internal::AudioSendStream send_stream(
       helper.config(), helper.audio_state(), helper.worker_queue(),
-      helper.packet_router(), helper.send_side_cc(), helper.bitrate_allocator(),
-      helper.event_log(), helper.rtcp_rtt_stats());
+      helper.transport(), helper.bitrate_allocator(), helper.event_log(),
+      helper.rtcp_rtt_stats());
   helper.SetupMockForGetStats();
   AudioSendStream::Stats stats = send_stream.GetStats();
   EXPECT_EQ(kSsrc, stats.local_ssrc);
@@ -368,8 +386,8 @@
   ConfigHelper helper(false);
   internal::AudioSendStream send_stream(
       helper.config(), helper.audio_state(), helper.worker_queue(),
-      helper.packet_router(), helper.send_side_cc(), helper.bitrate_allocator(),
-      helper.event_log(), helper.rtcp_rtt_stats());
+      helper.transport(), helper.bitrate_allocator(), helper.event_log(),
+      helper.rtcp_rtt_stats());
   helper.SetupMockForGetStats();
   EXPECT_FALSE(send_stream.GetStats().typing_noise_detected);
 
@@ -422,8 +440,8 @@
       EnableAudioNetworkAdaptor(*stream_config.audio_network_adaptor_config));
   internal::AudioSendStream send_stream(
       stream_config, helper.audio_state(), helper.worker_queue(),
-      helper.packet_router(), helper.send_side_cc(), helper.bitrate_allocator(),
-      helper.event_log(), helper.rtcp_rtt_stats());
+      helper.transport(), helper.bitrate_allocator(), helper.event_log(),
+      helper.rtcp_rtt_stats());
 }
 
 // VAD is applied when codec is mono and the CNG frequency matches the codec
@@ -439,16 +457,16 @@
       .WillOnce(Return(true));
   internal::AudioSendStream send_stream(
       stream_config, helper.audio_state(), helper.worker_queue(),
-      helper.packet_router(), helper.send_side_cc(), helper.bitrate_allocator(),
-      helper.event_log(), helper.rtcp_rtt_stats());
+      helper.transport(), helper.bitrate_allocator(), helper.event_log(),
+      helper.rtcp_rtt_stats());
 }
 
 TEST(AudioSendStreamTest, DoesNotPassHigherBitrateThanMaxBitrate) {
   ConfigHelper helper(false);
   internal::AudioSendStream send_stream(
       helper.config(), helper.audio_state(), helper.worker_queue(),
-      helper.packet_router(), helper.send_side_cc(), helper.bitrate_allocator(),
-      helper.event_log(), helper.rtcp_rtt_stats());
+      helper.transport(), helper.bitrate_allocator(), helper.event_log(),
+      helper.rtcp_rtt_stats());
   EXPECT_CALL(*helper.channel_proxy(),
               SetBitrate(helper.config().max_bitrate_bps, _));
   send_stream.OnBitrateUpdated(helper.config().max_bitrate_bps + 5000, 0.0, 50,
@@ -459,8 +477,8 @@
   ConfigHelper helper(false);
   internal::AudioSendStream send_stream(
       helper.config(), helper.audio_state(), helper.worker_queue(),
-      helper.packet_router(), helper.send_side_cc(), helper.bitrate_allocator(),
-      helper.event_log(), helper.rtcp_rtt_stats());
+      helper.transport(), helper.bitrate_allocator(), helper.event_log(),
+      helper.rtcp_rtt_stats());
   EXPECT_CALL(*helper.channel_proxy(), SetBitrate(_, 5000));
   send_stream.OnBitrateUpdated(50000, 0.0, 50, 5000);
 }
diff --git a/webrtc/call/BUILD.gn b/webrtc/call/BUILD.gn
index 154ae04..a4e4f7c 100644
--- a/webrtc/call/BUILD.gn
+++ b/webrtc/call/BUILD.gn
@@ -16,6 +16,7 @@
     "audio_state.h",
     "call.h",
     "flexfec_receive_stream.h",
+    "rtp_transport_controller_send.h",
     "syncable.cc",
     "syncable.h",
   ]
diff --git a/webrtc/call/call.cc b/webrtc/call/call.cc
index 6e620b6..ef3bc85 100644
--- a/webrtc/call/call.cc
+++ b/webrtc/call/call.cc
@@ -33,6 +33,7 @@
 #include "webrtc/call/bitrate_allocator.h"
 #include "webrtc/call/call.h"
 #include "webrtc/call/flexfec_receive_stream_impl.h"
+#include "webrtc/call/rtp_transport_controller_send.h"
 #include "webrtc/config.h"
 #include "webrtc/logging/rtc_event_log/rtc_event_log.h"
 #include "webrtc/modules/bitrate_controller/include/bitrate_controller.h"
@@ -88,6 +89,43 @@
   return UseSendSideBwe(config.rtp_header_extensions, config.transport_cc);
 }
 
+class RtpTransportControllerSend : public RtpTransportControllerSendInterface {
+ public:
+  RtpTransportControllerSend(Clock* clock, webrtc::RtcEventLog* event_log);
+
+  void InitCongestionControl(SendSideCongestionController::Observer* observer);
+  PacketRouter* packet_router() override { return &packet_router_; }
+  SendSideCongestionController* send_side_cc() override {
+    return send_side_cc_.get();
+  }
+  TransportFeedbackObserver* transport_feedback_observer() override {
+    return send_side_cc_.get();
+  }
+  RtpPacketSender* packet_sender() override { return send_side_cc_->pacer(); }
+
+ private:
+  Clock* const clock_;
+  webrtc::RtcEventLog* const event_log_;
+  PacketRouter packet_router_;
+  // Construction delayed until InitCongestionControl, since the
+  // CongestionController wants its observer as a construction time
+  // argument, and setting it later seems non-trivial.
+  std::unique_ptr<SendSideCongestionController> send_side_cc_;
+};
+
+RtpTransportControllerSend::RtpTransportControllerSend(
+    Clock* clock,
+    webrtc::RtcEventLog* event_log)
+    : clock_(clock), event_log_(event_log) {}
+
+void RtpTransportControllerSend::InitCongestionControl(
+    SendSideCongestionController::Observer* observer) {
+  // Must be called only once.
+  RTC_CHECK(!send_side_cc_);
+  send_side_cc_.reset(new SendSideCongestionController(
+      clock_, observer, event_log_, &packet_router_));
+}
+
 }  // namespace
 
 namespace internal {
@@ -98,7 +136,8 @@
              public SendSideCongestionController::Observer,
              public BitrateAllocator::LimitObserver {
  public:
-  explicit Call(const Call::Config& config);
+  Call(const Call::Config& config,
+       std::unique_ptr<RtpTransportControllerSend> transport_send);
   virtual ~Call();
 
   // Implements webrtc::Call.
@@ -272,9 +311,8 @@
 
   std::map<std::string, rtc::NetworkRoute> network_routes_;
 
+  std::unique_ptr<RtpTransportControllerSend> transport_send_;
   VieRemb remb_;
-  PacketRouter packet_router_;
-  SendSideCongestionController send_side_cc_;
   ReceiveSideCongestionController receive_side_cc_;
   const std::unique_ptr<SendDelayStats> video_send_delay_stats_;
   const int64_t start_ms_;
@@ -301,12 +339,16 @@
 }
 
 Call* Call::Create(const Call::Config& config) {
-  return new internal::Call(config);
+  return new internal::Call(
+      config, std::unique_ptr<RtpTransportControllerSend>(
+                  new RtpTransportControllerSend(Clock::GetRealTimeClock(),
+                                                 config.event_log)));
 }
 
 namespace internal {
 
-Call::Call(const Call::Config& config)
+Call::Call(const Call::Config& config,
+           std::unique_ptr<RtpTransportControllerSend> transport_send)
     : clock_(Clock::GetRealTimeClock()),
       num_cpu_cores_(CpuInfo::DetectNumberOfCores()),
       module_process_thread_(ProcessThread::Create("ModuleProcessThread")),
@@ -328,9 +370,9 @@
       configured_max_padding_bitrate_bps_(0),
       estimated_send_bitrate_kbps_counter_(clock_, nullptr, true),
       pacer_bitrate_kbps_counter_(clock_, nullptr, true),
+      transport_send_(std::move(transport_send)),
       remb_(clock_),
-      send_side_cc_(clock_, this, event_log_, &packet_router_),
-      receive_side_cc_(clock_, &remb_, &packet_router_),
+      receive_side_cc_(clock_, &remb_, transport_send_->packet_router()),
       video_send_delay_stats_(new SendDelayStats(clock_)),
       start_ms_(clock_->TimeInMilliseconds()),
       worker_queue_("call_worker_queue") {
@@ -344,20 +386,24 @@
                   config.bitrate_config.start_bitrate_bps);
   }
   Trace::CreateTrace();
-  call_stats_->RegisterStatsObserver(&send_side_cc_);
-
-  send_side_cc_.SignalNetworkState(kNetworkDown);
-  send_side_cc_.SetBweBitrates(config_.bitrate_config.min_bitrate_bps,
-                               config_.bitrate_config.start_bitrate_bps,
-                               config_.bitrate_config.max_bitrate_bps);
+  transport_send_->InitCongestionControl(this);
+  transport_send_->send_side_cc()->SignalNetworkState(kNetworkDown);
+  transport_send_->send_side_cc()->SetBweBitrates(
+      config_.bitrate_config.min_bitrate_bps,
+      config_.bitrate_config.start_bitrate_bps,
+      config_.bitrate_config.max_bitrate_bps);
+  call_stats_->RegisterStatsObserver(transport_send_->send_side_cc());
 
   module_process_thread_->Start();
   module_process_thread_->RegisterModule(call_stats_.get(), RTC_FROM_HERE);
-  module_process_thread_->RegisterModule(&send_side_cc_, RTC_FROM_HERE);
   module_process_thread_->RegisterModule(&receive_side_cc_, RTC_FROM_HERE);
-  pacer_thread_->RegisterModule(send_side_cc_.pacer(), RTC_FROM_HERE);
+  module_process_thread_->RegisterModule(transport_send_->send_side_cc(),
+                                         RTC_FROM_HERE);
+  pacer_thread_->RegisterModule(transport_send_->send_side_cc()->pacer(),
+                                RTC_FROM_HERE);
   pacer_thread_->RegisterModule(
       receive_side_cc_.GetRemoteBitrateEstimator(true), RTC_FROM_HERE);
+
   pacer_thread_->Start();
 }
 
@@ -373,14 +419,14 @@
   RTC_CHECK(video_receive_streams_.empty());
 
   pacer_thread_->Stop();
-  pacer_thread_->DeRegisterModule(send_side_cc_.pacer());
+  pacer_thread_->DeRegisterModule(transport_send_->send_side_cc()->pacer());
   pacer_thread_->DeRegisterModule(
       receive_side_cc_.GetRemoteBitrateEstimator(true));
-  module_process_thread_->DeRegisterModule(&send_side_cc_);
+  module_process_thread_->DeRegisterModule(transport_send_->send_side_cc());
   module_process_thread_->DeRegisterModule(&receive_side_cc_);
   module_process_thread_->DeRegisterModule(call_stats_.get());
   module_process_thread_->Stop();
-  call_stats_->DeregisterStatsObserver(&send_side_cc_);
+  call_stats_->DeregisterStatsObserver(transport_send_->send_side_cc());
 
   // Only update histograms after process threads have been shut down, so that
   // they won't try to concurrently update stats.
@@ -498,9 +544,8 @@
   RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
   event_log_->LogAudioSendStreamConfig(config);
   AudioSendStream* send_stream = new AudioSendStream(
-      config, config_.audio_state, &worker_queue_, &packet_router_,
-      &send_side_cc_, bitrate_allocator_.get(), event_log_,
-      call_stats_->rtcp_rtt_stats());
+      config, config_.audio_state, &worker_queue_, transport_send_.get(),
+      bitrate_allocator_.get(), event_log_, call_stats_->rtcp_rtt_stats());
   {
     WriteLockScoped write_lock(*send_crit_);
     RTC_DCHECK(audio_send_ssrcs_.find(config.rtp.ssrc) ==
@@ -552,9 +597,9 @@
   TRACE_EVENT0("webrtc", "Call::CreateAudioReceiveStream");
   RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
   event_log_->LogAudioReceiveStreamConfig(config);
-  AudioReceiveStream* receive_stream = new AudioReceiveStream(
-      &packet_router_, config,
-      config_.audio_state, event_log_);
+  AudioReceiveStream* receive_stream =
+      new AudioReceiveStream(transport_send_->packet_router(), config,
+                             config_.audio_state, event_log_);
   {
     WriteLockScoped write_lock(*receive_crit_);
     RTC_DCHECK(audio_receive_ssrcs_.find(config.rtp.remote_ssrc) ==
@@ -620,10 +665,9 @@
   std::vector<uint32_t> ssrcs = config.rtp.ssrcs;
   VideoSendStream* send_stream = new VideoSendStream(
       num_cpu_cores_, module_process_thread_.get(), &worker_queue_,
-      call_stats_.get(), &send_side_cc_, &packet_router_,
-      bitrate_allocator_.get(), video_send_delay_stats_.get(), &remb_,
-      event_log_, std::move(config), std::move(encoder_config),
-      suspended_video_send_ssrcs_);
+      call_stats_.get(), transport_send_.get(), bitrate_allocator_.get(),
+      video_send_delay_stats_.get(), &remb_, event_log_, std::move(config),
+      std::move(encoder_config), suspended_video_send_ssrcs_);
 
   {
     WriteLockScoped write_lock(*send_crit_);
@@ -680,8 +724,9 @@
   RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
 
   VideoReceiveStream* receive_stream = new VideoReceiveStream(
-      num_cpu_cores_, &packet_router_, std::move(configuration),
-      module_process_thread_.get(), call_stats_.get(), &remb_);
+      num_cpu_cores_, transport_send_->packet_router(),
+      std::move(configuration), module_process_thread_.get(), call_stats_.get(),
+      &remb_);
 
   const webrtc::VideoReceiveStream::Config& config = receive_stream->config();
   ReceiveRtpConfig receive_config(config.rtp.extensions,
@@ -694,7 +739,7 @@
     if (config.rtp.rtx_ssrc) {
       video_receive_ssrcs_[config.rtp.rtx_ssrc] = receive_stream;
       // We record identical config for the rtx stream as for the main
-      // stream. Since the transport_cc negotiation is per payload
+      // stream. Since the transport_send_cc negotiation is per payload
       // type, we may get an incorrect value for the rtx stream, but
       // that is unlikely to matter in practice.
       receive_rtp_config_[config.rtp.rtx_ssrc] = receive_config;
@@ -829,14 +874,16 @@
   Stats stats;
   // Fetch available send/receive bitrates.
   uint32_t send_bandwidth = 0;
-  send_side_cc_.GetBitrateController()->AvailableBandwidth(&send_bandwidth);
+  transport_send_->send_side_cc()->GetBitrateController()->AvailableBandwidth(
+      &send_bandwidth);
   std::vector<unsigned int> ssrcs;
   uint32_t recv_bandwidth = 0;
   receive_side_cc_.GetRemoteBitrateEstimator(false)->LatestEstimate(
       &ssrcs, &recv_bandwidth);
   stats.send_bandwidth_bps = send_bandwidth;
   stats.recv_bandwidth_bps = recv_bandwidth;
-  stats.pacer_delay_ms = send_side_cc_.GetPacerQueuingDelayMs();
+  stats.pacer_delay_ms =
+      transport_send_->send_side_cc()->GetPacerQueuingDelayMs();
   stats.rtt_ms = call_stats_->rtcp_rtt_stats()->LastProcessedRtt();
   {
     rtc::CritScope cs(&bitrate_crit_);
@@ -869,9 +916,9 @@
     config_.bitrate_config.start_bitrate_bps = bitrate_config.start_bitrate_bps;
   config_.bitrate_config.max_bitrate_bps = bitrate_config.max_bitrate_bps;
   RTC_DCHECK_NE(bitrate_config.start_bitrate_bps, 0);
-  send_side_cc_.SetBweBitrates(bitrate_config.min_bitrate_bps,
-                               bitrate_config.start_bitrate_bps,
-                               bitrate_config.max_bitrate_bps);
+  transport_send_->send_side_cc()->SetBweBitrates(
+      bitrate_config.min_bitrate_bps, bitrate_config.start_bitrate_bps,
+      bitrate_config.max_bitrate_bps);
 }
 
 void Call::SignalChannelNetworkState(MediaType media, NetworkState state) {
@@ -966,7 +1013,7 @@
                  << " bps,  max: " << config_.bitrate_config.start_bitrate_bps
                  << " bps.";
     RTC_DCHECK_GT(config_.bitrate_config.start_bitrate_bps, 0);
-    send_side_cc_.OnNetworkRouteChanged(
+    transport_send_->send_side_cc()->OnNetworkRouteChanged(
         network_route, config_.bitrate_config.start_bitrate_bps,
         config_.bitrate_config.min_bitrate_bps,
         config_.bitrate_config.max_bitrate_bps);
@@ -1002,7 +1049,7 @@
   LOG(LS_INFO) << "UpdateAggregateNetworkState: aggregate_state="
                << (aggregate_state == kNetworkUp ? "up" : "down");
 
-  send_side_cc_.SignalNetworkState(aggregate_state);
+  transport_send_->send_side_cc()->SignalNetworkState(aggregate_state);
 }
 
 void Call::OnSentPacket(const rtc::SentPacket& sent_packet) {
@@ -1010,7 +1057,7 @@
     first_packet_sent_ms_ = clock_->TimeInMilliseconds();
   video_send_delay_stats_->OnSentPacket(sent_packet.packet_id,
                                         clock_->TimeInMilliseconds());
-  send_side_cc_.OnSentPacket(sent_packet);
+  transport_send_->send_side_cc()->OnSentPacket(sent_packet);
 }
 
 void Call::OnNetworkChanged(uint32_t target_bitrate_bps,
@@ -1063,8 +1110,8 @@
 
 void Call::OnAllocationLimitsChanged(uint32_t min_send_bitrate_bps,
                                      uint32_t max_padding_bitrate_bps) {
-  send_side_cc_.SetAllocatedSendBitrateLimits(min_send_bitrate_bps,
-                                              max_padding_bitrate_bps);
+  transport_send_->send_side_cc()->SetAllocatedSendBitrateLimits(
+      min_send_bitrate_bps, max_padding_bitrate_bps);
   rtc::CritScope lock(&bitrate_crit_);
   min_allocated_send_bitrate_bps_ = min_send_bitrate_bps;
   configured_max_padding_bitrate_bps_ = max_padding_bitrate_bps;
@@ -1283,4 +1330,5 @@
 }
 
 }  // namespace internal
+
 }  // namespace webrtc
diff --git a/webrtc/call/rtp_transport_controller_send.h b/webrtc/call/rtp_transport_controller_send.h
new file mode 100644
index 0000000..f4384d4
--- /dev/null
+++ b/webrtc/call/rtp_transport_controller_send.h
@@ -0,0 +1,59 @@
+/*
+ *  Copyright (c) 2017 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 WEBRTC_CALL_RTP_TRANSPORT_CONTROLLER_SEND_H_
+#define WEBRTC_CALL_RTP_TRANSPORT_CONTROLLER_SEND_H_
+
+namespace webrtc {
+
+class Module;
+class PacketRouter;
+class RtpPacketSender;
+class SendSideCongestionController;
+class TransportFeedbackObserver;
+class VieRemb;
+
+// An RtpTransportController should own everything related to the RTP
+// transport to/from a remote endpoint. We should have separate
+// interfaces for send and receive side, even if they are implemented
+// by the same class. This is an ongoing refactoring project. At some
+// point, this class should be promoted to a public api under
+// webrtc/api/rtp/.
+//
+// For a start, this object is just a collection of the objects needed
+// by the VideoSendStream constructor. The plan is to move ownership
+// of all RTP-related objects here, and add methods to create per-ssrc
+// objects which would then be passed to VideoSendStream. Eventually,
+// direct accessors like packet_router() should be removed.
+//
+// This should also have a reference to the underlying
+// webrtc::Transport(s). Currently, webrtc::Transport is implemented by
+// WebRtcVideoChannel2 and WebRtcVoiceMediaChannel, and owned by
+// WebrtcSession. Video and audio always uses different transport
+// objects, even in the common case where they are bundled over the
+// same underlying transport.
+//
+// Extracting the logic of the webrtc::Transport from BaseChannel and
+// subclasses into a separate class seems to be a prerequesite for
+// moving the transport here.
+class RtpTransportControllerSendInterface {
+ public:
+  virtual ~RtpTransportControllerSendInterface() {}
+  virtual PacketRouter* packet_router() = 0;
+  // Currently returning the same pointer, but with different types.
+  virtual SendSideCongestionController* send_side_cc() = 0;
+  virtual TransportFeedbackObserver* transport_feedback_observer() = 0;
+
+  virtual RtpPacketSender* packet_sender() = 0;
+};
+
+}  // namespace webrtc
+
+#endif  // WEBRTC_CALL_RTP_TRANSPORT_CONTROLLER_SEND_H_
diff --git a/webrtc/modules/congestion_controller/include/congestion_controller.h b/webrtc/modules/congestion_controller/include/congestion_controller.h
index be2d68d..3bb1c53 100644
--- a/webrtc/modules/congestion_controller/include/congestion_controller.h
+++ b/webrtc/modules/congestion_controller/include/congestion_controller.h
@@ -88,8 +88,11 @@
       bool send_side_bwe);
   virtual int64_t GetPacerQueuingDelayMs() const;
   // TODO(nisse): Delete this accessor function. The pacer should be
-  // internal to the congestion controller.
+  // internal to the congestion controller. Currently needed by Call,
+  // to register the pacer module on the right thread.
   virtual PacedSender* pacer() { return send_side_cc_.pacer(); }
+  // TODO(nisse): Delete this method, as soon as downstream projects
+  // are updated.
   virtual TransportFeedbackObserver* GetTransportFeedbackObserver() {
     return this;
   }
diff --git a/webrtc/test/mock_voe_channel_proxy.h b/webrtc/test/mock_voe_channel_proxy.h
index d704e19..43cdc78 100644
--- a/webrtc/test/mock_voe_channel_proxy.h
+++ b/webrtc/test/mock_voe_channel_proxy.h
@@ -30,10 +30,8 @@
   MOCK_METHOD2(SetReceiveAudioLevelIndicationStatus, void(bool enable, int id));
   MOCK_METHOD1(EnableSendTransportSequenceNumber, void(int id));
   MOCK_METHOD1(EnableReceiveTransportSequenceNumber, void(int id));
-  MOCK_METHOD4(RegisterSenderCongestionControlObjects,
-               void(RtpPacketSender* rtp_packet_sender,
-                    TransportFeedbackObserver* transport_feedback_observer,
-                    PacketRouter* packet_router,
+  MOCK_METHOD2(RegisterSenderCongestionControlObjects,
+               void(RtpTransportControllerSendInterface* transport,
                     RtcpBandwidthObserver* bandwidth_observer));
   MOCK_METHOD1(RegisterReceiverCongestionControlObjects,
                void(PacketRouter* packet_router));
diff --git a/webrtc/video/video_send_stream.cc b/webrtc/video/video_send_stream.cc
index 656bfb5..73247d8 100644
--- a/webrtc/video/video_send_stream.cc
+++ b/webrtc/video/video_send_stream.cc
@@ -22,6 +22,7 @@
 #include "webrtc/base/logging.h"
 #include "webrtc/base/trace_event.h"
 #include "webrtc/base/weak_ptr.h"
+#include "webrtc/call/rtp_transport_controller_send.h"
 #include "webrtc/common_types.h"
 #include "webrtc/common_video/include/video_bitrate_allocator.h"
 #include "webrtc/modules/bitrate_controller/include/bitrate_controller.h"
@@ -32,6 +33,7 @@
 #include "webrtc/modules/video_coding/utility/ivf_file_writer.h"
 #include "webrtc/system_wrappers/include/field_trial.h"
 #include "webrtc/video/call_stats.h"
+#include "webrtc/video/payload_router.h"
 #include "webrtc/video/vie_remb.h"
 #include "webrtc/video_send_stream.h"
 
@@ -47,10 +49,8 @@
     Transport* outgoing_transport,
     RtcpIntraFrameObserver* intra_frame_callback,
     RtcpBandwidthObserver* bandwidth_callback,
-    TransportFeedbackObserver* transport_feedback_callback,
+    RtpTransportControllerSendInterface* transport,
     RtcpRttStats* rtt_stats,
-    RtpPacketSender* paced_sender,
-    TransportSequenceNumberAllocator* transport_sequence_number_allocator,
     FlexfecSender* flexfec_sender,
     SendStatisticsProxy* stats_proxy,
     SendDelayStats* send_delay_stats,
@@ -68,12 +68,13 @@
   configuration.outgoing_transport = outgoing_transport;
   configuration.intra_frame_callback = intra_frame_callback;
   configuration.bandwidth_callback = bandwidth_callback;
-  configuration.transport_feedback_callback = transport_feedback_callback;
+  configuration.transport_feedback_callback =
+      transport->transport_feedback_observer();
   configuration.rtt_stats = rtt_stats;
   configuration.rtcp_packet_type_counter_observer = stats_proxy;
-  configuration.paced_sender = paced_sender;
+  configuration.paced_sender = transport->packet_sender();
   configuration.transport_sequence_number_allocator =
-      transport_sequence_number_allocator;
+      transport->packet_router();
   configuration.send_bitrate_observer = stats_proxy;
   configuration.send_frame_count_observer = stats_proxy;
   configuration.send_side_delay_observer = stats_proxy;
@@ -325,8 +326,7 @@
   VideoSendStreamImpl(SendStatisticsProxy* stats_proxy,
                       rtc::TaskQueue* worker_queue,
                       CallStats* call_stats,
-                      SendSideCongestionController* send_side_cc,
-                      PacketRouter* packet_router,
+                      RtpTransportControllerSendInterface* transport,
                       BitrateAllocator* bitrate_allocator,
                       SendDelayStats* send_delay_stats,
                       VieRemb* remb,
@@ -411,8 +411,7 @@
       GUARDED_BY(encoder_activity_crit_sect_);
 
   CallStats* const call_stats_;
-  SendSideCongestionController* const send_side_cc_;
-  PacketRouter* const packet_router_;
+  RtpTransportControllerSendInterface* const transport_;
   BitrateAllocator* const bitrate_allocator_;
   VieRemb* const remb_;
 
@@ -460,8 +459,7 @@
                    ViEEncoder* vie_encoder,
                    ProcessThread* module_process_thread,
                    CallStats* call_stats,
-                   SendSideCongestionController* send_side_cc,
-                   PacketRouter* packet_router,
+                   RtpTransportControllerSendInterface* transport,
                    BitrateAllocator* bitrate_allocator,
                    SendDelayStats* send_delay_stats,
                    VieRemb* remb,
@@ -474,8 +472,7 @@
         stats_proxy_(stats_proxy),
         vie_encoder_(vie_encoder),
         call_stats_(call_stats),
-        send_side_cc_(send_side_cc),
-        packet_router_(packet_router),
+        transport_(transport),
         bitrate_allocator_(bitrate_allocator),
         send_delay_stats_(send_delay_stats),
         remb_(remb),
@@ -489,10 +486,9 @@
  private:
   bool Run() override {
     send_stream_->reset(new VideoSendStreamImpl(
-        stats_proxy_, rtc::TaskQueue::Current(), call_stats_, send_side_cc_,
-        packet_router_, bitrate_allocator_, send_delay_stats_, remb_,
-        vie_encoder_, event_log_, config_, initial_encoder_max_bitrate_,
-        std::move(suspended_ssrcs_)));
+        stats_proxy_, rtc::TaskQueue::Current(), call_stats_, transport_,
+        bitrate_allocator_, send_delay_stats_, remb_, vie_encoder_, event_log_,
+        config_, initial_encoder_max_bitrate_, std::move(suspended_ssrcs_)));
     return true;
   }
 
@@ -501,8 +497,7 @@
   SendStatisticsProxy* const stats_proxy_;
   ViEEncoder* const vie_encoder_;
   CallStats* const call_stats_;
-  SendSideCongestionController* const send_side_cc_;
-  PacketRouter* const packet_router_;
+  RtpTransportControllerSendInterface* const transport_;
   BitrateAllocator* const bitrate_allocator_;
   SendDelayStats* const send_delay_stats_;
   VieRemb* const remb_;
@@ -616,8 +611,7 @@
     ProcessThread* module_process_thread,
     rtc::TaskQueue* worker_queue,
     CallStats* call_stats,
-    SendSideCongestionController* send_side_cc,
-    PacketRouter* packet_router,
+    RtpTransportControllerSendInterface* transport,
     BitrateAllocator* bitrate_allocator,
     SendDelayStats* send_delay_stats,
     VieRemb* remb,
@@ -637,8 +631,8 @@
       config_.pre_encode_callback, config_.post_encode_callback));
   worker_queue_->PostTask(std::unique_ptr<rtc::QueuedTask>(new ConstructionTask(
       &send_stream_, &thread_sync_event_, &stats_proxy_, vie_encoder_.get(),
-      module_process_thread, call_stats, send_side_cc, packet_router,
-      bitrate_allocator, send_delay_stats, remb, event_log, &config_,
+      module_process_thread, call_stats, transport, bitrate_allocator,
+      send_delay_stats, remb, event_log, &config_,
       encoder_config.max_bitrate_bps, suspended_ssrcs)));
 
   // Wait for ConstructionTask to complete so that |send_stream_| can be used.
@@ -750,8 +744,7 @@
     SendStatisticsProxy* stats_proxy,
     rtc::TaskQueue* worker_queue,
     CallStats* call_stats,
-    SendSideCongestionController* send_side_cc,
-    PacketRouter* packet_router,
+    RtpTransportControllerSendInterface* transport,
     BitrateAllocator* bitrate_allocator,
     SendDelayStats* send_delay_stats,
     VieRemb* remb,
@@ -769,8 +762,7 @@
       worker_queue_(worker_queue),
       check_encoder_activity_task_(nullptr),
       call_stats_(call_stats),
-      send_side_cc_(send_side_cc),
-      packet_router_(packet_router),
+      transport_(transport),
       bitrate_allocator_(bitrate_allocator),
       remb_(remb),
       flexfec_sender_(MaybeCreateFlexfecSender(*config_)),
@@ -783,23 +775,22 @@
                         config_->rtp.ssrcs,
                         vie_encoder),
       protection_bitrate_calculator_(Clock::GetRealTimeClock(), this),
-      bandwidth_observer_(
-          send_side_cc_->GetBitrateController()->CreateRtcpBandwidthObserver()),
-      rtp_rtcp_modules_(
-          CreateRtpRtcpModules(config_->send_transport,
-                               &encoder_feedback_,
-                               bandwidth_observer_.get(),
-                               send_side_cc_,
-                               call_stats_->rtcp_rtt_stats(),
-                               send_side_cc_->pacer(),
-                               packet_router_,
-                               flexfec_sender_.get(),
-                               stats_proxy_,
-                               send_delay_stats,
-                               event_log,
-                               send_side_cc_->GetRetransmissionRateLimiter(),
-                               this,
-                               config_->rtp.ssrcs.size())),
+      bandwidth_observer_(transport->send_side_cc()
+                              ->GetBitrateController()
+                              ->CreateRtcpBandwidthObserver()),
+      rtp_rtcp_modules_(CreateRtpRtcpModules(
+          config_->send_transport,
+          &encoder_feedback_,
+          bandwidth_observer_.get(),
+          transport,
+          call_stats_->rtcp_rtt_stats(),
+          flexfec_sender_.get(),
+          stats_proxy_,
+          send_delay_stats,
+          event_log,
+          transport->send_side_cc()->GetRetransmissionRateLimiter(),
+          this,
+          config_->rtp.ssrcs.size())),
       payload_router_(rtp_rtcp_modules_,
                       config_->encoder_settings.payload_type),
       weak_ptr_factory_(this),
@@ -812,10 +803,11 @@
 
   RTC_DCHECK(!config_->rtp.ssrcs.empty());
   RTC_DCHECK(call_stats_);
-  RTC_DCHECK(send_side_cc_);
   RTC_DCHECK(remb_);
+  RTC_DCHECK(transport_);
+  RTC_DCHECK(transport_->send_side_cc());
 
-  send_side_cc_->EnablePeriodicAlrProbing(
+  transport->send_side_cc()->EnablePeriodicAlrProbing(
       config_->periodic_alr_bandwidth_probing);
 
   // RTP/RTCP initialization.
@@ -824,7 +816,7 @@
   // when sending padding, with the hope that the packet rate will be smaller,
   // and that it's more important to protect than the lower layers.
   for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_)
-    packet_router_->AddRtpModule(rtp_rtcp);
+    transport->packet_router()->AddRtpModule(rtp_rtcp);
 
   for (size_t i = 0; i < config_->rtp.extensions.size(); ++i) {
     const std::string& extension = config_->rtp.extensions[i].uri;
@@ -903,7 +895,7 @@
   remb_->RemoveRembSender(rtp_rtcp_modules_[0]);
 
   for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
-    packet_router_->RemoveRtpModule(rtp_rtcp);
+    transport_->packet_router()->RemoveRtpModule(rtp_rtcp);
     delete rtp_rtcp;
   }
 }
@@ -1334,7 +1326,8 @@
 
   transport_overhead_bytes_per_packet_ = transport_overhead_bytes_per_packet;
 
-  send_side_cc_->SetTransportOverhead(transport_overhead_bytes_per_packet_);
+  transport_->send_side_cc()->SetTransportOverhead(
+      transport_overhead_bytes_per_packet_);
 
   size_t rtp_packet_size =
       std::min(config_->rtp.max_packet_size,
diff --git a/webrtc/video/video_send_stream.h b/webrtc/video/video_send_stream.h
index 8aba9cd..0cc1a34 100644
--- a/webrtc/video/video_send_stream.h
+++ b/webrtc/video/video_send_stream.h
@@ -22,7 +22,6 @@
 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
 #include "webrtc/modules/video_coding/protection_bitrate_calculator.h"
 #include "webrtc/video/encoder_rtcp_feedback.h"
-#include "webrtc/video/payload_router.h"
 #include "webrtc/video/send_delay_stats.h"
 #include "webrtc/video/send_statistics_proxy.h"
 #include "webrtc/video/vie_encoder.h"
@@ -31,15 +30,14 @@
 
 namespace webrtc {
 
-class BitrateAllocator;
 class CallStats;
 class SendSideCongestionController;
 class IvfFileWriter;
-class PacketRouter;
 class ProcessThread;
 class RtpRtcp;
-class VieRemb;
+class RtpTransportControllerSendInterface;
 class RtcEventLog;
+class VieRemb;
 
 namespace internal {
 
@@ -54,8 +52,7 @@
                   ProcessThread* module_process_thread,
                   rtc::TaskQueue* worker_queue,
                   CallStats* call_stats,
-                  SendSideCongestionController* congestion_controller,
-                  PacketRouter* packet_router,
+                  RtpTransportControllerSendInterface* transport,
                   BitrateAllocator* bitrate_allocator,
                   SendDelayStats* send_delay_stats,
                   VieRemb* remb,
diff --git a/webrtc/voice_engine/BUILD.gn b/webrtc/voice_engine/BUILD.gn
index 7c54c37..233d129 100644
--- a/webrtc/voice_engine/BUILD.gn
+++ b/webrtc/voice_engine/BUILD.gn
@@ -137,6 +137,10 @@
     "../api/audio_codecs:builtin_audio_decoder_factory",
     "../audio/utility:audio_frame_operations",
     "../base:rtc_base_approved",
+
+    # TODO(nisse): Delete when declaration of RtpTransportController
+    # and related interfaces move to api/.
+    "../call:call_interfaces",
     "../common_audio",
     "../logging:rtc_event_log_api",
     "../modules/audio_coding:audio_format_conversion",
diff --git a/webrtc/voice_engine/channel.cc b/webrtc/voice_engine/channel.cc
index d2b30ca..e9cbc77 100644
--- a/webrtc/voice_engine/channel.cc
+++ b/webrtc/voice_engine/channel.cc
@@ -22,6 +22,7 @@
 #include "webrtc/base/logging.h"
 #include "webrtc/base/rate_limiter.h"
 #include "webrtc/base/timeutils.h"
+#include "webrtc/call/rtp_transport_controller_send.h"
 #include "webrtc/config.h"
 #include "webrtc/logging/rtc_event_log/rtc_event_log.h"
 #include "webrtc/modules/audio_coding/codecs/audio_format_conversion.h"
@@ -2371,10 +2372,13 @@
 }
 
 void Channel::RegisterSenderCongestionControlObjects(
-    RtpPacketSender* rtp_packet_sender,
-    TransportFeedbackObserver* transport_feedback_observer,
-    PacketRouter* packet_router,
+    RtpTransportControllerSendInterface* transport,
     RtcpBandwidthObserver* bandwidth_observer) {
+  RtpPacketSender* rtp_packet_sender = transport->packet_sender();
+  TransportFeedbackObserver* transport_feedback_observer =
+      transport->transport_feedback_observer();
+  PacketRouter* packet_router = transport->packet_router();
+
   RTC_DCHECK(rtp_packet_sender);
   RTC_DCHECK(transport_feedback_observer);
   RTC_DCHECK(packet_router && !packet_router_);
diff --git a/webrtc/voice_engine/channel.h b/webrtc/voice_engine/channel.h
index 0a12f21..a4761c6 100644
--- a/webrtc/voice_engine/channel.h
+++ b/webrtc/voice_engine/channel.h
@@ -55,6 +55,7 @@
 class RTPReceiverAudio;
 class RtpPacketReceived;
 class RtpRtcp;
+class RtpTransportControllerSendInterface;
 class TelephoneEventHandler;
 class VoERTPObserver;
 class VoiceEngineObserver;
@@ -275,9 +276,7 @@
   void EnableReceiveTransportSequenceNumber(int id);
 
   void RegisterSenderCongestionControlObjects(
-      RtpPacketSender* rtp_packet_sender,
-      TransportFeedbackObserver* transport_feedback_observer,
-      PacketRouter* packet_router,
+      RtpTransportControllerSendInterface* transport,
       RtcpBandwidthObserver* bandwidth_observer);
   void RegisterReceiverCongestionControlObjects(PacketRouter* packet_router);
   void ResetCongestionControlObjects();
diff --git a/webrtc/voice_engine/channel_proxy.cc b/webrtc/voice_engine/channel_proxy.cc
index 45cbf10..97e3f99 100644
--- a/webrtc/voice_engine/channel_proxy.cc
+++ b/webrtc/voice_engine/channel_proxy.cc
@@ -15,6 +15,7 @@
 #include "webrtc/api/call/audio_sink.h"
 #include "webrtc/base/checks.h"
 #include "webrtc/base/logging.h"
+#include "webrtc/call/rtp_transport_controller_send.h"
 #include "webrtc/voice_engine/channel.h"
 
 namespace webrtc {
@@ -76,14 +77,11 @@
 }
 
 void ChannelProxy::RegisterSenderCongestionControlObjects(
-    RtpPacketSender* rtp_packet_sender,
-    TransportFeedbackObserver* transport_feedback_observer,
-    PacketRouter* packet_router,
+    RtpTransportControllerSendInterface* transport,
     RtcpBandwidthObserver* bandwidth_observer) {
   RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
-  channel()->RegisterSenderCongestionControlObjects(
-      rtp_packet_sender, transport_feedback_observer, packet_router,
-      bandwidth_observer);
+  channel()->RegisterSenderCongestionControlObjects(transport,
+                                                    bandwidth_observer);
 }
 
 void ChannelProxy::RegisterReceiverCongestionControlObjects(
diff --git a/webrtc/voice_engine/channel_proxy.h b/webrtc/voice_engine/channel_proxy.h
index 685a168..5cac258 100644
--- a/webrtc/voice_engine/channel_proxy.h
+++ b/webrtc/voice_engine/channel_proxy.h
@@ -33,6 +33,7 @@
 class RtpPacketReceived;
 class RtpReceiver;
 class RtpRtcp;
+class RtpTransportControllerSendInterface;
 class Transport;
 class TransportFeedbackObserver;
 
@@ -62,9 +63,7 @@
   virtual void EnableSendTransportSequenceNumber(int id);
   virtual void EnableReceiveTransportSequenceNumber(int id);
   virtual void RegisterSenderCongestionControlObjects(
-      RtpPacketSender* rtp_packet_sender,
-      TransportFeedbackObserver* transport_feedback_observer,
-      PacketRouter* packet_router,
+      RtpTransportControllerSendInterface* transport,
       RtcpBandwidthObserver* bandwidth_observer);
   virtual void RegisterReceiverCongestionControlObjects(
       PacketRouter* packet_router);