Remove the VoiceEngineObserver callback interface.

BUG=webrtc:4690
TBR=kwiberg@webrtc.org

Review-Url: https://codereview.webrtc.org/3019513002
Cr-Commit-Position: refs/heads/master@{#19976}
This commit is contained in:
solenberg 2017-09-26 09:35:01 -07:00 committed by Commit Bot
parent 6ffffe7cb5
commit fc3a2e3393
18 changed files with 41 additions and 385 deletions

View File

@ -75,10 +75,6 @@ struct ConfigHelper {
audio_mixer_(new rtc::RefCountedObject<MockAudioMixer>()) { audio_mixer_(new rtc::RefCountedObject<MockAudioMixer>()) {
using testing::Invoke; using testing::Invoke;
EXPECT_CALL(voice_engine_,
RegisterVoiceEngineObserver(_)).WillOnce(Return(0));
EXPECT_CALL(voice_engine_,
DeRegisterVoiceEngineObserver()).WillOnce(Return(0));
EXPECT_CALL(voice_engine_, audio_device_module()); EXPECT_CALL(voice_engine_, audio_device_module());
EXPECT_CALL(voice_engine_, audio_transport()); EXPECT_CALL(voice_engine_, audio_transport());

View File

@ -87,6 +87,7 @@ class MockTransmitMixer : public voe::TransmitMixer {
MOCK_CONST_METHOD0(AudioLevelFullRange, int16_t()); MOCK_CONST_METHOD0(AudioLevelFullRange, int16_t());
MOCK_CONST_METHOD0(GetTotalInputEnergy, double()); MOCK_CONST_METHOD0(GetTotalInputEnergy, double());
MOCK_CONST_METHOD0(GetTotalInputDuration, double()); MOCK_CONST_METHOD0(GetTotalInputDuration, double());
MOCK_CONST_METHOD0(typing_noise_detected, bool());
}; };
std::unique_ptr<MockAudioEncoder> SetupAudioEncoderMock( std::unique_ptr<MockAudioEncoder> SetupAudioEncoderMock(
@ -146,10 +147,6 @@ struct ConfigHelper {
audio_encoder_(nullptr) { audio_encoder_(nullptr) {
using testing::Invoke; using testing::Invoke;
EXPECT_CALL(voice_engine_,
RegisterVoiceEngineObserver(_)).WillOnce(Return(0));
EXPECT_CALL(voice_engine_,
DeRegisterVoiceEngineObserver()).WillOnce(Return(0));
EXPECT_CALL(voice_engine_, audio_device_module()); EXPECT_CALL(voice_engine_, audio_device_module());
EXPECT_CALL(voice_engine_, audio_transport()); EXPECT_CALL(voice_engine_, audio_transport());
@ -312,6 +309,8 @@ struct ConfigHelper {
.WillRepeatedly(Return(kTotalInputEnergy)); .WillRepeatedly(Return(kTotalInputEnergy));
EXPECT_CALL(transmit_mixer_, GetTotalInputDuration()) EXPECT_CALL(transmit_mixer_, GetTotalInputDuration())
.WillRepeatedly(Return(kTotalInputDuration)); .WillRepeatedly(Return(kTotalInputDuration));
EXPECT_CALL(transmit_mixer_, typing_noise_detected())
.WillRepeatedly(Return(true));
// We have to set the instantaneous value, the average, min and max. We only // We have to set the instantaneous value, the average, min and max. We only
// care about the instantaneous value, so we set all to the same value. // care about the instantaneous value, so we set all to the same value.
@ -456,26 +455,7 @@ TEST(AudioSendStreamTest, GetStats) {
EXPECT_EQ(kEchoReturnLoss, stats.echo_return_loss); EXPECT_EQ(kEchoReturnLoss, stats.echo_return_loss);
EXPECT_EQ(kEchoReturnLossEnhancement, stats.echo_return_loss_enhancement); EXPECT_EQ(kEchoReturnLossEnhancement, stats.echo_return_loss_enhancement);
EXPECT_EQ(kResidualEchoLikelihood, stats.residual_echo_likelihood); EXPECT_EQ(kResidualEchoLikelihood, stats.residual_echo_likelihood);
EXPECT_FALSE(stats.typing_noise_detected); EXPECT_TRUE(stats.typing_noise_detected);
}
TEST(AudioSendStreamTest, GetStatsTypingNoiseDetected) {
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::Optional<RtpState>());
helper.SetupMockForGetStats();
EXPECT_FALSE(send_stream.GetStats().typing_noise_detected);
internal::AudioState* internal_audio_state =
static_cast<internal::AudioState*>(helper.audio_state().get());
VoiceEngineObserver* voe_observer =
static_cast<VoiceEngineObserver*>(internal_audio_state);
voe_observer->CallbackOnError(-1, VE_TYPING_NOISE_WARNING);
EXPECT_TRUE(send_stream.GetStats().typing_noise_detected);
voe_observer->CallbackOnError(-1, VE_TYPING_NOISE_OFF_WARNING);
EXPECT_FALSE(send_stream.GetStats().typing_noise_detected);
} }
TEST(AudioSendStreamTest, SendCodecAppliesAudioNetworkAdaptor) { TEST(AudioSendStreamTest, SendCodecAppliesAudioNetworkAdaptor) {

View File

@ -14,7 +14,7 @@
#include "rtc_base/atomicops.h" #include "rtc_base/atomicops.h"
#include "rtc_base/checks.h" #include "rtc_base/checks.h"
#include "rtc_base/logging.h" #include "rtc_base/logging.h"
#include "voice_engine/include/voe_errors.h" #include "voice_engine/transmit_mixer.h"
namespace webrtc { namespace webrtc {
namespace internal { namespace internal {
@ -28,9 +28,6 @@ AudioState::AudioState(const AudioState::Config& config)
process_thread_checker_.DetachFromThread(); process_thread_checker_.DetachFromThread();
RTC_DCHECK(config_.audio_mixer); RTC_DCHECK(config_.audio_mixer);
// Only one AudioState should be created per VoiceEngine.
RTC_CHECK(voe_base_->RegisterVoiceEngineObserver(*this) != -1);
auto* const device = voe_base_->audio_device_module(); auto* const device = voe_base_->audio_device_module();
RTC_DCHECK(device); RTC_DCHECK(device);
@ -41,7 +38,6 @@ AudioState::AudioState(const AudioState::Config& config)
AudioState::~AudioState() { AudioState::~AudioState() {
RTC_DCHECK(thread_checker_.CalledOnValidThread()); RTC_DCHECK(thread_checker_.CalledOnValidThread());
voe_base_->DeRegisterVoiceEngineObserver();
} }
VoiceEngine* AudioState::voice_engine() { VoiceEngine* AudioState::voice_engine() {
@ -56,8 +52,11 @@ rtc::scoped_refptr<AudioMixer> AudioState::mixer() {
bool AudioState::typing_noise_detected() const { bool AudioState::typing_noise_detected() const {
RTC_DCHECK(thread_checker_.CalledOnValidThread()); RTC_DCHECK(thread_checker_.CalledOnValidThread());
rtc::CritScope lock(&crit_sect_); // TODO(solenberg): Remove const_cast once AudioState owns transmit mixer
return typing_noise_detected_; // functionality.
voe::TransmitMixer* transmit_mixer =
const_cast<AudioState*>(this)->voe_base_->transmit_mixer();
return transmit_mixer->typing_noise_detected();
} }
// Reference count; implementation copied from rtc::RefCountedObject. // Reference count; implementation copied from rtc::RefCountedObject.
@ -73,22 +72,6 @@ int AudioState::Release() const {
} }
return count; return count;
} }
void AudioState::CallbackOnError(int channel_id, int err_code) {
RTC_DCHECK(process_thread_checker_.CalledOnValidThread());
// All call sites in VoE, as of this writing, specify -1 as channel_id.
RTC_DCHECK(channel_id == -1);
LOG(LS_INFO) << "VoiceEngine error " << err_code << " reported on channel "
<< channel_id << ".";
if (err_code == VE_TYPING_NOISE_WARNING) {
rtc::CritScope lock(&crit_sect_);
typing_noise_detected_ = true;
} else if (err_code == VE_TYPING_NOISE_OFF_WARNING) {
rtc::CritScope lock(&crit_sect_);
typing_noise_detected_ = false;
}
}
} // namespace internal } // namespace internal
rtc::scoped_refptr<AudioState> AudioState::Create( rtc::scoped_refptr<AudioState> AudioState::Create(

View File

@ -22,8 +22,7 @@
namespace webrtc { namespace webrtc {
namespace internal { namespace internal {
class AudioState final : public webrtc::AudioState, class AudioState final : public webrtc::AudioState {
public webrtc::VoiceEngineObserver {
public: public:
explicit AudioState(const AudioState::Config& config); explicit AudioState(const AudioState::Config& config);
~AudioState() override; ~AudioState() override;
@ -42,9 +41,6 @@ class AudioState final : public webrtc::AudioState,
int AddRef() const override; int AddRef() const override;
int Release() const override; int Release() const override;
// webrtc::VoiceEngineObserver implementation.
void CallbackOnError(int channel_id, int err_code) override;
rtc::ThreadChecker thread_checker_; rtc::ThreadChecker thread_checker_;
rtc::ThreadChecker process_thread_checker_; rtc::ThreadChecker process_thread_checker_;
const webrtc::AudioState::Config config_; const webrtc::AudioState::Config config_;
@ -52,11 +48,6 @@ class AudioState final : public webrtc::AudioState,
// We hold one interface pointer to the VoE to make sure it is kept alive. // We hold one interface pointer to the VoE to make sure it is kept alive.
ScopedVoEInterface<VoEBase> voe_base_; ScopedVoEInterface<VoEBase> voe_base_;
// The critical section isn't strictly needed in this case, but xSAN bots may
// trigger on unprotected cross-thread access.
rtc::CriticalSection crit_sect_;
bool typing_noise_detected_ RTC_GUARDED_BY(crit_sect_) = false;
// Reference count; implementation copied from rtc::RefCountedObject. // Reference count; implementation copied from rtc::RefCountedObject.
mutable volatile int ref_count_ = 0; mutable volatile int ref_count_ = 0;

View File

@ -26,10 +26,6 @@ const int kBytesPerSample = 2;
struct ConfigHelper { struct ConfigHelper {
ConfigHelper() : audio_mixer(AudioMixerImpl::Create()) { ConfigHelper() : audio_mixer(AudioMixerImpl::Create()) {
EXPECT_CALL(mock_voice_engine, RegisterVoiceEngineObserver(testing::_))
.WillOnce(testing::Return(0));
EXPECT_CALL(mock_voice_engine, DeRegisterVoiceEngineObserver())
.WillOnce(testing::Return(0));
EXPECT_CALL(mock_voice_engine, audio_device_module()) EXPECT_CALL(mock_voice_engine, audio_device_module())
.Times(testing::AtLeast(1)); .Times(testing::AtLeast(1));
EXPECT_CALL(mock_voice_engine, audio_transport()) EXPECT_CALL(mock_voice_engine, audio_transport())
@ -101,28 +97,6 @@ TEST(AudioStateTest, GetVoiceEngine) {
EXPECT_EQ(audio_state->voice_engine(), &helper.voice_engine()); EXPECT_EQ(audio_state->voice_engine(), &helper.voice_engine());
} }
TEST(AudioStateTest, TypingNoiseDetected) {
ConfigHelper helper;
std::unique_ptr<internal::AudioState> audio_state(
new internal::AudioState(helper.config()));
VoiceEngineObserver* voe_observer =
static_cast<VoiceEngineObserver*>(audio_state.get());
EXPECT_FALSE(audio_state->typing_noise_detected());
voe_observer->CallbackOnError(-1, VE_NOT_INITED);
EXPECT_FALSE(audio_state->typing_noise_detected());
voe_observer->CallbackOnError(-1, VE_TYPING_NOISE_WARNING);
EXPECT_TRUE(audio_state->typing_noise_detected());
voe_observer->CallbackOnError(-1, VE_NOT_INITED);
EXPECT_TRUE(audio_state->typing_noise_detected());
voe_observer->CallbackOnError(-1, VE_TYPING_NOISE_OFF_WARNING);
EXPECT_FALSE(audio_state->typing_noise_detected());
voe_observer->CallbackOnError(-1, VE_NOT_INITED);
EXPECT_FALSE(audio_state->typing_noise_detected());
}
// Test that RecordedDataIsAvailable calls get to the original transport. // Test that RecordedDataIsAvailable calls get to the original transport.
TEST(AudioStateAudioPathTest, RecordedAudioArrivesAtOriginalTransport) { TEST(AudioStateAudioPathTest, RecordedAudioArrivesAtOriginalTransport) {
ConfigHelper helper; ConfigHelper helper;

View File

@ -57,9 +57,6 @@ class FakeWebRtcVoiceEngine : public webrtc::VoEBase {
WEBRTC_STUB(Release, ()); WEBRTC_STUB(Release, ());
// webrtc::VoEBase // webrtc::VoEBase
WEBRTC_STUB(RegisterVoiceEngineObserver, (
webrtc::VoiceEngineObserver& observer));
WEBRTC_STUB(DeRegisterVoiceEngineObserver, ());
WEBRTC_FUNC(Init, WEBRTC_FUNC(Init,
(webrtc::AudioDeviceModule* adm, (webrtc::AudioDeviceModule* adm,
webrtc::AudioProcessing* audioproc, webrtc::AudioProcessing* audioproc,

View File

@ -94,8 +94,6 @@ class MockVoiceEngine : public VoiceEngineImpl {
} }
// VoEBase // VoEBase
MOCK_METHOD1(RegisterVoiceEngineObserver, int(VoiceEngineObserver& observer));
MOCK_METHOD0(DeRegisterVoiceEngineObserver, int());
MOCK_METHOD3( MOCK_METHOD3(
Init, Init,
int(AudioDeviceModule* external_adm, int(AudioDeviceModule* external_adm,

View File

@ -18,7 +18,6 @@ rtc_static_library("voice_engine") {
"channel_proxy.h", "channel_proxy.h",
"include/voe_base.h", "include/voe_base.h",
"include/voe_errors.h", "include/voe_errors.h",
"monitor_module.h",
"shared_data.cc", "shared_data.cc",
"shared_data.h", "shared_data.h",
"statistics.cc", "statistics.cc",

View File

@ -773,7 +773,6 @@ Channel::Channel(int32_t channelId,
_engineStatisticsPtr(NULL), _engineStatisticsPtr(NULL),
_moduleProcessThreadPtr(NULL), _moduleProcessThreadPtr(NULL),
_audioDeviceModulePtr(NULL), _audioDeviceModulePtr(NULL),
_voiceEngineObserverPtr(NULL),
_callbackCritSectPtr(NULL), _callbackCritSectPtr(NULL),
_transportPtr(NULL), _transportPtr(NULL),
input_mute_(false), input_mute_(false),
@ -949,7 +948,6 @@ void Channel::Terminate() {
int32_t Channel::SetEngineInformation(Statistics& engineStatistics, int32_t Channel::SetEngineInformation(Statistics& engineStatistics,
ProcessThread& moduleProcessThread, ProcessThread& moduleProcessThread,
AudioDeviceModule& audioDeviceModule, AudioDeviceModule& audioDeviceModule,
VoiceEngineObserver* voiceEngineObserver,
rtc::CriticalSection* callbackCritSect, rtc::CriticalSection* callbackCritSect,
rtc::TaskQueue* encoder_queue) { rtc::TaskQueue* encoder_queue) {
RTC_DCHECK(encoder_queue); RTC_DCHECK(encoder_queue);
@ -959,7 +957,6 @@ int32_t Channel::SetEngineInformation(Statistics& engineStatistics,
_engineStatisticsPtr = &engineStatistics; _engineStatisticsPtr = &engineStatistics;
_moduleProcessThreadPtr = &moduleProcessThread; _moduleProcessThreadPtr = &moduleProcessThread;
_audioDeviceModulePtr = &audioDeviceModule; _audioDeviceModulePtr = &audioDeviceModule;
_voiceEngineObserverPtr = voiceEngineObserver;
_callbackCritSectPtr = callbackCritSect; _callbackCritSectPtr = callbackCritSect;
encoder_queue_ = encoder_queue; encoder_queue_ = encoder_queue;
return 0; return 0;
@ -1124,36 +1121,6 @@ void Channel::ModifyEncoder(
audio_coding_->ModifyEncoder(modifier); audio_coding_->ModifyEncoder(modifier);
} }
int32_t Channel::RegisterVoiceEngineObserver(VoiceEngineObserver& observer) {
WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
"Channel::RegisterVoiceEngineObserver()");
rtc::CritScope cs(&_callbackCritSect);
if (_voiceEngineObserverPtr) {
_engineStatisticsPtr->SetLastError(
VE_INVALID_OPERATION, kTraceError,
"RegisterVoiceEngineObserver() observer already enabled");
return -1;
}
_voiceEngineObserverPtr = &observer;
return 0;
}
int32_t Channel::DeRegisterVoiceEngineObserver() {
WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
"Channel::DeRegisterVoiceEngineObserver()");
rtc::CritScope cs(&_callbackCritSect);
if (!_voiceEngineObserverPtr) {
_engineStatisticsPtr->SetLastError(
VE_INVALID_OPERATION, kTraceWarning,
"DeRegisterVoiceEngineObserver() observer already disabled");
return 0;
}
_voiceEngineObserverPtr = NULL;
return 0;
}
int32_t Channel::GetSendCodec(CodecInst& codec) { int32_t Channel::GetSendCodec(CodecInst& codec) {
if (cached_send_codec_) { if (cached_send_codec_) {
codec = *cached_send_codec_; codec = *cached_send_codec_;

View File

@ -55,7 +55,6 @@ class RtpPacketReceived;
class RtpRtcp; class RtpRtcp;
class RtpTransportControllerSendInterface; class RtpTransportControllerSendInterface;
class TelephoneEventHandler; class TelephoneEventHandler;
class VoiceEngineObserver;
struct SenderInfo; struct SenderInfo;
@ -161,7 +160,6 @@ class Channel
int32_t SetEngineInformation(Statistics& engineStatistics, int32_t SetEngineInformation(Statistics& engineStatistics,
ProcessThread& moduleProcessThread, ProcessThread& moduleProcessThread,
AudioDeviceModule& audioDeviceModule, AudioDeviceModule& audioDeviceModule,
VoiceEngineObserver* voiceEngineObserver,
rtc::CriticalSection* callbackCritSect, rtc::CriticalSection* callbackCritSect,
rtc::TaskQueue* encoder_queue); rtc::TaskQueue* encoder_queue);
@ -187,8 +185,6 @@ class Channel
int32_t StopPlayout(); int32_t StopPlayout();
int32_t StartSend(); int32_t StartSend();
void StopSend(); void StopSend();
int32_t RegisterVoiceEngineObserver(VoiceEngineObserver& observer);
int32_t DeRegisterVoiceEngineObserver();
// Codecs // Codecs
int32_t GetSendCodec(CodecInst& codec); int32_t GetSendCodec(CodecInst& codec);
@ -427,7 +423,6 @@ class Channel
Statistics* _engineStatisticsPtr; Statistics* _engineStatisticsPtr;
ProcessThread* _moduleProcessThreadPtr; ProcessThread* _moduleProcessThreadPtr;
AudioDeviceModule* _audioDeviceModulePtr; AudioDeviceModule* _audioDeviceModulePtr;
VoiceEngineObserver* _voiceEngineObserverPtr; // owned by base
rtc::CriticalSection* _callbackCritSectPtr; // owned by base rtc::CriticalSection* _callbackCritSectPtr; // owned by base
Transport* _transportPtr; // WebRtc socket or external transport Transport* _transportPtr; // WebRtc socket or external transport
RmsLevel rms_level_ RTC_ACCESS_ON(encoder_queue_); RmsLevel rms_level_ RTC_ACCESS_ON(encoder_queue_);

View File

@ -48,18 +48,6 @@ namespace voe {
class TransmitMixer; class TransmitMixer;
} // namespace voe } // namespace voe
// VoiceEngineObserver
class WEBRTC_DLLEXPORT VoiceEngineObserver {
public:
// This method will be called after the occurrence of any runtime error
// code, or warning notification, when the observer interface has been
// installed using VoEBase::RegisterVoiceEngineObserver().
virtual void CallbackOnError(int channel, int errCode) = 0;
protected:
virtual ~VoiceEngineObserver() {}
};
// VoiceEngine // VoiceEngine
class WEBRTC_DLLEXPORT VoiceEngine { class WEBRTC_DLLEXPORT VoiceEngine {
public: public:
@ -96,14 +84,6 @@ class WEBRTC_DLLEXPORT VoEBase {
// for all sub-APIs before the VoiceEngine object can be safely deleted. // for all sub-APIs before the VoiceEngine object can be safely deleted.
virtual int Release() = 0; virtual int Release() = 0;
// Installs the observer class to enable runtime error control and
// warning notifications. Returns -1 in case of an error, 0 otherwise.
virtual int RegisterVoiceEngineObserver(VoiceEngineObserver& observer) = 0;
// Removes and disables the observer class for runtime error control
// and warning notifications. Returns 0.
virtual int DeRegisterVoiceEngineObserver() = 0;
// Initializes all common parts of the VoiceEngine; e.g. all // Initializes all common parts of the VoiceEngine; e.g. all
// encoders/decoders, the sound card and core receiving components. // encoders/decoders, the sound card and core receiving components.
// This method also makes it possible to install some user-defined external // This method also makes it possible to install some user-defined external

View File

@ -79,7 +79,7 @@
#define VE_DESTINATION_NOT_INITED 8104 #define VE_DESTINATION_NOT_INITED 8104
#define VE_RECEIVE_SOCKETS_CONFLICT 8105 #define VE_RECEIVE_SOCKETS_CONFLICT 8105
#define VE_SEND_SOCKETS_CONFLICT 8106 #define VE_SEND_SOCKETS_CONFLICT 8106
#define VE_TYPING_NOISE_WARNING 8107 // 8107 is not used
#define VE_NOISE_WARNING 8109 #define VE_NOISE_WARNING 8109
#define VE_CANNOT_GET_SEND_CODEC 8110 #define VE_CANNOT_GET_SEND_CODEC 8110
#define VE_CANNOT_GET_REC_CODEC 8111 #define VE_CANNOT_GET_REC_CODEC 8111
@ -87,7 +87,7 @@
#define VE_CANNOT_SET_SECONDARY_SEND_CODEC 8113 #define VE_CANNOT_SET_SECONDARY_SEND_CODEC 8113
#define VE_CANNOT_GET_SECONDARY_SEND_CODEC 8114 #define VE_CANNOT_GET_SECONDARY_SEND_CODEC 8114
#define VE_CANNOT_REMOVE_SECONDARY_SEND_CODEC 8115 #define VE_CANNOT_REMOVE_SECONDARY_SEND_CODEC 8115
#define VE_TYPING_NOISE_OFF_WARNING 8116 // 8116 is not used
// Errors causing limited functionality // Errors causing limited functionality
#define VE_RTCP_SOCKET_ERROR 9001 #define VE_RTCP_SOCKET_ERROR 9001

View File

@ -1,40 +0,0 @@
/*
* Copyright (c) 2012 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 VOICE_ENGINE_MONITOR_MODULE_H_
#define VOICE_ENGINE_MONITOR_MODULE_H_
#include "modules/include/module.h"
namespace webrtc {
namespace voe {
// When associated with a ProcessThread, calls a callback method
// |OnPeriodicProcess()| implemented by the |Observer|.
// TODO(tommi): This could be replaced with PostDelayedTask().
// Better yet, delete it and delete code related to |_saturationWarning|
// in TransmitMixer (and the OnPeriodicProcess callback).
template <typename Observer>
class MonitorModule : public Module {
public:
explicit MonitorModule(Observer* observer) : observer_(observer) {}
~MonitorModule() override {}
private:
int64_t TimeUntilNextProcess() override { return 1000; }
void Process() override { observer_->OnPeriodicProcess(); }
Observer* const observer_;
};
} // namespace voe
} // namespace webrtc
#endif // VOICE_ENGINE_MONITOR_MODULE

View File

@ -30,8 +30,7 @@ SharedData::SharedData()
encoder_queue_("AudioEncoderQueue") { encoder_queue_("AudioEncoderQueue") {
Trace::CreateTrace(); Trace::CreateTrace();
if (TransmitMixer::Create(_transmitMixerPtr, _gInstanceCounter) == 0) { if (TransmitMixer::Create(_transmitMixerPtr, _gInstanceCounter) == 0) {
_transmitMixerPtr->SetEngineInformation(*_moduleProcessThreadPtr, _transmitMixerPtr->SetEngineInformation(&_channelManager);
_engineStatistics, _channelManager);
} }
} }

View File

@ -22,50 +22,11 @@
#include "voice_engine/channel_manager.h" #include "voice_engine/channel_manager.h"
#include "voice_engine/statistics.h" #include "voice_engine/statistics.h"
#include "voice_engine/utility.h" #include "voice_engine/utility.h"
#include "voice_engine/voe_base_impl.h"
namespace webrtc { namespace webrtc {
namespace voe { namespace voe {
#if WEBRTC_VOICE_ENGINE_TYPING_DETECTION // TODO(solenberg): The thread safety in this class is dubious.
// TODO(ajm): The thread safety of this is dubious...
void TransmitMixer::OnPeriodicProcess()
{
WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, -1),
"TransmitMixer::OnPeriodicProcess()");
bool send_typing_noise_warning = false;
bool typing_noise_detected = false;
{
rtc::CritScope cs(&_critSect);
if (_typingNoiseWarningPending) {
send_typing_noise_warning = true;
typing_noise_detected = _typingNoiseDetected;
_typingNoiseWarningPending = false;
}
}
if (send_typing_noise_warning) {
rtc::CritScope cs(&_callbackCritSect);
if (_voiceEngineObserverPtr) {
if (typing_noise_detected) {
WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
"TransmitMixer::OnPeriodicProcess() => "
"CallbackOnError(VE_TYPING_NOISE_WARNING)");
_voiceEngineObserverPtr->CallbackOnError(
-1,
VE_TYPING_NOISE_WARNING);
} else {
WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
"TransmitMixer::OnPeriodicProcess() => "
"CallbackOnError(VE_TYPING_NOISE_OFF_WARNING)");
_voiceEngineObserverPtr->CallbackOnError(
-1,
VE_TYPING_NOISE_OFF_WARNING);
}
}
}
}
#endif // WEBRTC_VOICE_ENGINE_TYPING_DETECTION
int32_t int32_t
TransmitMixer::Create(TransmitMixer*& mixer, uint32_t instanceId) TransmitMixer::Create(TransmitMixer*& mixer, uint32_t instanceId)
@ -94,59 +55,16 @@ TransmitMixer::Destroy(TransmitMixer*& mixer)
} }
TransmitMixer::TransmitMixer(uint32_t instanceId) : TransmitMixer::TransmitMixer(uint32_t instanceId) :
#if WEBRTC_VOICE_ENGINE_TYPING_DETECTION
_monitorModule(this),
#endif
_instanceId(instanceId) _instanceId(instanceId)
{ {
WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId, -1), WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId, -1),
"TransmitMixer::TransmitMixer() - ctor"); "TransmitMixer::TransmitMixer() - ctor");
} }
TransmitMixer::~TransmitMixer() TransmitMixer::~TransmitMixer() = default;
{
WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId, -1),
"TransmitMixer::~TransmitMixer() - dtor");
#if WEBRTC_VOICE_ENGINE_TYPING_DETECTION
if (_processThreadPtr)
_processThreadPtr->DeRegisterModule(&_monitorModule);
#endif
}
int32_t void TransmitMixer::SetEngineInformation(ChannelManager* channelManager) {
TransmitMixer::SetEngineInformation(ProcessThread& processThread, _channelManagerPtr = channelManager;
Statistics& engineStatistics,
ChannelManager& channelManager)
{
WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
"TransmitMixer::SetEngineInformation()");
_processThreadPtr = &processThread;
_engineStatisticsPtr = &engineStatistics;
_channelManagerPtr = &channelManager;
#if WEBRTC_VOICE_ENGINE_TYPING_DETECTION
_processThreadPtr->RegisterModule(&_monitorModule, RTC_FROM_HERE);
#endif
return 0;
}
int32_t
TransmitMixer::RegisterVoiceEngineObserver(VoiceEngineObserver& observer)
{
WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
"TransmitMixer::RegisterVoiceEngineObserver()");
rtc::CritScope cs(&_callbackCritSect);
if (_voiceEngineObserverPtr)
{
_engineStatisticsPtr->SetLastError(
VE_INVALID_OPERATION, kTraceError,
"RegisterVoiceEngineObserver() observer already enabled");
return -1;
}
_voiceEngineObserverPtr = &observer;
return 0;
} }
int32_t int32_t
@ -323,27 +241,18 @@ void TransmitMixer::ProcessAudio(int delay_ms, int clock_drift,
} }
#if WEBRTC_VOICE_ENGINE_TYPING_DETECTION #if WEBRTC_VOICE_ENGINE_TYPING_DETECTION
void TransmitMixer::TypingDetection(bool keyPressed) void TransmitMixer::TypingDetection(bool key_pressed)
{ {
// We let the VAD determine if we're using this feature or not. // We let the VAD determine if we're using this feature or not.
if (_audioFrame.vad_activity_ == AudioFrame::kVadUnknown) { if (_audioFrame.vad_activity_ == AudioFrame::kVadUnknown) {
return; return;
} }
bool vadActive = _audioFrame.vad_activity_ == AudioFrame::kVadActive; bool vad_active = _audioFrame.vad_activity_ == AudioFrame::kVadActive;
if (_typingDetection.Process(keyPressed, vadActive)) { bool typing_detected = typing_detection_.Process(key_pressed, vad_active);
rtc::CritScope cs(&_critSect);
_typingNoiseWarningPending = true; rtc::CritScope cs(&lock_);
_typingNoiseDetected = true; typing_noise_detected_ = typing_detected;
} else {
rtc::CritScope cs(&_critSect);
// If there is already a warning pending, do not change the state.
// Otherwise set a warning pending if last callback was for noise detected.
if (!_typingNoiseWarningPending && _typingNoiseDetected) {
_typingNoiseWarningPending = true;
_typingNoiseDetected = false;
}
}
} }
#endif #endif
@ -355,5 +264,10 @@ bool TransmitMixer::IsStereoChannelSwappingEnabled() {
return swap_stereo_channels_; return swap_stereo_channels_;
} }
bool TransmitMixer::typing_noise_detected() const {
rtc::CritScope cs(&lock_);
return typing_noise_detected_;
}
} // namespace voe } // namespace voe
} // namespace webrtc } // namespace webrtc

View File

@ -20,7 +20,6 @@
#include "rtc_base/criticalsection.h" #include "rtc_base/criticalsection.h"
#include "voice_engine/audio_level.h" #include "voice_engine/audio_level.h"
#include "voice_engine/include/voe_base.h" #include "voice_engine/include/voe_base.h"
#include "voice_engine/monitor_module.h"
#include "voice_engine/voice_engine_defines.h" #include "voice_engine/voice_engine_defines.h"
#if !defined(WEBRTC_ANDROID) && !defined(WEBRTC_IOS) #if !defined(WEBRTC_ANDROID) && !defined(WEBRTC_IOS)
@ -45,12 +44,9 @@ public:
static void Destroy(TransmitMixer*& mixer); static void Destroy(TransmitMixer*& mixer);
int32_t SetEngineInformation(ProcessThread& processThread, void SetEngineInformation(ChannelManager* channelManager);
Statistics& engineStatistics,
ChannelManager& channelManager);
int32_t SetAudioProcessingModule( int32_t SetAudioProcessingModule(AudioProcessing* audioProcessingModule);
AudioProcessing* audioProcessingModule);
int32_t PrepareDemux(const void* audioSamples, int32_t PrepareDemux(const void* audioSamples,
size_t nSamples, size_t nSamples,
@ -82,25 +78,17 @@ public:
// 'virtual' to allow mocking. // 'virtual' to allow mocking.
virtual double GetTotalInputDuration() const; virtual double GetTotalInputDuration() const;
int32_t RegisterVoiceEngineObserver(VoiceEngineObserver& observer);
virtual ~TransmitMixer(); virtual ~TransmitMixer();
#if WEBRTC_VOICE_ENGINE_TYPING_DETECTION
// Periodic callback from the MonitorModule.
void OnPeriodicProcess();
#endif
// Virtual to allow mocking. // Virtual to allow mocking.
virtual void EnableStereoChannelSwapping(bool enable); virtual void EnableStereoChannelSwapping(bool enable);
bool IsStereoChannelSwappingEnabled(); bool IsStereoChannelSwappingEnabled();
// Virtual to allow mocking.
virtual bool typing_noise_detected() const;
protected: protected:
#if WEBRTC_VOICE_ENGINE_TYPING_DETECTION
TransmitMixer() : _monitorModule(this) {}
#else
TransmitMixer() = default; TransmitMixer() = default;
#endif
private: private:
TransmitMixer(uint32_t instanceId); TransmitMixer(uint32_t instanceId);
@ -118,31 +106,25 @@ private:
bool key_pressed); bool key_pressed);
#if WEBRTC_VOICE_ENGINE_TYPING_DETECTION #if WEBRTC_VOICE_ENGINE_TYPING_DETECTION
void TypingDetection(bool keyPressed); void TypingDetection(bool key_pressed);
#endif #endif
// uses // uses
Statistics* _engineStatisticsPtr = nullptr;
ChannelManager* _channelManagerPtr = nullptr; ChannelManager* _channelManagerPtr = nullptr;
AudioProcessing* audioproc_ = nullptr; AudioProcessing* audioproc_ = nullptr;
VoiceEngineObserver* _voiceEngineObserverPtr = nullptr;
ProcessThread* _processThreadPtr = nullptr;
// owns // owns
AudioFrame _audioFrame; AudioFrame _audioFrame;
PushResampler<int16_t> resampler_; // ADM sample rate -> mixing rate PushResampler<int16_t> resampler_; // ADM sample rate -> mixing rate
voe::AudioLevel _audioLevel; voe::AudioLevel _audioLevel;
// protect file instances and their variables in MixedParticipants()
rtc::CriticalSection _critSect;
rtc::CriticalSection _callbackCritSect;
#if WEBRTC_VOICE_ENGINE_TYPING_DETECTION #if WEBRTC_VOICE_ENGINE_TYPING_DETECTION
MonitorModule<TransmitMixer> _monitorModule; webrtc::TypingDetection typing_detection_;
webrtc::TypingDetection _typingDetection;
bool _typingNoiseWarningPending = false;
bool _typingNoiseDetected = false;
#endif #endif
rtc::CriticalSection lock_;
bool typing_noise_detected_ RTC_GUARDED_BY(lock_) = false;
int _instanceId = 0; int _instanceId = 0;
uint32_t _captureLevel = 0; uint32_t _captureLevel = 0;
bool stereo_codec_ = false; bool stereo_codec_ = false;

View File

@ -35,8 +35,7 @@ VoEBase* VoEBase::GetInterface(VoiceEngine* voiceEngine) {
} }
VoEBaseImpl::VoEBaseImpl(voe::SharedData* shared) VoEBaseImpl::VoEBaseImpl(voe::SharedData* shared)
: voiceEngineObserverPtr_(nullptr), : shared_(shared) {}
shared_(shared) {}
VoEBaseImpl::~VoEBaseImpl() { VoEBaseImpl::~VoEBaseImpl() {
TerminateInternal(); TerminateInternal();
@ -44,34 +43,20 @@ VoEBaseImpl::~VoEBaseImpl() {
void VoEBaseImpl::OnErrorIsReported(const ErrorCode error) { void VoEBaseImpl::OnErrorIsReported(const ErrorCode error) {
rtc::CritScope cs(&callbackCritSect_); rtc::CritScope cs(&callbackCritSect_);
int errCode = 0;
if (error == AudioDeviceObserver::kRecordingError) { if (error == AudioDeviceObserver::kRecordingError) {
errCode = VE_RUNTIME_REC_ERROR;
LOG_F(LS_ERROR) << "VE_RUNTIME_REC_ERROR"; LOG_F(LS_ERROR) << "VE_RUNTIME_REC_ERROR";
} else if (error == AudioDeviceObserver::kPlayoutError) { } else if (error == AudioDeviceObserver::kPlayoutError) {
errCode = VE_RUNTIME_PLAY_ERROR;
LOG_F(LS_ERROR) << "VE_RUNTIME_PLAY_ERROR"; LOG_F(LS_ERROR) << "VE_RUNTIME_PLAY_ERROR";
} }
if (voiceEngineObserverPtr_) {
// Deliver callback (-1 <=> no channel dependency)
voiceEngineObserverPtr_->CallbackOnError(-1, errCode);
}
} }
void VoEBaseImpl::OnWarningIsReported(const WarningCode warning) { void VoEBaseImpl::OnWarningIsReported(const WarningCode warning) {
rtc::CritScope cs(&callbackCritSect_); rtc::CritScope cs(&callbackCritSect_);
int warningCode = 0;
if (warning == AudioDeviceObserver::kRecordingWarning) { if (warning == AudioDeviceObserver::kRecordingWarning) {
warningCode = VE_RUNTIME_REC_WARNING;
LOG_F(LS_WARNING) << "VE_RUNTIME_REC_WARNING"; LOG_F(LS_WARNING) << "VE_RUNTIME_REC_WARNING";
} else if (warning == AudioDeviceObserver::kPlayoutWarning) { } else if (warning == AudioDeviceObserver::kPlayoutWarning) {
warningCode = VE_RUNTIME_PLAY_WARNING;
LOG_F(LS_WARNING) << "VE_RUNTIME_PLAY_WARNING"; LOG_F(LS_WARNING) << "VE_RUNTIME_PLAY_WARNING";
} }
if (voiceEngineObserverPtr_) {
// Deliver callback (-1 <=> no channel dependency)
voiceEngineObserverPtr_->CallbackOnError(-1, warningCode);
}
} }
int32_t VoEBaseImpl::RecordedDataIsAvailable( int32_t VoEBaseImpl::RecordedDataIsAvailable(
@ -175,45 +160,6 @@ void VoEBaseImpl::PullRenderData(int bits_per_sample,
RTC_NOTREACHED(); RTC_NOTREACHED();
} }
int VoEBaseImpl::RegisterVoiceEngineObserver(VoiceEngineObserver& observer) {
rtc::CritScope cs(&callbackCritSect_);
if (voiceEngineObserverPtr_) {
shared_->SetLastError(
VE_INVALID_OPERATION, kTraceError,
"RegisterVoiceEngineObserver() observer already enabled");
return -1;
}
// Register the observer in all active channels
for (voe::ChannelManager::Iterator it(&shared_->channel_manager());
it.IsValid(); it.Increment()) {
it.GetChannel()->RegisterVoiceEngineObserver(observer);
}
shared_->transmit_mixer()->RegisterVoiceEngineObserver(observer);
voiceEngineObserverPtr_ = &observer;
return 0;
}
int VoEBaseImpl::DeRegisterVoiceEngineObserver() {
rtc::CritScope cs(&callbackCritSect_);
if (!voiceEngineObserverPtr_) {
shared_->SetLastError(
VE_INVALID_OPERATION, kTraceError,
"DeRegisterVoiceEngineObserver() observer already disabled");
return 0;
}
voiceEngineObserverPtr_ = nullptr;
// Deregister the observer in all active channels
for (voe::ChannelManager::Iterator it(&shared_->channel_manager());
it.IsValid(); it.Increment()) {
it.GetChannel()->DeRegisterVoiceEngineObserver();
}
return 0;
}
int VoEBaseImpl::Init( int VoEBaseImpl::Init(
AudioDeviceModule* external_adm, AudioDeviceModule* external_adm,
AudioProcessing* audio_processing, AudioProcessing* audio_processing,
@ -411,8 +357,7 @@ int VoEBaseImpl::InitializeChannel(voe::ChannelOwner* channel_owner) {
if (channel_owner->channel()->SetEngineInformation( if (channel_owner->channel()->SetEngineInformation(
shared_->statistics(), shared_->statistics(),
*shared_->process_thread(), *shared_->audio_device(), *shared_->process_thread(), *shared_->audio_device(),
voiceEngineObserverPtr_, &callbackCritSect_, &callbackCritSect_, shared_->encoder_queue()) != 0) {
shared_->encoder_queue()) != 0) {
shared_->SetLastError( shared_->SetLastError(
VE_CHANNEL_NOT_CREATED, kTraceError, VE_CHANNEL_NOT_CREATED, kTraceError,
"CreateChannel() failed to associate engine and channel." "CreateChannel() failed to associate engine and channel."

View File

@ -25,9 +25,6 @@ class VoEBaseImpl : public VoEBase,
public AudioTransport, public AudioTransport,
public AudioDeviceObserver { public AudioDeviceObserver {
public: public:
int RegisterVoiceEngineObserver(VoiceEngineObserver& observer) override;
int DeRegisterVoiceEngineObserver() override;
int Init( int Init(
AudioDeviceModule* external_adm, AudioDeviceModule* external_adm,
AudioProcessing* audio_processing, AudioProcessing* audio_processing,
@ -107,7 +104,6 @@ class VoEBaseImpl : public VoEBase,
// Initialize channel by setting Engine Information then initializing // Initialize channel by setting Engine Information then initializing
// channel. // channel.
int InitializeChannel(voe::ChannelOwner* channel_owner); int InitializeChannel(voe::ChannelOwner* channel_owner);
VoiceEngineObserver* voiceEngineObserverPtr_;
rtc::CriticalSection callbackCritSect_; rtc::CriticalSection callbackCritSect_;
rtc::scoped_refptr<AudioDecoderFactory> decoder_factory_; rtc::scoped_refptr<AudioDecoderFactory> decoder_factory_;