Delete class ChannelReceiveProxy.

Replaced by an interface ChannelReceiveInterface, implemented
by ChannelReceive and the corresponding mock class.

Moved thread checkers to ChannelReceive. That class is moved to the
anonymous namespace in the .cc file, and exposed only via a function
CreateChannelReceive.

Bug: webrtc:9801
Change-Id: Iecacbb1858885bf86da9484f2422e53323dbe87a
Reviewed-on: https://webrtc-review.googlesource.com/c/110610
Commit-Queue: Niels Moller <nisse@webrtc.org>
Reviewed-by: Fredrik Solenberg <solenberg@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25665}
diff --git a/audio/BUILD.gn b/audio/BUILD.gn
index 4b2ec61..b6369e0 100644
--- a/audio/BUILD.gn
+++ b/audio/BUILD.gn
@@ -26,8 +26,6 @@
     "audio_transport_impl.h",
     "channel_receive.cc",
     "channel_receive.h",
-    "channel_receive_proxy.cc",
-    "channel_receive_proxy.h",
     "channel_send.cc",
     "channel_send.h",
     "channel_send_proxy.cc",
diff --git a/audio/audio_receive_stream.cc b/audio/audio_receive_stream.cc
index 4f2e29c..4848491 100644
--- a/audio/audio_receive_stream.cc
+++ b/audio/audio_receive_stream.cc
@@ -21,7 +21,6 @@
 #include "audio/audio_send_stream.h"
 #include "audio/audio_state.h"
 #include "audio/channel_receive.h"
-#include "audio/channel_receive_proxy.h"
 #include "audio/conversion.h"
 #include "call/rtp_config.h"
 #include "call/rtp_stream_receiver_controller_interface.h"
@@ -68,7 +67,7 @@
 
 namespace internal {
 namespace {
-std::unique_ptr<voe::ChannelReceiveProxy> CreateChannelAndProxy(
+std::unique_ptr<voe::ChannelReceiveInterface> CreateChannelReceive(
     webrtc::AudioState* audio_state,
     ProcessThread* module_process_thread,
     const webrtc::AudioReceiveStream::Config& config,
@@ -76,13 +75,12 @@
   RTC_DCHECK(audio_state);
   internal::AudioState* internal_audio_state =
       static_cast<internal::AudioState*>(audio_state);
-  return absl::make_unique<voe::ChannelReceiveProxy>(
-      absl::make_unique<voe::ChannelReceive>(
-          module_process_thread, internal_audio_state->audio_device_module(),
-          config.media_transport, config.rtcp_send_transport, event_log,
-          config.rtp.remote_ssrc, config.jitter_buffer_max_packets,
-          config.jitter_buffer_fast_accelerate, config.decoder_factory,
-          config.codec_pair_id, config.frame_decryptor, config.crypto_options));
+  return voe::CreateChannelReceive(
+      module_process_thread, internal_audio_state->audio_device_module(),
+      config.media_transport, config.rtcp_send_transport, event_log,
+      config.rtp.remote_ssrc, config.jitter_buffer_max_packets,
+      config.jitter_buffer_fast_accelerate, config.decoder_factory,
+      config.codec_pair_id, config.frame_decryptor, config.crypto_options);
 }
 }  // namespace
 
@@ -98,10 +96,10 @@
                          config,
                          audio_state,
                          event_log,
-                         CreateChannelAndProxy(audio_state.get(),
-                                               module_process_thread,
-                                               config,
-                                               event_log)) {}
+                         CreateChannelReceive(audio_state.get(),
+                                              module_process_thread,
+                                              config,
+                                              event_log)) {}
 
 AudioReceiveStream::AudioReceiveStream(
     RtpStreamReceiverControllerInterface* receiver_controller,
@@ -109,13 +107,13 @@
     const webrtc::AudioReceiveStream::Config& config,
     const rtc::scoped_refptr<webrtc::AudioState>& audio_state,
     webrtc::RtcEventLog* event_log,
-    std::unique_ptr<voe::ChannelReceiveProxy> channel_proxy)
-    : audio_state_(audio_state), channel_proxy_(std::move(channel_proxy)) {
+    std::unique_ptr<voe::ChannelReceiveInterface> channel_receive)
+    : audio_state_(audio_state), channel_receive_(std::move(channel_receive)) {
   RTC_LOG(LS_INFO) << "AudioReceiveStream: " << config.rtp.remote_ssrc;
   RTC_DCHECK(config.decoder_factory);
   RTC_DCHECK(config.rtcp_send_transport);
   RTC_DCHECK(audio_state_);
-  RTC_DCHECK(channel_proxy_);
+  RTC_DCHECK(channel_receive_);
 
   module_process_thread_checker_.DetachFromThread();
 
@@ -123,11 +121,11 @@
     RTC_DCHECK(receiver_controller);
     RTC_DCHECK(packet_router);
     // Configure bandwidth estimation.
-    channel_proxy_->RegisterReceiverCongestionControlObjects(packet_router);
+    channel_receive_->RegisterReceiverCongestionControlObjects(packet_router);
 
     // Register with transport.
     rtp_stream_receiver_ = receiver_controller->CreateReceiver(
-        config.rtp.remote_ssrc, channel_proxy_.get());
+        config.rtp.remote_ssrc, channel_receive_.get());
   }
   ConfigureStream(this, config, true);
 }
@@ -136,9 +134,9 @@
   RTC_DCHECK_RUN_ON(&worker_thread_checker_);
   RTC_LOG(LS_INFO) << "~AudioReceiveStream: " << config_.rtp.remote_ssrc;
   Stop();
-  channel_proxy_->DisassociateSendChannel();
+  channel_receive_->SetAssociatedSendChannel(nullptr);
   if (!config_.media_transport) {
-    channel_proxy_->ResetReceiverCongestionControlObjects();
+    channel_receive_->ResetReceiverCongestionControlObjects();
   }
 }
 
@@ -153,7 +151,7 @@
   if (playing_) {
     return;
   }
-  channel_proxy_->StartPlayout();
+  channel_receive_->StartPlayout();
   playing_ = true;
   audio_state()->AddReceivingStream(this);
 }
@@ -163,7 +161,7 @@
   if (!playing_) {
     return;
   }
-  channel_proxy_->StopPlayout();
+  channel_receive_->StopPlayout();
   playing_ = false;
   audio_state()->RemoveReceivingStream(this);
 }
@@ -174,11 +172,11 @@
   stats.remote_ssrc = config_.rtp.remote_ssrc;
 
   webrtc::CallReceiveStatistics call_stats =
-      channel_proxy_->GetRTCPStatistics();
+      channel_receive_->GetRTCPStatistics();
   // TODO(solenberg): Don't return here if we can't get the codec - return the
   //                  stats we *can* get.
   webrtc::CodecInst codec_inst = {0};
-  if (!channel_proxy_->GetRecCodec(&codec_inst)) {
+  if (!channel_receive_->GetRecCodec(&codec_inst)) {
     return stats;
   }
 
@@ -195,13 +193,13 @@
   if (codec_inst.plfreq / 1000 > 0) {
     stats.jitter_ms = call_stats.jitterSamples / (codec_inst.plfreq / 1000);
   }
-  stats.delay_estimate_ms = channel_proxy_->GetDelayEstimate();
-  stats.audio_level = channel_proxy_->GetSpeechOutputLevelFullRange();
-  stats.total_output_energy = channel_proxy_->GetTotalOutputEnergy();
-  stats.total_output_duration = channel_proxy_->GetTotalOutputDuration();
+  stats.delay_estimate_ms = channel_receive_->GetDelayEstimate();
+  stats.audio_level = channel_receive_->GetSpeechOutputLevelFullRange();
+  stats.total_output_energy = channel_receive_->GetTotalOutputEnergy();
+  stats.total_output_duration = channel_receive_->GetTotalOutputDuration();
 
   // Get jitter buffer and total delay (alg + jitter + playout) stats.
-  auto ns = channel_proxy_->GetNetworkStatistics();
+  auto ns = channel_receive_->GetNetworkStatistics();
   stats.jitter_buffer_ms = ns.currentBufferSize;
   stats.jitter_buffer_preferred_ms = ns.preferredBufferSize;
   stats.total_samples_received = ns.totalSamplesReceived;
@@ -217,7 +215,7 @@
   stats.accelerate_rate = Q14ToFloat(ns.currentAccelerateRate);
   stats.preemptive_expand_rate = Q14ToFloat(ns.currentPreemptiveRate);
 
-  auto ds = channel_proxy_->GetDecodingCallStatistics();
+  auto ds = channel_receive_->GetDecodingCallStatistics();
   stats.decoding_calls_to_silence_generator = ds.calls_to_silence_generator;
   stats.decoding_calls_to_neteq = ds.calls_to_neteq;
   stats.decoding_normal = ds.decoded_normal;
@@ -231,23 +229,23 @@
 
 void AudioReceiveStream::SetSink(AudioSinkInterface* sink) {
   RTC_DCHECK_RUN_ON(&worker_thread_checker_);
-  channel_proxy_->SetSink(sink);
+  channel_receive_->SetSink(sink);
 }
 
 void AudioReceiveStream::SetGain(float gain) {
   RTC_DCHECK_RUN_ON(&worker_thread_checker_);
-  channel_proxy_->SetChannelOutputVolumeScaling(gain);
+  channel_receive_->SetChannelOutputVolumeScaling(gain);
 }
 
 std::vector<RtpSource> AudioReceiveStream::GetSources() const {
   RTC_DCHECK_RUN_ON(&worker_thread_checker_);
-  return channel_proxy_->GetSources();
+  return channel_receive_->GetSources();
 }
 
 AudioMixer::Source::AudioFrameInfo AudioReceiveStream::GetAudioFrameWithInfo(
     int sample_rate_hz,
     AudioFrame* audio_frame) {
-  return channel_proxy_->GetAudioFrameWithInfo(sample_rate_hz, audio_frame);
+  return channel_receive_->GetAudioFrameWithInfo(sample_rate_hz, audio_frame);
 }
 
 int AudioReceiveStream::Ssrc() const {
@@ -255,7 +253,7 @@
 }
 
 int AudioReceiveStream::PreferredSampleRate() const {
-  return channel_proxy_->PreferredSampleRate();
+  return channel_receive_->PreferredSampleRate();
 }
 
 int AudioReceiveStream::id() const {
@@ -265,32 +263,29 @@
 
 absl::optional<Syncable::Info> AudioReceiveStream::GetInfo() const {
   RTC_DCHECK_RUN_ON(&module_process_thread_checker_);
-  absl::optional<Syncable::Info> info = channel_proxy_->GetSyncInfo();
+  absl::optional<Syncable::Info> info = channel_receive_->GetSyncInfo();
 
   if (!info)
     return absl::nullopt;
 
-  info->current_delay_ms = channel_proxy_->GetDelayEstimate();
+  info->current_delay_ms = channel_receive_->GetDelayEstimate();
   return info;
 }
 
 uint32_t AudioReceiveStream::GetPlayoutTimestamp() const {
   // Called on video capture thread.
-  return channel_proxy_->GetPlayoutTimestamp();
+  return channel_receive_->GetPlayoutTimestamp();
 }
 
 void AudioReceiveStream::SetMinimumPlayoutDelay(int delay_ms) {
   RTC_DCHECK_RUN_ON(&module_process_thread_checker_);
-  return channel_proxy_->SetMinimumPlayoutDelay(delay_ms);
+  return channel_receive_->SetMinimumPlayoutDelay(delay_ms);
 }
 
 void AudioReceiveStream::AssociateSendStream(AudioSendStream* send_stream) {
   RTC_DCHECK_RUN_ON(&worker_thread_checker_);
-  if (send_stream) {
-    channel_proxy_->AssociateSendChannel(send_stream->GetChannelProxy());
-  } else {
-    channel_proxy_->DisassociateSendChannel();
-  }
+  channel_receive_->SetAssociatedSendChannel(
+      send_stream ? send_stream->GetChannel() : nullptr);
   associated_send_stream_ = send_stream;
 }
 
@@ -303,7 +298,7 @@
   // calls on the worker thread. We should move towards always using a network
   // thread. Then this check can be enabled.
   // RTC_DCHECK(!thread_checker_.CalledOnValidThread());
-  return channel_proxy_->ReceivedRTCPPacket(packet, length);
+  return channel_receive_->ReceivedRTCPPacket(packet, length);
 }
 
 void AudioReceiveStream::OnRtpPacket(const RtpPacketReceived& packet) {
@@ -311,7 +306,7 @@
   // calls on the worker thread. We should move towards always using a network
   // thread. Then this check can be enabled.
   // RTC_DCHECK(!thread_checker_.CalledOnValidThread());
-  channel_proxy_->OnRtpPacket(packet);
+  channel_receive_->OnRtpPacket(packet);
 }
 
 const webrtc::AudioReceiveStream::Config& AudioReceiveStream::config() const {
@@ -337,7 +332,7 @@
   RTC_LOG(LS_INFO) << "AudioReceiveStream::ConfigureStream: "
                    << new_config.ToString();
   RTC_DCHECK(stream);
-  const auto& channel_proxy = stream->channel_proxy_;
+  const auto& channel_receive = stream->channel_receive_;
   const auto& old_config = stream->config_;
 
   // Configuration parameters which cannot be changed.
@@ -351,7 +346,7 @@
              old_config.decoder_factory == new_config.decoder_factory);
 
   if (first_time || old_config.rtp.local_ssrc != new_config.rtp.local_ssrc) {
-    channel_proxy->SetLocalSSRC(new_config.rtp.local_ssrc);
+    channel_receive->SetLocalSSRC(new_config.rtp.local_ssrc);
   }
 
   if (!first_time) {
@@ -363,11 +358,11 @@
   // using the actual packet size for the configured codec.
   if (first_time || old_config.rtp.nack.rtp_history_ms !=
                         new_config.rtp.nack.rtp_history_ms) {
-    channel_proxy->SetNACKStatus(new_config.rtp.nack.rtp_history_ms != 0,
-                                 new_config.rtp.nack.rtp_history_ms / 20);
+    channel_receive->SetNACKStatus(new_config.rtp.nack.rtp_history_ms != 0,
+                                   new_config.rtp.nack.rtp_history_ms / 20);
   }
   if (first_time || old_config.decoder_map != new_config.decoder_map) {
-    channel_proxy->SetReceiveCodecs(new_config.decoder_map);
+    channel_receive->SetReceiveCodecs(new_config.decoder_map);
   }
 
   stream->config_ = new_config;
diff --git a/audio/audio_receive_stream.h b/audio/audio_receive_stream.h
index dde0da4..5b41f1a 100644
--- a/audio/audio_receive_stream.h
+++ b/audio/audio_receive_stream.h
@@ -31,7 +31,7 @@
 class RtpStreamReceiverInterface;
 
 namespace voe {
-class ChannelReceiveProxy;
+class ChannelReceiveInterface;
 }  // namespace voe
 
 namespace internal {
@@ -47,13 +47,14 @@
                      const webrtc::AudioReceiveStream::Config& config,
                      const rtc::scoped_refptr<webrtc::AudioState>& audio_state,
                      webrtc::RtcEventLog* event_log);
-  // For unit tests, which need to supply a mock channel proxy.
-  AudioReceiveStream(RtpStreamReceiverControllerInterface* receiver_controller,
-                     PacketRouter* packet_router,
-                     const webrtc::AudioReceiveStream::Config& config,
-                     const rtc::scoped_refptr<webrtc::AudioState>& audio_state,
-                     webrtc::RtcEventLog* event_log,
-                     std::unique_ptr<voe::ChannelReceiveProxy> channel_proxy);
+  // For unit tests, which need to supply a mock channel receive.
+  AudioReceiveStream(
+      RtpStreamReceiverControllerInterface* receiver_controller,
+      PacketRouter* packet_router,
+      const webrtc::AudioReceiveStream::Config& config,
+      const rtc::scoped_refptr<webrtc::AudioState>& audio_state,
+      webrtc::RtcEventLog* event_log,
+      std::unique_ptr<voe::ChannelReceiveInterface> channel_receive);
   ~AudioReceiveStream() override;
 
   // webrtc::AudioReceiveStream implementation.
@@ -100,7 +101,7 @@
   rtc::ThreadChecker module_process_thread_checker_;
   webrtc::AudioReceiveStream::Config config_;
   rtc::scoped_refptr<webrtc::AudioState> audio_state_;
-  std::unique_ptr<voe::ChannelReceiveProxy> channel_proxy_;
+  std::unique_ptr<voe::ChannelReceiveInterface> channel_receive_;
   AudioSendStream* associated_send_stream_ = nullptr;
 
   bool playing_ RTC_GUARDED_BY(worker_thread_checker_) = false;
diff --git a/audio/audio_receive_stream_unittest.cc b/audio/audio_receive_stream_unittest.cc
index a5c7e20..7422810 100644
--- a/audio/audio_receive_stream_unittest.cc
+++ b/audio/audio_receive_stream_unittest.cc
@@ -83,16 +83,16 @@
         new rtc::RefCountedObject<testing::NiceMock<MockAudioDeviceModule>>();
     audio_state_ = AudioState::Create(config);
 
-    channel_proxy_ = new testing::StrictMock<MockChannelReceiveProxy>();
-    EXPECT_CALL(*channel_proxy_, SetLocalSSRC(kLocalSsrc)).Times(1);
-    EXPECT_CALL(*channel_proxy_, SetNACKStatus(true, 15)).Times(1);
-    EXPECT_CALL(*channel_proxy_,
+    channel_receive_ = new testing::StrictMock<MockChannelReceive>();
+    EXPECT_CALL(*channel_receive_, SetLocalSSRC(kLocalSsrc)).Times(1);
+    EXPECT_CALL(*channel_receive_, SetNACKStatus(true, 15)).Times(1);
+    EXPECT_CALL(*channel_receive_,
                 RegisterReceiverCongestionControlObjects(&packet_router_))
         .Times(1);
-    EXPECT_CALL(*channel_proxy_, ResetReceiverCongestionControlObjects())
+    EXPECT_CALL(*channel_receive_, ResetReceiverCongestionControlObjects())
         .Times(1);
-    EXPECT_CALL(*channel_proxy_, DisassociateSendChannel()).Times(1);
-    EXPECT_CALL(*channel_proxy_, SetReceiveCodecs(_))
+    EXPECT_CALL(*channel_receive_, SetAssociatedSendChannel(nullptr)).Times(1);
+    EXPECT_CALL(*channel_receive_, SetReceiveCodecs(_))
         .WillRepeatedly(Invoke([](const std::map<int, SdpAudioFormat>& codecs) {
           EXPECT_THAT(codecs, testing::IsEmpty());
         }));
@@ -114,33 +114,33 @@
         new internal::AudioReceiveStream(
             &rtp_stream_receiver_controller_, &packet_router_, stream_config_,
             audio_state_, &event_log_,
-            std::unique_ptr<voe::ChannelReceiveProxy>(channel_proxy_)));
+            std::unique_ptr<voe::ChannelReceiveInterface>(channel_receive_)));
   }
 
   AudioReceiveStream::Config& config() { return stream_config_; }
   rtc::scoped_refptr<MockAudioMixer> audio_mixer() { return audio_mixer_; }
-  MockChannelReceiveProxy* channel_proxy() { return channel_proxy_; }
+  MockChannelReceive* channel_receive() { return channel_receive_; }
 
   void SetupMockForGetStats() {
     using testing::DoAll;
     using testing::SetArgPointee;
 
-    ASSERT_TRUE(channel_proxy_);
-    EXPECT_CALL(*channel_proxy_, GetRTCPStatistics())
+    ASSERT_TRUE(channel_receive_);
+    EXPECT_CALL(*channel_receive_, GetRTCPStatistics())
         .WillOnce(Return(kCallStats));
-    EXPECT_CALL(*channel_proxy_, GetDelayEstimate())
+    EXPECT_CALL(*channel_receive_, GetDelayEstimate())
         .WillOnce(Return(kJitterBufferDelay + kPlayoutBufferDelay));
-    EXPECT_CALL(*channel_proxy_, GetSpeechOutputLevelFullRange())
+    EXPECT_CALL(*channel_receive_, GetSpeechOutputLevelFullRange())
         .WillOnce(Return(kSpeechOutputLevel));
-    EXPECT_CALL(*channel_proxy_, GetTotalOutputEnergy())
+    EXPECT_CALL(*channel_receive_, GetTotalOutputEnergy())
         .WillOnce(Return(kTotalOutputEnergy));
-    EXPECT_CALL(*channel_proxy_, GetTotalOutputDuration())
+    EXPECT_CALL(*channel_receive_, GetTotalOutputDuration())
         .WillOnce(Return(kTotalOutputDuration));
-    EXPECT_CALL(*channel_proxy_, GetNetworkStatistics())
+    EXPECT_CALL(*channel_receive_, GetNetworkStatistics())
         .WillOnce(Return(kNetworkStats));
-    EXPECT_CALL(*channel_proxy_, GetDecodingCallStatistics())
+    EXPECT_CALL(*channel_receive_, GetDecodingCallStatistics())
         .WillOnce(Return(kAudioDecodeStats));
-    EXPECT_CALL(*channel_proxy_, GetRecCodec(_))
+    EXPECT_CALL(*channel_receive_, GetRecCodec(_))
         .WillOnce(DoAll(SetArgPointee<0>(kCodecInst), Return(true)));
   }
 
@@ -150,7 +150,7 @@
   rtc::scoped_refptr<AudioState> audio_state_;
   rtc::scoped_refptr<MockAudioMixer> audio_mixer_;
   AudioReceiveStream::Config stream_config_;
-  testing::StrictMock<MockChannelReceiveProxy>* channel_proxy_ = nullptr;
+  testing::StrictMock<MockChannelReceive>* channel_receive_ = nullptr;
   RtpStreamReceiverController rtp_stream_receiver_controller_;
   MockTransport rtcp_send_transport_;
 };
@@ -239,7 +239,7 @@
   ASSERT_TRUE(parsed_packet.Parse(&rtp_packet[0], rtp_packet.size()));
   parsed_packet.set_arrival_time_ms((packet_time_us + 500) / 1000);
 
-  EXPECT_CALL(*helper.channel_proxy(),
+  EXPECT_CALL(*helper.channel_receive(),
               OnRtpPacket(testing::Ref(parsed_packet)));
 
   recv_stream->OnRtpPacket(parsed_packet);
@@ -250,7 +250,7 @@
   helper.config().rtp.transport_cc = true;
   auto recv_stream = helper.CreateAudioReceiveStream();
   std::vector<uint8_t> rtcp_packet = CreateRtcpSenderReport();
-  EXPECT_CALL(*helper.channel_proxy(),
+  EXPECT_CALL(*helper.channel_receive(),
               ReceivedRTCPPacket(&rtcp_packet[0], rtcp_packet.size()))
       .WillOnce(Return(true));
   EXPECT_TRUE(recv_stream->DeliverRtcp(&rtcp_packet[0], rtcp_packet.size()));
@@ -312,7 +312,7 @@
 TEST(AudioReceiveStreamTest, SetGain) {
   ConfigHelper helper;
   auto recv_stream = helper.CreateAudioReceiveStream();
-  EXPECT_CALL(*helper.channel_proxy(),
+  EXPECT_CALL(*helper.channel_receive(),
               SetChannelOutputVolumeScaling(FloatEq(0.765f)));
   recv_stream->SetGain(0.765f);
 }
@@ -323,10 +323,10 @@
   auto recv_stream1 = helper1.CreateAudioReceiveStream();
   auto recv_stream2 = helper2.CreateAudioReceiveStream();
 
-  EXPECT_CALL(*helper1.channel_proxy(), StartPlayout()).Times(1);
-  EXPECT_CALL(*helper2.channel_proxy(), StartPlayout()).Times(1);
-  EXPECT_CALL(*helper1.channel_proxy(), StopPlayout()).Times(1);
-  EXPECT_CALL(*helper2.channel_proxy(), StopPlayout()).Times(1);
+  EXPECT_CALL(*helper1.channel_receive(), StartPlayout()).Times(1);
+  EXPECT_CALL(*helper2.channel_receive(), StartPlayout()).Times(1);
+  EXPECT_CALL(*helper1.channel_receive(), StopPlayout()).Times(1);
+  EXPECT_CALL(*helper2.channel_receive(), StopPlayout()).Times(1);
   EXPECT_CALL(*helper1.audio_mixer(), AddSource(recv_stream1.get()))
       .WillOnce(Return(true));
   EXPECT_CALL(*helper1.audio_mixer(), AddSource(recv_stream2.get()))
@@ -367,10 +367,10 @@
                    kTransportSequenceNumberId + 1));
   new_config.decoder_map.emplace(1, SdpAudioFormat("foo", 8000, 1));
 
-  MockChannelReceiveProxy& channel_proxy = *helper.channel_proxy();
-  EXPECT_CALL(channel_proxy, SetLocalSSRC(kLocalSsrc + 1)).Times(1);
-  EXPECT_CALL(channel_proxy, SetNACKStatus(true, 15 + 1)).Times(1);
-  EXPECT_CALL(channel_proxy, SetReceiveCodecs(new_config.decoder_map));
+  MockChannelReceive& channel_receive = *helper.channel_receive();
+  EXPECT_CALL(channel_receive, SetLocalSSRC(kLocalSsrc + 1)).Times(1);
+  EXPECT_CALL(channel_receive, SetNACKStatus(true, 15 + 1)).Times(1);
+  EXPECT_CALL(channel_receive, SetReceiveCodecs(new_config.decoder_map));
 
   recv_stream->Reconfigure(new_config);
 }
diff --git a/audio/audio_send_stream.cc b/audio/audio_send_stream.cc
index 7824653..00c66a2 100644
--- a/audio/audio_send_stream.cc
+++ b/audio/audio_send_stream.cc
@@ -553,9 +553,9 @@
   return rtp_rtcp_module_->GetRtpState();
 }
 
-const voe::ChannelSendProxy& AudioSendStream::GetChannelProxy() const {
+const voe::ChannelSend* AudioSendStream::GetChannel() const {
   RTC_DCHECK(channel_proxy_.get());
-  return *channel_proxy_.get();
+  return channel_proxy_->GetChannel();
 }
 
 internal::AudioState* AudioSendStream::audio_state() {
diff --git a/audio/audio_send_stream.h b/audio/audio_send_stream.h
index c86a9dc..5f7ea14 100644
--- a/audio/audio_send_stream.h
+++ b/audio/audio_send_stream.h
@@ -31,6 +31,7 @@
 class RtpTransportControllerSendInterface;
 
 namespace voe {
+class ChannelSend;
 class ChannelSendProxy;
 }  // namespace voe
 
@@ -93,7 +94,7 @@
   void SetTransportOverhead(int transport_overhead_per_packet);
 
   RtpState GetRtpState() const;
-  const voe::ChannelSendProxy& GetChannelProxy() const;
+  const voe::ChannelSend* GetChannel() const;
 
  private:
   class TimedTransport;
diff --git a/audio/channel_receive.cc b/audio/channel_receive.cc
index 1d6f089..9c100fb 100644
--- a/audio/channel_receive.cc
+++ b/audio/channel_receive.cc
@@ -18,14 +18,19 @@
 #include <vector>
 
 #include "absl/memory/memory.h"
+#include "audio/audio_level.h"
 #include "audio/channel_send.h"
 #include "audio/utility/audio_frame_operations.h"
 #include "logging/rtc_event_log/events/rtc_event_audio_playout.h"
 #include "logging/rtc_event_log/rtc_event_log.h"
 #include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h"
+#include "modules/audio_coding/include/audio_coding_module.h"
 #include "modules/audio_device/include/audio_device.h"
 #include "modules/pacing/packet_router.h"
 #include "modules/rtp_rtcp/include/receive_statistics.h"
+#include "modules/rtp_rtcp/include/remote_ntp_time_estimator.h"
+#include "modules/rtp_rtcp/include/rtp_rtcp.h"
+#include "modules/rtp_rtcp/source/contributing_sources.h"
 #include "modules/rtp_rtcp/source/rtp_header_extensions.h"
 #include "modules/rtp_rtcp/source/rtp_packet_received.h"
 #include "modules/utility/include/process_thread.h"
@@ -34,10 +39,16 @@
 #include "rtc_base/format_macros.h"
 #include "rtc_base/location.h"
 #include "rtc_base/logging.h"
+#include "rtc_base/numerics/safe_minmax.h"
+#include "rtc_base/race_checker.h"
 #include "rtc_base/thread_checker.h"
 #include "rtc_base/timeutils.h"
 #include "system_wrappers/include/metrics.h"
 
+// TODO(solenberg, nisse): This file contains a few NOLINT marks, to silence
+// warnings about non-const reference arguments.
+// These need cleanup, in a separate cl.
+
 namespace webrtc {
 namespace voe {
 
@@ -83,7 +94,219 @@
   return webrtc_header;
 }
 
-}  // namespace
+// Helper class to simplify locking scheme for members that are accessed from
+// multiple threads.
+// Example: a member can be set on thread T1 and read by an internal audio
+// thread T2. Accessing the member via this class ensures that we are
+// safe and also avoid TSan v2 warnings.
+class ChannelReceiveState {
+ public:
+  struct State {
+    bool playing = false;
+  };
+
+  ChannelReceiveState() {}
+  virtual ~ChannelReceiveState() {}
+
+  void Reset() {
+    rtc::CritScope lock(&lock_);
+    state_ = State();
+  }
+
+  State Get() const {
+    rtc::CritScope lock(&lock_);
+    return state_;
+  }
+
+  void SetPlaying(bool enable) {
+    rtc::CritScope lock(&lock_);
+    state_.playing = enable;
+  }
+
+ private:
+  rtc::CriticalSection lock_;
+  State state_;
+};
+
+class ChannelReceive : public ChannelReceiveInterface,
+                       public MediaTransportAudioSinkInterface {
+ public:
+  // Used for receive streams.
+  ChannelReceive(ProcessThread* module_process_thread,
+                 AudioDeviceModule* audio_device_module,
+                 MediaTransportInterface* media_transport,
+                 Transport* rtcp_send_transport,
+                 RtcEventLog* rtc_event_log,
+                 uint32_t remote_ssrc,
+                 size_t jitter_buffer_max_packets,
+                 bool jitter_buffer_fast_playout,
+                 rtc::scoped_refptr<AudioDecoderFactory> decoder_factory,
+                 absl::optional<AudioCodecPairId> codec_pair_id,
+                 rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor,
+                 const webrtc::CryptoOptions& crypto_options);
+  ~ChannelReceive() override;
+
+  void SetSink(AudioSinkInterface* sink) override;
+
+  void SetReceiveCodecs(const std::map<int, SdpAudioFormat>& codecs) override;
+
+  // API methods
+
+  void StartPlayout() override;
+  void StopPlayout() override;
+
+  // Codecs
+  bool GetRecCodec(CodecInst* codec) const override;
+
+  bool ReceivedRTCPPacket(const uint8_t* data, size_t length) override;
+
+  // RtpPacketSinkInterface.
+  void OnRtpPacket(const RtpPacketReceived& packet) override;
+
+  // Muting, Volume and Level.
+  void SetChannelOutputVolumeScaling(float scaling) override;
+  int GetSpeechOutputLevelFullRange() const override;
+  // See description of "totalAudioEnergy" in the WebRTC stats spec:
+  // https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamtrackstats-totalaudioenergy
+  double GetTotalOutputEnergy() const override;
+  double GetTotalOutputDuration() const override;
+
+  // Stats.
+  NetworkStatistics GetNetworkStatistics() const override;
+  AudioDecodingCallStats GetDecodingCallStatistics() const override;
+
+  // Audio+Video Sync.
+  uint32_t GetDelayEstimate() const override;
+  void SetMinimumPlayoutDelay(int delayMs) override;
+  uint32_t GetPlayoutTimestamp() const override;
+
+  // Produces the transport-related timestamps; current_delay_ms is left unset.
+  absl::optional<Syncable::Info> GetSyncInfo() const override;
+
+  // RTP+RTCP
+  void SetLocalSSRC(unsigned int ssrc) override;
+
+  void RegisterReceiverCongestionControlObjects(
+      PacketRouter* packet_router) override;
+  void ResetReceiverCongestionControlObjects() override;
+
+  CallReceiveStatistics GetRTCPStatistics() const override;
+  void SetNACKStatus(bool enable, int maxNumberOfPackets) override;
+
+  AudioMixer::Source::AudioFrameInfo GetAudioFrameWithInfo(
+      int sample_rate_hz,
+      AudioFrame* audio_frame) override;
+
+  int PreferredSampleRate() const override;
+
+  // Associate to a send channel.
+  // Used for obtaining RTT for a receive-only channel.
+  void SetAssociatedSendChannel(const ChannelSend* channel) override;
+
+  std::vector<RtpSource> GetSources() const override;
+
+ private:
+  void Init();
+  void Terminate();
+
+  int GetRemoteSSRC(unsigned int& ssrc);  // NOLINT
+
+  bool ReceivePacket(const uint8_t* packet,
+                     size_t packet_length,
+                     const RTPHeader& header);
+  int ResendPackets(const uint16_t* sequence_numbers, int length);
+  void UpdatePlayoutTimestamp(bool rtcp);
+
+  int GetRtpTimestampRateHz() const;
+  int64_t GetRTT() const;
+
+  // MediaTransportAudioSinkInterface override;
+  void OnData(uint64_t channel_id,
+              MediaTransportEncodedAudioFrame frame) override;
+
+  int32_t OnReceivedPayloadData(const uint8_t* payloadData,
+                                size_t payloadSize,
+                                const WebRtcRTPHeader* rtpHeader);
+
+  // Thread checkers document and lock usage of some methods to specific threads
+  // we know about. The goal is to eventually split up voe::ChannelReceive into
+  // parts with single-threaded semantics, and thereby reduce the need for
+  // locks.
+  rtc::ThreadChecker worker_thread_checker_;
+  rtc::ThreadChecker module_process_thread_checker_;
+  // Methods accessed from audio and video threads are checked for sequential-
+  // only access. We don't necessarily own and control these threads, so thread
+  // checkers cannot be used. E.g. Chromium may transfer "ownership" from one
+  // audio thread to another, but access is still sequential.
+  rtc::RaceChecker audio_thread_race_checker_;
+  rtc::RaceChecker video_capture_thread_race_checker_;
+  rtc::CriticalSection _callbackCritSect;
+  rtc::CriticalSection volume_settings_critsect_;
+
+  ChannelReceiveState channel_state_;
+
+  RtcEventLog* const event_log_;
+
+  // Indexed by payload type.
+  std::map<uint8_t, int> payload_type_frequencies_;
+
+  std::unique_ptr<ReceiveStatistics> rtp_receive_statistics_;
+  std::unique_ptr<RtpRtcp> _rtpRtcpModule;
+  const uint32_t remote_ssrc_;
+
+  // Info for GetSources and GetSyncInfo is updated on network or worker thread,
+  // queried on the worker thread.
+  rtc::CriticalSection rtp_sources_lock_;
+  ContributingSources contributing_sources_ RTC_GUARDED_BY(&rtp_sources_lock_);
+  absl::optional<uint32_t> last_received_rtp_timestamp_
+      RTC_GUARDED_BY(&rtp_sources_lock_);
+  absl::optional<int64_t> last_received_rtp_system_time_ms_
+      RTC_GUARDED_BY(&rtp_sources_lock_);
+  absl::optional<uint8_t> last_received_rtp_audio_level_
+      RTC_GUARDED_BY(&rtp_sources_lock_);
+
+  std::unique_ptr<AudioCodingModule> audio_coding_;
+  AudioSinkInterface* audio_sink_ = nullptr;
+  AudioLevel _outputAudioLevel;
+
+  RemoteNtpTimeEstimator ntp_estimator_ RTC_GUARDED_BY(ts_stats_lock_);
+
+  // Timestamp of the audio pulled from NetEq.
+  absl::optional<uint32_t> jitter_buffer_playout_timestamp_;
+
+  rtc::CriticalSection video_sync_lock_;
+  uint32_t playout_timestamp_rtp_ RTC_GUARDED_BY(video_sync_lock_);
+  uint32_t playout_delay_ms_ RTC_GUARDED_BY(video_sync_lock_);
+
+  rtc::CriticalSection ts_stats_lock_;
+
+  std::unique_ptr<rtc::TimestampWrapAroundHandler> rtp_ts_wraparound_handler_;
+  // The rtp timestamp of the first played out audio frame.
+  int64_t capture_start_rtp_time_stamp_;
+  // The capture ntp time (in local timebase) of the first played out audio
+  // frame.
+  int64_t capture_start_ntp_time_ms_ RTC_GUARDED_BY(ts_stats_lock_);
+
+  // uses
+  ProcessThread* _moduleProcessThreadPtr;
+  AudioDeviceModule* _audioDeviceModulePtr;
+  float _outputGain RTC_GUARDED_BY(volume_settings_critsect_);
+
+  // An associated send channel.
+  rtc::CriticalSection assoc_send_channel_lock_;
+  const ChannelSend* associated_send_channel_
+      RTC_GUARDED_BY(assoc_send_channel_lock_);
+
+  PacketRouter* packet_router_ = nullptr;
+
+  rtc::ThreadChecker construction_thread_;
+
+  MediaTransportInterface* const media_transport_;
+
+  // E2EE Audio Frame Decryption
+  rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor_;
+  webrtc::CryptoOptions crypto_options_;
+};
 
 int32_t ChannelReceive::OnReceivedPayloadData(
     const uint8_t* payloadData,
@@ -142,6 +365,7 @@
 AudioMixer::Source::AudioFrameInfo ChannelReceive::GetAudioFrameWithInfo(
     int sample_rate_hz,
     AudioFrame* audio_frame) {
+  RTC_DCHECK_RUNS_SERIALIZED(&audio_thread_race_checker_);
   audio_frame->sample_rate_hz_ = sample_rate_hz;
 
   unsigned int ssrc;
@@ -248,6 +472,7 @@
 }
 
 int ChannelReceive::PreferredSampleRate() const {
+  RTC_DCHECK_RUNS_SERIALIZED(&audio_thread_race_checker_);
   // Return the bigger of playout and receive frequency in the ACM.
   return std::max(audio_coding_->ReceiveFrequency(),
                   audio_coding_->PlayoutFrequency());
@@ -284,6 +509,9 @@
       media_transport_(media_transport),
       frame_decryptor_(frame_decryptor),
       crypto_options_(crypto_options) {
+  // TODO(nisse): Use _moduleProcessThreadPtr instead?
+  module_process_thread_checker_.DetachFromThread();
+
   RTC_DCHECK(module_process_thread);
   RTC_DCHECK(audio_device_module);
   AudioCodingModule::Config acm_config;
@@ -368,11 +596,13 @@
 }
 
 void ChannelReceive::SetSink(AudioSinkInterface* sink) {
+  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
   rtc::CritScope cs(&_callbackCritSect);
   audio_sink_ = sink;
 }
 
 void ChannelReceive::StartPlayout() {
+  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
   if (channel_state_.Get().playing) {
     return;
   }
@@ -381,6 +611,7 @@
 }
 
 void ChannelReceive::StopPlayout() {
+  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
   if (!channel_state_.Get().playing) {
     return;
   }
@@ -389,11 +620,13 @@
   _outputAudioLevel.Clear();
 }
 
-bool ChannelReceive::GetRecCodec(CodecInst* codec) {
+bool ChannelReceive::GetRecCodec(CodecInst* codec) const {
+  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
   return (audio_coding_->ReceiveCodec(codec) == 0);
 }
 
 std::vector<webrtc::RtpSource> ChannelReceive::GetSources() const {
+  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
   int64_t now_ms = rtc::TimeMillis();
   std::vector<RtpSource> sources;
   {
@@ -411,6 +644,7 @@
 
 void ChannelReceive::SetReceiveCodecs(
     const std::map<int, SdpAudioFormat>& codecs) {
+  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
   for (const auto& kv : codecs) {
     RTC_DCHECK_GE(kv.second.clockrate_hz, 1000);
     payload_type_frequencies_[kv.first] = kv.second.clockrate_hz;
@@ -418,7 +652,7 @@
   audio_coding_->SetReceiveCodecs(codecs);
 }
 
-// TODO(nisse): Move receive logic up to AudioReceiveStream.
+// May be called on either worker thread or network thread.
 void ChannelReceive::OnRtpPacket(const RtpPacketReceived& packet) {
   int64_t now_ms = rtc::TimeMillis();
   uint8_t audio_level;
@@ -509,6 +743,7 @@
                                &webrtc_rtp_header);
 }
 
+// May be called on either worker thread or network thread.
 // TODO(nisse): Drop always-true return value.
 bool ChannelReceive::ReceivedRTCPPacket(const uint8_t* data, size_t length) {
   // Store playout timestamp for the received RTCP packet
@@ -547,23 +782,28 @@
 }
 
 int ChannelReceive::GetSpeechOutputLevelFullRange() const {
+  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
   return _outputAudioLevel.LevelFullRange();
 }
 
 double ChannelReceive::GetTotalOutputEnergy() const {
+  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
   return _outputAudioLevel.TotalEnergy();
 }
 
 double ChannelReceive::GetTotalOutputDuration() const {
+  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
   return _outputAudioLevel.TotalDuration();
 }
 
 void ChannelReceive::SetChannelOutputVolumeScaling(float scaling) {
+  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
   rtc::CritScope cs(&volume_settings_critsect_);
   _outputGain = scaling;
 }
 
-void ChannelReceive::SetLocalSSRC(unsigned int ssrc) {
+void ChannelReceive::SetLocalSSRC(uint32_t ssrc) {
+  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
   _rtpRtcpModule->SetSSRC(ssrc);
 }
 
@@ -575,6 +815,7 @@
 
 void ChannelReceive::RegisterReceiverCongestionControlObjects(
     PacketRouter* packet_router) {
+  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
   RTC_DCHECK(packet_router);
   RTC_DCHECK(!packet_router_);
   constexpr bool remb_candidate = false;
@@ -583,12 +824,14 @@
 }
 
 void ChannelReceive::ResetReceiverCongestionControlObjects() {
+  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
   RTC_DCHECK(packet_router_);
   packet_router_->RemoveReceiveRtpModule(_rtpRtcpModule.get());
   packet_router_ = nullptr;
 }
 
-CallReceiveStatistics ChannelReceive::GetRTCPStatistics() {
+CallReceiveStatistics ChannelReceive::GetRTCPStatistics() const {
+  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
   // --- RtcpStatistics
   CallReceiveStatistics stats;
 
@@ -630,11 +873,12 @@
   return stats;
 }
 
-void ChannelReceive::SetNACKStatus(bool enable, int maxNumberOfPackets) {
+void ChannelReceive::SetNACKStatus(bool enable, int max_packets) {
+  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
   // None of these functions can fail.
-  rtp_receive_statistics_->SetMaxReorderingThreshold(maxNumberOfPackets);
+  rtp_receive_statistics_->SetMaxReorderingThreshold(max_packets);
   if (enable)
-    audio_coding_->EnableNack(maxNumberOfPackets);
+    audio_coding_->EnableNack(max_packets);
   else
     audio_coding_->DisableNack();
 }
@@ -645,12 +889,14 @@
   return _rtpRtcpModule->SendNACK(sequence_numbers, length);
 }
 
-void ChannelReceive::SetAssociatedSendChannel(ChannelSend* channel) {
+void ChannelReceive::SetAssociatedSendChannel(const ChannelSend* channel) {
+  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
   rtc::CritScope lock(&assoc_send_channel_lock_);
   associated_send_channel_ = channel;
 }
 
 NetworkStatistics ChannelReceive::GetNetworkStatistics() const {
+  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
   NetworkStatistics stats;
   int error = audio_coding_->GetNetworkStatistics(&stats);
   RTC_DCHECK_EQ(0, error);
@@ -658,29 +904,37 @@
 }
 
 AudioDecodingCallStats ChannelReceive::GetDecodingCallStatistics() const {
+  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
   AudioDecodingCallStats stats;
   audio_coding_->GetDecodingCallStatistics(&stats);
   return stats;
 }
 
 uint32_t ChannelReceive::GetDelayEstimate() const {
+  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread() ||
+             module_process_thread_checker_.CalledOnValidThread());
   rtc::CritScope lock(&video_sync_lock_);
   return audio_coding_->FilteredCurrentDelayMs() + playout_delay_ms_;
 }
 
-void ChannelReceive::SetMinimumPlayoutDelay(int delayMs) {
-  if ((delayMs < kVoiceEngineMinMinPlayoutDelayMs) ||
-      (delayMs > kVoiceEngineMaxMinPlayoutDelayMs)) {
+void ChannelReceive::SetMinimumPlayoutDelay(int delay_ms) {
+  RTC_DCHECK(module_process_thread_checker_.CalledOnValidThread());
+  // Limit to range accepted by both VoE and ACM, so we're at least getting as
+  // close as possible, instead of failing.
+  delay_ms = rtc::SafeClamp(delay_ms, 0, 10000);
+  if ((delay_ms < kVoiceEngineMinMinPlayoutDelayMs) ||
+      (delay_ms > kVoiceEngineMaxMinPlayoutDelayMs)) {
     RTC_DLOG(LS_ERROR) << "SetMinimumPlayoutDelay() invalid min delay";
     return;
   }
-  if (audio_coding_->SetMinimumPlayoutDelay(delayMs) != 0) {
+  if (audio_coding_->SetMinimumPlayoutDelay(delay_ms) != 0) {
     RTC_DLOG(LS_ERROR)
         << "SetMinimumPlayoutDelay() failed to set min playout delay";
   }
 }
 
-uint32_t ChannelReceive::GetPlayoutTimestamp() {
+uint32_t ChannelReceive::GetPlayoutTimestamp() const {
+  RTC_DCHECK_RUNS_SERIALIZED(&video_capture_thread_race_checker_);
   {
     rtc::CritScope lock(&video_sync_lock_);
     return playout_timestamp_rtp_;
@@ -688,6 +942,7 @@
 }
 
 absl::optional<Syncable::Info> ChannelReceive::GetSyncInfo() const {
+  RTC_DCHECK(module_process_thread_checker_.CalledOnValidThread());
   Syncable::Info info;
   if (_rtpRtcpModule->RemoteNTP(&info.capture_time_ntp_secs,
                                 &info.capture_time_ntp_frac, nullptr, nullptr,
@@ -780,5 +1035,27 @@
   return rtt;
 }
 
+}  // namespace
+
+std::unique_ptr<ChannelReceiveInterface> CreateChannelReceive(
+    ProcessThread* module_process_thread,
+    AudioDeviceModule* audio_device_module,
+    MediaTransportInterface* media_transport,
+    Transport* rtcp_send_transport,
+    RtcEventLog* rtc_event_log,
+    uint32_t remote_ssrc,
+    size_t jitter_buffer_max_packets,
+    bool jitter_buffer_fast_playout,
+    rtc::scoped_refptr<AudioDecoderFactory> decoder_factory,
+    absl::optional<AudioCodecPairId> codec_pair_id,
+    rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor,
+    const webrtc::CryptoOptions& crypto_options) {
+  return absl::make_unique<ChannelReceive>(
+      module_process_thread, audio_device_module, media_transport,
+      rtcp_send_transport, rtc_event_log, remote_ssrc,
+      jitter_buffer_max_packets, jitter_buffer_fast_playout, decoder_factory,
+      codec_pair_id, frame_decryptor, crypto_options);
+}
+
 }  // namespace voe
 }  // namespace webrtc
diff --git a/audio/channel_receive.h b/audio/channel_receive.h
index de2ae2a..fbfd7f0 100644
--- a/audio/channel_receive.h
+++ b/audio/channel_receive.h
@@ -17,24 +17,18 @@
 
 #include "absl/types/optional.h"
 #include "api/audio/audio_mixer.h"
+#include "api/audio_codecs/audio_decoder_factory.h"
 #include "api/call/audio_sink.h"
 #include "api/call/transport.h"
 #include "api/crypto/cryptooptions.h"
 #include "api/media_transport_interface.h"
 #include "api/rtpreceiverinterface.h"
-#include "audio/audio_level.h"
+#include "call/rtp_packet_sink_interface.h"
 #include "call/syncable.h"
 #include "common_types.h"  // NOLINT(build/include)
-#include "modules/audio_coding/include/audio_coding_module.h"
-#include "modules/rtp_rtcp/include/remote_ntp_time_estimator.h"
-#include "modules/rtp_rtcp/include/rtp_header_parser.h"
-#include "modules/rtp_rtcp/include/rtp_rtcp.h"
-#include "modules/rtp_rtcp/source/contributing_sources.h"
-#include "rtc_base/criticalsection.h"
-#include "rtc_base/thread_checker.h"
 
 // TODO(solenberg, nisse): This file contains a few NOLINT marks, to silence
-// warnings about use of unsigned short, and non-const reference arguments.
+// warnings about use of unsigned short.
 // These need cleanup, in a separate cl.
 
 namespace rtc {
@@ -70,205 +64,81 @@
 
 class ChannelSend;
 
-// Helper class to simplify locking scheme for members that are accessed from
-// multiple threads.
-// Example: a member can be set on thread T1 and read by an internal audio
-// thread T2. Accessing the member via this class ensures that we are
-// safe and also avoid TSan v2 warnings.
-class ChannelReceiveState {
+// Interface class needed for AudioReceiveStream tests that use a
+// MockChannelReceive.
+
+class ChannelReceiveInterface : public RtpPacketSinkInterface {
  public:
-  struct State {
-    bool playing = false;
-  };
+  virtual ~ChannelReceiveInterface() = default;
 
-  ChannelReceiveState() {}
-  virtual ~ChannelReceiveState() {}
+  virtual void SetSink(AudioSinkInterface* sink) = 0;
 
-  void Reset() {
-    rtc::CritScope lock(&lock_);
-    state_ = State();
-  }
+  virtual void SetReceiveCodecs(
+      const std::map<int, SdpAudioFormat>& codecs) = 0;
 
-  State Get() const {
-    rtc::CritScope lock(&lock_);
-    return state_;
-  }
+  virtual void StartPlayout() = 0;
+  virtual void StopPlayout() = 0;
 
-  void SetPlaying(bool enable) {
-    rtc::CritScope lock(&lock_);
-    state_.playing = enable;
-  }
+  virtual bool GetRecCodec(CodecInst* codec) const = 0;
 
- private:
-  rtc::CriticalSection lock_;
-  State state_;
-};
+  virtual bool ReceivedRTCPPacket(const uint8_t* data, size_t length) = 0;
 
-class ChannelReceive : public MediaTransportAudioSinkInterface {
- public:
-  // Used for receive streams.
-  ChannelReceive(ProcessThread* module_process_thread,
-                 AudioDeviceModule* audio_device_module,
-                 MediaTransportInterface* media_transport,
-                 Transport* rtcp_send_transport,
-                 RtcEventLog* rtc_event_log,
-                 uint32_t remote_ssrc,
-                 size_t jitter_buffer_max_packets,
-                 bool jitter_buffer_fast_playout,
-                 rtc::scoped_refptr<AudioDecoderFactory> decoder_factory,
-                 absl::optional<AudioCodecPairId> codec_pair_id,
-                 rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor,
-                 const webrtc::CryptoOptions& crypto_options);
-  virtual ~ChannelReceive();
-
-  void SetSink(AudioSinkInterface* sink);
-
-  void SetReceiveCodecs(const std::map<int, SdpAudioFormat>& codecs);
-
-  // API methods
-
-  void StartPlayout();
-  void StopPlayout();
-
-  // Codecs
-  bool GetRecCodec(CodecInst* codec);
-
-  // TODO(nisse, solenberg): Delete when VoENetwork is deleted.
-  bool ReceivedRTCPPacket(const uint8_t* data, size_t length);
-  void OnRtpPacket(const RtpPacketReceived& packet);
-
-  // Muting, Volume and Level.
-  void SetChannelOutputVolumeScaling(float scaling);
-  int GetSpeechOutputLevelFullRange() const;
+  virtual void SetChannelOutputVolumeScaling(float scaling) = 0;
+  virtual int GetSpeechOutputLevelFullRange() const = 0;
   // See description of "totalAudioEnergy" in the WebRTC stats spec:
   // https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamtrackstats-totalaudioenergy
-  double GetTotalOutputEnergy() const;
-  double GetTotalOutputDuration() const;
+  virtual double GetTotalOutputEnergy() const = 0;
+  virtual double GetTotalOutputDuration() const = 0;
 
   // Stats.
-  NetworkStatistics GetNetworkStatistics() const;
-  AudioDecodingCallStats GetDecodingCallStatistics() const;
+  virtual NetworkStatistics GetNetworkStatistics() const = 0;
+  virtual AudioDecodingCallStats GetDecodingCallStatistics() const = 0;
 
   // Audio+Video Sync.
-  uint32_t GetDelayEstimate() const;
-  void SetMinimumPlayoutDelay(int delayMs);
-  uint32_t GetPlayoutTimestamp();
+  virtual uint32_t GetDelayEstimate() const = 0;
+  virtual void SetMinimumPlayoutDelay(int delay_ms) = 0;
+  virtual uint32_t GetPlayoutTimestamp() const = 0;
 
   // Produces the transport-related timestamps; current_delay_ms is left unset.
-  absl::optional<Syncable::Info> GetSyncInfo() const;
+  virtual absl::optional<Syncable::Info> GetSyncInfo() const = 0;
 
   // RTP+RTCP
-  void SetLocalSSRC(unsigned int ssrc);
+  virtual void SetLocalSSRC(uint32_t ssrc) = 0;
 
-  void RegisterReceiverCongestionControlObjects(PacketRouter* packet_router);
-  void ResetReceiverCongestionControlObjects();
+  virtual void RegisterReceiverCongestionControlObjects(
+      PacketRouter* packet_router) = 0;
+  virtual void ResetReceiverCongestionControlObjects() = 0;
 
-  CallReceiveStatistics GetRTCPStatistics();
-  void SetNACKStatus(bool enable, int maxNumberOfPackets);
+  virtual CallReceiveStatistics GetRTCPStatistics() const = 0;
+  virtual void SetNACKStatus(bool enable, int max_packets) = 0;
 
-  // From AudioMixer::Source.
-  AudioMixer::Source::AudioFrameInfo GetAudioFrameWithInfo(
+  virtual AudioMixer::Source::AudioFrameInfo GetAudioFrameWithInfo(
       int sample_rate_hz,
-      AudioFrame* audio_frame);
+      AudioFrame* audio_frame) = 0;
 
-  int PreferredSampleRate() const;
+  virtual int PreferredSampleRate() const = 0;
 
   // Associate to a send channel.
   // Used for obtaining RTT for a receive-only channel.
-  void SetAssociatedSendChannel(ChannelSend* channel);
+  virtual void SetAssociatedSendChannel(const ChannelSend* channel) = 0;
 
-  std::vector<RtpSource> GetSources() const;
-
- private:
-  void Init();
-  void Terminate();
-
-  int GetRemoteSSRC(unsigned int& ssrc);  // NOLINT
-
-  bool ReceivePacket(const uint8_t* packet,
-                     size_t packet_length,
-                     const RTPHeader& header);
-  int ResendPackets(const uint16_t* sequence_numbers, int length);
-  void UpdatePlayoutTimestamp(bool rtcp);
-
-  int GetRtpTimestampRateHz() const;
-  int64_t GetRTT() const;
-
-  // MediaTransportAudioSinkInterface override;
-  void OnData(uint64_t channel_id,
-              MediaTransportEncodedAudioFrame frame) override;
-
-  int32_t OnReceivedPayloadData(const uint8_t* payloadData,
-                                size_t payloadSize,
-                                const WebRtcRTPHeader* rtpHeader);
-  rtc::CriticalSection _callbackCritSect;
-  rtc::CriticalSection volume_settings_critsect_;
-
-  ChannelReceiveState channel_state_;
-
-  RtcEventLog* const event_log_;
-
-  // Indexed by payload type.
-  std::map<uint8_t, int> payload_type_frequencies_;
-
-  std::unique_ptr<ReceiveStatistics> rtp_receive_statistics_;
-  std::unique_ptr<RtpRtcp> _rtpRtcpModule;
-  const uint32_t remote_ssrc_;
-
-  // Info for GetSources and GetSyncInfo is updated on network or worker thread,
-  // queried on the worker thread.
-  rtc::CriticalSection rtp_sources_lock_;
-  ContributingSources contributing_sources_ RTC_GUARDED_BY(&rtp_sources_lock_);
-  absl::optional<uint32_t> last_received_rtp_timestamp_
-      RTC_GUARDED_BY(&rtp_sources_lock_);
-  absl::optional<int64_t> last_received_rtp_system_time_ms_
-      RTC_GUARDED_BY(&rtp_sources_lock_);
-  absl::optional<uint8_t> last_received_rtp_audio_level_
-      RTC_GUARDED_BY(&rtp_sources_lock_);
-
-  std::unique_ptr<AudioCodingModule> audio_coding_;
-  AudioSinkInterface* audio_sink_ = nullptr;
-  AudioLevel _outputAudioLevel;
-
-  RemoteNtpTimeEstimator ntp_estimator_ RTC_GUARDED_BY(ts_stats_lock_);
-
-  // Timestamp of the audio pulled from NetEq.
-  absl::optional<uint32_t> jitter_buffer_playout_timestamp_;
-
-  rtc::CriticalSection video_sync_lock_;
-  uint32_t playout_timestamp_rtp_ RTC_GUARDED_BY(video_sync_lock_);
-  uint32_t playout_delay_ms_ RTC_GUARDED_BY(video_sync_lock_);
-
-  rtc::CriticalSection ts_stats_lock_;
-
-  std::unique_ptr<rtc::TimestampWrapAroundHandler> rtp_ts_wraparound_handler_;
-  // The rtp timestamp of the first played out audio frame.
-  int64_t capture_start_rtp_time_stamp_;
-  // The capture ntp time (in local timebase) of the first played out audio
-  // frame.
-  int64_t capture_start_ntp_time_ms_ RTC_GUARDED_BY(ts_stats_lock_);
-
-  // uses
-  ProcessThread* _moduleProcessThreadPtr;
-  AudioDeviceModule* _audioDeviceModulePtr;
-  float _outputGain RTC_GUARDED_BY(volume_settings_critsect_);
-
-  // An associated send channel.
-  rtc::CriticalSection assoc_send_channel_lock_;
-  ChannelSend* associated_send_channel_
-      RTC_GUARDED_BY(assoc_send_channel_lock_);
-
-  PacketRouter* packet_router_ = nullptr;
-
-  rtc::ThreadChecker construction_thread_;
-
-  MediaTransportInterface* const media_transport_;
-
-  // E2EE Audio Frame Decryption
-  rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor_;
-  webrtc::CryptoOptions crypto_options_;
+  virtual std::vector<RtpSource> GetSources() const = 0;
 };
 
+std::unique_ptr<ChannelReceiveInterface> CreateChannelReceive(
+    ProcessThread* module_process_thread,
+    AudioDeviceModule* audio_device_module,
+    MediaTransportInterface* media_transport,
+    Transport* rtcp_send_transport,
+    RtcEventLog* rtc_event_log,
+    uint32_t remote_ssrc,
+    size_t jitter_buffer_max_packets,
+    bool jitter_buffer_fast_playout,
+    rtc::scoped_refptr<AudioDecoderFactory> decoder_factory,
+    absl::optional<AudioCodecPairId> codec_pair_id,
+    rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor,
+    const webrtc::CryptoOptions& crypto_options);
+
 }  // namespace voe
 }  // namespace webrtc
 
diff --git a/audio/channel_receive_proxy.cc b/audio/channel_receive_proxy.cc
deleted file mode 100644
index 36beaf1..0000000
--- a/audio/channel_receive_proxy.cc
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- *  Copyright (c) 2015 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.
- */
-
-#include "audio/channel_receive_proxy.h"
-
-#include <utility>
-
-#include "api/call/audio_sink.h"
-#include "audio/channel_send_proxy.h"
-#include "rtc_base/checks.h"
-#include "rtc_base/logging.h"
-#include "rtc_base/numerics/safe_minmax.h"
-
-namespace webrtc {
-namespace voe {
-ChannelReceiveProxy::ChannelReceiveProxy() {}
-
-ChannelReceiveProxy::ChannelReceiveProxy(
-    std::unique_ptr<ChannelReceive> channel)
-    : channel_(std::move(channel)) {
-  RTC_DCHECK(channel_);
-  module_process_thread_checker_.DetachFromThread();
-}
-
-ChannelReceiveProxy::~ChannelReceiveProxy() {}
-
-void ChannelReceiveProxy::SetLocalSSRC(uint32_t ssrc) {
-  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
-  channel_->SetLocalSSRC(ssrc);
-}
-
-void ChannelReceiveProxy::SetNACKStatus(bool enable, int max_packets) {
-  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
-  channel_->SetNACKStatus(enable, max_packets);
-}
-
-CallReceiveStatistics ChannelReceiveProxy::GetRTCPStatistics() const {
-  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
-  return channel_->GetRTCPStatistics();
-}
-
-bool ChannelReceiveProxy::ReceivedRTCPPacket(const uint8_t* packet,
-                                             size_t length) {
-  // May be called on either worker thread or network thread.
-  return channel_->ReceivedRTCPPacket(packet, length) == 0;
-}
-
-void ChannelReceiveProxy::RegisterReceiverCongestionControlObjects(
-    PacketRouter* packet_router) {
-  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
-  channel_->RegisterReceiverCongestionControlObjects(packet_router);
-}
-
-void ChannelReceiveProxy::ResetReceiverCongestionControlObjects() {
-  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
-  channel_->ResetReceiverCongestionControlObjects();
-}
-
-NetworkStatistics ChannelReceiveProxy::GetNetworkStatistics() const {
-  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
-  return channel_->GetNetworkStatistics();
-}
-
-AudioDecodingCallStats ChannelReceiveProxy::GetDecodingCallStatistics() const {
-  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
-  return channel_->GetDecodingCallStatistics();
-}
-
-int ChannelReceiveProxy::GetSpeechOutputLevelFullRange() const {
-  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
-  return channel_->GetSpeechOutputLevelFullRange();
-}
-
-double ChannelReceiveProxy::GetTotalOutputEnergy() const {
-  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
-  return channel_->GetTotalOutputEnergy();
-}
-
-double ChannelReceiveProxy::GetTotalOutputDuration() const {
-  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
-  return channel_->GetTotalOutputDuration();
-}
-
-uint32_t ChannelReceiveProxy::GetDelayEstimate() const {
-  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread() ||
-             module_process_thread_checker_.CalledOnValidThread());
-  return channel_->GetDelayEstimate();
-}
-
-void ChannelReceiveProxy::SetReceiveCodecs(
-    const std::map<int, SdpAudioFormat>& codecs) {
-  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
-  channel_->SetReceiveCodecs(codecs);
-}
-
-void ChannelReceiveProxy::SetSink(AudioSinkInterface* sink) {
-  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
-  channel_->SetSink(sink);
-}
-
-void ChannelReceiveProxy::OnRtpPacket(const RtpPacketReceived& packet) {
-  // May be called on either worker thread or network thread.
-  channel_->OnRtpPacket(packet);
-}
-
-void ChannelReceiveProxy::SetChannelOutputVolumeScaling(float scaling) {
-  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
-  channel_->SetChannelOutputVolumeScaling(scaling);
-}
-
-AudioMixer::Source::AudioFrameInfo ChannelReceiveProxy::GetAudioFrameWithInfo(
-    int sample_rate_hz,
-    AudioFrame* audio_frame) {
-  RTC_DCHECK_RUNS_SERIALIZED(&audio_thread_race_checker_);
-  return channel_->GetAudioFrameWithInfo(sample_rate_hz, audio_frame);
-}
-
-int ChannelReceiveProxy::PreferredSampleRate() const {
-  RTC_DCHECK_RUNS_SERIALIZED(&audio_thread_race_checker_);
-  return channel_->PreferredSampleRate();
-}
-
-void ChannelReceiveProxy::AssociateSendChannel(
-    const ChannelSendProxy& send_channel_proxy) {
-  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
-  channel_->SetAssociatedSendChannel(send_channel_proxy.GetChannel());
-}
-
-void ChannelReceiveProxy::DisassociateSendChannel() {
-  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
-  channel_->SetAssociatedSendChannel(nullptr);
-}
-
-absl::optional<Syncable::Info> ChannelReceiveProxy::GetSyncInfo() const {
-  RTC_DCHECK(module_process_thread_checker_.CalledOnValidThread());
-  return channel_->GetSyncInfo();
-}
-
-uint32_t ChannelReceiveProxy::GetPlayoutTimestamp() const {
-  RTC_DCHECK_RUNS_SERIALIZED(&video_capture_thread_race_checker_);
-  return channel_->GetPlayoutTimestamp();
-}
-
-void ChannelReceiveProxy::SetMinimumPlayoutDelay(int delay_ms) {
-  RTC_DCHECK(module_process_thread_checker_.CalledOnValidThread());
-  // Limit to range accepted by both VoE and ACM, so we're at least getting as
-  // close as possible, instead of failing.
-  delay_ms = rtc::SafeClamp(delay_ms, 0, 10000);
-  channel_->SetMinimumPlayoutDelay(delay_ms);
-}
-
-bool ChannelReceiveProxy::GetRecCodec(CodecInst* codec_inst) const {
-  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
-  return channel_->GetRecCodec(codec_inst);
-}
-
-std::vector<RtpSource> ChannelReceiveProxy::GetSources() const {
-  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
-  return channel_->GetSources();
-}
-
-void ChannelReceiveProxy::StartPlayout() {
-  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
-  channel_->StartPlayout();
-}
-
-void ChannelReceiveProxy::StopPlayout() {
-  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
-  channel_->StopPlayout();
-}
-}  // namespace voe
-}  // namespace webrtc
diff --git a/audio/channel_receive_proxy.h b/audio/channel_receive_proxy.h
deleted file mode 100644
index 8ebacc3..0000000
--- a/audio/channel_receive_proxy.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- *  Copyright (c) 2015 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 AUDIO_CHANNEL_RECEIVE_PROXY_H_
-#define AUDIO_CHANNEL_RECEIVE_PROXY_H_
-
-#include <map>
-#include <memory>
-#include <vector>
-
-#include "api/audio/audio_mixer.h"
-#include "api/rtpreceiverinterface.h"
-#include "audio/channel_receive.h"
-#include "call/rtp_packet_sink_interface.h"
-#include "rtc_base/constructormagic.h"
-#include "rtc_base/race_checker.h"
-#include "rtc_base/thread_checker.h"
-
-namespace webrtc {
-
-class AudioSinkInterface;
-class PacketRouter;
-class RtpPacketReceived;
-class Transport;
-
-namespace voe {
-
-class ChannelSendProxy;
-
-// This class provides the "view" of a voe::Channel that we need to implement
-// webrtc::AudioReceiveStream. It serves two purposes:
-//  1. Allow mocking just the interfaces used, instead of the entire
-//     voe::Channel class.
-//  2. Provide a refined interface for the stream classes, including assumptions
-//     on return values and input adaptation.
-class ChannelReceiveProxy : public RtpPacketSinkInterface {
- public:
-  ChannelReceiveProxy();
-  explicit ChannelReceiveProxy(std::unique_ptr<ChannelReceive> channel);
-  virtual ~ChannelReceiveProxy();
-
-  // Shared with ChannelSendProxy
-  virtual void SetLocalSSRC(uint32_t ssrc);
-  virtual void SetNACKStatus(bool enable, int max_packets);
-  virtual CallReceiveStatistics GetRTCPStatistics() const;
-  virtual bool ReceivedRTCPPacket(const uint8_t* packet, size_t length);
-
-  virtual void RegisterReceiverCongestionControlObjects(
-      PacketRouter* packet_router);
-  virtual void ResetReceiverCongestionControlObjects();
-  virtual NetworkStatistics GetNetworkStatistics() const;
-  virtual AudioDecodingCallStats GetDecodingCallStatistics() const;
-  virtual int GetSpeechOutputLevelFullRange() const;
-  // See description of "totalAudioEnergy" in the WebRTC stats spec:
-  // https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamtrackstats-totalaudioenergy
-  virtual double GetTotalOutputEnergy() const;
-  virtual double GetTotalOutputDuration() const;
-  virtual uint32_t GetDelayEstimate() const;
-  virtual void SetReceiveCodecs(const std::map<int, SdpAudioFormat>& codecs);
-  virtual void SetSink(AudioSinkInterface* sink);
-
-  // Implements RtpPacketSinkInterface
-  void OnRtpPacket(const RtpPacketReceived& packet) override;
-
-  virtual void SetChannelOutputVolumeScaling(float scaling);
-  virtual AudioMixer::Source::AudioFrameInfo GetAudioFrameWithInfo(
-      int sample_rate_hz,
-      AudioFrame* audio_frame);
-  virtual int PreferredSampleRate() const;
-  virtual void AssociateSendChannel(const ChannelSendProxy& send_channel_proxy);
-  virtual void DisassociateSendChannel();
-
-  // Produces the transport-related timestamps; current_delay_ms is left unset.
-  absl::optional<Syncable::Info> GetSyncInfo() const;
-  virtual uint32_t GetPlayoutTimestamp() const;
-  virtual void SetMinimumPlayoutDelay(int delay_ms);
-  virtual bool GetRecCodec(CodecInst* codec_inst) const;
-  virtual std::vector<webrtc::RtpSource> GetSources() const;
-  virtual void StartPlayout();
-  virtual void StopPlayout();
-
- private:
-  // Thread checkers document and lock usage of some methods on voe::Channel to
-  // specific threads we know about. The goal is to eventually split up
-  // voe::Channel into parts with single-threaded semantics, and thereby reduce
-  // the need for locks.
-  rtc::ThreadChecker worker_thread_checker_;
-  rtc::ThreadChecker module_process_thread_checker_;
-  // Methods accessed from audio and video threads are checked for sequential-
-  // only access. We don't necessarily own and control these threads, so thread
-  // checkers cannot be used. E.g. Chromium may transfer "ownership" from one
-  // audio thread to another, but access is still sequential.
-  rtc::RaceChecker audio_thread_race_checker_;
-  rtc::RaceChecker video_capture_thread_race_checker_;
-  std::unique_ptr<ChannelReceive> channel_;
-
-  RTC_DISALLOW_COPY_AND_ASSIGN(ChannelReceiveProxy);
-};
-}  // namespace voe
-}  // namespace webrtc
-
-#endif  // AUDIO_CHANNEL_RECEIVE_PROXY_H_
diff --git a/audio/mock_voe_channel_proxy.h b/audio/mock_voe_channel_proxy.h
index 962152f..0571c8d 100644
--- a/audio/mock_voe_channel_proxy.h
+++ b/audio/mock_voe_channel_proxy.h
@@ -17,7 +17,7 @@
 #include <vector>
 
 #include "api/test/mock_frame_encryptor.h"
-#include "audio/channel_receive_proxy.h"
+#include "audio/channel_receive.h"
 #include "audio/channel_send_proxy.h"
 #include "modules/rtp_rtcp/source/rtp_packet_received.h"
 #include "test/gmock.h"
@@ -25,7 +25,7 @@
 namespace webrtc {
 namespace test {
 
-class MockChannelReceiveProxy : public voe::ChannelReceiveProxy {
+class MockChannelReceive : public voe::ChannelReceiveInterface {
  public:
   MOCK_METHOD1(SetLocalSSRC, void(uint32_t ssrc));
   MOCK_METHOD2(SetNACKStatus, void(bool enable, int max_packets));
@@ -47,10 +47,10 @@
                AudioMixer::Source::AudioFrameInfo(int sample_rate_hz,
                                                   AudioFrame* audio_frame));
   MOCK_CONST_METHOD0(PreferredSampleRate, int());
-  MOCK_METHOD1(AssociateSendChannel,
-               void(const voe::ChannelSendProxy& send_channel_proxy));
-  MOCK_METHOD0(DisassociateSendChannel, void());
+  MOCK_METHOD1(SetAssociatedSendChannel,
+               void(const voe::ChannelSend* send_channel));
   MOCK_CONST_METHOD0(GetPlayoutTimestamp, uint32_t());
+  MOCK_CONST_METHOD0(GetSyncInfo, absl::optional<Syncable::Info>());
   MOCK_METHOD1(SetMinimumPlayoutDelay, void(int delay_ms));
   MOCK_CONST_METHOD1(GetRecCodec, bool(CodecInst* codec_inst));
   MOCK_METHOD1(SetReceiveCodecs,