Replace VoEBase::[Start/Stop]Playout().

The functionality is moved into AudioState.

TBR: henrika@webrtc.org
Bug: webrtc:4690
Change-Id: I015482ad18a39609634f6ead9e991d5210107f0f
Reviewed-on: https://webrtc-review.googlesource.com/34502
Reviewed-by: Fredrik Solenberg <solenberg@webrtc.org>
Commit-Queue: Fredrik Solenberg <solenberg@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#21338}
diff --git a/audio/audio_receive_stream.cc b/audio/audio_receive_stream.cc
index a1233f2..74f1773 100644
--- a/audio/audio_receive_stream.cc
+++ b/audio/audio_receive_stream.cc
@@ -118,9 +118,7 @@
 AudioReceiveStream::~AudioReceiveStream() {
   RTC_DCHECK_RUN_ON(&worker_thread_checker_);
   RTC_LOG(LS_INFO) << "~AudioReceiveStream: " << config_.ToString();
-  if (playing_) {
-    Stop();
-  }
+  Stop();
   channel_proxy_->DisassociateSendChannel();
   channel_proxy_->RegisterTransport(nullptr);
   channel_proxy_->ResetReceiverCongestionControlObjects();
@@ -132,21 +130,9 @@
   if (playing_) {
     return;
   }
-
-  int error = SetVoiceEnginePlayout(true);
-  if (error != 0) {
-    RTC_LOG(LS_ERROR) << "AudioReceiveStream::Start failed with error: "
-                      << error;
-    return;
-  }
-
-  if (!audio_state()->mixer()->AddSource(this)) {
-    RTC_LOG(LS_ERROR) << "Failed to add source to mixer.";
-    SetVoiceEnginePlayout(false);
-    return;
-  }
-
+  channel_proxy_->StartPlayout();
   playing_ = true;
+  audio_state()->AddReceivingStream(this);
 }
 
 void AudioReceiveStream::Stop() {
@@ -154,10 +140,9 @@
   if (!playing_) {
     return;
   }
+  channel_proxy_->StopPlayout();
   playing_ = false;
-
-  audio_state()->mixer()->RemoveSource(this);
-  SetVoiceEnginePlayout(false);
+  audio_state()->RemoveReceivingStream(this);
 }
 
 webrtc::AudioReceiveStream::Stats AudioReceiveStream::GetStats() const {
@@ -344,14 +329,5 @@
   RTC_DCHECK(audio_state);
   return audio_state;
 }
-
-int AudioReceiveStream::SetVoiceEnginePlayout(bool playout) {
-  ScopedVoEInterface<VoEBase> base(voice_engine());
-  if (playout) {
-    return base->StartPlayout(config_.voe_channel_id);
-  } else {
-    return base->StopPlayout(config_.voe_channel_id);
-  }
-}
 }  // namespace internal
 }  // namespace webrtc
diff --git a/audio/audio_receive_stream.h b/audio/audio_receive_stream.h
index a61c896..55e58d7 100644
--- a/audio/audio_receive_stream.h
+++ b/audio/audio_receive_stream.h
@@ -82,7 +82,6 @@
  private:
   VoiceEngine* voice_engine() const;
   AudioState* audio_state() const;
-  int SetVoiceEnginePlayout(bool playout);
 
   rtc::ThreadChecker worker_thread_checker_;
   rtc::ThreadChecker module_process_thread_checker_;
diff --git a/audio/audio_receive_stream_unittest.cc b/audio/audio_receive_stream_unittest.cc
index d24bed5..4d4af2e 100644
--- a/audio/audio_receive_stream_unittest.cc
+++ b/audio/audio_receive_stream_unittest.cc
@@ -48,7 +48,8 @@
   return audio_decode_stats;
 }
 
-const int kChannelId = 2;
+const int kChannelId1 = 2;
+const int kChannelId2 = 29;
 const uint32_t kRemoteSsrc = 1234;
 const uint32_t kLocalSsrc = 5678;
 const size_t kOneByteExtensionHeaderLength = 4;
@@ -84,7 +85,7 @@
         new rtc::RefCountedObject<MockAudioDeviceModule>();
     audio_state_ = AudioState::Create(config);
 
-    EXPECT_CALL(voice_engine_, ChannelProxyFactory(kChannelId))
+    EXPECT_CALL(voice_engine_, ChannelProxyFactory(kChannelId1))
         .WillOnce(Invoke([this](int channel_id) {
           EXPECT_FALSE(channel_proxy_);
           channel_proxy_ = new testing::StrictMock<MockVoEChannelProxy>();
@@ -118,7 +119,15 @@
                   }));
           return channel_proxy_;
         }));
-    stream_config_.voe_channel_id = kChannelId;
+    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;
     stream_config_.rtp.local_ssrc = kLocalSsrc;
     stream_config_.rtp.remote_ssrc = kRemoteSsrc;
     stream_config_.rtp.nack.rtp_history_ms = 300;
@@ -231,7 +240,7 @@
   AudioReceiveStream::Config config;
   config.rtp.remote_ssrc = kRemoteSsrc;
   config.rtp.local_ssrc = kLocalSsrc;
-  config.voe_channel_id = kChannelId;
+  config.voe_channel_id = kChannelId1;
   config.rtp.extensions.push_back(
       RtpExtension(RtpExtension::kAudioLevelUri, kAudioLevelId));
   EXPECT_EQ(
@@ -354,32 +363,36 @@
   recv_stream.SetGain(0.765f);
 }
 
-TEST(AudioReceiveStreamTest, StreamShouldNotBeAddedToMixerWhenVoEReturnsError) {
+TEST(AudioReceiveStreamTest, StreamsShouldBeAddedToMixerOnceOnStart) {
   ConfigHelper helper;
-  internal::AudioReceiveStream recv_stream(
+  internal::AudioReceiveStream recv_stream1(
       helper.rtp_stream_receiver_controller(),
       helper.packet_router(),
       helper.config(), helper.audio_state(), helper.event_log());
-
-  EXPECT_CALL(helper.voice_engine(), StartPlayout(_)).WillOnce(Return(-1));
-  EXPECT_CALL(*helper.audio_mixer(), AddSource(_)).Times(0);
-
-  recv_stream.Start();
-}
-
-TEST(AudioReceiveStreamTest, StreamShouldBeAddedToMixerOnStart) {
-  ConfigHelper helper;
-  internal::AudioReceiveStream recv_stream(
+  AudioReceiveStream::Config config2 = helper.config();
+  config2.voe_channel_id = kChannelId2;
+  internal::AudioReceiveStream recv_stream2(
       helper.rtp_stream_receiver_controller(),
       helper.packet_router(),
-      helper.config(), helper.audio_state(), helper.event_log());
+      config2, helper.audio_state(), helper.event_log());
 
-  EXPECT_CALL(helper.voice_engine(), StartPlayout(_)).WillOnce(Return(0));
-  EXPECT_CALL(helper.voice_engine(), StopPlayout(_));
-  EXPECT_CALL(*helper.audio_mixer(), AddSource(&recv_stream))
+  EXPECT_CALL(*helper.channel_proxy(), StartPlayout()).Times(1);
+  EXPECT_CALL(*helper.channel_proxy(), StopPlayout()).Times(1);
+  EXPECT_CALL(*helper.audio_mixer(), AddSource(&recv_stream1))
       .WillOnce(Return(true));
+  EXPECT_CALL(*helper.audio_mixer(), AddSource(&recv_stream2))
+      .WillOnce(Return(true));
+  EXPECT_CALL(*helper.audio_mixer(), RemoveSource(&recv_stream1)).Times(1);
+  EXPECT_CALL(*helper.audio_mixer(), RemoveSource(&recv_stream2)).Times(1);
 
-  recv_stream.Start();
+  recv_stream1.Start();
+  recv_stream2.Start();
+
+  // One more should not result in any more mixer sources added.
+  recv_stream1.Start();
+
+  // Stop stream before it is being destructed.
+  recv_stream2.Stop();
 }
 }  // namespace test
 }  // namespace webrtc
diff --git a/audio/audio_state.cc b/audio/audio_state.cc
index ac7eaf7..9d980e8 100644
--- a/audio/audio_state.cc
+++ b/audio/audio_state.cc
@@ -14,6 +14,7 @@
 #include <utility>
 #include <vector>
 
+#include "audio/audio_receive_stream.h"
 #include "modules/audio_device/include/audio_device.h"
 #include "rtc_base/atomicops.h"
 #include "rtc_base/checks.h"
@@ -37,6 +38,7 @@
 
 AudioState::~AudioState() {
   RTC_DCHECK(thread_checker_.CalledOnValidThread());
+  RTC_DCHECK(receiving_streams_.empty());
   RTC_DCHECK(sending_streams_.empty());
 }
 
@@ -45,16 +47,44 @@
   return config_.voice_engine;
 }
 
-rtc::scoped_refptr<AudioMixer> AudioState::mixer() {
-  RTC_DCHECK(thread_checker_.CalledOnValidThread());
-  return config_.audio_mixer;
-}
-
 bool AudioState::typing_noise_detected() const {
   RTC_DCHECK(thread_checker_.CalledOnValidThread());
   return audio_transport_.typing_noise_detected();
 }
 
+void AudioState::AddReceivingStream(webrtc::AudioReceiveStream* stream) {
+  RTC_DCHECK(thread_checker_.CalledOnValidThread());
+  RTC_DCHECK_EQ(0, receiving_streams_.count(stream));
+  receiving_streams_.insert(stream);
+  if (!config_.audio_mixer->AddSource(
+      static_cast<internal::AudioReceiveStream*>(stream))) {
+    RTC_LOG(LS_ERROR) << "Failed to add source to mixer.";
+  }
+
+  // Make sure playback is initialized; start playing if enabled.
+  auto* adm = config_.audio_device_module.get();
+  if (!adm->Playing()) {
+    if (adm->InitPlayout() == 0) {
+      if (playout_enabled_) {
+        adm->StartPlayout();
+      }
+    } else {
+      RTC_DLOG_F(LS_ERROR) << "Failed to initialize playout.";
+    }
+  }
+}
+
+void AudioState::RemoveReceivingStream(webrtc::AudioReceiveStream* stream) {
+  RTC_DCHECK(thread_checker_.CalledOnValidThread());
+  auto count = receiving_streams_.erase(stream);
+  RTC_DCHECK_EQ(1, count);
+  config_.audio_mixer->RemoveSource(
+      static_cast<internal::AudioReceiveStream*>(stream));
+  if (receiving_streams_.empty()) {
+    config_.audio_device_module->StopPlayout();
+  }
+}
+
 void AudioState::AddSendingStream(webrtc::AudioSendStream* stream,
                                   int sample_rate_hz, size_t num_channels) {
   RTC_DCHECK(thread_checker_.CalledOnValidThread());
@@ -89,20 +119,18 @@
 void AudioState::SetPlayout(bool enabled) {
   RTC_LOG(INFO) << "SetPlayout(" << enabled << ")";
   RTC_DCHECK(thread_checker_.CalledOnValidThread());
-  const bool currently_enabled = (null_audio_poller_ == nullptr);
-  if (enabled == currently_enabled) {
-    return;
-  }
-  if (enabled) {
-    null_audio_poller_.reset();
-  }
-  // Will stop/start playout of the underlying device, if necessary, and
-  // remember the setting for when it receives subsequent calls of
-  // StartPlayout.
-  voe_base_->SetPlayout(enabled);
-  if (!enabled) {
-    null_audio_poller_ =
-        rtc::MakeUnique<NullAudioPoller>(&audio_transport_);
+  if (playout_enabled_ != enabled) {
+    playout_enabled_ = enabled;
+    if (enabled) {
+      null_audio_poller_.reset();
+      if (!receiving_streams_.empty()) {
+        config_.audio_device_module->StartPlayout();
+      }
+    } else {
+      config_.audio_device_module->StopPlayout();
+      null_audio_poller_ =
+          rtc::MakeUnique<NullAudioPoller>(&audio_transport_);
+    }
   }
 }
 
@@ -157,7 +185,7 @@
 
 void AudioState::UpdateAudioTransportWithSendingStreams() {
   RTC_DCHECK(thread_checker_.CalledOnValidThread());
-  std::vector<AudioSendStream*> sending_streams;
+  std::vector<webrtc::AudioSendStream*> sending_streams;
   int max_sample_rate_hz = 8000;
   size_t max_num_channels = 1;
   for (const auto& kv : sending_streams_) {
diff --git a/audio/audio_state.h b/audio/audio_state.h
index 540a249..3a92d42 100644
--- a/audio/audio_state.h
+++ b/audio/audio_state.h
@@ -13,6 +13,7 @@
 
 #include <map>
 #include <memory>
+#include <unordered_set>
 
 #include "audio/audio_transport_impl.h"
 #include "audio/null_audio_poller.h"
@@ -27,6 +28,7 @@
 namespace webrtc {
 
 class AudioSendStream;
+class AudioReceiveStream;
 
 namespace internal {
 
@@ -50,9 +52,11 @@
   void SetStereoChannelSwapping(bool enable) override;
 
   VoiceEngine* voice_engine();
-  rtc::scoped_refptr<AudioMixer> mixer();
   bool typing_noise_detected() const;
 
+  void AddReceivingStream(webrtc::AudioReceiveStream* stream);
+  void RemoveReceivingStream(webrtc::AudioReceiveStream* stream);
+
   void AddSendingStream(webrtc::AudioSendStream* stream,
                         int sample_rate_hz, size_t num_channels);
   void RemoveSendingStream(webrtc::AudioSendStream* stream);
@@ -68,6 +72,7 @@
   rtc::ThreadChecker process_thread_checker_;
   const webrtc::AudioState::Config config_;
   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_;
@@ -85,6 +90,7 @@
   // stats are still updated.
   std::unique_ptr<NullAudioPoller> null_audio_poller_;
 
+  std::unordered_set<webrtc::AudioReceiveStream*> receiving_streams_;
   struct StreamProperties {
     int sample_rate_hz = 0;
     size_t num_channels = 0;
diff --git a/media/engine/fakewebrtcvoiceengine.h b/media/engine/fakewebrtcvoiceengine.h
index a70975b..e171bbc 100644
--- a/media/engine/fakewebrtcvoiceengine.h
+++ b/media/engine/fakewebrtcvoiceengine.h
@@ -81,9 +81,6 @@
     channels_.erase(channel);
     return 0;
   }
-  WEBRTC_STUB(StartPlayout, (int channel));
-  WEBRTC_STUB(StopPlayout, (int channel));
-  WEBRTC_STUB(SetPlayout, (bool enable));
 
   size_t GetNetEqCapacity() const {
     auto ch = channels_.find(last_channel_);
diff --git a/test/mock_voe_channel_proxy.h b/test/mock_voe_channel_proxy.h
index ac3ffca..5760781 100644
--- a/test/mock_voe_channel_proxy.h
+++ b/test/mock_voe_channel_proxy.h
@@ -100,6 +100,8 @@
   MOCK_CONST_METHOD0(GetSources, std::vector<RtpSource>());
   MOCK_METHOD0(StartSend, void());
   MOCK_METHOD0(StopSend, void());
+  MOCK_METHOD0(StartPlayout, void());
+  MOCK_METHOD0(StopPlayout, void());
 };
 }  // namespace test
 }  // namespace webrtc
diff --git a/test/mock_voice_engine.h b/test/mock_voice_engine.h
index a31c90f..0bbf5ee 100644
--- a/test/mock_voice_engine.h
+++ b/test/mock_voice_engine.h
@@ -90,8 +90,6 @@
   MOCK_METHOD0(CreateChannel, int());
   MOCK_METHOD1(CreateChannel, int(const ChannelConfig& config));
   MOCK_METHOD1(DeleteChannel, int(int channel));
-  MOCK_METHOD1(StartPlayout, int(int channel));
-  MOCK_METHOD1(StopPlayout, int(int channel));
 
  private:
   // TODO(ossu): I'm not particularly happy about keeping the decoder factory
diff --git a/video/video_quality_test.cc b/video/video_quality_test.cc
index eaa9099..2392e9f 100644
--- a/video/video_quality_test.cc
+++ b/video/video_quality_test.cc
@@ -2080,7 +2080,6 @@
     if (params_.audio.enabled) {
       // Start receiving audio.
       audio_receive_stream->Start();
-      EXPECT_EQ(0, voe.base->StartPlayout(voe.receive_channel_id));
 
       // Start sending audio.
       audio_send_stream_->Start();
@@ -2095,7 +2094,6 @@
       audio_send_stream_->Stop();
 
       // Stop receiving audio.
-      EXPECT_EQ(0, voe.base->StopPlayout(voe.receive_channel_id));
       audio_receive_stream->Stop();
       sender_call_->DestroyAudioSendStream(audio_send_stream_);
       receiver_call_->DestroyAudioReceiveStream(audio_receive_stream);
diff --git a/voice_engine/channel_proxy.cc b/voice_engine/channel_proxy.cc
index 8adc1e2..08233ae 100644
--- a/voice_engine/channel_proxy.cc
+++ b/voice_engine/channel_proxy.cc
@@ -343,6 +343,18 @@
   channel()->StopSend();
 }
 
+void ChannelProxy::StartPlayout() {
+  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
+  int error = channel()->StartPlayout();
+  RTC_DCHECK_EQ(0, error);
+}
+
+void ChannelProxy::StopPlayout() {
+  RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
+  int error = channel()->StopPlayout();
+  RTC_DCHECK_EQ(0, error);
+}
+
 Channel* ChannelProxy::channel() const {
   RTC_DCHECK(channel_owner_.channel());
   return channel_owner_.channel();
diff --git a/voice_engine/channel_proxy.h b/voice_engine/channel_proxy.h
index 060f9d5..d4fa048 100644
--- a/voice_engine/channel_proxy.h
+++ b/voice_engine/channel_proxy.h
@@ -123,6 +123,8 @@
   virtual std::vector<webrtc::RtpSource> GetSources() const;
   virtual void StartSend();
   virtual void StopSend();
+  virtual void StartPlayout();
+  virtual void StopPlayout();
 
  private:
   Channel* channel() const;
diff --git a/voice_engine/include/voe_base.h b/voice_engine/include/voe_base.h
index f94279c..a76d2bc 100644
--- a/voice_engine/include/voe_base.h
+++ b/voice_engine/include/voe_base.h
@@ -109,21 +109,6 @@
   // Returns -1 in case of an error, 0 otherwise.
   virtual int DeleteChannel(int channel) = 0;
 
-  // Starts forwarding the packets to the mixer/soundcard for a
-  // specified |channel|.
-  virtual int StartPlayout(int channel) = 0;
-
-  // Stops forwarding the packets to the mixer/soundcard for a
-  // specified |channel|.
-  virtual int StopPlayout(int channel) = 0;
-
-  // Enable or disable playout to the underlying device. Takes precedence over
-  // StartPlayout. Though calls to StartPlayout are remembered; if
-  // SetPlayout(true) is called after StartPlayout, playout will be started.
-  //
-  // By default, playout is enabled.
-  virtual int SetPlayout(bool enabled) = 0;
-
  protected:
   VoEBase() {}
   virtual ~VoEBase() {}
diff --git a/voice_engine/shared_data.cc b/voice_engine/shared_data.cc
index ae54079..420a7da 100644
--- a/voice_engine/shared_data.cc
+++ b/voice_engine/shared_data.cc
@@ -43,20 +43,6 @@
     const rtc::scoped_refptr<AudioDeviceModule>& audio_device) {
   _audioDevicePtr = audio_device;
 }
-
-int SharedData::NumOfPlayingChannels() {
-  ChannelManager::Iterator it(&_channelManager);
-  int playout_channels = 0;
-
-  for (ChannelManager::Iterator it(&_channelManager); it.IsValid();
-       it.Increment()) {
-    if (it.GetChannel()->Playing())
-      ++playout_channels;
-  }
-
-  return playout_channels;
-}
-
 }  // namespace voe
 
 }  // namespace webrtc
diff --git a/voice_engine/shared_data.h b/voice_engine/shared_data.h
index 7c72f91..f1364b9 100644
--- a/voice_engine/shared_data.h
+++ b/voice_engine/shared_data.h
@@ -40,8 +40,6 @@
     ProcessThread* process_thread() { return _moduleProcessThreadPtr.get(); }
     rtc::TaskQueue* encoder_queue();
 
-    int NumOfPlayingChannels();
-
 protected:
  rtc::ThreadChecker construction_thread_;
  const uint32_t _instanceId;
diff --git a/voice_engine/voe_base_impl.cc b/voice_engine/voe_base_impl.cc
index 793444b..88371eb 100644
--- a/voice_engine/voe_base_impl.cc
+++ b/voice_engine/voe_base_impl.cc
@@ -107,99 +107,9 @@
   }
 
   shared_->channel_manager().DestroyChannel(channel);
-  if (StopPlayout() != 0) {
-    return -1;
-  }
   return 0;
 }
 
-int VoEBaseImpl::StartPlayout(int channel) {
-  rtc::CritScope cs(shared_->crit_sec());
-  voe::ChannelOwner ch = shared_->channel_manager().GetChannel(channel);
-  voe::Channel* channelPtr = ch.channel();
-  if (channelPtr == nullptr) {
-    RTC_LOG(LS_ERROR) << "StartPlayout() failed to locate channel";
-    return -1;
-  }
-  if (channelPtr->Playing()) {
-    return 0;
-  }
-  if (StartPlayout() != 0) {
-    RTC_LOG(LS_ERROR) << "StartPlayout() failed to start playout";
-    return -1;
-  }
-  return channelPtr->StartPlayout();
-}
-
-int VoEBaseImpl::StopPlayout(int channel) {
-  rtc::CritScope cs(shared_->crit_sec());
-  voe::ChannelOwner ch = shared_->channel_manager().GetChannel(channel);
-  voe::Channel* channelPtr = ch.channel();
-  if (channelPtr == nullptr) {
-    RTC_LOG(LS_ERROR) << "StopPlayout() failed to locate channel";
-    return -1;
-  }
-  if (channelPtr->StopPlayout() != 0) {
-    RTC_LOG_F(LS_WARNING) << "StopPlayout() failed to stop playout for channel "
-                          << channel;
-  }
-  return StopPlayout();
-}
-
-int32_t VoEBaseImpl::StartPlayout() {
-  if (!shared_->audio_device()->Playing()) {
-    if (shared_->audio_device()->InitPlayout() != 0) {
-      RTC_LOG_F(LS_ERROR) << "Failed to initialize playout";
-      return -1;
-    }
-    if (playout_enabled_ && shared_->audio_device()->StartPlayout() != 0) {
-      RTC_LOG_F(LS_ERROR) << "Failed to start playout";
-      return -1;
-    }
-  }
-  return 0;
-}
-
-int32_t VoEBaseImpl::StopPlayout() {
-  if (!playout_enabled_) {
-    return 0;
-  }
-  // Stop audio-device playing if no channel is playing out.
-  if (shared_->NumOfPlayingChannels() == 0) {
-    if (shared_->audio_device()->StopPlayout() != 0) {
-      RTC_LOG(LS_ERROR) << "StopPlayout() failed to stop playout";
-      return -1;
-    }
-  }
-  return 0;
-}
-
-int32_t VoEBaseImpl::SetPlayout(bool enabled) {
-  RTC_LOG(INFO) << "SetPlayout(" << enabled << ")";
-  if (playout_enabled_ == enabled) {
-    return 0;
-  }
-  playout_enabled_ = enabled;
-  if (shared_->NumOfPlayingChannels() == 0) {
-    // If there are no channels attempting to play out yet, there's nothing to
-    // be done; we should be in a "not playing out" state either way.
-    return 0;
-  }
-  int32_t ret;
-  if (enabled) {
-    ret = shared_->audio_device()->StartPlayout();
-    if (ret != 0) {
-      RTC_LOG(LS_ERROR) << "SetPlayout(true) failed to start playout";
-    }
-  } else {
-    ret = shared_->audio_device()->StopPlayout();
-    if (ret != 0) {
-      RTC_LOG(LS_ERROR) << "SetPlayout(false) failed to stop playout";
-    }
-  }
-  return ret;
-}
-
 void VoEBaseImpl::TerminateInternal() {
   // Delete any remaining channel objects
   shared_->channel_manager().DestroyAllChannels();
diff --git a/voice_engine/voe_base_impl.h b/voice_engine/voe_base_impl.h
index 2692c04..a56e520 100644
--- a/voice_engine/voe_base_impl.h
+++ b/voice_engine/voe_base_impl.h
@@ -33,28 +33,18 @@
   int CreateChannel(const ChannelConfig& config) override;
   int DeleteChannel(int channel) override;
 
-  int StartPlayout(int channel) override;
-  int StopPlayout(int channel) override;
-
-  int SetPlayout(bool enabled) override;
-
  protected:
   VoEBaseImpl(voe::SharedData* shared);
   ~VoEBaseImpl() override;
 
  private:
-  int32_t StartPlayout();
-  int32_t StopPlayout();
   void TerminateInternal();
 
   // Initialize channel by setting Engine Information then initializing
   // channel.
   int InitializeChannel(voe::ChannelOwner* channel_owner);
   rtc::scoped_refptr<AudioDecoderFactory> decoder_factory_;
-
-  AudioFrame audioFrame_;
   voe::SharedData* shared_;
-  bool playout_enabled_ = true;
 };
 
 }  // namespace webrtc