Move ownership of voe::Channel into Audio[Receive|Send]Stream.

* VoEBase contains only stub methods (until downstream code is
  updated).

* voe::Channel and ChannelProxy classes remain, but are now created
  internally to the streams. As a result,
  internal::Audio[Receive|Send]Stream can have a ChannelProxy injected
  for testing.

* Stream classes share Call::module_process_thread_ for their RtpRtcp
  modules, rather than using a separate thread shared only among audio
  streams.

* voe::Channel instances use Call::worker_queue_ for encoding packets,
  rather than having a separate queue for audio (send) streams.

Bug: webrtc:4690
Change-Id: I8059ef224ad13aa0a6ded2cafc52599c7f64d68d
Reviewed-on: https://webrtc-review.googlesource.com/34640
Commit-Queue: Fredrik Solenberg <solenberg@webrtc.org>
Reviewed-by: Oskar Sundbom <ossu@webrtc.org>
Reviewed-by: Henrik Andreassson <henrika@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#21578}
diff --git a/audio/BUILD.gn b/audio/BUILD.gn
index 0fd0ac8..f7b1cb5 100644
--- a/audio/BUILD.gn
+++ b/audio/BUILD.gn
@@ -25,7 +25,6 @@
     "conversion.h",
     "null_audio_poller.cc",
     "null_audio_poller.h",
-    "scoped_voe_interface.h",
     "time_interval.cc",
     "time_interval.h",
   ]
diff --git a/audio/audio_receive_stream.cc b/audio/audio_receive_stream.cc
index 3c53818..bfa125a 100644
--- a/audio/audio_receive_stream.cc
+++ b/audio/audio_receive_stream.cc
@@ -25,8 +25,6 @@
 #include "rtc_base/logging.h"
 #include "rtc_base/timeutils.h"
 #include "voice_engine/channel_proxy.h"
-#include "voice_engine/include/voe_base.h"
-#include "voice_engine/voice_engine_impl.h"
 
 namespace webrtc {
 
@@ -53,7 +51,6 @@
   ss << "{rtp: " << rtp.ToString();
   ss << ", rtcp_send_transport: "
      << (rtcp_send_transport ? "(Transport)" : "null");
-  ss << ", voe_channel_id: " << voe_channel_id;
   if (!sync_group.empty()) {
     ss << ", sync_group: " << sync_group;
   }
@@ -62,32 +59,58 @@
 }
 
 namespace internal {
+namespace {
+std::unique_ptr<voe::ChannelProxy> CreateChannelAndProxy(
+    webrtc::AudioState* audio_state,
+    ProcessThread* module_process_thread,
+    const webrtc::AudioReceiveStream::Config& config) {
+  RTC_DCHECK(audio_state);
+  internal::AudioState* internal_audio_state =
+      static_cast<internal::AudioState*>(audio_state);
+  return std::unique_ptr<voe::ChannelProxy>(new voe::ChannelProxy(
+      std::unique_ptr<voe::Channel>(new voe::Channel(
+              module_process_thread,
+              internal_audio_state->audio_device_module(),
+              config.jitter_buffer_max_packets,
+              config.jitter_buffer_fast_accelerate,
+              config.decoder_factory))));
+}
+}  // namespace
+
+AudioReceiveStream::AudioReceiveStream(
+    RtpStreamReceiverControllerInterface* receiver_controller,
+    PacketRouter* packet_router,
+    ProcessThread* module_process_thread,
+    const webrtc::AudioReceiveStream::Config& config,
+    const rtc::scoped_refptr<webrtc::AudioState>& audio_state,
+    webrtc::RtcEventLog* event_log)
+    : AudioReceiveStream(receiver_controller,
+                         packet_router,
+                         config,
+                         audio_state,
+                         event_log,
+                         CreateChannelAndProxy(audio_state.get(),
+                                               module_process_thread,
+                                               config)) {}
+
 AudioReceiveStream::AudioReceiveStream(
     RtpStreamReceiverControllerInterface* receiver_controller,
     PacketRouter* packet_router,
     const webrtc::AudioReceiveStream::Config& config,
     const rtc::scoped_refptr<webrtc::AudioState>& audio_state,
-    webrtc::RtcEventLog* event_log)
-    : audio_state_(audio_state) {
+    webrtc::RtcEventLog* event_log,
+    std::unique_ptr<voe::ChannelProxy> channel_proxy)
+    : audio_state_(audio_state),
+      channel_proxy_(std::move(channel_proxy)) {
   RTC_LOG(LS_INFO) << "AudioReceiveStream: " << config.ToString();
-  RTC_DCHECK_NE(config.voe_channel_id, -1);
-  RTC_DCHECK(audio_state_.get());
+  RTC_DCHECK(receiver_controller);
   RTC_DCHECK(packet_router);
+  RTC_DCHECK(config.decoder_factory);
+  RTC_DCHECK(audio_state_);
+  RTC_DCHECK(channel_proxy_);
 
   module_process_thread_checker_.DetachFromThread();
 
-  VoiceEngineImpl* voe_impl = static_cast<VoiceEngineImpl*>(voice_engine());
-  channel_proxy_ = voe_impl->GetChannelProxy(config.voe_channel_id);
-
-  // TODO(ossu): This is where we'd like to set the decoder factory to
-  // use. However, since it needs to be included when constructing Channel, we
-  // cannot do that until we're able to move Channel ownership into the
-  // Audio{Send,Receive}Streams.  The best we can do is check that we're not
-  // trying to use two different factories using the different interfaces.
-  RTC_CHECK(config.decoder_factory);
-  RTC_CHECK_EQ(config.decoder_factory,
-               channel_proxy_->GetAudioDecoderFactory());
-
   channel_proxy_->SetRtcEventLog(event_log);
   channel_proxy_->RegisterTransport(config.rtcp_send_transport);
 
@@ -204,9 +227,9 @@
   return channel_proxy_->GetSpeechOutputLevel();
 }
 
-void AudioReceiveStream::SetSink(std::unique_ptr<AudioSinkInterface> sink) {
+void AudioReceiveStream::SetSink(AudioSinkInterface* sink) {
   RTC_DCHECK_RUN_ON(&worker_thread_checker_);
-  channel_proxy_->SetSink(std::move(sink));
+  channel_proxy_->SetSink(sink);
 }
 
 void AudioReceiveStream::SetGain(float gain) {
@@ -278,13 +301,11 @@
 void AudioReceiveStream::AssociateSendStream(AudioSendStream* send_stream) {
   RTC_DCHECK_RUN_ON(&worker_thread_checker_);
   if (send_stream) {
-    VoiceEngineImpl* voe_impl = static_cast<VoiceEngineImpl*>(voice_engine());
-    std::unique_ptr<voe::ChannelProxy> send_channel_proxy =
-        voe_impl->GetChannelProxy(send_stream->GetConfig().voe_channel_id);
-    channel_proxy_->AssociateSendChannel(*send_channel_proxy.get());
+    channel_proxy_->AssociateSendChannel(send_stream->GetChannelProxy());
   } else {
     channel_proxy_->DisassociateSendChannel();
   }
+  associated_send_stream_ = send_stream;
 }
 
 void AudioReceiveStream::SignalNetworkState(NetworkState state) {
@@ -312,10 +333,10 @@
   return config_;
 }
 
-VoiceEngine* AudioReceiveStream::voice_engine() const {
-  auto* voice_engine = audio_state()->voice_engine();
-  RTC_DCHECK(voice_engine);
-  return voice_engine;
+const AudioSendStream*
+    AudioReceiveStream::GetAssociatedSendStreamForTesting() const {
+  RTC_DCHECK_RUN_ON(&worker_thread_checker_);
+  return associated_send_stream_;
 }
 
 internal::AudioState* AudioReceiveStream::audio_state() const {
@@ -346,8 +367,6 @@
 
   // Configuration parameters which cannot be changed.
   RTC_DCHECK(first_time ||
-             old_config.voe_channel_id == new_config.voe_channel_id);
-  RTC_DCHECK(first_time ||
              old_config.rtp.remote_ssrc == new_config.rtp.remote_ssrc);
   RTC_DCHECK(first_time ||
              old_config.rtcp_send_transport == new_config.rtcp_send_transport);
diff --git a/audio/audio_receive_stream.h b/audio/audio_receive_stream.h
index 0c843be..999039f 100644
--- a/audio/audio_receive_stream.h
+++ b/audio/audio_receive_stream.h
@@ -24,6 +24,7 @@
 
 namespace webrtc {
 class PacketRouter;
+class ProcessThread;
 class RtcEventLog;
 class RtpPacketReceived;
 class RtpStreamReceiverControllerInterface;
@@ -42,9 +43,17 @@
  public:
   AudioReceiveStream(RtpStreamReceiverControllerInterface* receiver_controller,
                      PacketRouter* packet_router,
+                     ProcessThread* module_process_thread,
                      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::ChannelProxy> channel_proxy);
   ~AudioReceiveStream() override;
 
   // webrtc::AudioReceiveStream implementation.
@@ -53,7 +62,7 @@
   void Stop() override;
   webrtc::AudioReceiveStream::Stats GetStats() const override;
   int GetOutputLevel() const override;
-  void SetSink(std::unique_ptr<AudioSinkInterface> sink) override;
+  void SetSink(AudioSinkInterface* sink) override;
   void SetGain(float gain) override;
   std::vector<webrtc::RtpSource> GetSources() const override;
 
@@ -79,6 +88,7 @@
   void SignalNetworkState(NetworkState state);
   bool DeliverRtcp(const uint8_t* packet, size_t length);
   const webrtc::AudioReceiveStream::Config& config() const;
+  const AudioSendStream* GetAssociatedSendStreamForTesting() const;
 
  private:
   // RFC 5285: Each distinct extension MUST have a unique ID. The value 0 is
@@ -94,7 +104,6 @@
                               const Config& new_config,
                               bool first_time);
 
-  VoiceEngine* voice_engine() const;
   AudioState* audio_state() const;
 
   rtc::ThreadChecker worker_thread_checker_;
@@ -102,6 +111,7 @@
   webrtc::AudioReceiveStream::Config config_;
   rtc::scoped_refptr<webrtc::AudioState> audio_state_;
   std::unique_ptr<voe::ChannelProxy> channel_proxy_;
+  AudioSendStream* associated_send_stream_ = nullptr;
 
   bool playing_ RTC_ACCESS_ON(worker_thread_checker_) = false;
 
diff --git a/audio/audio_receive_stream_unittest.cc b/audio/audio_receive_stream_unittest.cc
index e03fbd5..062e71f 100644
--- a/audio/audio_receive_stream_unittest.cc
+++ b/audio/audio_receive_stream_unittest.cc
@@ -25,7 +25,6 @@
 #include "test/gtest.h"
 #include "test/mock_audio_decoder_factory.h"
 #include "test/mock_voe_channel_proxy.h"
-#include "test/mock_voice_engine.h"
 
 namespace webrtc {
 namespace test {
@@ -48,8 +47,6 @@
   return audio_decode_stats;
 }
 
-const int kChannelId1 = 2;
-const int kChannelId2 = 29;
 const uint32_t kRemoteSsrc = 1234;
 const uint32_t kLocalSsrc = 5678;
 const size_t kOneByteExtensionHeaderLength = 4;
@@ -73,61 +70,47 @@
 
 struct ConfigHelper {
   ConfigHelper()
-      : decoder_factory_(new rtc::RefCountedObject<MockAudioDecoderFactory>),
-        audio_mixer_(new rtc::RefCountedObject<MockAudioMixer>()) {
+      : ConfigHelper(new rtc::RefCountedObject<MockAudioMixer>()) {}
+
+  explicit ConfigHelper(rtc::scoped_refptr<MockAudioMixer> audio_mixer)
+      : audio_mixer_(audio_mixer) {
     using testing::Invoke;
 
     AudioState::Config config;
-    config.voice_engine = &voice_engine_;
     config.audio_mixer = audio_mixer_;
     config.audio_processing = new rtc::RefCountedObject<MockAudioProcessing>();
     config.audio_device_module =
-        new rtc::RefCountedObject<MockAudioDeviceModule>();
+        new rtc::RefCountedObject<testing::NiceMock<MockAudioDeviceModule>>();
     audio_state_ = AudioState::Create(config);
 
-    EXPECT_CALL(voice_engine_, ChannelProxyFactory(kChannelId1))
-        .WillOnce(Invoke([this](int channel_id) {
-          EXPECT_FALSE(channel_proxy_);
-          channel_proxy_ = new testing::StrictMock<MockVoEChannelProxy>();
-          EXPECT_CALL(*channel_proxy_, SetLocalSSRC(kLocalSsrc)).Times(1);
-          EXPECT_CALL(*channel_proxy_, SetNACKStatus(true, 15)).Times(1);
-          EXPECT_CALL(*channel_proxy_,
-              SetReceiveAudioLevelIndicationStatus(true, kAudioLevelId))
-                  .Times(1);
-          EXPECT_CALL(*channel_proxy_,
-              EnableReceiveTransportSequenceNumber(kTransportSequenceNumberId))
-                  .Times(1);
-          EXPECT_CALL(*channel_proxy_,
-              RegisterReceiverCongestionControlObjects(&packet_router_))
-                  .Times(1);
-          EXPECT_CALL(*channel_proxy_, ResetReceiverCongestionControlObjects())
-              .Times(1);
-          EXPECT_CALL(*channel_proxy_, RegisterTransport(nullptr)).Times(2);
-          EXPECT_CALL(*channel_proxy_, GetAudioDecoderFactory())
-              .WillOnce(ReturnRef(decoder_factory_));
-          testing::Expectation expect_set =
-              EXPECT_CALL(*channel_proxy_, SetRtcEventLog(&event_log_))
-                  .Times(1);
-          EXPECT_CALL(*channel_proxy_, SetRtcEventLog(testing::IsNull()))
-              .Times(1)
-              .After(expect_set);
-          EXPECT_CALL(*channel_proxy_, DisassociateSendChannel()).Times(1);
-          EXPECT_CALL(*channel_proxy_, SetReceiveCodecs(_))
-              .WillRepeatedly(
-                  Invoke([](const std::map<int, SdpAudioFormat>& codecs) {
-                    EXPECT_THAT(codecs, testing::IsEmpty());
-                  }));
-          return channel_proxy_;
-        }));
-    EXPECT_CALL(voice_engine_, ChannelProxyFactory(kChannelId2))
-        .WillRepeatedly(Invoke([this](int channel_id) {
-          testing::NiceMock<MockVoEChannelProxy>* proxy =
-              new testing::NiceMock<MockVoEChannelProxy>();
-          EXPECT_CALL(*proxy, GetAudioDecoderFactory())
-              .WillOnce(ReturnRef(decoder_factory_));
-          return proxy;
-        }));
-    stream_config_.voe_channel_id = kChannelId1;
+    channel_proxy_ = new testing::StrictMock<MockVoEChannelProxy>();
+    EXPECT_CALL(*channel_proxy_, SetLocalSSRC(kLocalSsrc)).Times(1);
+    EXPECT_CALL(*channel_proxy_, SetNACKStatus(true, 15)).Times(1);
+    EXPECT_CALL(*channel_proxy_,
+        SetReceiveAudioLevelIndicationStatus(true, kAudioLevelId))
+            .Times(1);
+    EXPECT_CALL(*channel_proxy_,
+        EnableReceiveTransportSequenceNumber(kTransportSequenceNumberId))
+            .Times(1);
+    EXPECT_CALL(*channel_proxy_,
+        RegisterReceiverCongestionControlObjects(&packet_router_))
+            .Times(1);
+    EXPECT_CALL(*channel_proxy_, ResetReceiverCongestionControlObjects())
+        .Times(1);
+    EXPECT_CALL(*channel_proxy_, RegisterTransport(nullptr)).Times(2);
+    testing::Expectation expect_set =
+        EXPECT_CALL(*channel_proxy_, SetRtcEventLog(&event_log_))
+            .Times(1);
+    EXPECT_CALL(*channel_proxy_, SetRtcEventLog(testing::IsNull()))
+        .Times(1)
+        .After(expect_set);
+    EXPECT_CALL(*channel_proxy_, DisassociateSendChannel()).Times(1);
+    EXPECT_CALL(*channel_proxy_, SetReceiveCodecs(_))
+        .WillRepeatedly(
+            Invoke([](const std::map<int, SdpAudioFormat>& codecs) {
+              EXPECT_THAT(codecs, testing::IsEmpty());
+            }));
+
     stream_config_.rtp.local_ssrc = kLocalSsrc;
     stream_config_.rtp.remote_ssrc = kRemoteSsrc;
     stream_config_.rtp.nack.rtp_history_ms = 300;
@@ -135,20 +118,25 @@
         RtpExtension(RtpExtension::kAudioLevelUri, kAudioLevelId));
     stream_config_.rtp.extensions.push_back(RtpExtension(
         RtpExtension::kTransportSequenceNumberUri, kTransportSequenceNumberId));
-    stream_config_.decoder_factory = decoder_factory_;
+    stream_config_.decoder_factory =
+        new rtc::RefCountedObject<MockAudioDecoderFactory>;
   }
 
-  PacketRouter* packet_router() { return &packet_router_; }
-  MockRtcEventLog* event_log() { return &event_log_; }
-  AudioReceiveStream::Config& config() { return stream_config_; }
-  rtc::scoped_refptr<AudioState> audio_state() { return audio_state_; }
-  rtc::scoped_refptr<MockAudioMixer> audio_mixer() { return audio_mixer_; }
-  MockVoiceEngine& voice_engine() { return voice_engine_; }
-  MockVoEChannelProxy* channel_proxy() { return channel_proxy_; }
-  RtpStreamReceiverControllerInterface* rtp_stream_receiver_controller() {
-    return &rtp_stream_receiver_controller_;
+  std::unique_ptr<internal::AudioReceiveStream> CreateAudioReceiveStream() {
+    return std::unique_ptr<internal::AudioReceiveStream>(
+        new internal::AudioReceiveStream(
+            &rtp_stream_receiver_controller_,
+            &packet_router_,
+            stream_config_,
+            audio_state_,
+            &event_log_,
+            std::unique_ptr<voe::ChannelProxy>(channel_proxy_)));
   }
 
+  AudioReceiveStream::Config& config() { return stream_config_; }
+  rtc::scoped_refptr<MockAudioMixer> audio_mixer() { return audio_mixer_; }
+  MockVoEChannelProxy* channel_proxy() { return channel_proxy_; }
+
   void SetupMockForGetStats() {
     using testing::DoAll;
     using testing::SetArgPointee;
@@ -174,9 +162,7 @@
 
  private:
   PacketRouter packet_router_;
-  rtc::scoped_refptr<AudioDecoderFactory> decoder_factory_;
   MockRtcEventLog event_log_;
-  testing::StrictMock<MockVoiceEngine> voice_engine_;
   rtc::scoped_refptr<AudioState> audio_state_;
   rtc::scoped_refptr<MockAudioMixer> audio_mixer_;
   AudioReceiveStream::Config stream_config_;
@@ -240,32 +226,25 @@
   AudioReceiveStream::Config config;
   config.rtp.remote_ssrc = kRemoteSsrc;
   config.rtp.local_ssrc = kLocalSsrc;
-  config.voe_channel_id = kChannelId1;
   config.rtp.extensions.push_back(
       RtpExtension(RtpExtension::kAudioLevelUri, kAudioLevelId));
   EXPECT_EQ(
       "{rtp: {remote_ssrc: 1234, local_ssrc: 5678, transport_cc: off, nack: "
       "{rtp_history_ms: 0}, extensions: [{uri: "
       "urn:ietf:params:rtp-hdrext:ssrc-audio-level, id: 3}]}, "
-      "rtcp_send_transport: null, voe_channel_id: 2}",
+      "rtcp_send_transport: null}",
       config.ToString());
 }
 
 TEST(AudioReceiveStreamTest, ConstructDestruct) {
   ConfigHelper helper;
-  internal::AudioReceiveStream recv_stream(
-      helper.rtp_stream_receiver_controller(),
-      helper.packet_router(),
-      helper.config(), helper.audio_state(), helper.event_log());
+  auto recv_stream = helper.CreateAudioReceiveStream();
 }
 
 TEST(AudioReceiveStreamTest, ReceiveRtpPacket) {
   ConfigHelper helper;
   helper.config().rtp.transport_cc = true;
-  internal::AudioReceiveStream recv_stream(
-      helper.rtp_stream_receiver_controller(),
-      helper.packet_router(),
-      helper.config(), helper.audio_state(), helper.event_log());
+  auto recv_stream = helper.CreateAudioReceiveStream();
   const int kTransportSequenceNumberValue = 1234;
   std::vector<uint8_t> rtp_packet = CreateRtpHeaderWithOneByteExtension(
       kTransportSequenceNumberId, kTransportSequenceNumberValue, 2);
@@ -278,32 +257,25 @@
   EXPECT_CALL(*helper.channel_proxy(),
               OnRtpPacket(testing::Ref(parsed_packet)));
 
-  recv_stream.OnRtpPacket(parsed_packet);
+  recv_stream->OnRtpPacket(parsed_packet);
 }
 
 TEST(AudioReceiveStreamTest, ReceiveRtcpPacket) {
   ConfigHelper helper;
   helper.config().rtp.transport_cc = true;
-  internal::AudioReceiveStream recv_stream(
-      helper.rtp_stream_receiver_controller(),
-      helper.packet_router(),
-      helper.config(), helper.audio_state(), helper.event_log());
-
+  auto recv_stream = helper.CreateAudioReceiveStream();
   std::vector<uint8_t> rtcp_packet = CreateRtcpSenderReport();
   EXPECT_CALL(*helper.channel_proxy(),
               ReceivedRTCPPacket(&rtcp_packet[0], rtcp_packet.size()))
       .WillOnce(Return(true));
-  EXPECT_TRUE(recv_stream.DeliverRtcp(&rtcp_packet[0], rtcp_packet.size()));
+  EXPECT_TRUE(recv_stream->DeliverRtcp(&rtcp_packet[0], rtcp_packet.size()));
 }
 
 TEST(AudioReceiveStreamTest, GetStats) {
   ConfigHelper helper;
-  internal::AudioReceiveStream recv_stream(
-      helper.rtp_stream_receiver_controller(),
-      helper.packet_router(),
-      helper.config(), helper.audio_state(), helper.event_log());
+  auto recv_stream = helper.CreateAudioReceiveStream();
   helper.SetupMockForGetStats();
-  AudioReceiveStream::Stats stats = recv_stream.GetStats();
+  AudioReceiveStream::Stats stats = recv_stream->GetStats();
   EXPECT_EQ(kRemoteSsrc, stats.remote_ssrc);
   EXPECT_EQ(static_cast<int64_t>(kCallStats.bytesReceived), stats.bytes_rcvd);
   EXPECT_EQ(static_cast<uint32_t>(kCallStats.packetsReceived),
@@ -354,62 +326,50 @@
 
 TEST(AudioReceiveStreamTest, SetGain) {
   ConfigHelper helper;
-  internal::AudioReceiveStream recv_stream(
-      helper.rtp_stream_receiver_controller(),
-      helper.packet_router(),
-      helper.config(), helper.audio_state(), helper.event_log());
+  auto recv_stream = helper.CreateAudioReceiveStream();
   EXPECT_CALL(*helper.channel_proxy(),
       SetChannelOutputVolumeScaling(FloatEq(0.765f)));
-  recv_stream.SetGain(0.765f);
+  recv_stream->SetGain(0.765f);
 }
 
 TEST(AudioReceiveStreamTest, StreamsShouldBeAddedToMixerOnceOnStart) {
-  ConfigHelper helper;
-  internal::AudioReceiveStream recv_stream1(
-      helper.rtp_stream_receiver_controller(),
-      helper.packet_router(),
-      helper.config(), helper.audio_state(), helper.event_log());
-  AudioReceiveStream::Config config2 = helper.config();
-  config2.voe_channel_id = kChannelId2;
-  internal::AudioReceiveStream recv_stream2(
-      helper.rtp_stream_receiver_controller(),
-      helper.packet_router(),
-      config2, helper.audio_state(), helper.event_log());
+  ConfigHelper helper1;
+  ConfigHelper helper2(helper1.audio_mixer());
+  auto recv_stream1 = helper1.CreateAudioReceiveStream();
+  auto recv_stream2 = helper2.CreateAudioReceiveStream();
 
-  EXPECT_CALL(*helper.channel_proxy(), StartPlayout()).Times(1);
-  EXPECT_CALL(*helper.channel_proxy(), StopPlayout()).Times(1);
-  EXPECT_CALL(*helper.audio_mixer(), AddSource(&recv_stream1))
+  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.audio_mixer(), AddSource(recv_stream1.get()))
       .WillOnce(Return(true));
-  EXPECT_CALL(*helper.audio_mixer(), AddSource(&recv_stream2))
+  EXPECT_CALL(*helper1.audio_mixer(), AddSource(recv_stream2.get()))
       .WillOnce(Return(true));
-  EXPECT_CALL(*helper.audio_mixer(), RemoveSource(&recv_stream1)).Times(1);
-  EXPECT_CALL(*helper.audio_mixer(), RemoveSource(&recv_stream2)).Times(1);
+  EXPECT_CALL(*helper1.audio_mixer(), RemoveSource(recv_stream1.get()))
+      .Times(1);
+  EXPECT_CALL(*helper1.audio_mixer(), RemoveSource(recv_stream2.get()))
+      .Times(1);
 
-  recv_stream1.Start();
-  recv_stream2.Start();
+  recv_stream1->Start();
+  recv_stream2->Start();
 
   // One more should not result in any more mixer sources added.
-  recv_stream1.Start();
+  recv_stream1->Start();
 
   // Stop stream before it is being destructed.
-  recv_stream2.Stop();
+  recv_stream2->Stop();
 }
 
 TEST(AudioReceiveStreamTest, ReconfigureWithSameConfig) {
   ConfigHelper helper;
-  internal::AudioReceiveStream recv_stream(
-      helper.rtp_stream_receiver_controller(),
-      helper.packet_router(),
-      helper.config(), helper.audio_state(), helper.event_log());
-  recv_stream.Reconfigure(helper.config());
+  auto recv_stream = helper.CreateAudioReceiveStream();
+  recv_stream->Reconfigure(helper.config());
 }
 
 TEST(AudioReceiveStreamTest, ReconfigureWithUpdatedConfig) {
   ConfigHelper helper;
-  internal::AudioReceiveStream recv_stream(
-      helper.rtp_stream_receiver_controller(),
-      helper.packet_router(),
-      helper.config(), helper.audio_state(), helper.event_log());
+  auto recv_stream = helper.CreateAudioReceiveStream();
 
   auto new_config = helper.config();
   new_config.rtp.local_ssrc = kLocalSsrc + 1;
@@ -433,7 +393,7 @@
       EnableReceiveTransportSequenceNumber(kTransportSequenceNumberId + 1))
           .Times(1);
 
-  recv_stream.Reconfigure(new_config);
+  recv_stream->Reconfigure(new_config);
 }
 }  // namespace test
 }  // namespace webrtc
diff --git a/audio/audio_send_stream.cc b/audio/audio_send_stream.cc
index 2e5654a..d207dbd 100644
--- a/audio/audio_send_stream.cc
+++ b/audio/audio_send_stream.cc
@@ -29,17 +29,15 @@
 #include "rtc_base/timeutils.h"
 #include "system_wrappers/include/field_trial.h"
 #include "voice_engine/channel_proxy.h"
-#include "voice_engine/voice_engine_impl.h"
 
 namespace webrtc {
-
 namespace internal {
+namespace {
 // TODO(eladalon): Subsequent CL will make these values experiment-dependent.
 constexpr size_t kPacketLossTrackerMaxWindowSizeMs = 15000;
 constexpr size_t kPacketLossRateMinNumAckedPackets = 50;
 constexpr size_t kRecoverablePacketLossRateMinNumAckedPairs = 40;
 
-namespace {
 void CallEncoder(const std::unique_ptr<voe::ChannelProxy>& channel_proxy,
                  rtc::FunctionView<void(AudioEncoder*)> lambda) {
   channel_proxy->ModifyEncoder([&](std::unique_ptr<AudioEncoder>* encoder_ptr) {
@@ -47,6 +45,20 @@
     lambda(encoder_ptr->get());
   });
 }
+
+std::unique_ptr<voe::ChannelProxy> CreateChannelAndProxy(
+    webrtc::AudioState* audio_state,
+    rtc::TaskQueue* worker_queue,
+    ProcessThread* module_process_thread) {
+  RTC_DCHECK(audio_state);
+  internal::AudioState* internal_audio_state =
+      static_cast<internal::AudioState*>(audio_state);
+  return std::unique_ptr<voe::ChannelProxy>(new voe::ChannelProxy(
+      std::unique_ptr<voe::Channel>(new voe::Channel(
+          worker_queue,
+          module_process_thread,
+          internal_audio_state->audio_device_module()))));
+}
 }  // namespace
 
 // TODO(saza): Move this declaration further down when we can use
@@ -77,14 +89,38 @@
     const webrtc::AudioSendStream::Config& config,
     const rtc::scoped_refptr<webrtc::AudioState>& audio_state,
     rtc::TaskQueue* worker_queue,
+    ProcessThread* module_process_thread,
     RtpTransportControllerSendInterface* transport,
     BitrateAllocator* bitrate_allocator,
     RtcEventLog* event_log,
     RtcpRttStats* rtcp_rtt_stats,
     const rtc::Optional<RtpState>& suspended_rtp_state)
+    : AudioSendStream(config,
+                      audio_state,
+                      worker_queue,
+                      transport,
+                      bitrate_allocator,
+                      event_log,
+                      rtcp_rtt_stats,
+                      suspended_rtp_state,
+                      CreateChannelAndProxy(audio_state.get(),
+                                            worker_queue,
+                                            module_process_thread)) {}
+
+AudioSendStream::AudioSendStream(
+    const webrtc::AudioSendStream::Config& config,
+    const rtc::scoped_refptr<webrtc::AudioState>& audio_state,
+    rtc::TaskQueue* worker_queue,
+    RtpTransportControllerSendInterface* transport,
+    BitrateAllocator* bitrate_allocator,
+    RtcEventLog* event_log,
+    RtcpRttStats* rtcp_rtt_stats,
+    const rtc::Optional<RtpState>& suspended_rtp_state,
+    std::unique_ptr<voe::ChannelProxy> channel_proxy)
     : worker_queue_(worker_queue),
       config_(Config(nullptr)),
       audio_state_(audio_state),
+      channel_proxy_(std::move(channel_proxy)),
       event_log_(event_log),
       bitrate_allocator_(bitrate_allocator),
       transport_(transport),
@@ -94,13 +130,13 @@
       rtp_rtcp_module_(nullptr),
       suspended_rtp_state_(suspended_rtp_state) {
   RTC_LOG(LS_INFO) << "AudioSendStream: " << config.ToString();
-  RTC_DCHECK_NE(config.voe_channel_id, -1);
-  RTC_DCHECK(audio_state_.get());
+  RTC_DCHECK(worker_queue_);
+  RTC_DCHECK(audio_state_);
+  RTC_DCHECK(channel_proxy_);
+  RTC_DCHECK(bitrate_allocator_);
   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);
   channel_proxy_->SetRtcEventLog(event_log_);
   channel_proxy_->SetRtcpRttStats(rtcp_rtt_stats);
   channel_proxy_->SetRTCPStatus(true);
@@ -423,6 +459,11 @@
   return active_lifetime_;
 }
 
+const voe::ChannelProxy& AudioSendStream::GetChannelProxy() const {
+  RTC_DCHECK(channel_proxy_.get());
+  return *channel_proxy_.get();
+}
+
 internal::AudioState* AudioSendStream::audio_state() {
   internal::AudioState* audio_state =
       static_cast<internal::AudioState*>(audio_state_.get());
@@ -437,14 +478,6 @@
   return audio_state;
 }
 
-VoiceEngine* AudioSendStream::voice_engine() const {
-  internal::AudioState* audio_state =
-      static_cast<internal::AudioState*>(audio_state_.get());
-  VoiceEngine* voice_engine = audio_state->voice_engine();
-  RTC_DCHECK(voice_engine);
-  return voice_engine;
-}
-
 void AudioSendStream::StoreEncoderProperties(int sample_rate_hz,
                                              size_t num_channels) {
   RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
diff --git a/audio/audio_send_stream.h b/audio/audio_send_stream.h
index 9060e64..bab8f80 100644
--- a/audio/audio_send_stream.h
+++ b/audio/audio_send_stream.h
@@ -25,7 +25,6 @@
 #include "voice_engine/transport_feedback_packet_loss_tracker.h"
 
 namespace webrtc {
-class VoiceEngine;
 class RtcEventLog;
 class RtcpBandwidthObserver;
 class RtcpRttStats;
@@ -45,11 +44,22 @@
   AudioSendStream(const webrtc::AudioSendStream::Config& config,
                   const rtc::scoped_refptr<webrtc::AudioState>& audio_state,
                   rtc::TaskQueue* worker_queue,
+                  ProcessThread* module_process_thread,
                   RtpTransportControllerSendInterface* transport,
                   BitrateAllocator* bitrate_allocator,
                   RtcEventLog* event_log,
                   RtcpRttStats* rtcp_rtt_stats,
                   const rtc::Optional<RtpState>& suspended_rtp_state);
+  // For unit tests, which need to supply a mock channel proxy.
+  AudioSendStream(const webrtc::AudioSendStream::Config& config,
+                  const rtc::scoped_refptr<webrtc::AudioState>& audio_state,
+                  rtc::TaskQueue* worker_queue,
+                  RtpTransportControllerSendInterface* transport,
+                  BitrateAllocator* bitrate_allocator,
+                  RtcEventLog* event_log,
+                  RtcpRttStats* rtcp_rtt_stats,
+                  const rtc::Optional<RtpState>& suspended_rtp_state,
+                  std::unique_ptr<voe::ChannelProxy> channel_proxy);
   ~AudioSendStream() override;
 
   // webrtc::AudioSendStream implementation.
@@ -83,13 +93,13 @@
 
   RtpState GetRtpState() const;
   const TimeInterval& GetActiveLifetime() const;
+  const voe::ChannelProxy& GetChannelProxy() const;
 
  private:
   class TimedTransport;
 
   internal::AudioState* audio_state();
   const internal::AudioState* audio_state() const;
-  VoiceEngine* voice_engine() const;
 
   void StoreEncoderProperties(int sample_rate_hz, size_t num_channels);
 
diff --git a/audio/audio_send_stream_unittest.cc b/audio/audio_send_stream_unittest.cc
index 5afdffe..4644bf4 100644
--- a/audio/audio_send_stream_unittest.cc
+++ b/audio/audio_send_stream_unittest.cc
@@ -33,7 +33,6 @@
 #include "test/mock_audio_encoder.h"
 #include "test/mock_audio_encoder_factory.h"
 #include "test/mock_voe_channel_proxy.h"
-#include "test/mock_voice_engine.h"
 
 namespace webrtc {
 namespace test {
@@ -46,7 +45,6 @@
 using testing::Return;
 using testing::StrEq;
 
-const int kChannelId = 1;
 const uint32_t kSsrc = 1234;
 const char* kCName = "foo_name";
 const int kAudioLevelId = 2;
@@ -141,7 +139,6 @@
     using testing::Invoke;
 
     AudioState::Config config;
-    config.voice_engine = &voice_engine_;
     config.audio_mixer = AudioMixerImpl::Create();
     config.audio_processing = audio_processing_;
     config.audio_device_module =
@@ -149,19 +146,12 @@
     audio_state_ = AudioState::Create(config);
 
     SetupDefaultChannelProxy(audio_bwe_enabled);
-
-    EXPECT_CALL(voice_engine_, ChannelProxyFactory(kChannelId))
-        .WillOnce(Invoke([this](int channel_id) {
-          return channel_proxy_;
-        }));
-
     SetupMockForSetupSendCodec(expect_set_encoder_call);
 
-    // Use ISAC as default codec so as to prevent unnecessary |voice_engine_|
+    // Use ISAC as default codec so as to prevent unnecessary |channel_proxy_|
     // calls from the default ctor behavior.
     stream_config_.send_codec_spec =
         AudioSendStream::Config::SendCodecSpec(kIsacPayloadType, kIsacFormat);
-    stream_config_.voe_channel_id = kChannelId;
     stream_config_.rtp.ssrc = kSsrc;
     stream_config_.rtp.nack.rtp_history_ms = 200;
     stream_config_.rtp.c_name = kCName;
@@ -175,18 +165,27 @@
     stream_config_.max_bitrate_bps = 65000;
   }
 
+  std::unique_ptr<internal::AudioSendStream> CreateAudioSendStream() {
+    return std::unique_ptr<internal::AudioSendStream>(
+        new internal::AudioSendStream(
+            stream_config_,
+            audio_state_,
+            &worker_queue_,
+            &fake_transport_,
+            &bitrate_allocator_,
+            &event_log_,
+            &rtcp_rtt_stats_,
+            rtc::nullopt,
+            std::unique_ptr<voe::ChannelProxy>(channel_proxy_)));
+  }
+
   AudioSendStream::Config& config() { return stream_config_; }
   MockAudioEncoderFactory& mock_encoder_factory() {
     return *static_cast<MockAudioEncoderFactory*>(
         stream_config_.encoder_factory.get());
   }
-  rtc::scoped_refptr<AudioState> audio_state() { return audio_state_; }
   MockVoEChannelProxy* channel_proxy() { return channel_proxy_; }
   RtpTransportControllerSendInterface* transport() { return &fake_transport_; }
-  BitrateAllocator* bitrate_allocator() { return &bitrate_allocator_; }
-  rtc::TaskQueue* worker_queue() { return &worker_queue_; }
-  RtcEventLog* event_log() { return &event_log_; }
-  MockVoiceEngine* voice_engine() { return &voice_engine_; }
 
   static void AddBweToConfig(AudioSendStream::Config* config) {
     config->rtp.extensions.push_back(
@@ -255,8 +254,6 @@
             }));
   }
 
-  RtcpRttStats* rtcp_rtt_stats() { return &rtcp_rtt_stats_; }
-
   void SetupMockForSendTelephoneEvent() {
     EXPECT_TRUE(channel_proxy_);
     EXPECT_CALL(*channel_proxy_,
@@ -305,7 +302,6 @@
   }
 
  private:
-  testing::StrictMock<MockVoiceEngine> voice_engine_;
   rtc::scoped_refptr<AudioState> audio_state_;
   AudioSendStream::Config stream_config_;
   testing::StrictMock<MockVoEChannelProxy>* channel_proxy_ = nullptr;
@@ -332,7 +328,6 @@
   AudioSendStream::Config config(nullptr);
   config.rtp.ssrc = kSsrc;
   config.rtp.c_name = kCName;
-  config.voe_channel_id = kChannelId;
   config.min_bitrate_bps = 12000;
   config.max_bitrate_bps = 34000;
   config.send_codec_spec =
@@ -347,7 +342,7 @@
       "{rtp: {ssrc: 1234, extensions: [{uri: "
       "urn:ietf:params:rtp-hdrext:ssrc-audio-level, id: 2}], nack: "
       "{rtp_history_ms: 0}, c_name: foo_name}, send_transport: null, "
-      "voe_channel_id: 1, min_bitrate_bps: 12000, max_bitrate_bps: 34000, "
+      "min_bitrate_bps: 12000, max_bitrate_bps: 34000, "
       "send_codec_spec: {nack_enabled: true, transport_cc_enabled: false, "
       "cng_payload_type: 42, payload_type: 103, "
       "format: {name: isac, clockrate_hz: 16000, num_channels: 1, "
@@ -357,58 +352,40 @@
 
 TEST(AudioSendStreamTest, ConstructDestruct) {
   ConfigHelper helper(false, true);
-  internal::AudioSendStream send_stream(
-      helper.config(), helper.audio_state(), helper.worker_queue(),
-      helper.transport(), helper.bitrate_allocator(), helper.event_log(),
-      helper.rtcp_rtt_stats(), rtc::nullopt);
+  auto send_stream = helper.CreateAudioSendStream();
 }
 
 TEST(AudioSendStreamTest, SendTelephoneEvent) {
   ConfigHelper helper(false, true);
-  internal::AudioSendStream send_stream(
-      helper.config(), helper.audio_state(), helper.worker_queue(),
-      helper.transport(), helper.bitrate_allocator(), helper.event_log(),
-      helper.rtcp_rtt_stats(), rtc::nullopt);
+  auto send_stream = helper.CreateAudioSendStream();
   helper.SetupMockForSendTelephoneEvent();
-  EXPECT_TRUE(send_stream.SendTelephoneEvent(kTelephoneEventPayloadType,
+  EXPECT_TRUE(send_stream->SendTelephoneEvent(kTelephoneEventPayloadType,
       kTelephoneEventPayloadFrequency, kTelephoneEventCode,
       kTelephoneEventDuration));
 }
 
 TEST(AudioSendStreamTest, SetMuted) {
   ConfigHelper helper(false, true);
-  internal::AudioSendStream send_stream(
-      helper.config(), helper.audio_state(), helper.worker_queue(),
-      helper.transport(), helper.bitrate_allocator(), helper.event_log(),
-      helper.rtcp_rtt_stats(), rtc::nullopt);
+  auto send_stream = helper.CreateAudioSendStream();
   EXPECT_CALL(*helper.channel_proxy(), SetInputMute(true));
-  send_stream.SetMuted(true);
+  send_stream->SetMuted(true);
 }
 
 TEST(AudioSendStreamTest, AudioBweCorrectObjectsOnChannelProxy) {
   ConfigHelper helper(true, true);
-  internal::AudioSendStream send_stream(
-      helper.config(), helper.audio_state(), helper.worker_queue(),
-      helper.transport(), helper.bitrate_allocator(), helper.event_log(),
-      helper.rtcp_rtt_stats(), rtc::nullopt);
+  auto send_stream = helper.CreateAudioSendStream();
 }
 
 TEST(AudioSendStreamTest, NoAudioBweCorrectObjectsOnChannelProxy) {
   ConfigHelper helper(false, true);
-  internal::AudioSendStream send_stream(
-      helper.config(), helper.audio_state(), helper.worker_queue(),
-      helper.transport(), helper.bitrate_allocator(), helper.event_log(),
-      helper.rtcp_rtt_stats(), rtc::nullopt);
+  auto send_stream = helper.CreateAudioSendStream();
 }
 
 TEST(AudioSendStreamTest, GetStats) {
   ConfigHelper helper(false, true);
-  internal::AudioSendStream send_stream(
-      helper.config(), helper.audio_state(), helper.worker_queue(),
-      helper.transport(), helper.bitrate_allocator(), helper.event_log(),
-      helper.rtcp_rtt_stats(), rtc::nullopt);
+  auto send_stream = helper.CreateAudioSendStream();
   helper.SetupMockForGetStats();
-  AudioSendStream::Stats stats = send_stream.GetStats(true);
+  AudioSendStream::Stats stats = send_stream->GetStats(true);
   EXPECT_EQ(kSsrc, stats.local_ssrc);
   EXPECT_EQ(static_cast<int64_t>(kCallStats.bytesSent), stats.bytes_sent);
   EXPECT_EQ(kCallStats.packetsSent, stats.packets_sent);
@@ -441,13 +418,12 @@
 
 TEST(AudioSendStreamTest, SendCodecAppliesAudioNetworkAdaptor) {
   ConfigHelper helper(false, true);
-  auto stream_config = helper.config();
-  stream_config.send_codec_spec =
+  helper.config().send_codec_spec =
       AudioSendStream::Config::SendCodecSpec(0, kOpusFormat);
   const std::string kAnaConfigString = "abcde";
   const std::string kAnaReconfigString = "12345";
 
-  stream_config.audio_network_adaptor_config = kAnaConfigString;
+  helper.config().audio_network_adaptor_config = kAnaConfigString;
 
   EXPECT_CALL(helper.mock_encoder_factory(), MakeAudioEncoderMock(_, _, _))
       .WillOnce(Invoke([&kAnaConfigString, &kAnaReconfigString](
@@ -463,25 +439,22 @@
         *return_value = std::move(mock_encoder);
       }));
 
-  internal::AudioSendStream send_stream(
-      stream_config, helper.audio_state(), helper.worker_queue(),
-      helper.transport(), helper.bitrate_allocator(), helper.event_log(),
-      helper.rtcp_rtt_stats(), rtc::nullopt);
+  auto send_stream = helper.CreateAudioSendStream();
 
+  auto stream_config = helper.config();
   stream_config.audio_network_adaptor_config = kAnaReconfigString;
 
   helper.SetupMockForModifyEncoder();
-  send_stream.Reconfigure(stream_config);
+  send_stream->Reconfigure(stream_config);
 }
 
 // VAD is applied when codec is mono and the CNG frequency matches the codec
 // clock rate.
 TEST(AudioSendStreamTest, SendCodecCanApplyVad) {
   ConfigHelper helper(false, false);
-  auto stream_config = helper.config();
-  stream_config.send_codec_spec =
+  helper.config().send_codec_spec =
       AudioSendStream::Config::SendCodecSpec(9, kG722Format);
-  stream_config.send_codec_spec->cng_payload_type = 105;
+  helper.config().send_codec_spec->cng_payload_type = 105;
   using ::testing::Invoke;
   std::unique_ptr<AudioEncoder> stolen_encoder;
   EXPECT_CALL(*helper.channel_proxy(), SetEncoderForMock(_, _))
@@ -492,10 +465,7 @@
             return true;
           }));
 
-  internal::AudioSendStream send_stream(
-      stream_config, helper.audio_state(), helper.worker_queue(),
-      helper.transport(), helper.bitrate_allocator(), helper.event_log(),
-      helper.rtcp_rtt_stats(), rtc::nullopt);
+  auto send_stream = helper.CreateAudioSendStream();
 
   // We cannot truly determine if the encoder created is an AudioEncoderCng.  It
   // is the only reasonable implementation that will return something from
@@ -506,24 +476,18 @@
 
 TEST(AudioSendStreamTest, DoesNotPassHigherBitrateThanMaxBitrate) {
   ConfigHelper helper(false, true);
-  internal::AudioSendStream send_stream(
-      helper.config(), helper.audio_state(), helper.worker_queue(),
-      helper.transport(), helper.bitrate_allocator(), helper.event_log(),
-      helper.rtcp_rtt_stats(), rtc::nullopt);
+  auto send_stream = helper.CreateAudioSendStream();
   EXPECT_CALL(*helper.channel_proxy(),
               SetBitrate(helper.config().max_bitrate_bps, _));
-  send_stream.OnBitrateUpdated(helper.config().max_bitrate_bps + 5000, 0.0, 50,
-                               6000);
+  send_stream->OnBitrateUpdated(helper.config().max_bitrate_bps + 5000, 0.0, 50,
+                                6000);
 }
 
 TEST(AudioSendStreamTest, ProbingIntervalOnBitrateUpdated) {
   ConfigHelper helper(false, true);
-  internal::AudioSendStream send_stream(
-      helper.config(), helper.audio_state(), helper.worker_queue(),
-      helper.transport(), helper.bitrate_allocator(), helper.event_log(),
-      helper.rtcp_rtt_stats(), rtc::nullopt);
+  auto send_stream = helper.CreateAudioSendStream();
   EXPECT_CALL(*helper.channel_proxy(), SetBitrate(_, 5000));
-  send_stream.OnBitrateUpdated(50000, 0.0, 50, 5000);
+  send_stream->OnBitrateUpdated(50000, 0.0, 50, 5000);
 }
 
 // Test that AudioSendStream doesn't recreate the encoder unnecessarily.
@@ -537,23 +501,16 @@
   EXPECT_CALL(*helper.channel_proxy(), SetEncoderForMock(_, _))
       .WillOnce(Return(true));
 
-  auto stream_config = helper.config();
-  stream_config.send_codec_spec =
+  helper.config().send_codec_spec =
       AudioSendStream::Config::SendCodecSpec(9, kG722Format);
-  stream_config.send_codec_spec->cng_payload_type = 105;
-  internal::AudioSendStream send_stream(
-      stream_config, helper.audio_state(), helper.worker_queue(),
-      helper.transport(), helper.bitrate_allocator(), helper.event_log(),
-      helper.rtcp_rtt_stats(), rtc::nullopt);
-  send_stream.Reconfigure(stream_config);
+  helper.config().send_codec_spec->cng_payload_type = 105;
+  auto send_stream = helper.CreateAudioSendStream();
+  send_stream->Reconfigure(helper.config());
 }
 
 TEST(AudioSendStreamTest, ReconfigureTransportCcResetsFirst) {
   ConfigHelper helper(false, true);
-  internal::AudioSendStream send_stream(
-      helper.config(), helper.audio_state(), helper.worker_queue(),
-      helper.transport(), helper.bitrate_allocator(), helper.event_log(),
-      helper.rtcp_rtt_stats(), rtc::nullopt);
+  auto send_stream = helper.CreateAudioSendStream();
   auto new_config = helper.config();
   ConfigHelper::AddBweToConfig(&new_config);
   EXPECT_CALL(*helper.channel_proxy(),
@@ -567,7 +524,7 @@
         helper.transport(), Ne(nullptr)))
         .Times(1);
   }
-  send_stream.Reconfigure(new_config);
+  send_stream->Reconfigure(new_config);
 }
 }  // namespace test
 }  // namespace webrtc
diff --git a/audio/audio_state.cc b/audio/audio_state.cc
index 9d980e8..24a7ce8 100644
--- a/audio/audio_state.cc
+++ b/audio/audio_state.cc
@@ -27,7 +27,6 @@
 
 AudioState::AudioState(const AudioState::Config& config)
     : config_(config),
-      voe_base_(config.voice_engine),
       audio_transport_(config_.audio_mixer,
                        config_.audio_processing.get(),
                        config_.audio_device_module.get()) {
@@ -42,11 +41,6 @@
   RTC_DCHECK(sending_streams_.empty());
 }
 
-VoiceEngine* AudioState::voice_engine() {
-  RTC_DCHECK(thread_checker_.CalledOnValidThread());
-  return config_.voice_engine;
-}
-
 bool AudioState::typing_noise_detected() const {
   RTC_DCHECK(thread_checker_.CalledOnValidThread());
   return audio_transport_.typing_noise_detected();
diff --git a/audio/audio_state.h b/audio/audio_state.h
index 3a92d42..d4e4e3f 100644
--- a/audio/audio_state.h
+++ b/audio/audio_state.h
@@ -17,13 +17,11 @@
 
 #include "audio/audio_transport_impl.h"
 #include "audio/null_audio_poller.h"
-#include "audio/scoped_voe_interface.h"
 #include "call/audio_state.h"
 #include "rtc_base/constructormagic.h"
 #include "rtc_base/criticalsection.h"
 #include "rtc_base/refcount.h"
 #include "rtc_base/thread_checker.h"
-#include "voice_engine/include/voe_base.h"
 
 namespace webrtc {
 
@@ -51,7 +49,11 @@
   Stats GetAudioInputStats() const override;
   void SetStereoChannelSwapping(bool enable) override;
 
-  VoiceEngine* voice_engine();
+  AudioDeviceModule* audio_device_module() {
+    RTC_DCHECK(config_.audio_device_module);
+    return config_.audio_device_module.get();
+  }
+
   bool typing_noise_detected() const;
 
   void AddReceivingStream(webrtc::AudioReceiveStream* stream);
@@ -74,9 +76,6 @@
   bool recording_enabled_ = true;
   bool playout_enabled_ = true;
 
-  // We hold one interface pointer to the VoE to make sure it is kept alive.
-  ScopedVoEInterface<VoEBase> voe_base_;
-
   // Reference count; implementation copied from rtc::RefCountedObject.
   // TODO(nisse): Use RefCountedObject or RefCountedBase instead.
   mutable volatile int ref_count_ = 0;
diff --git a/audio/audio_state_unittest.cc b/audio/audio_state_unittest.cc
index abae985..b4452ad 100644
--- a/audio/audio_state_unittest.cc
+++ b/audio/audio_state_unittest.cc
@@ -16,8 +16,8 @@
 #include "modules/audio_device/include/mock_audio_device.h"
 #include "modules/audio_mixer/audio_mixer_impl.h"
 #include "modules/audio_processing/include/mock_audio_processing.h"
+#include "rtc_base/refcountedobject.h"
 #include "test/gtest.h"
-#include "test/mock_voice_engine.h"
 
 namespace webrtc {
 namespace test {
@@ -28,7 +28,6 @@
 
 struct ConfigHelper {
   ConfigHelper() : audio_mixer(AudioMixerImpl::Create()) {
-    audio_state_config.voice_engine = &mock_voice_engine;
     audio_state_config.audio_mixer = audio_mixer;
     audio_state_config.audio_processing =
         new rtc::RefCountedObject<testing::NiceMock<MockAudioProcessing>>();
@@ -36,11 +35,9 @@
         new rtc::RefCountedObject<MockAudioDeviceModule>();
   }
   AudioState::Config& config() { return audio_state_config; }
-  MockVoiceEngine& voice_engine() { return mock_voice_engine; }
   rtc::scoped_refptr<AudioMixer> mixer() { return audio_mixer; }
 
  private:
-  testing::StrictMock<MockVoiceEngine> mock_voice_engine;
   AudioState::Config audio_state_config;
   rtc::scoped_refptr<AudioMixer> audio_mixer;
 };
@@ -106,13 +103,6 @@
       new internal::AudioState(helper.config()));
 }
 
-TEST(AudioStateTest, GetVoiceEngine) {
-  ConfigHelper helper;
-  std::unique_ptr<internal::AudioState> audio_state(
-      new internal::AudioState(helper.config()));
-  EXPECT_EQ(audio_state->voice_engine(), &helper.voice_engine());
-}
-
 TEST(AudioStateTest, RecordedAudioArrivesAtSingleStream) {
   ConfigHelper helper;
   std::unique_ptr<internal::AudioState> audio_state(
diff --git a/audio/scoped_voe_interface.h b/audio/scoped_voe_interface.h
deleted file mode 100644
index 7aa2d1d..0000000
--- a/audio/scoped_voe_interface.h
+++ /dev/null
@@ -1,45 +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_SCOPED_VOE_INTERFACE_H_
-#define AUDIO_SCOPED_VOE_INTERFACE_H_
-
-#include "rtc_base/checks.h"
-
-namespace webrtc {
-
-class VoiceEngine;
-
-namespace internal {
-
-// Utility template for obtaining and holding a reference to a VoiceEngine
-// interface and making sure it is released when this object goes out of scope.
-template<class T> class ScopedVoEInterface {
- public:
-  explicit ScopedVoEInterface(webrtc::VoiceEngine* e)
-      : ptr_(T::GetInterface(e)) {
-    RTC_DCHECK(ptr_);
-  }
-  ~ScopedVoEInterface() {
-    if (ptr_) {
-      ptr_->Release();
-    }
-  }
-  T* operator->() {
-    RTC_DCHECK(ptr_);
-    return ptr_;
-  }
- private:
-  T* ptr_;
-};
-}  // namespace internal
-}  // namespace webrtc
-
-#endif  // AUDIO_SCOPED_VOE_INTERFACE_H_