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}
This commit is contained in:
parent
086c9f5e4e
commit
d5247510dc
@ -118,9 +118,7 @@ AudioReceiveStream::AudioReceiveStream(
|
||||
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 @@ void AudioReceiveStream::Start() {
|
||||
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 @@ void AudioReceiveStream::Stop() {
|
||||
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 @@ internal::AudioState* AudioReceiveStream::audio_state() const {
|
||||
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
|
||||
|
||||
@ -82,7 +82,6 @@ class AudioReceiveStream final : public webrtc::AudioReceiveStream,
|
||||
private:
|
||||
VoiceEngine* voice_engine() const;
|
||||
AudioState* audio_state() const;
|
||||
int SetVoiceEnginePlayout(bool playout);
|
||||
|
||||
rtc::ThreadChecker worker_thread_checker_;
|
||||
rtc::ThreadChecker module_process_thread_checker_;
|
||||
|
||||
@ -48,7 +48,8 @@ AudioDecodingCallStats MakeAudioDecodeStatsForTest() {
|
||||
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 @@ struct ConfigHelper {
|
||||
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 @@ struct ConfigHelper {
|
||||
}));
|
||||
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 @@ TEST(AudioReceiveStreamTest, ConfigToString) {
|
||||
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 @@ TEST(AudioReceiveStreamTest, SetGain) {
|
||||
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
|
||||
|
||||
@ -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(const AudioState::Config& config)
|
||||
|
||||
AudioState::~AudioState() {
|
||||
RTC_DCHECK(thread_checker_.CalledOnValidThread());
|
||||
RTC_DCHECK(receiving_streams_.empty());
|
||||
RTC_DCHECK(sending_streams_.empty());
|
||||
}
|
||||
|
||||
@ -45,16 +47,44 @@ VoiceEngine* AudioState::voice_engine() {
|
||||
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::RemoveSendingStream(webrtc::AudioSendStream* stream) {
|
||||
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 @@ rtc::RefCountReleaseStatus AudioState::Release() const {
|
||||
|
||||
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_) {
|
||||
|
||||
@ -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 @@ class AudioState final : public webrtc::AudioState {
|
||||
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 @@ class AudioState final : public webrtc::AudioState {
|
||||
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 @@ class AudioState final : public webrtc::AudioState {
|
||||
// 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;
|
||||
|
||||
@ -81,9 +81,6 @@ class FakeWebRtcVoiceEngine : public webrtc::VoEBase {
|
||||
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_);
|
||||
|
||||
@ -100,6 +100,8 @@ class MockVoEChannelProxy : public voe::ChannelProxy {
|
||||
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
|
||||
|
||||
@ -90,8 +90,6 @@ class MockVoiceEngine : public VoiceEngineImpl {
|
||||
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
|
||||
|
||||
@ -2080,7 +2080,6 @@ void VideoQualityTest::RunWithRenderers(const Params& params) {
|
||||
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 @@ void VideoQualityTest::RunWithRenderers(const Params& params) {
|
||||
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);
|
||||
|
||||
@ -343,6 +343,18 @@ void ChannelProxy::StopSend() {
|
||||
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();
|
||||
|
||||
@ -123,6 +123,8 @@ class ChannelProxy : public RtpPacketSinkInterface {
|
||||
virtual std::vector<webrtc::RtpSource> GetSources() const;
|
||||
virtual void StartSend();
|
||||
virtual void StopSend();
|
||||
virtual void StartPlayout();
|
||||
virtual void StopPlayout();
|
||||
|
||||
private:
|
||||
Channel* channel() const;
|
||||
|
||||
@ -109,21 +109,6 @@ class WEBRTC_DLLEXPORT VoEBase {
|
||||
// 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() {}
|
||||
|
||||
@ -43,20 +43,6 @@ void SharedData::set_audio_device(
|
||||
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
|
||||
|
||||
@ -40,8 +40,6 @@ public:
|
||||
ProcessThread* process_thread() { return _moduleProcessThreadPtr.get(); }
|
||||
rtc::TaskQueue* encoder_queue();
|
||||
|
||||
int NumOfPlayingChannels();
|
||||
|
||||
protected:
|
||||
rtc::ThreadChecker construction_thread_;
|
||||
const uint32_t _instanceId;
|
||||
|
||||
@ -107,99 +107,9 @@ int VoEBaseImpl::DeleteChannel(int channel) {
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
@ -33,28 +33,18 @@ class VoEBaseImpl : public VoEBase {
|
||||
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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user