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