APM: Add build flag to allow building WebRTC without APM
This CL adds a build flag to allow building the non-test parts of WebRTC without the audio processing module. The CL also ensures that the WebRTC code correctly handles the case when no APM is available. Bug: webrtc:5298 Change-Id: I5c8b5d1f7115e5cce2af4c2b5ff701fa1c54e49e Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/171509 Commit-Queue: Per Åhgren <peah@webrtc.org> Reviewed-by: Sam Zackrisson <saza@webrtc.org> Reviewed-by: Karl Wiberg <kwiberg@webrtc.org> Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31133}
This commit is contained in:
parent
86bd33a1e7
commit
cc73ed3e70
4
BUILD.gn
4
BUILD.gn
@ -281,6 +281,10 @@ config("common_config") {
|
|||||||
defines += [ "WEBRTC_EXCLUDE_TRANSIENT_SUPPRESSOR" ]
|
defines += [ "WEBRTC_EXCLUDE_TRANSIENT_SUPPRESSOR" ]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rtc_exclude_audio_processing_module) {
|
||||||
|
defines += [ "WEBRTC_EXCLUDE_AUDIO_PROCESSING_MODULE" ]
|
||||||
|
}
|
||||||
|
|
||||||
cflags = []
|
cflags = []
|
||||||
|
|
||||||
if (build_with_chromium) {
|
if (build_with_chromium) {
|
||||||
|
|||||||
@ -75,15 +75,21 @@ const NetworkStatistics kNetworkStats = {
|
|||||||
const AudioDecodingCallStats kAudioDecodeStats = MakeAudioDecodeStatsForTest();
|
const AudioDecodingCallStats kAudioDecodeStats = MakeAudioDecodeStatsForTest();
|
||||||
|
|
||||||
struct ConfigHelper {
|
struct ConfigHelper {
|
||||||
ConfigHelper() : ConfigHelper(new rtc::RefCountedObject<MockAudioMixer>()) {}
|
explicit ConfigHelper(bool use_null_audio_processing)
|
||||||
|
: ConfigHelper(new rtc::RefCountedObject<MockAudioMixer>(),
|
||||||
|
use_null_audio_processing) {}
|
||||||
|
|
||||||
explicit ConfigHelper(rtc::scoped_refptr<MockAudioMixer> audio_mixer)
|
ConfigHelper(rtc::scoped_refptr<MockAudioMixer> audio_mixer,
|
||||||
|
bool use_null_audio_processing)
|
||||||
: audio_mixer_(audio_mixer) {
|
: audio_mixer_(audio_mixer) {
|
||||||
using ::testing::Invoke;
|
using ::testing::Invoke;
|
||||||
|
|
||||||
AudioState::Config config;
|
AudioState::Config config;
|
||||||
config.audio_mixer = audio_mixer_;
|
config.audio_mixer = audio_mixer_;
|
||||||
config.audio_processing = new rtc::RefCountedObject<MockAudioProcessing>();
|
config.audio_processing =
|
||||||
|
use_null_audio_processing
|
||||||
|
? nullptr
|
||||||
|
: new rtc::RefCountedObject<MockAudioProcessing>();
|
||||||
config.audio_device_module =
|
config.audio_device_module =
|
||||||
new rtc::RefCountedObject<testing::NiceMock<MockAudioDeviceModule>>();
|
new rtc::RefCountedObject<testing::NiceMock<MockAudioDeviceModule>>();
|
||||||
audio_state_ = AudioState::Create(config);
|
audio_state_ = AudioState::Create(config);
|
||||||
@ -230,12 +236,15 @@ TEST(AudioReceiveStreamTest, ConfigToString) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(AudioReceiveStreamTest, ConstructDestruct) {
|
TEST(AudioReceiveStreamTest, ConstructDestruct) {
|
||||||
ConfigHelper helper;
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
ConfigHelper helper(use_null_audio_processing);
|
||||||
auto recv_stream = helper.CreateAudioReceiveStream();
|
auto recv_stream = helper.CreateAudioReceiveStream();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(AudioReceiveStreamTest, ReceiveRtpPacket) {
|
TEST(AudioReceiveStreamTest, ReceiveRtpPacket) {
|
||||||
ConfigHelper helper;
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
ConfigHelper helper(use_null_audio_processing);
|
||||||
helper.config().rtp.transport_cc = true;
|
helper.config().rtp.transport_cc = true;
|
||||||
auto recv_stream = helper.CreateAudioReceiveStream();
|
auto recv_stream = helper.CreateAudioReceiveStream();
|
||||||
const int kTransportSequenceNumberValue = 1234;
|
const int kTransportSequenceNumberValue = 1234;
|
||||||
@ -252,9 +261,11 @@ TEST(AudioReceiveStreamTest, ReceiveRtpPacket) {
|
|||||||
|
|
||||||
recv_stream->OnRtpPacket(parsed_packet);
|
recv_stream->OnRtpPacket(parsed_packet);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(AudioReceiveStreamTest, ReceiveRtcpPacket) {
|
TEST(AudioReceiveStreamTest, ReceiveRtcpPacket) {
|
||||||
ConfigHelper helper;
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
ConfigHelper helper(use_null_audio_processing);
|
||||||
helper.config().rtp.transport_cc = true;
|
helper.config().rtp.transport_cc = true;
|
||||||
auto recv_stream = helper.CreateAudioReceiveStream();
|
auto recv_stream = helper.CreateAudioReceiveStream();
|
||||||
std::vector<uint8_t> rtcp_packet = CreateRtcpSenderReport();
|
std::vector<uint8_t> rtcp_packet = CreateRtcpSenderReport();
|
||||||
@ -263,9 +274,11 @@ TEST(AudioReceiveStreamTest, ReceiveRtcpPacket) {
|
|||||||
.WillOnce(Return());
|
.WillOnce(Return());
|
||||||
recv_stream->DeliverRtcp(&rtcp_packet[0], rtcp_packet.size());
|
recv_stream->DeliverRtcp(&rtcp_packet[0], rtcp_packet.size());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(AudioReceiveStreamTest, GetStats) {
|
TEST(AudioReceiveStreamTest, GetStats) {
|
||||||
ConfigHelper helper;
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
ConfigHelper helper(use_null_audio_processing);
|
||||||
auto recv_stream = helper.CreateAudioReceiveStream();
|
auto recv_stream = helper.CreateAudioReceiveStream();
|
||||||
helper.SetupMockForGetStats();
|
helper.SetupMockForGetStats();
|
||||||
AudioReceiveStream::Stats stats = recv_stream->GetStats();
|
AudioReceiveStream::Stats stats = recv_stream->GetStats();
|
||||||
@ -324,18 +337,22 @@ TEST(AudioReceiveStreamTest, GetStats) {
|
|||||||
stats.capture_start_ntp_time_ms);
|
stats.capture_start_ntp_time_ms);
|
||||||
EXPECT_EQ(kPlayoutNtpTimestampMs, stats.estimated_playout_ntp_timestamp_ms);
|
EXPECT_EQ(kPlayoutNtpTimestampMs, stats.estimated_playout_ntp_timestamp_ms);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(AudioReceiveStreamTest, SetGain) {
|
TEST(AudioReceiveStreamTest, SetGain) {
|
||||||
ConfigHelper helper;
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
ConfigHelper helper(use_null_audio_processing);
|
||||||
auto recv_stream = helper.CreateAudioReceiveStream();
|
auto recv_stream = helper.CreateAudioReceiveStream();
|
||||||
EXPECT_CALL(*helper.channel_receive(),
|
EXPECT_CALL(*helper.channel_receive(),
|
||||||
SetChannelOutputVolumeScaling(FloatEq(0.765f)));
|
SetChannelOutputVolumeScaling(FloatEq(0.765f)));
|
||||||
recv_stream->SetGain(0.765f);
|
recv_stream->SetGain(0.765f);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(AudioReceiveStreamTest, StreamsShouldBeAddedToMixerOnceOnStart) {
|
TEST(AudioReceiveStreamTest, StreamsShouldBeAddedToMixerOnceOnStart) {
|
||||||
ConfigHelper helper1;
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
ConfigHelper helper2(helper1.audio_mixer());
|
ConfigHelper helper1(use_null_audio_processing);
|
||||||
|
ConfigHelper helper2(helper1.audio_mixer(), use_null_audio_processing);
|
||||||
auto recv_stream1 = helper1.CreateAudioReceiveStream();
|
auto recv_stream1 = helper1.CreateAudioReceiveStream();
|
||||||
auto recv_stream2 = helper2.CreateAudioReceiveStream();
|
auto recv_stream2 = helper2.CreateAudioReceiveStream();
|
||||||
|
|
||||||
@ -361,15 +378,19 @@ TEST(AudioReceiveStreamTest, StreamsShouldBeAddedToMixerOnceOnStart) {
|
|||||||
// Stop stream before it is being destructed.
|
// Stop stream before it is being destructed.
|
||||||
recv_stream2->Stop();
|
recv_stream2->Stop();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(AudioReceiveStreamTest, ReconfigureWithSameConfig) {
|
TEST(AudioReceiveStreamTest, ReconfigureWithSameConfig) {
|
||||||
ConfigHelper helper;
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
ConfigHelper helper(use_null_audio_processing);
|
||||||
auto recv_stream = helper.CreateAudioReceiveStream();
|
auto recv_stream = helper.CreateAudioReceiveStream();
|
||||||
recv_stream->Reconfigure(helper.config());
|
recv_stream->Reconfigure(helper.config());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(AudioReceiveStreamTest, ReconfigureWithUpdatedConfig) {
|
TEST(AudioReceiveStreamTest, ReconfigureWithUpdatedConfig) {
|
||||||
ConfigHelper helper;
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
ConfigHelper helper(use_null_audio_processing);
|
||||||
auto recv_stream = helper.CreateAudioReceiveStream();
|
auto recv_stream = helper.CreateAudioReceiveStream();
|
||||||
|
|
||||||
auto new_config = helper.config();
|
auto new_config = helper.config();
|
||||||
@ -388,9 +409,11 @@ TEST(AudioReceiveStreamTest, ReconfigureWithUpdatedConfig) {
|
|||||||
|
|
||||||
recv_stream->Reconfigure(new_config);
|
recv_stream->Reconfigure(new_config);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(AudioReceiveStreamTest, ReconfigureWithFrameDecryptor) {
|
TEST(AudioReceiveStreamTest, ReconfigureWithFrameDecryptor) {
|
||||||
ConfigHelper helper;
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
ConfigHelper helper(use_null_audio_processing);
|
||||||
auto recv_stream = helper.CreateAudioReceiveStream();
|
auto recv_stream = helper.CreateAudioReceiveStream();
|
||||||
|
|
||||||
auto new_config_0 = helper.config();
|
auto new_config_0 = helper.config();
|
||||||
@ -407,6 +430,7 @@ TEST(AudioReceiveStreamTest, ReconfigureWithFrameDecryptor) {
|
|||||||
new_config_1.crypto_options.sframe.require_frame_encryption = true;
|
new_config_1.crypto_options.sframe.require_frame_encryption = true;
|
||||||
recv_stream->Reconfigure(new_config_1);
|
recv_stream->Reconfigure(new_config_1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace test
|
} // namespace test
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -490,9 +490,11 @@ webrtc::AudioSendStream::Stats AudioSendStream::GetStats(
|
|||||||
|
|
||||||
stats.typing_noise_detected = audio_state()->typing_noise_detected();
|
stats.typing_noise_detected = audio_state()->typing_noise_detected();
|
||||||
stats.ana_statistics = channel_send_->GetANAStatistics();
|
stats.ana_statistics = channel_send_->GetANAStatistics();
|
||||||
RTC_DCHECK(audio_state_->audio_processing());
|
|
||||||
stats.apm_statistics =
|
AudioProcessing* ap = audio_state_->audio_processing();
|
||||||
audio_state_->audio_processing()->GetStatistics(has_remote_tracks);
|
if (ap) {
|
||||||
|
stats.apm_statistics = ap->GetStatistics(has_remote_tracks);
|
||||||
|
}
|
||||||
|
|
||||||
stats.report_block_datas = std::move(call_stats.report_block_datas);
|
stats.report_block_datas = std::move(call_stats.report_block_datas);
|
||||||
|
|
||||||
|
|||||||
@ -141,11 +141,16 @@ rtc::scoped_refptr<MockAudioEncoderFactory> SetupEncoderFactoryMock() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct ConfigHelper {
|
struct ConfigHelper {
|
||||||
ConfigHelper(bool audio_bwe_enabled, bool expect_set_encoder_call)
|
ConfigHelper(bool audio_bwe_enabled,
|
||||||
|
bool expect_set_encoder_call,
|
||||||
|
bool use_null_audio_processing)
|
||||||
: clock_(1000000),
|
: clock_(1000000),
|
||||||
task_queue_factory_(CreateDefaultTaskQueueFactory()),
|
task_queue_factory_(CreateDefaultTaskQueueFactory()),
|
||||||
stream_config_(/*send_transport=*/nullptr),
|
stream_config_(/*send_transport=*/nullptr),
|
||||||
audio_processing_(new rtc::RefCountedObject<MockAudioProcessing>()),
|
audio_processing_(
|
||||||
|
use_null_audio_processing
|
||||||
|
? nullptr
|
||||||
|
: new rtc::RefCountedObject<MockAudioProcessing>()),
|
||||||
bitrate_allocator_(&limit_observer_),
|
bitrate_allocator_(&limit_observer_),
|
||||||
worker_queue_(task_queue_factory_->CreateTaskQueue(
|
worker_queue_(task_queue_factory_->CreateTaskQueue(
|
||||||
"ConfigHelper_worker_queue",
|
"ConfigHelper_worker_queue",
|
||||||
@ -273,7 +278,7 @@ struct ConfigHelper {
|
|||||||
.WillOnce(Return(true));
|
.WillOnce(Return(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetupMockForGetStats() {
|
void SetupMockForGetStats(bool use_null_audio_processing) {
|
||||||
using ::testing::DoAll;
|
using ::testing::DoAll;
|
||||||
using ::testing::SetArgPointee;
|
using ::testing::SetArgPointee;
|
||||||
using ::testing::SetArgReferee;
|
using ::testing::SetArgReferee;
|
||||||
@ -305,10 +310,13 @@ struct ConfigHelper {
|
|||||||
audio_processing_stats_.residual_echo_likelihood = kResidualEchoLikelihood;
|
audio_processing_stats_.residual_echo_likelihood = kResidualEchoLikelihood;
|
||||||
audio_processing_stats_.residual_echo_likelihood_recent_max =
|
audio_processing_stats_.residual_echo_likelihood_recent_max =
|
||||||
kResidualEchoLikelihoodMax;
|
kResidualEchoLikelihoodMax;
|
||||||
|
if (!use_null_audio_processing) {
|
||||||
|
ASSERT_TRUE(audio_processing_);
|
||||||
EXPECT_CALL(*audio_processing_, GetStatistics(true))
|
EXPECT_CALL(*audio_processing_, GetStatistics(true))
|
||||||
.WillRepeatedly(Return(audio_processing_stats_));
|
.WillRepeatedly(Return(audio_processing_stats_));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TaskQueueForTest* worker() { return &worker_queue_; }
|
TaskQueueForTest* worker() { return &worker_queue_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -381,41 +389,52 @@ TEST(AudioSendStreamTest, ConfigToString) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(AudioSendStreamTest, ConstructDestruct) {
|
TEST(AudioSendStreamTest, ConstructDestruct) {
|
||||||
ConfigHelper helper(false, true);
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
ConfigHelper helper(false, true, use_null_audio_processing);
|
||||||
auto send_stream = helper.CreateAudioSendStream();
|
auto send_stream = helper.CreateAudioSendStream();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(AudioSendStreamTest, SendTelephoneEvent) {
|
TEST(AudioSendStreamTest, SendTelephoneEvent) {
|
||||||
ConfigHelper helper(false, true);
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
ConfigHelper helper(false, true, use_null_audio_processing);
|
||||||
auto send_stream = helper.CreateAudioSendStream();
|
auto send_stream = helper.CreateAudioSendStream();
|
||||||
helper.SetupMockForSendTelephoneEvent();
|
helper.SetupMockForSendTelephoneEvent();
|
||||||
EXPECT_TRUE(send_stream->SendTelephoneEvent(
|
EXPECT_TRUE(send_stream->SendTelephoneEvent(
|
||||||
kTelephoneEventPayloadType, kTelephoneEventPayloadFrequency,
|
kTelephoneEventPayloadType, kTelephoneEventPayloadFrequency,
|
||||||
kTelephoneEventCode, kTelephoneEventDuration));
|
kTelephoneEventCode, kTelephoneEventDuration));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(AudioSendStreamTest, SetMuted) {
|
TEST(AudioSendStreamTest, SetMuted) {
|
||||||
ConfigHelper helper(false, true);
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
ConfigHelper helper(false, true, use_null_audio_processing);
|
||||||
auto send_stream = helper.CreateAudioSendStream();
|
auto send_stream = helper.CreateAudioSendStream();
|
||||||
EXPECT_CALL(*helper.channel_send(), SetInputMute(true));
|
EXPECT_CALL(*helper.channel_send(), SetInputMute(true));
|
||||||
send_stream->SetMuted(true);
|
send_stream->SetMuted(true);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(AudioSendStreamTest, AudioBweCorrectObjectsOnChannelProxy) {
|
TEST(AudioSendStreamTest, AudioBweCorrectObjectsOnChannelProxy) {
|
||||||
ScopedFieldTrials field_trials("WebRTC-Audio-SendSideBwe/Enabled/");
|
ScopedFieldTrials field_trials("WebRTC-Audio-SendSideBwe/Enabled/");
|
||||||
ConfigHelper helper(true, true);
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
ConfigHelper helper(true, true, use_null_audio_processing);
|
||||||
auto send_stream = helper.CreateAudioSendStream();
|
auto send_stream = helper.CreateAudioSendStream();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(AudioSendStreamTest, NoAudioBweCorrectObjectsOnChannelProxy) {
|
TEST(AudioSendStreamTest, NoAudioBweCorrectObjectsOnChannelProxy) {
|
||||||
ConfigHelper helper(false, true);
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
ConfigHelper helper(false, true, use_null_audio_processing);
|
||||||
auto send_stream = helper.CreateAudioSendStream();
|
auto send_stream = helper.CreateAudioSendStream();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(AudioSendStreamTest, GetStats) {
|
TEST(AudioSendStreamTest, GetStats) {
|
||||||
ConfigHelper helper(false, true);
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
ConfigHelper helper(false, true, use_null_audio_processing);
|
||||||
auto send_stream = helper.CreateAudioSendStream();
|
auto send_stream = helper.CreateAudioSendStream();
|
||||||
helper.SetupMockForGetStats();
|
helper.SetupMockForGetStats(use_null_audio_processing);
|
||||||
AudioSendStream::Stats stats = send_stream->GetStats(true);
|
AudioSendStream::Stats stats = send_stream->GetStats(true);
|
||||||
EXPECT_EQ(kSsrc, stats.local_ssrc);
|
EXPECT_EQ(kSsrc, stats.local_ssrc);
|
||||||
EXPECT_EQ(kCallStats.payload_bytes_sent, stats.payload_bytes_sent);
|
EXPECT_EQ(kCallStats.payload_bytes_sent, stats.payload_bytes_sent);
|
||||||
@ -432,8 +451,11 @@ TEST(AudioSendStreamTest, GetStats) {
|
|||||||
EXPECT_EQ(0, stats.audio_level);
|
EXPECT_EQ(0, stats.audio_level);
|
||||||
EXPECT_EQ(0, stats.total_input_energy);
|
EXPECT_EQ(0, stats.total_input_energy);
|
||||||
EXPECT_EQ(0, stats.total_input_duration);
|
EXPECT_EQ(0, stats.total_input_duration);
|
||||||
|
|
||||||
|
if (!use_null_audio_processing) {
|
||||||
EXPECT_EQ(kEchoDelayMedian, stats.apm_statistics.delay_median_ms);
|
EXPECT_EQ(kEchoDelayMedian, stats.apm_statistics.delay_median_ms);
|
||||||
EXPECT_EQ(kEchoDelayStdDev, stats.apm_statistics.delay_standard_deviation_ms);
|
EXPECT_EQ(kEchoDelayStdDev,
|
||||||
|
stats.apm_statistics.delay_standard_deviation_ms);
|
||||||
EXPECT_EQ(kEchoReturnLoss, stats.apm_statistics.echo_return_loss);
|
EXPECT_EQ(kEchoReturnLoss, stats.apm_statistics.echo_return_loss);
|
||||||
EXPECT_EQ(kEchoReturnLossEnhancement,
|
EXPECT_EQ(kEchoReturnLossEnhancement,
|
||||||
stats.apm_statistics.echo_return_loss_enhancement);
|
stats.apm_statistics.echo_return_loss_enhancement);
|
||||||
@ -445,11 +467,14 @@ TEST(AudioSendStreamTest, GetStats) {
|
|||||||
stats.apm_statistics.residual_echo_likelihood_recent_max);
|
stats.apm_statistics.residual_echo_likelihood_recent_max);
|
||||||
EXPECT_FALSE(stats.typing_noise_detected);
|
EXPECT_FALSE(stats.typing_noise_detected);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(AudioSendStreamTest, GetStatsAudioLevel) {
|
TEST(AudioSendStreamTest, GetStatsAudioLevel) {
|
||||||
ConfigHelper helper(false, true);
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
ConfigHelper helper(false, true, use_null_audio_processing);
|
||||||
auto send_stream = helper.CreateAudioSendStream();
|
auto send_stream = helper.CreateAudioSendStream();
|
||||||
helper.SetupMockForGetStats();
|
helper.SetupMockForGetStats(use_null_audio_processing);
|
||||||
EXPECT_CALL(*helper.channel_send(), ProcessAndEncodeAudioForMock(_))
|
EXPECT_CALL(*helper.channel_send(), ProcessAndEncodeAudioForMock(_))
|
||||||
.Times(AnyNumber());
|
.Times(AnyNumber());
|
||||||
|
|
||||||
@ -461,16 +486,18 @@ TEST(AudioSendStreamTest, GetStatsAudioLevel) {
|
|||||||
constexpr int kAudioFrameDurationMs = 10;
|
constexpr int kAudioFrameDurationMs = 10;
|
||||||
|
|
||||||
// Process 10 audio frames (100 ms) of silence. After this, on the next
|
// Process 10 audio frames (100 ms) of silence. After this, on the next
|
||||||
// (11-th) frame, the audio level will be updated with the maximum audio level
|
// (11-th) frame, the audio level will be updated with the maximum audio
|
||||||
// of the first 11 frames. See AudioLevel.
|
// level of the first 11 frames. See AudioLevel.
|
||||||
for (size_t i = 0; i < 10; ++i) {
|
for (size_t i = 0; i < 10; ++i) {
|
||||||
send_stream->SendAudioData(CreateAudioFrame1kHzSineWave(
|
send_stream->SendAudioData(
|
||||||
kSilentAudioLevel, kAudioFrameDurationMs, kSampleRateHz, kNumChannels));
|
CreateAudioFrame1kHzSineWave(kSilentAudioLevel, kAudioFrameDurationMs,
|
||||||
|
kSampleRateHz, kNumChannels));
|
||||||
}
|
}
|
||||||
AudioSendStream::Stats stats = send_stream->GetStats();
|
AudioSendStream::Stats stats = send_stream->GetStats();
|
||||||
EXPECT_EQ(kSilentAudioLevel, stats.audio_level);
|
EXPECT_EQ(kSilentAudioLevel, stats.audio_level);
|
||||||
EXPECT_NEAR(0.0f, stats.total_input_energy, kTolerance);
|
EXPECT_NEAR(0.0f, stats.total_input_energy, kTolerance);
|
||||||
EXPECT_NEAR(0.1f, stats.total_input_duration, kTolerance); // 100 ms = 0.1 s
|
EXPECT_NEAR(0.1f, stats.total_input_duration,
|
||||||
|
kTolerance); // 100 ms = 0.1 s
|
||||||
|
|
||||||
// Process 10 audio frames (100 ms) of maximum audio level.
|
// Process 10 audio frames (100 ms) of maximum audio level.
|
||||||
// Note that AudioLevel updates the audio level every 11th frame, processing
|
// Note that AudioLevel updates the audio level every 11th frame, processing
|
||||||
@ -481,13 +508,17 @@ TEST(AudioSendStreamTest, GetStatsAudioLevel) {
|
|||||||
}
|
}
|
||||||
stats = send_stream->GetStats();
|
stats = send_stream->GetStats();
|
||||||
EXPECT_EQ(kMaxAudioLevel, stats.audio_level);
|
EXPECT_EQ(kMaxAudioLevel, stats.audio_level);
|
||||||
// Energy increases by energy*duration, where energy is audio level in [0,1].
|
// Energy increases by energy*duration, where energy is audio level in
|
||||||
|
// [0,1].
|
||||||
EXPECT_NEAR(0.1f, stats.total_input_energy, kTolerance); // 0.1 s of max
|
EXPECT_NEAR(0.1f, stats.total_input_energy, kTolerance); // 0.1 s of max
|
||||||
EXPECT_NEAR(0.2f, stats.total_input_duration, kTolerance); // 200 ms = 0.2 s
|
EXPECT_NEAR(0.2f, stats.total_input_duration,
|
||||||
|
kTolerance); // 200 ms = 0.2 s
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(AudioSendStreamTest, SendCodecAppliesAudioNetworkAdaptor) {
|
TEST(AudioSendStreamTest, SendCodecAppliesAudioNetworkAdaptor) {
|
||||||
ConfigHelper helper(false, true);
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
ConfigHelper helper(false, true, use_null_audio_processing);
|
||||||
helper.config().send_codec_spec =
|
helper.config().send_codec_spec =
|
||||||
AudioSendStream::Config::SendCodecSpec(0, kOpusFormat);
|
AudioSendStream::Config::SendCodecSpec(0, kOpusFormat);
|
||||||
const std::string kAnaConfigString = "abcde";
|
const std::string kAnaConfigString = "abcde";
|
||||||
@ -519,11 +550,13 @@ TEST(AudioSendStreamTest, SendCodecAppliesAudioNetworkAdaptor) {
|
|||||||
|
|
||||||
send_stream->Reconfigure(stream_config);
|
send_stream->Reconfigure(stream_config);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// VAD is applied when codec is mono and the CNG frequency matches the codec
|
// VAD is applied when codec is mono and the CNG frequency matches the codec
|
||||||
// clock rate.
|
// clock rate.
|
||||||
TEST(AudioSendStreamTest, SendCodecCanApplyVad) {
|
TEST(AudioSendStreamTest, SendCodecCanApplyVad) {
|
||||||
ConfigHelper helper(false, false);
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
ConfigHelper helper(false, false, use_null_audio_processing);
|
||||||
helper.config().send_codec_spec =
|
helper.config().send_codec_spec =
|
||||||
AudioSendStream::Config::SendCodecSpec(9, kG722Format);
|
AudioSendStream::Config::SendCodecSpec(9, kG722Format);
|
||||||
helper.config().send_codec_spec->cng_payload_type = 105;
|
helper.config().send_codec_spec->cng_payload_type = 105;
|
||||||
@ -540,19 +573,22 @@ TEST(AudioSendStreamTest, SendCodecCanApplyVad) {
|
|||||||
|
|
||||||
auto send_stream = helper.CreateAudioSendStream();
|
auto send_stream = helper.CreateAudioSendStream();
|
||||||
|
|
||||||
// We cannot truly determine if the encoder created is an AudioEncoderCng. It
|
// We cannot truly determine if the encoder created is an AudioEncoderCng.
|
||||||
// is the only reasonable implementation that will return something from
|
// It is the only reasonable implementation that will return something from
|
||||||
// ReclaimContainedEncoders, though.
|
// ReclaimContainedEncoders, though.
|
||||||
ASSERT_TRUE(stolen_encoder);
|
ASSERT_TRUE(stolen_encoder);
|
||||||
EXPECT_FALSE(stolen_encoder->ReclaimContainedEncoders().empty());
|
EXPECT_FALSE(stolen_encoder->ReclaimContainedEncoders().empty());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(AudioSendStreamTest, DoesNotPassHigherBitrateThanMaxBitrate) {
|
TEST(AudioSendStreamTest, DoesNotPassHigherBitrateThanMaxBitrate) {
|
||||||
ConfigHelper helper(false, true);
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
ConfigHelper helper(false, true, use_null_audio_processing);
|
||||||
auto send_stream = helper.CreateAudioSendStream();
|
auto send_stream = helper.CreateAudioSendStream();
|
||||||
EXPECT_CALL(*helper.channel_send(),
|
EXPECT_CALL(
|
||||||
OnBitrateAllocation(Field(
|
*helper.channel_send(),
|
||||||
&BitrateAllocationUpdate::target_bitrate,
|
OnBitrateAllocation(
|
||||||
|
Field(&BitrateAllocationUpdate::target_bitrate,
|
||||||
Eq(DataRate::BitsPerSec(helper.config().max_bitrate_bps)))));
|
Eq(DataRate::BitsPerSec(helper.config().max_bitrate_bps)))));
|
||||||
BitrateAllocationUpdate update;
|
BitrateAllocationUpdate update;
|
||||||
update.target_bitrate =
|
update.target_bitrate =
|
||||||
@ -563,10 +599,12 @@ TEST(AudioSendStreamTest, DoesNotPassHigherBitrateThanMaxBitrate) {
|
|||||||
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
|
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
|
||||||
RTC_FROM_HERE);
|
RTC_FROM_HERE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(AudioSendStreamTest, SSBweTargetInRangeRespected) {
|
TEST(AudioSendStreamTest, SSBweTargetInRangeRespected) {
|
||||||
ScopedFieldTrials field_trials("WebRTC-Audio-SendSideBwe/Enabled/");
|
ScopedFieldTrials field_trials("WebRTC-Audio-SendSideBwe/Enabled/");
|
||||||
ConfigHelper helper(true, true);
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
ConfigHelper helper(true, true, use_null_audio_processing);
|
||||||
auto send_stream = helper.CreateAudioSendStream();
|
auto send_stream = helper.CreateAudioSendStream();
|
||||||
EXPECT_CALL(
|
EXPECT_CALL(
|
||||||
*helper.channel_send(),
|
*helper.channel_send(),
|
||||||
@ -579,12 +617,14 @@ TEST(AudioSendStreamTest, SSBweTargetInRangeRespected) {
|
|||||||
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
|
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
|
||||||
RTC_FROM_HERE);
|
RTC_FROM_HERE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(AudioSendStreamTest, SSBweFieldTrialMinRespected) {
|
TEST(AudioSendStreamTest, SSBweFieldTrialMinRespected) {
|
||||||
ScopedFieldTrials field_trials(
|
ScopedFieldTrials field_trials(
|
||||||
"WebRTC-Audio-SendSideBwe/Enabled/"
|
"WebRTC-Audio-SendSideBwe/Enabled/"
|
||||||
"WebRTC-Audio-Allocation/min:6kbps,max:64kbps/");
|
"WebRTC-Audio-Allocation/min:6kbps,max:64kbps/");
|
||||||
ConfigHelper helper(true, true);
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
ConfigHelper helper(true, true, use_null_audio_processing);
|
||||||
auto send_stream = helper.CreateAudioSendStream();
|
auto send_stream = helper.CreateAudioSendStream();
|
||||||
EXPECT_CALL(
|
EXPECT_CALL(
|
||||||
*helper.channel_send(),
|
*helper.channel_send(),
|
||||||
@ -595,12 +635,14 @@ TEST(AudioSendStreamTest, SSBweFieldTrialMinRespected) {
|
|||||||
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
|
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
|
||||||
RTC_FROM_HERE);
|
RTC_FROM_HERE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(AudioSendStreamTest, SSBweFieldTrialMaxRespected) {
|
TEST(AudioSendStreamTest, SSBweFieldTrialMaxRespected) {
|
||||||
ScopedFieldTrials field_trials(
|
ScopedFieldTrials field_trials(
|
||||||
"WebRTC-Audio-SendSideBwe/Enabled/"
|
"WebRTC-Audio-SendSideBwe/Enabled/"
|
||||||
"WebRTC-Audio-Allocation/min:6kbps,max:64kbps/");
|
"WebRTC-Audio-Allocation/min:6kbps,max:64kbps/");
|
||||||
ConfigHelper helper(true, true);
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
ConfigHelper helper(true, true, use_null_audio_processing);
|
||||||
auto send_stream = helper.CreateAudioSendStream();
|
auto send_stream = helper.CreateAudioSendStream();
|
||||||
EXPECT_CALL(
|
EXPECT_CALL(
|
||||||
*helper.channel_send(),
|
*helper.channel_send(),
|
||||||
@ -611,18 +653,21 @@ TEST(AudioSendStreamTest, SSBweFieldTrialMaxRespected) {
|
|||||||
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
|
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
|
||||||
RTC_FROM_HERE);
|
RTC_FROM_HERE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(AudioSendStreamTest, SSBweWithOverhead) {
|
TEST(AudioSendStreamTest, SSBweWithOverhead) {
|
||||||
ScopedFieldTrials field_trials(
|
ScopedFieldTrials field_trials(
|
||||||
"WebRTC-Audio-SendSideBwe/Enabled/"
|
"WebRTC-Audio-SendSideBwe/Enabled/"
|
||||||
"WebRTC-SendSideBwe-WithOverhead/Enabled/"
|
"WebRTC-SendSideBwe-WithOverhead/Enabled/"
|
||||||
"WebRTC-Audio-LegacyOverhead/Disabled/");
|
"WebRTC-Audio-LegacyOverhead/Disabled/");
|
||||||
ConfigHelper helper(true, true);
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
ConfigHelper helper(true, true, use_null_audio_processing);
|
||||||
auto send_stream = helper.CreateAudioSendStream();
|
auto send_stream = helper.CreateAudioSendStream();
|
||||||
EXPECT_CALL(*helper.channel_send(), CallEncoder(_)).Times(1);
|
EXPECT_CALL(*helper.channel_send(), CallEncoder(_)).Times(1);
|
||||||
send_stream->OnOverheadChanged(kOverheadPerPacket.bytes<size_t>());
|
send_stream->OnOverheadChanged(kOverheadPerPacket.bytes<size_t>());
|
||||||
const DataRate bitrate =
|
const DataRate bitrate =
|
||||||
DataRate::BitsPerSec(helper.config().max_bitrate_bps) + kMaxOverheadRate;
|
DataRate::BitsPerSec(helper.config().max_bitrate_bps) +
|
||||||
|
kMaxOverheadRate;
|
||||||
EXPECT_CALL(*helper.channel_send(),
|
EXPECT_CALL(*helper.channel_send(),
|
||||||
OnBitrateAllocation(Field(
|
OnBitrateAllocation(Field(
|
||||||
&BitrateAllocationUpdate::target_bitrate, Eq(bitrate))));
|
&BitrateAllocationUpdate::target_bitrate, Eq(bitrate))));
|
||||||
@ -631,6 +676,7 @@ TEST(AudioSendStreamTest, SSBweWithOverhead) {
|
|||||||
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
|
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
|
||||||
RTC_FROM_HERE);
|
RTC_FROM_HERE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(AudioSendStreamTest, SSBweWithOverheadMinRespected) {
|
TEST(AudioSendStreamTest, SSBweWithOverheadMinRespected) {
|
||||||
ScopedFieldTrials field_trials(
|
ScopedFieldTrials field_trials(
|
||||||
@ -638,7 +684,8 @@ TEST(AudioSendStreamTest, SSBweWithOverheadMinRespected) {
|
|||||||
"WebRTC-SendSideBwe-WithOverhead/Enabled/"
|
"WebRTC-SendSideBwe-WithOverhead/Enabled/"
|
||||||
"WebRTC-Audio-LegacyOverhead/Disabled/"
|
"WebRTC-Audio-LegacyOverhead/Disabled/"
|
||||||
"WebRTC-Audio-Allocation/min:6kbps,max:64kbps/");
|
"WebRTC-Audio-Allocation/min:6kbps,max:64kbps/");
|
||||||
ConfigHelper helper(true, true);
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
ConfigHelper helper(true, true, use_null_audio_processing);
|
||||||
auto send_stream = helper.CreateAudioSendStream();
|
auto send_stream = helper.CreateAudioSendStream();
|
||||||
EXPECT_CALL(*helper.channel_send(), CallEncoder(_)).Times(1);
|
EXPECT_CALL(*helper.channel_send(), CallEncoder(_)).Times(1);
|
||||||
send_stream->OnOverheadChanged(kOverheadPerPacket.bytes<size_t>());
|
send_stream->OnOverheadChanged(kOverheadPerPacket.bytes<size_t>());
|
||||||
@ -651,6 +698,7 @@ TEST(AudioSendStreamTest, SSBweWithOverheadMinRespected) {
|
|||||||
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
|
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
|
||||||
RTC_FROM_HERE);
|
RTC_FROM_HERE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(AudioSendStreamTest, SSBweWithOverheadMaxRespected) {
|
TEST(AudioSendStreamTest, SSBweWithOverheadMaxRespected) {
|
||||||
ScopedFieldTrials field_trials(
|
ScopedFieldTrials field_trials(
|
||||||
@ -658,7 +706,8 @@ TEST(AudioSendStreamTest, SSBweWithOverheadMaxRespected) {
|
|||||||
"WebRTC-SendSideBwe-WithOverhead/Enabled/"
|
"WebRTC-SendSideBwe-WithOverhead/Enabled/"
|
||||||
"WebRTC-Audio-LegacyOverhead/Disabled/"
|
"WebRTC-Audio-LegacyOverhead/Disabled/"
|
||||||
"WebRTC-Audio-Allocation/min:6kbps,max:64kbps/");
|
"WebRTC-Audio-Allocation/min:6kbps,max:64kbps/");
|
||||||
ConfigHelper helper(true, true);
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
ConfigHelper helper(true, true, use_null_audio_processing);
|
||||||
auto send_stream = helper.CreateAudioSendStream();
|
auto send_stream = helper.CreateAudioSendStream();
|
||||||
EXPECT_CALL(*helper.channel_send(), CallEncoder(_)).Times(1);
|
EXPECT_CALL(*helper.channel_send(), CallEncoder(_)).Times(1);
|
||||||
send_stream->OnOverheadChanged(kOverheadPerPacket.bytes<size_t>());
|
send_stream->OnOverheadChanged(kOverheadPerPacket.bytes<size_t>());
|
||||||
@ -671,9 +720,11 @@ TEST(AudioSendStreamTest, SSBweWithOverheadMaxRespected) {
|
|||||||
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
|
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
|
||||||
RTC_FROM_HERE);
|
RTC_FROM_HERE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(AudioSendStreamTest, ProbingIntervalOnBitrateUpdated) {
|
TEST(AudioSendStreamTest, ProbingIntervalOnBitrateUpdated) {
|
||||||
ConfigHelper helper(false, true);
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
ConfigHelper helper(false, true, use_null_audio_processing);
|
||||||
auto send_stream = helper.CreateAudioSendStream();
|
auto send_stream = helper.CreateAudioSendStream();
|
||||||
|
|
||||||
EXPECT_CALL(*helper.channel_send(),
|
EXPECT_CALL(*helper.channel_send(),
|
||||||
@ -688,15 +739,17 @@ TEST(AudioSendStreamTest, ProbingIntervalOnBitrateUpdated) {
|
|||||||
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
|
helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
|
||||||
RTC_FROM_HERE);
|
RTC_FROM_HERE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Test that AudioSendStream doesn't recreate the encoder unnecessarily.
|
// Test that AudioSendStream doesn't recreate the encoder unnecessarily.
|
||||||
TEST(AudioSendStreamTest, DontRecreateEncoder) {
|
TEST(AudioSendStreamTest, DontRecreateEncoder) {
|
||||||
ConfigHelper helper(false, false);
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
// WillOnce is (currently) the default used by ConfigHelper if asked to set an
|
ConfigHelper helper(false, false, use_null_audio_processing);
|
||||||
// expectation for SetEncoder. Since this behavior is essential for this test
|
// WillOnce is (currently) the default used by ConfigHelper if asked to set
|
||||||
// to be correct, it's instead set-up manually here. Otherwise a simple change
|
// an expectation for SetEncoder. Since this behavior is essential for this
|
||||||
// to ConfigHelper (say to WillRepeatedly) would silently make this test
|
// test to be correct, it's instead set-up manually here. Otherwise a simple
|
||||||
// useless.
|
// change to ConfigHelper (say to WillRepeatedly) would silently make this
|
||||||
|
// test useless.
|
||||||
EXPECT_CALL(*helper.channel_send(), SetEncoderForMock(_, _))
|
EXPECT_CALL(*helper.channel_send(), SetEncoderForMock(_, _))
|
||||||
.WillOnce(Return());
|
.WillOnce(Return());
|
||||||
|
|
||||||
@ -708,10 +761,12 @@ TEST(AudioSendStreamTest, DontRecreateEncoder) {
|
|||||||
auto send_stream = helper.CreateAudioSendStream();
|
auto send_stream = helper.CreateAudioSendStream();
|
||||||
send_stream->Reconfigure(helper.config());
|
send_stream->Reconfigure(helper.config());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(AudioSendStreamTest, ReconfigureTransportCcResetsFirst) {
|
TEST(AudioSendStreamTest, ReconfigureTransportCcResetsFirst) {
|
||||||
ScopedFieldTrials field_trials("WebRTC-Audio-SendSideBwe/Enabled/");
|
ScopedFieldTrials field_trials("WebRTC-Audio-SendSideBwe/Enabled/");
|
||||||
ConfigHelper helper(false, true);
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
ConfigHelper helper(false, true, use_null_audio_processing);
|
||||||
auto send_stream = helper.CreateAudioSendStream();
|
auto send_stream = helper.CreateAudioSendStream();
|
||||||
auto new_config = helper.config();
|
auto new_config = helper.config();
|
||||||
ConfigHelper::AddBweToConfig(&new_config);
|
ConfigHelper::AddBweToConfig(&new_config);
|
||||||
@ -724,16 +779,19 @@ TEST(AudioSendStreamTest, ReconfigureTransportCcResetsFirst) {
|
|||||||
::testing::InSequence seq;
|
::testing::InSequence seq;
|
||||||
EXPECT_CALL(*helper.channel_send(), ResetSenderCongestionControlObjects())
|
EXPECT_CALL(*helper.channel_send(), ResetSenderCongestionControlObjects())
|
||||||
.Times(1);
|
.Times(1);
|
||||||
EXPECT_CALL(*helper.channel_send(), RegisterSenderCongestionControlObjects(
|
EXPECT_CALL(*helper.channel_send(),
|
||||||
helper.transport(), Ne(nullptr)))
|
RegisterSenderCongestionControlObjects(helper.transport(),
|
||||||
|
Ne(nullptr)))
|
||||||
.Times(1);
|
.Times(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
send_stream->Reconfigure(new_config);
|
send_stream->Reconfigure(new_config);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(AudioSendStreamTest, OnTransportOverheadChanged) {
|
TEST(AudioSendStreamTest, OnTransportOverheadChanged) {
|
||||||
ConfigHelper helper(false, true);
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
ConfigHelper helper(false, true, use_null_audio_processing);
|
||||||
auto send_stream = helper.CreateAudioSendStream();
|
auto send_stream = helper.CreateAudioSendStream();
|
||||||
auto new_config = helper.config();
|
auto new_config = helper.config();
|
||||||
|
|
||||||
@ -746,9 +804,11 @@ TEST(AudioSendStreamTest, OnTransportOverheadChanged) {
|
|||||||
EXPECT_EQ(transport_overhead_per_packet_bytes,
|
EXPECT_EQ(transport_overhead_per_packet_bytes,
|
||||||
send_stream->TestOnlyGetPerPacketOverheadBytes());
|
send_stream->TestOnlyGetPerPacketOverheadBytes());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(AudioSendStreamTest, OnAudioOverheadChanged) {
|
TEST(AudioSendStreamTest, OnAudioOverheadChanged) {
|
||||||
ConfigHelper helper(false, true);
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
ConfigHelper helper(false, true, use_null_audio_processing);
|
||||||
auto send_stream = helper.CreateAudioSendStream();
|
auto send_stream = helper.CreateAudioSendStream();
|
||||||
auto new_config = helper.config();
|
auto new_config = helper.config();
|
||||||
|
|
||||||
@ -760,9 +820,11 @@ TEST(AudioSendStreamTest, OnAudioOverheadChanged) {
|
|||||||
EXPECT_EQ(audio_overhead_per_packet_bytes,
|
EXPECT_EQ(audio_overhead_per_packet_bytes,
|
||||||
send_stream->TestOnlyGetPerPacketOverheadBytes());
|
send_stream->TestOnlyGetPerPacketOverheadBytes());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(AudioSendStreamTest, OnAudioAndTransportOverheadChanged) {
|
TEST(AudioSendStreamTest, OnAudioAndTransportOverheadChanged) {
|
||||||
ConfigHelper helper(false, true);
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
ConfigHelper helper(false, true, use_null_audio_processing);
|
||||||
auto send_stream = helper.CreateAudioSendStream();
|
auto send_stream = helper.CreateAudioSendStream();
|
||||||
auto new_config = helper.config();
|
auto new_config = helper.config();
|
||||||
|
|
||||||
@ -779,31 +841,37 @@ TEST(AudioSendStreamTest, OnAudioAndTransportOverheadChanged) {
|
|||||||
transport_overhead_per_packet_bytes + audio_overhead_per_packet_bytes,
|
transport_overhead_per_packet_bytes + audio_overhead_per_packet_bytes,
|
||||||
send_stream->TestOnlyGetPerPacketOverheadBytes());
|
send_stream->TestOnlyGetPerPacketOverheadBytes());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Validates that reconfiguring the AudioSendStream with a Frame encryptor
|
// Validates that reconfiguring the AudioSendStream with a Frame encryptor
|
||||||
// correctly reconfigures on the object without crashing.
|
// correctly reconfigures on the object without crashing.
|
||||||
TEST(AudioSendStreamTest, ReconfigureWithFrameEncryptor) {
|
TEST(AudioSendStreamTest, ReconfigureWithFrameEncryptor) {
|
||||||
ConfigHelper helper(false, true);
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
ConfigHelper helper(false, true, use_null_audio_processing);
|
||||||
auto send_stream = helper.CreateAudioSendStream();
|
auto send_stream = helper.CreateAudioSendStream();
|
||||||
auto new_config = helper.config();
|
auto new_config = helper.config();
|
||||||
|
|
||||||
rtc::scoped_refptr<FrameEncryptorInterface> mock_frame_encryptor_0(
|
rtc::scoped_refptr<FrameEncryptorInterface> mock_frame_encryptor_0(
|
||||||
new rtc::RefCountedObject<MockFrameEncryptor>());
|
new rtc::RefCountedObject<MockFrameEncryptor>());
|
||||||
new_config.frame_encryptor = mock_frame_encryptor_0;
|
new_config.frame_encryptor = mock_frame_encryptor_0;
|
||||||
EXPECT_CALL(*helper.channel_send(), SetFrameEncryptor(Ne(nullptr))).Times(1);
|
EXPECT_CALL(*helper.channel_send(), SetFrameEncryptor(Ne(nullptr)))
|
||||||
|
.Times(1);
|
||||||
send_stream->Reconfigure(new_config);
|
send_stream->Reconfigure(new_config);
|
||||||
|
|
||||||
// Not updating the frame encryptor shouldn't force it to reconfigure.
|
// Not updating the frame encryptor shouldn't force it to reconfigure.
|
||||||
EXPECT_CALL(*helper.channel_send(), SetFrameEncryptor(_)).Times(0);
|
EXPECT_CALL(*helper.channel_send(), SetFrameEncryptor(_)).Times(0);
|
||||||
send_stream->Reconfigure(new_config);
|
send_stream->Reconfigure(new_config);
|
||||||
|
|
||||||
// Updating frame encryptor to a new object should force a call to the proxy.
|
// Updating frame encryptor to a new object should force a call to the
|
||||||
|
// proxy.
|
||||||
rtc::scoped_refptr<FrameEncryptorInterface> mock_frame_encryptor_1(
|
rtc::scoped_refptr<FrameEncryptorInterface> mock_frame_encryptor_1(
|
||||||
new rtc::RefCountedObject<MockFrameEncryptor>());
|
new rtc::RefCountedObject<MockFrameEncryptor>());
|
||||||
new_config.frame_encryptor = mock_frame_encryptor_1;
|
new_config.frame_encryptor = mock_frame_encryptor_1;
|
||||||
new_config.crypto_options.sframe.require_frame_encryption = true;
|
new_config.crypto_options.sframe.require_frame_encryption = true;
|
||||||
EXPECT_CALL(*helper.channel_send(), SetFrameEncryptor(Ne(nullptr))).Times(1);
|
EXPECT_CALL(*helper.channel_send(), SetFrameEncryptor(Ne(nullptr)))
|
||||||
|
.Times(1);
|
||||||
send_stream->Reconfigure(new_config);
|
send_stream->Reconfigure(new_config);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} // namespace test
|
} // namespace test
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -41,7 +41,6 @@ AudioState::~AudioState() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
AudioProcessing* AudioState::audio_processing() {
|
AudioProcessing* AudioState::audio_processing() {
|
||||||
RTC_DCHECK(config_.audio_processing);
|
|
||||||
return config_.audio_processing.get();
|
return config_.audio_processing.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -31,10 +31,14 @@ constexpr int kSampleRate = 16000;
|
|||||||
constexpr int kNumberOfChannels = 1;
|
constexpr int kNumberOfChannels = 1;
|
||||||
|
|
||||||
struct ConfigHelper {
|
struct ConfigHelper {
|
||||||
ConfigHelper() : audio_mixer(AudioMixerImpl::Create()) {
|
explicit ConfigHelper(bool use_null_audio_processing)
|
||||||
|
: audio_mixer(AudioMixerImpl::Create()) {
|
||||||
audio_state_config.audio_mixer = audio_mixer;
|
audio_state_config.audio_mixer = audio_mixer;
|
||||||
audio_state_config.audio_processing =
|
audio_state_config.audio_processing =
|
||||||
new rtc::RefCountedObject<testing::NiceMock<MockAudioProcessing>>();
|
use_null_audio_processing
|
||||||
|
? nullptr
|
||||||
|
: new rtc::RefCountedObject<
|
||||||
|
testing::NiceMock<MockAudioProcessing>>();
|
||||||
audio_state_config.audio_device_module =
|
audio_state_config.audio_device_module =
|
||||||
new rtc::RefCountedObject<MockAudioDeviceModule>();
|
new rtc::RefCountedObject<MockAudioDeviceModule>();
|
||||||
}
|
}
|
||||||
@ -88,19 +92,24 @@ std::vector<uint32_t> ComputeChannelLevels(AudioFrame* audio_frame) {
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
TEST(AudioStateTest, Create) {
|
TEST(AudioStateTest, Create) {
|
||||||
ConfigHelper helper;
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
ConfigHelper helper(use_null_audio_processing);
|
||||||
auto audio_state = AudioState::Create(helper.config());
|
auto audio_state = AudioState::Create(helper.config());
|
||||||
EXPECT_TRUE(audio_state.get());
|
EXPECT_TRUE(audio_state.get());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(AudioStateTest, ConstructDestruct) {
|
TEST(AudioStateTest, ConstructDestruct) {
|
||||||
ConfigHelper helper;
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
ConfigHelper helper(use_null_audio_processing);
|
||||||
rtc::scoped_refptr<internal::AudioState> audio_state(
|
rtc::scoped_refptr<internal::AudioState> audio_state(
|
||||||
new rtc::RefCountedObject<internal::AudioState>(helper.config()));
|
new rtc::RefCountedObject<internal::AudioState>(helper.config()));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(AudioStateTest, RecordedAudioArrivesAtSingleStream) {
|
TEST(AudioStateTest, RecordedAudioArrivesAtSingleStream) {
|
||||||
ConfigHelper helper;
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
ConfigHelper helper(use_null_audio_processing);
|
||||||
rtc::scoped_refptr<internal::AudioState> audio_state(
|
rtc::scoped_refptr<internal::AudioState> audio_state(
|
||||||
new rtc::RefCountedObject<internal::AudioState>(helper.config()));
|
new rtc::RefCountedObject<internal::AudioState>(helper.config()));
|
||||||
|
|
||||||
@ -119,11 +128,15 @@ TEST(AudioStateTest, RecordedAudioArrivesAtSingleStream) {
|
|||||||
EXPECT_LT(0u, levels[0]);
|
EXPECT_LT(0u, levels[0]);
|
||||||
EXPECT_EQ(0u, levels[1]);
|
EXPECT_EQ(0u, levels[1]);
|
||||||
}));
|
}));
|
||||||
MockAudioProcessing* ap =
|
MockAudioProcessing* ap = use_null_audio_processing
|
||||||
static_cast<MockAudioProcessing*>(audio_state->audio_processing());
|
? nullptr
|
||||||
|
: static_cast<MockAudioProcessing*>(
|
||||||
|
audio_state->audio_processing());
|
||||||
|
if (ap) {
|
||||||
EXPECT_CALL(*ap, set_stream_delay_ms(0));
|
EXPECT_CALL(*ap, set_stream_delay_ms(0));
|
||||||
EXPECT_CALL(*ap, set_stream_key_pressed(false));
|
EXPECT_CALL(*ap, set_stream_key_pressed(false));
|
||||||
EXPECT_CALL(*ap, ProcessStream(_, _, _, Matcher<int16_t*>(_)));
|
EXPECT_CALL(*ap, ProcessStream(_, _, _, Matcher<int16_t*>(_)));
|
||||||
|
}
|
||||||
|
|
||||||
constexpr int kSampleRate = 16000;
|
constexpr int kSampleRate = 16000;
|
||||||
constexpr size_t kNumChannels = 2;
|
constexpr size_t kNumChannels = 2;
|
||||||
@ -136,9 +149,11 @@ TEST(AudioStateTest, RecordedAudioArrivesAtSingleStream) {
|
|||||||
|
|
||||||
audio_state->RemoveSendingStream(&stream);
|
audio_state->RemoveSendingStream(&stream);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(AudioStateTest, RecordedAudioArrivesAtMultipleStreams) {
|
TEST(AudioStateTest, RecordedAudioArrivesAtMultipleStreams) {
|
||||||
ConfigHelper helper;
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
ConfigHelper helper(use_null_audio_processing);
|
||||||
rtc::scoped_refptr<internal::AudioState> audio_state(
|
rtc::scoped_refptr<internal::AudioState> audio_state(
|
||||||
new rtc::RefCountedObject<internal::AudioState>(helper.config()));
|
new rtc::RefCountedObject<internal::AudioState>(helper.config()));
|
||||||
|
|
||||||
@ -150,7 +165,8 @@ TEST(AudioStateTest, RecordedAudioArrivesAtMultipleStreams) {
|
|||||||
EXPECT_CALL(
|
EXPECT_CALL(
|
||||||
stream_1,
|
stream_1,
|
||||||
SendAudioDataForMock(::testing::AllOf(
|
SendAudioDataForMock(::testing::AllOf(
|
||||||
::testing::Field(&AudioFrame::sample_rate_hz_, ::testing::Eq(16000)),
|
::testing::Field(&AudioFrame::sample_rate_hz_,
|
||||||
|
::testing::Eq(16000)),
|
||||||
::testing::Field(&AudioFrame::num_channels_, ::testing::Eq(1u)))))
|
::testing::Field(&AudioFrame::num_channels_, ::testing::Eq(1u)))))
|
||||||
.WillOnce(
|
.WillOnce(
|
||||||
// Verify that there is output signal.
|
// Verify that there is output signal.
|
||||||
@ -161,7 +177,8 @@ TEST(AudioStateTest, RecordedAudioArrivesAtMultipleStreams) {
|
|||||||
EXPECT_CALL(
|
EXPECT_CALL(
|
||||||
stream_2,
|
stream_2,
|
||||||
SendAudioDataForMock(::testing::AllOf(
|
SendAudioDataForMock(::testing::AllOf(
|
||||||
::testing::Field(&AudioFrame::sample_rate_hz_, ::testing::Eq(16000)),
|
::testing::Field(&AudioFrame::sample_rate_hz_,
|
||||||
|
::testing::Eq(16000)),
|
||||||
::testing::Field(&AudioFrame::num_channels_, ::testing::Eq(1u)))))
|
::testing::Field(&AudioFrame::num_channels_, ::testing::Eq(1u)))))
|
||||||
.WillOnce(
|
.WillOnce(
|
||||||
// Verify that there is output signal.
|
// Verify that there is output signal.
|
||||||
@ -171,9 +188,11 @@ TEST(AudioStateTest, RecordedAudioArrivesAtMultipleStreams) {
|
|||||||
}));
|
}));
|
||||||
MockAudioProcessing* ap =
|
MockAudioProcessing* ap =
|
||||||
static_cast<MockAudioProcessing*>(audio_state->audio_processing());
|
static_cast<MockAudioProcessing*>(audio_state->audio_processing());
|
||||||
|
if (ap) {
|
||||||
EXPECT_CALL(*ap, set_stream_delay_ms(5));
|
EXPECT_CALL(*ap, set_stream_delay_ms(5));
|
||||||
EXPECT_CALL(*ap, set_stream_key_pressed(true));
|
EXPECT_CALL(*ap, set_stream_key_pressed(true));
|
||||||
EXPECT_CALL(*ap, ProcessStream(_, _, _, Matcher<int16_t*>(_)));
|
EXPECT_CALL(*ap, ProcessStream(_, _, _, Matcher<int16_t*>(_)));
|
||||||
|
}
|
||||||
|
|
||||||
constexpr int kSampleRate = 16000;
|
constexpr int kSampleRate = 16000;
|
||||||
constexpr size_t kNumChannels = 1;
|
constexpr size_t kNumChannels = 1;
|
||||||
@ -187,12 +206,14 @@ TEST(AudioStateTest, RecordedAudioArrivesAtMultipleStreams) {
|
|||||||
audio_state->RemoveSendingStream(&stream_1);
|
audio_state->RemoveSendingStream(&stream_1);
|
||||||
audio_state->RemoveSendingStream(&stream_2);
|
audio_state->RemoveSendingStream(&stream_2);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(AudioStateTest, EnableChannelSwap) {
|
TEST(AudioStateTest, EnableChannelSwap) {
|
||||||
constexpr int kSampleRate = 16000;
|
constexpr int kSampleRate = 16000;
|
||||||
constexpr size_t kNumChannels = 2;
|
constexpr size_t kNumChannels = 2;
|
||||||
|
|
||||||
ConfigHelper helper;
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
ConfigHelper helper(use_null_audio_processing);
|
||||||
rtc::scoped_refptr<internal::AudioState> audio_state(
|
rtc::scoped_refptr<internal::AudioState> audio_state(
|
||||||
new rtc::RefCountedObject<internal::AudioState>(helper.config()));
|
new rtc::RefCountedObject<internal::AudioState>(helper.config()));
|
||||||
|
|
||||||
@ -219,10 +240,12 @@ TEST(AudioStateTest, EnableChannelSwap) {
|
|||||||
|
|
||||||
audio_state->RemoveSendingStream(&stream);
|
audio_state->RemoveSendingStream(&stream);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(AudioStateTest,
|
TEST(AudioStateTest,
|
||||||
QueryingTransportForAudioShouldResultInGetAudioCallOnMixerSource) {
|
QueryingTransportForAudioShouldResultInGetAudioCallOnMixerSource) {
|
||||||
ConfigHelper helper;
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
ConfigHelper helper(use_null_audio_processing);
|
||||||
auto audio_state = AudioState::Create(helper.config());
|
auto audio_state = AudioState::Create(helper.config());
|
||||||
|
|
||||||
FakeAudioSource fake_source;
|
FakeAudioSource fake_source;
|
||||||
@ -242,8 +265,10 @@ TEST(AudioStateTest,
|
|||||||
int64_t elapsed_time_ms;
|
int64_t elapsed_time_ms;
|
||||||
int64_t ntp_time_ms;
|
int64_t ntp_time_ms;
|
||||||
audio_state->audio_transport()->NeedMorePlayData(
|
audio_state->audio_transport()->NeedMorePlayData(
|
||||||
kSampleRate / 100, kNumberOfChannels * 2, kNumberOfChannels, kSampleRate,
|
kSampleRate / 100, kNumberOfChannels * 2, kNumberOfChannels,
|
||||||
audio_buffer, n_samples_out, &elapsed_time_ms, &ntp_time_ms);
|
kSampleRate, audio_buffer, n_samples_out, &elapsed_time_ms,
|
||||||
|
&ntp_time_ms);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} // namespace test
|
} // namespace test
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -49,13 +49,15 @@ void ProcessCaptureFrame(uint32_t delay_ms,
|
|||||||
bool swap_stereo_channels,
|
bool swap_stereo_channels,
|
||||||
AudioProcessing* audio_processing,
|
AudioProcessing* audio_processing,
|
||||||
AudioFrame* audio_frame) {
|
AudioFrame* audio_frame) {
|
||||||
RTC_DCHECK(audio_processing);
|
|
||||||
RTC_DCHECK(audio_frame);
|
RTC_DCHECK(audio_frame);
|
||||||
|
if (audio_processing) {
|
||||||
audio_processing->set_stream_delay_ms(delay_ms);
|
audio_processing->set_stream_delay_ms(delay_ms);
|
||||||
audio_processing->set_stream_key_pressed(key_pressed);
|
audio_processing->set_stream_key_pressed(key_pressed);
|
||||||
int error = ProcessAudioFrame(audio_processing, audio_frame);
|
int error = ProcessAudioFrame(audio_processing, audio_frame);
|
||||||
|
|
||||||
RTC_DCHECK_EQ(0, error) << "ProcessStream() error: " << error;
|
RTC_DCHECK_EQ(0, error) << "ProcessStream() error: " << error;
|
||||||
|
}
|
||||||
|
|
||||||
if (swap_stereo_channels) {
|
if (swap_stereo_channels) {
|
||||||
AudioFrameOperations::SwapStereoChannels(audio_frame);
|
AudioFrameOperations::SwapStereoChannels(audio_frame);
|
||||||
}
|
}
|
||||||
@ -85,7 +87,6 @@ AudioTransportImpl::AudioTransportImpl(AudioMixer* mixer,
|
|||||||
AudioProcessing* audio_processing)
|
AudioProcessing* audio_processing)
|
||||||
: audio_processing_(audio_processing), mixer_(mixer) {
|
: audio_processing_(audio_processing), mixer_(mixer) {
|
||||||
RTC_DCHECK(mixer);
|
RTC_DCHECK(mixer);
|
||||||
RTC_DCHECK(audio_processing);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioTransportImpl::~AudioTransportImpl() {}
|
AudioTransportImpl::~AudioTransportImpl() {}
|
||||||
@ -137,7 +138,8 @@ int32_t AudioTransportImpl::RecordedDataIsAvailable(
|
|||||||
// if we're using this feature or not.
|
// if we're using this feature or not.
|
||||||
// TODO(solenberg): GetConfig() takes a lock. Work around that.
|
// TODO(solenberg): GetConfig() takes a lock. Work around that.
|
||||||
bool typing_detected = false;
|
bool typing_detected = false;
|
||||||
if (audio_processing_->GetConfig().voice_detection.enabled) {
|
if (audio_processing_ &&
|
||||||
|
audio_processing_->GetConfig().voice_detection.enabled) {
|
||||||
if (audio_frame->vad_activity_ != AudioFrame::kVadUnknown) {
|
if (audio_frame->vad_activity_ != AudioFrame::kVadUnknown) {
|
||||||
bool vad_active = audio_frame->vad_activity_ == AudioFrame::kVadActive;
|
bool vad_active = audio_frame->vad_activity_ == AudioFrame::kVadActive;
|
||||||
typing_detected = typing_detection_.Process(key_pressed, vad_active);
|
typing_detected = typing_detection_.Process(key_pressed, vad_active);
|
||||||
@ -192,8 +194,11 @@ int32_t AudioTransportImpl::NeedMorePlayData(const size_t nSamples,
|
|||||||
*elapsed_time_ms = mixed_frame_.elapsed_time_ms_;
|
*elapsed_time_ms = mixed_frame_.elapsed_time_ms_;
|
||||||
*ntp_time_ms = mixed_frame_.ntp_time_ms_;
|
*ntp_time_ms = mixed_frame_.ntp_time_ms_;
|
||||||
|
|
||||||
const auto error = ProcessReverseAudioFrame(audio_processing_, &mixed_frame_);
|
if (audio_processing_) {
|
||||||
|
const auto error =
|
||||||
|
ProcessReverseAudioFrame(audio_processing_, &mixed_frame_);
|
||||||
RTC_DCHECK_EQ(error, AudioProcessing::kNoError);
|
RTC_DCHECK_EQ(error, AudioProcessing::kNoError);
|
||||||
|
}
|
||||||
|
|
||||||
nSamplesOut = Resample(mixed_frame_, samplesPerSec, &render_resampler_,
|
nSamplesOut = Resample(mixed_frame_, samplesPerSec, &render_resampler_,
|
||||||
static_cast<int16_t*>(audioSamples));
|
static_cast<int16_t*>(audioSamples));
|
||||||
|
|||||||
@ -35,13 +35,15 @@
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
struct CallHelper {
|
struct CallHelper {
|
||||||
CallHelper() {
|
explicit CallHelper(bool use_null_audio_processing) {
|
||||||
task_queue_factory_ = webrtc::CreateDefaultTaskQueueFactory();
|
task_queue_factory_ = webrtc::CreateDefaultTaskQueueFactory();
|
||||||
webrtc::AudioState::Config audio_state_config;
|
webrtc::AudioState::Config audio_state_config;
|
||||||
audio_state_config.audio_mixer =
|
audio_state_config.audio_mixer =
|
||||||
new rtc::RefCountedObject<webrtc::test::MockAudioMixer>();
|
new rtc::RefCountedObject<webrtc::test::MockAudioMixer>();
|
||||||
audio_state_config.audio_processing =
|
audio_state_config.audio_processing =
|
||||||
new rtc::RefCountedObject<webrtc::test::MockAudioProcessing>();
|
use_null_audio_processing
|
||||||
|
? nullptr
|
||||||
|
: new rtc::RefCountedObject<webrtc::test::MockAudioProcessing>();
|
||||||
audio_state_config.audio_device_module =
|
audio_state_config.audio_device_module =
|
||||||
new rtc::RefCountedObject<webrtc::test::MockAudioDeviceModule>();
|
new rtc::RefCountedObject<webrtc::test::MockAudioDeviceModule>();
|
||||||
webrtc::Call::Config config(&event_log_);
|
webrtc::Call::Config config(&event_log_);
|
||||||
@ -64,11 +66,14 @@ struct CallHelper {
|
|||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
TEST(CallTest, ConstructDestruct) {
|
TEST(CallTest, ConstructDestruct) {
|
||||||
CallHelper call;
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
CallHelper call(use_null_audio_processing);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CallTest, CreateDestroy_AudioSendStream) {
|
TEST(CallTest, CreateDestroy_AudioSendStream) {
|
||||||
CallHelper call;
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
CallHelper call(use_null_audio_processing);
|
||||||
MockTransport send_transport;
|
MockTransport send_transport;
|
||||||
AudioSendStream::Config config(&send_transport);
|
AudioSendStream::Config config(&send_transport);
|
||||||
config.rtp.ssrc = 42;
|
config.rtp.ssrc = 42;
|
||||||
@ -76,9 +81,11 @@ TEST(CallTest, CreateDestroy_AudioSendStream) {
|
|||||||
EXPECT_NE(stream, nullptr);
|
EXPECT_NE(stream, nullptr);
|
||||||
call->DestroyAudioSendStream(stream);
|
call->DestroyAudioSendStream(stream);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(CallTest, CreateDestroy_AudioReceiveStream) {
|
TEST(CallTest, CreateDestroy_AudioReceiveStream) {
|
||||||
CallHelper call;
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
CallHelper call(use_null_audio_processing);
|
||||||
AudioReceiveStream::Config config;
|
AudioReceiveStream::Config config;
|
||||||
MockTransport rtcp_send_transport;
|
MockTransport rtcp_send_transport;
|
||||||
config.rtp.remote_ssrc = 42;
|
config.rtp.remote_ssrc = 42;
|
||||||
@ -89,9 +96,11 @@ TEST(CallTest, CreateDestroy_AudioReceiveStream) {
|
|||||||
EXPECT_NE(stream, nullptr);
|
EXPECT_NE(stream, nullptr);
|
||||||
call->DestroyAudioReceiveStream(stream);
|
call->DestroyAudioReceiveStream(stream);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(CallTest, CreateDestroy_AudioSendStreams) {
|
TEST(CallTest, CreateDestroy_AudioSendStreams) {
|
||||||
CallHelper call;
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
CallHelper call(use_null_audio_processing);
|
||||||
MockTransport send_transport;
|
MockTransport send_transport;
|
||||||
AudioSendStream::Config config(&send_transport);
|
AudioSendStream::Config config(&send_transport);
|
||||||
std::list<AudioSendStream*> streams;
|
std::list<AudioSendStream*> streams;
|
||||||
@ -112,9 +121,11 @@ TEST(CallTest, CreateDestroy_AudioSendStreams) {
|
|||||||
streams.clear();
|
streams.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(CallTest, CreateDestroy_AudioReceiveStreams) {
|
TEST(CallTest, CreateDestroy_AudioReceiveStreams) {
|
||||||
CallHelper call;
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
CallHelper call(use_null_audio_processing);
|
||||||
AudioReceiveStream::Config config;
|
AudioReceiveStream::Config config;
|
||||||
MockTransport rtcp_send_transport;
|
MockTransport rtcp_send_transport;
|
||||||
config.rtcp_send_transport = &rtcp_send_transport;
|
config.rtcp_send_transport = &rtcp_send_transport;
|
||||||
@ -138,9 +149,11 @@ TEST(CallTest, CreateDestroy_AudioReceiveStreams) {
|
|||||||
streams.clear();
|
streams.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(CallTest, CreateDestroy_AssociateAudioSendReceiveStreams_RecvFirst) {
|
TEST(CallTest, CreateDestroy_AssociateAudioSendReceiveStreams_RecvFirst) {
|
||||||
CallHelper call;
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
CallHelper call(use_null_audio_processing);
|
||||||
AudioReceiveStream::Config recv_config;
|
AudioReceiveStream::Config recv_config;
|
||||||
MockTransport rtcp_send_transport;
|
MockTransport rtcp_send_transport;
|
||||||
recv_config.rtp.remote_ssrc = 42;
|
recv_config.rtp.remote_ssrc = 42;
|
||||||
@ -148,7 +161,8 @@ TEST(CallTest, CreateDestroy_AssociateAudioSendReceiveStreams_RecvFirst) {
|
|||||||
recv_config.rtcp_send_transport = &rtcp_send_transport;
|
recv_config.rtcp_send_transport = &rtcp_send_transport;
|
||||||
recv_config.decoder_factory =
|
recv_config.decoder_factory =
|
||||||
new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>();
|
new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>();
|
||||||
AudioReceiveStream* recv_stream = call->CreateAudioReceiveStream(recv_config);
|
AudioReceiveStream* recv_stream =
|
||||||
|
call->CreateAudioReceiveStream(recv_config);
|
||||||
EXPECT_NE(recv_stream, nullptr);
|
EXPECT_NE(recv_stream, nullptr);
|
||||||
|
|
||||||
MockTransport send_transport;
|
MockTransport send_transport;
|
||||||
@ -163,13 +177,16 @@ TEST(CallTest, CreateDestroy_AssociateAudioSendReceiveStreams_RecvFirst) {
|
|||||||
internal_recv_stream->GetAssociatedSendStreamForTesting());
|
internal_recv_stream->GetAssociatedSendStreamForTesting());
|
||||||
|
|
||||||
call->DestroyAudioSendStream(send_stream);
|
call->DestroyAudioSendStream(send_stream);
|
||||||
EXPECT_EQ(nullptr, internal_recv_stream->GetAssociatedSendStreamForTesting());
|
EXPECT_EQ(nullptr,
|
||||||
|
internal_recv_stream->GetAssociatedSendStreamForTesting());
|
||||||
|
|
||||||
call->DestroyAudioReceiveStream(recv_stream);
|
call->DestroyAudioReceiveStream(recv_stream);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(CallTest, CreateDestroy_AssociateAudioSendReceiveStreams_SendFirst) {
|
TEST(CallTest, CreateDestroy_AssociateAudioSendReceiveStreams_SendFirst) {
|
||||||
CallHelper call;
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
CallHelper call(use_null_audio_processing);
|
||||||
MockTransport send_transport;
|
MockTransport send_transport;
|
||||||
AudioSendStream::Config send_config(&send_transport);
|
AudioSendStream::Config send_config(&send_transport);
|
||||||
send_config.rtp.ssrc = 777;
|
send_config.rtp.ssrc = 777;
|
||||||
@ -183,7 +200,8 @@ TEST(CallTest, CreateDestroy_AssociateAudioSendReceiveStreams_SendFirst) {
|
|||||||
recv_config.rtcp_send_transport = &rtcp_send_transport;
|
recv_config.rtcp_send_transport = &rtcp_send_transport;
|
||||||
recv_config.decoder_factory =
|
recv_config.decoder_factory =
|
||||||
new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>();
|
new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>();
|
||||||
AudioReceiveStream* recv_stream = call->CreateAudioReceiveStream(recv_config);
|
AudioReceiveStream* recv_stream =
|
||||||
|
call->CreateAudioReceiveStream(recv_config);
|
||||||
EXPECT_NE(recv_stream, nullptr);
|
EXPECT_NE(recv_stream, nullptr);
|
||||||
|
|
||||||
internal::AudioReceiveStream* internal_recv_stream =
|
internal::AudioReceiveStream* internal_recv_stream =
|
||||||
@ -195,9 +213,11 @@ TEST(CallTest, CreateDestroy_AssociateAudioSendReceiveStreams_SendFirst) {
|
|||||||
|
|
||||||
call->DestroyAudioSendStream(send_stream);
|
call->DestroyAudioSendStream(send_stream);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(CallTest, CreateDestroy_FlexfecReceiveStream) {
|
TEST(CallTest, CreateDestroy_FlexfecReceiveStream) {
|
||||||
CallHelper call;
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
CallHelper call(use_null_audio_processing);
|
||||||
MockTransport rtcp_send_transport;
|
MockTransport rtcp_send_transport;
|
||||||
FlexfecReceiveStream::Config config(&rtcp_send_transport);
|
FlexfecReceiveStream::Config config(&rtcp_send_transport);
|
||||||
config.payload_type = 118;
|
config.payload_type = 118;
|
||||||
@ -208,9 +228,11 @@ TEST(CallTest, CreateDestroy_FlexfecReceiveStream) {
|
|||||||
EXPECT_NE(stream, nullptr);
|
EXPECT_NE(stream, nullptr);
|
||||||
call->DestroyFlexfecReceiveStream(stream);
|
call->DestroyFlexfecReceiveStream(stream);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(CallTest, CreateDestroy_FlexfecReceiveStreams) {
|
TEST(CallTest, CreateDestroy_FlexfecReceiveStreams) {
|
||||||
CallHelper call;
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
CallHelper call(use_null_audio_processing);
|
||||||
MockTransport rtcp_send_transport;
|
MockTransport rtcp_send_transport;
|
||||||
FlexfecReceiveStream::Config config(&rtcp_send_transport);
|
FlexfecReceiveStream::Config config(&rtcp_send_transport);
|
||||||
config.payload_type = 118;
|
config.payload_type = 118;
|
||||||
@ -234,9 +256,11 @@ TEST(CallTest, CreateDestroy_FlexfecReceiveStreams) {
|
|||||||
streams.clear();
|
streams.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(CallTest, MultipleFlexfecReceiveStreamsProtectingSingleVideoStream) {
|
TEST(CallTest, MultipleFlexfecReceiveStreamsProtectingSingleVideoStream) {
|
||||||
CallHelper call;
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
CallHelper call(use_null_audio_processing);
|
||||||
MockTransport rtcp_send_transport;
|
MockTransport rtcp_send_transport;
|
||||||
FlexfecReceiveStream::Config config(&rtcp_send_transport);
|
FlexfecReceiveStream::Config config(&rtcp_send_transport);
|
||||||
config.payload_type = 118;
|
config.payload_type = 118;
|
||||||
@ -268,10 +292,12 @@ TEST(CallTest, MultipleFlexfecReceiveStreamsProtectingSingleVideoStream) {
|
|||||||
call->DestroyFlexfecReceiveStream(s);
|
call->DestroyFlexfecReceiveStream(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(CallTest, RecreatingAudioStreamWithSameSsrcReusesRtpState) {
|
TEST(CallTest, RecreatingAudioStreamWithSameSsrcReusesRtpState) {
|
||||||
constexpr uint32_t kSSRC = 12345;
|
constexpr uint32_t kSSRC = 12345;
|
||||||
CallHelper call;
|
for (bool use_null_audio_processing : {false, true}) {
|
||||||
|
CallHelper call(use_null_audio_processing);
|
||||||
|
|
||||||
auto create_stream_and_get_rtp_state = [&](uint32_t ssrc) {
|
auto create_stream_and_get_rtp_state = [&](uint32_t ssrc) {
|
||||||
MockTransport send_transport;
|
MockTransport send_transport;
|
||||||
@ -295,5 +321,6 @@ TEST(CallTest, RecreatingAudioStreamWithSameSsrcReusesRtpState) {
|
|||||||
rtp_state2.last_timestamp_time_ms);
|
rtp_state2.last_timestamp_time_ms);
|
||||||
EXPECT_EQ(rtp_state1.media_has_been_sent, rtp_state2.media_has_been_sent);
|
EXPECT_EQ(rtp_state1.media_has_been_sent, rtp_state2.media_has_been_sent);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -206,7 +206,6 @@ WebRtcVoiceEngine::WebRtcVoiceEngine(
|
|||||||
RTC_LOG(LS_INFO) << "WebRtcVoiceEngine::WebRtcVoiceEngine";
|
RTC_LOG(LS_INFO) << "WebRtcVoiceEngine::WebRtcVoiceEngine";
|
||||||
RTC_DCHECK(decoder_factory);
|
RTC_DCHECK(decoder_factory);
|
||||||
RTC_DCHECK(encoder_factory);
|
RTC_DCHECK(encoder_factory);
|
||||||
RTC_DCHECK(audio_processing);
|
|
||||||
// The rest of our initialization will happen in Init.
|
// The rest of our initialization will happen in Init.
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -458,6 +457,14 @@ bool WebRtcVoiceEngine::ApplyOptions(const AudioOptions& options_in) {
|
|||||||
*options.audio_jitter_buffer_enable_rtx_handling;
|
*options.audio_jitter_buffer_enable_rtx_handling;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
webrtc::AudioProcessing* ap = apm();
|
||||||
|
if (!ap) {
|
||||||
|
RTC_LOG(LS_INFO)
|
||||||
|
<< "No audio processing module present. No software-provided effects "
|
||||||
|
"(AEC, NS, AGC, ...) are activated";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
webrtc::Config config;
|
webrtc::Config config;
|
||||||
|
|
||||||
if (options.experimental_ns) {
|
if (options.experimental_ns) {
|
||||||
@ -469,7 +476,7 @@ bool WebRtcVoiceEngine::ApplyOptions(const AudioOptions& options_in) {
|
|||||||
new webrtc::ExperimentalNs(*experimental_ns_));
|
new webrtc::ExperimentalNs(*experimental_ns_));
|
||||||
}
|
}
|
||||||
|
|
||||||
webrtc::AudioProcessing::Config apm_config = apm()->GetConfig();
|
webrtc::AudioProcessing::Config apm_config = ap->GetConfig();
|
||||||
|
|
||||||
if (options.echo_cancellation) {
|
if (options.echo_cancellation) {
|
||||||
apm_config.echo_canceller.enabled = *options.echo_cancellation;
|
apm_config.echo_canceller.enabled = *options.echo_cancellation;
|
||||||
@ -524,8 +531,8 @@ bool WebRtcVoiceEngine::ApplyOptions(const AudioOptions& options_in) {
|
|||||||
apm_config.voice_detection.enabled = *options.typing_detection;
|
apm_config.voice_detection.enabled = *options.typing_detection;
|
||||||
}
|
}
|
||||||
|
|
||||||
apm()->SetExtraOptions(config);
|
ap->SetExtraOptions(config);
|
||||||
apm()->ApplyConfig(apm_config);
|
ap->ApplyConfig(apm_config);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -571,18 +578,34 @@ void WebRtcVoiceEngine::UnregisterChannel(WebRtcVoiceMediaChannel* channel) {
|
|||||||
bool WebRtcVoiceEngine::StartAecDump(webrtc::FileWrapper file,
|
bool WebRtcVoiceEngine::StartAecDump(webrtc::FileWrapper file,
|
||||||
int64_t max_size_bytes) {
|
int64_t max_size_bytes) {
|
||||||
RTC_DCHECK(worker_thread_checker_.IsCurrent());
|
RTC_DCHECK(worker_thread_checker_.IsCurrent());
|
||||||
|
|
||||||
|
webrtc::AudioProcessing* ap = apm();
|
||||||
|
if (!ap) {
|
||||||
|
RTC_LOG(LS_WARNING)
|
||||||
|
<< "Attempting to start aecdump when no audio processing module is "
|
||||||
|
"present, hence no aecdump is started.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
auto aec_dump = webrtc::AecDumpFactory::Create(
|
auto aec_dump = webrtc::AecDumpFactory::Create(
|
||||||
std::move(file), max_size_bytes, low_priority_worker_queue_.get());
|
std::move(file), max_size_bytes, low_priority_worker_queue_.get());
|
||||||
if (!aec_dump) {
|
if (!aec_dump) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
apm()->AttachAecDump(std::move(aec_dump));
|
|
||||||
|
ap->AttachAecDump(std::move(aec_dump));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebRtcVoiceEngine::StopAecDump() {
|
void WebRtcVoiceEngine::StopAecDump() {
|
||||||
RTC_DCHECK(worker_thread_checker_.IsCurrent());
|
RTC_DCHECK(worker_thread_checker_.IsCurrent());
|
||||||
apm()->DetachAecDump();
|
webrtc::AudioProcessing* ap = apm();
|
||||||
|
if (ap) {
|
||||||
|
ap->DetachAecDump();
|
||||||
|
} else {
|
||||||
|
RTC_LOG(LS_WARNING) << "Attempting to stop aecdump when no audio "
|
||||||
|
"processing module is present";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
webrtc::AudioDeviceModule* WebRtcVoiceEngine::adm() {
|
webrtc::AudioDeviceModule* WebRtcVoiceEngine::adm() {
|
||||||
@ -593,7 +616,6 @@ webrtc::AudioDeviceModule* WebRtcVoiceEngine::adm() {
|
|||||||
|
|
||||||
webrtc::AudioProcessing* WebRtcVoiceEngine::apm() const {
|
webrtc::AudioProcessing* WebRtcVoiceEngine::apm() const {
|
||||||
RTC_DCHECK(worker_thread_checker_.IsCurrent());
|
RTC_DCHECK(worker_thread_checker_.IsCurrent());
|
||||||
RTC_DCHECK(apm_);
|
|
||||||
return apm_.get();
|
return apm_.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2141,7 +2163,10 @@ bool WebRtcVoiceMediaChannel::MuteStream(uint32_t ssrc, bool muted) {
|
|||||||
for (const auto& kv : send_streams_) {
|
for (const auto& kv : send_streams_) {
|
||||||
all_muted = all_muted && kv.second->muted();
|
all_muted = all_muted && kv.second->muted();
|
||||||
}
|
}
|
||||||
engine()->apm()->set_output_will_be_muted(all_muted);
|
webrtc::AudioProcessing* ap = engine()->apm();
|
||||||
|
if (ap) {
|
||||||
|
ap->set_output_will_be_muted(all_muted);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -116,6 +116,7 @@ rtc_library("audio_processing") {
|
|||||||
visibility = [ "*" ]
|
visibility = [ "*" ]
|
||||||
configs += [ ":apm_debug_dump" ]
|
configs += [ ":apm_debug_dump" ]
|
||||||
sources = [
|
sources = [
|
||||||
|
"audio_processing_builder_impl.cc",
|
||||||
"audio_processing_impl.cc",
|
"audio_processing_impl.cc",
|
||||||
"audio_processing_impl.h",
|
"audio_processing_impl.h",
|
||||||
"common.h",
|
"common.h",
|
||||||
@ -169,6 +170,7 @@ rtc_library("audio_processing") {
|
|||||||
"../../rtc_base:deprecation",
|
"../../rtc_base:deprecation",
|
||||||
"../../rtc_base:gtest_prod",
|
"../../rtc_base:gtest_prod",
|
||||||
"../../rtc_base:ignore_wundef",
|
"../../rtc_base:ignore_wundef",
|
||||||
|
"../../rtc_base:refcount",
|
||||||
"../../rtc_base:safe_minmax",
|
"../../rtc_base:safe_minmax",
|
||||||
"../../rtc_base:sanitizer",
|
"../../rtc_base:sanitizer",
|
||||||
"../../rtc_base/system:rtc_export",
|
"../../rtc_base/system:rtc_export",
|
||||||
@ -556,41 +558,6 @@ if (rtc_include_tests) {
|
|||||||
} # audioproc_f_impl
|
} # audioproc_f_impl
|
||||||
}
|
}
|
||||||
|
|
||||||
rtc_library("audioproc_test_utils") {
|
|
||||||
visibility = [ "*" ]
|
|
||||||
testonly = true
|
|
||||||
sources = [
|
|
||||||
"test/audio_buffer_tools.cc",
|
|
||||||
"test/audio_buffer_tools.h",
|
|
||||||
"test/bitexactness_tools.cc",
|
|
||||||
"test/bitexactness_tools.h",
|
|
||||||
"test/performance_timer.cc",
|
|
||||||
"test/performance_timer.h",
|
|
||||||
"test/simulator_buffers.cc",
|
|
||||||
"test/simulator_buffers.h",
|
|
||||||
"test/test_utils.cc",
|
|
||||||
"test/test_utils.h",
|
|
||||||
]
|
|
||||||
|
|
||||||
deps = [
|
|
||||||
":api",
|
|
||||||
":audio_buffer",
|
|
||||||
":audio_processing",
|
|
||||||
"../../api:array_view",
|
|
||||||
"../../api/audio:audio_frame_api",
|
|
||||||
"../../common_audio",
|
|
||||||
"../../rtc_base:checks",
|
|
||||||
"../../rtc_base:rtc_base_approved",
|
|
||||||
"../../rtc_base/system:arch",
|
|
||||||
"../../system_wrappers",
|
|
||||||
"../../test:fileutils",
|
|
||||||
"../../test:test_support",
|
|
||||||
"../audio_coding:neteq_input_audio_tools",
|
|
||||||
"//testing/gtest",
|
|
||||||
"//third_party/abseil-cpp/absl/types:optional",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rtc_enable_protobuf) {
|
if (rtc_enable_protobuf) {
|
||||||
proto_library("audioproc_unittest_proto") {
|
proto_library("audioproc_unittest_proto") {
|
||||||
sources = [ "test/unittest.proto" ]
|
sources = [ "test/unittest.proto" ]
|
||||||
@ -629,3 +596,42 @@ if (rtc_include_tests) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rtc_library("audioproc_test_utils") {
|
||||||
|
visibility = [ "*" ]
|
||||||
|
testonly = true
|
||||||
|
sources = [
|
||||||
|
"test/audio_buffer_tools.cc",
|
||||||
|
"test/audio_buffer_tools.h",
|
||||||
|
"test/audio_processing_builder_for_testing.cc",
|
||||||
|
"test/audio_processing_builder_for_testing.h",
|
||||||
|
"test/bitexactness_tools.cc",
|
||||||
|
"test/bitexactness_tools.h",
|
||||||
|
"test/performance_timer.cc",
|
||||||
|
"test/performance_timer.h",
|
||||||
|
"test/simulator_buffers.cc",
|
||||||
|
"test/simulator_buffers.h",
|
||||||
|
"test/test_utils.cc",
|
||||||
|
"test/test_utils.h",
|
||||||
|
]
|
||||||
|
|
||||||
|
configs += [ ":apm_debug_dump" ]
|
||||||
|
|
||||||
|
deps = [
|
||||||
|
":api",
|
||||||
|
":audio_buffer",
|
||||||
|
":audio_processing",
|
||||||
|
"../../api:array_view",
|
||||||
|
"../../api/audio:audio_frame_api",
|
||||||
|
"../../common_audio",
|
||||||
|
"../../rtc_base:checks",
|
||||||
|
"../../rtc_base:rtc_base_approved",
|
||||||
|
"../../rtc_base/system:arch",
|
||||||
|
"../../system_wrappers",
|
||||||
|
"../../test:fileutils",
|
||||||
|
"../../test:test_support",
|
||||||
|
"../audio_coding:neteq_input_audio_tools",
|
||||||
|
"//testing/gtest",
|
||||||
|
"//third_party/abseil-cpp/absl/types:optional",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
@ -20,6 +20,7 @@ rtc_source_set("aec_dump") {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rtc_include_tests) {
|
||||||
rtc_library("mock_aec_dump") {
|
rtc_library("mock_aec_dump") {
|
||||||
testonly = true
|
testonly = true
|
||||||
sources = [
|
sources = [
|
||||||
@ -28,6 +29,7 @@ rtc_library("mock_aec_dump") {
|
|||||||
]
|
]
|
||||||
|
|
||||||
deps = [
|
deps = [
|
||||||
|
"..:audioproc_test_utils",
|
||||||
"../",
|
"../",
|
||||||
"../../../test:test_support",
|
"../../../test:test_support",
|
||||||
]
|
]
|
||||||
@ -41,11 +43,13 @@ rtc_library("mock_aec_dump_unittests") {
|
|||||||
deps = [
|
deps = [
|
||||||
":mock_aec_dump",
|
":mock_aec_dump",
|
||||||
"..:api",
|
"..:api",
|
||||||
|
"..:audioproc_test_utils",
|
||||||
"../",
|
"../",
|
||||||
"../../../rtc_base:rtc_base_approved",
|
"../../../rtc_base:rtc_base_approved",
|
||||||
"//testing/gtest",
|
"//testing/gtest",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (rtc_enable_protobuf) {
|
if (rtc_enable_protobuf) {
|
||||||
rtc_library("aec_dump_impl") {
|
rtc_library("aec_dump_impl") {
|
||||||
@ -75,6 +79,7 @@ if (rtc_enable_protobuf) {
|
|||||||
deps += [ "../:audioproc_debug_proto" ]
|
deps += [ "../:audioproc_debug_proto" ]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rtc_include_tests) {
|
||||||
rtc_library("aec_dump_unittests") {
|
rtc_library("aec_dump_unittests") {
|
||||||
testonly = true
|
testonly = true
|
||||||
defines = []
|
defines = []
|
||||||
@ -91,6 +96,7 @@ if (rtc_enable_protobuf) {
|
|||||||
sources = [ "aec_dump_unittest.cc" ]
|
sources = [ "aec_dump_unittest.cc" ]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rtc_library("null_aec_dump_factory") {
|
rtc_library("null_aec_dump_factory") {
|
||||||
assert_no_deps = [ ":aec_dump_impl" ]
|
assert_no_deps = [ ":aec_dump_impl" ]
|
||||||
|
|||||||
@ -15,6 +15,7 @@
|
|||||||
#include "modules/audio_processing/aec_dump/mock_aec_dump.h"
|
#include "modules/audio_processing/aec_dump/mock_aec_dump.h"
|
||||||
#include "modules/audio_processing/audio_processing_impl.h"
|
#include "modules/audio_processing/audio_processing_impl.h"
|
||||||
#include "modules/audio_processing/include/audio_processing.h"
|
#include "modules/audio_processing/include/audio_processing.h"
|
||||||
|
#include "modules/audio_processing/test/audio_processing_builder_for_testing.h"
|
||||||
|
|
||||||
using ::testing::_;
|
using ::testing::_;
|
||||||
using ::testing::AtLeast;
|
using ::testing::AtLeast;
|
||||||
@ -25,7 +26,7 @@ namespace {
|
|||||||
std::unique_ptr<webrtc::AudioProcessing> CreateAudioProcessing() {
|
std::unique_ptr<webrtc::AudioProcessing> CreateAudioProcessing() {
|
||||||
webrtc::Config config;
|
webrtc::Config config;
|
||||||
std::unique_ptr<webrtc::AudioProcessing> apm(
|
std::unique_ptr<webrtc::AudioProcessing> apm(
|
||||||
webrtc::AudioProcessingBuilder().Create(config));
|
webrtc::AudioProcessingBuilderForTesting().Create(config));
|
||||||
RTC_DCHECK(apm);
|
RTC_DCHECK(apm);
|
||||||
return apm;
|
return apm;
|
||||||
}
|
}
|
||||||
|
|||||||
51
modules/audio_processing/audio_processing_builder_impl.cc
Normal file
51
modules/audio_processing/audio_processing_builder_impl.cc
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "modules/audio_processing/include/audio_processing.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "modules/audio_processing/audio_processing_impl.h"
|
||||||
|
#include "rtc_base/ref_counted_object.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
AudioProcessingBuilder::AudioProcessingBuilder() = default;
|
||||||
|
AudioProcessingBuilder::~AudioProcessingBuilder() = default;
|
||||||
|
|
||||||
|
AudioProcessing* AudioProcessingBuilder::Create() {
|
||||||
|
webrtc::Config config;
|
||||||
|
return Create(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioProcessing* AudioProcessingBuilder::Create(const webrtc::Config& config) {
|
||||||
|
#ifdef WEBRTC_EXCLUDE_AUDIO_PROCESSING_MODULE
|
||||||
|
|
||||||
|
// Implementation returning a null pointer for using when the APM is excluded
|
||||||
|
// from the build..
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// Standard implementation.
|
||||||
|
AudioProcessingImpl* apm = new rtc::RefCountedObject<AudioProcessingImpl>(
|
||||||
|
config, std::move(capture_post_processing_),
|
||||||
|
std::move(render_pre_processing_), std::move(echo_control_factory_),
|
||||||
|
std::move(echo_detector_), std::move(capture_analyzer_));
|
||||||
|
if (apm->Initialize() != AudioProcessing::kNoError) {
|
||||||
|
delete apm;
|
||||||
|
apm = nullptr;
|
||||||
|
}
|
||||||
|
return apm;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace webrtc
|
||||||
@ -229,56 +229,6 @@ bool AudioProcessingImpl::SubmoduleStates::HighPassFilteringRequired() const {
|
|||||||
noise_suppressor_enabled_;
|
noise_suppressor_enabled_;
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioProcessingBuilder::AudioProcessingBuilder() = default;
|
|
||||||
AudioProcessingBuilder::~AudioProcessingBuilder() = default;
|
|
||||||
|
|
||||||
AudioProcessingBuilder& AudioProcessingBuilder::SetCapturePostProcessing(
|
|
||||||
std::unique_ptr<CustomProcessing> capture_post_processing) {
|
|
||||||
capture_post_processing_ = std::move(capture_post_processing);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioProcessingBuilder& AudioProcessingBuilder::SetRenderPreProcessing(
|
|
||||||
std::unique_ptr<CustomProcessing> render_pre_processing) {
|
|
||||||
render_pre_processing_ = std::move(render_pre_processing);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioProcessingBuilder& AudioProcessingBuilder::SetCaptureAnalyzer(
|
|
||||||
std::unique_ptr<CustomAudioAnalyzer> capture_analyzer) {
|
|
||||||
capture_analyzer_ = std::move(capture_analyzer);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioProcessingBuilder& AudioProcessingBuilder::SetEchoControlFactory(
|
|
||||||
std::unique_ptr<EchoControlFactory> echo_control_factory) {
|
|
||||||
echo_control_factory_ = std::move(echo_control_factory);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioProcessingBuilder& AudioProcessingBuilder::SetEchoDetector(
|
|
||||||
rtc::scoped_refptr<EchoDetector> echo_detector) {
|
|
||||||
echo_detector_ = std::move(echo_detector);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioProcessing* AudioProcessingBuilder::Create() {
|
|
||||||
webrtc::Config config;
|
|
||||||
return Create(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioProcessing* AudioProcessingBuilder::Create(const webrtc::Config& config) {
|
|
||||||
AudioProcessingImpl* apm = new rtc::RefCountedObject<AudioProcessingImpl>(
|
|
||||||
config, std::move(capture_post_processing_),
|
|
||||||
std::move(render_pre_processing_), std::move(echo_control_factory_),
|
|
||||||
std::move(echo_detector_), std::move(capture_analyzer_));
|
|
||||||
if (apm->Initialize() != AudioProcessing::kNoError) {
|
|
||||||
delete apm;
|
|
||||||
apm = nullptr;
|
|
||||||
}
|
|
||||||
return apm;
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioProcessingImpl::AudioProcessingImpl(const webrtc::Config& config)
|
AudioProcessingImpl::AudioProcessingImpl(const webrtc::Config& config)
|
||||||
: AudioProcessingImpl(config,
|
: AudioProcessingImpl(config,
|
||||||
/*capture_post_processor=*/nullptr,
|
/*capture_post_processor=*/nullptr,
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#include "api/array_view.h"
|
#include "api/array_view.h"
|
||||||
#include "modules/audio_processing/audio_processing_impl.h"
|
#include "modules/audio_processing/audio_processing_impl.h"
|
||||||
|
#include "modules/audio_processing/test/audio_processing_builder_for_testing.h"
|
||||||
#include "modules/audio_processing/test/test_utils.h"
|
#include "modules/audio_processing/test/test_utils.h"
|
||||||
#include "rtc_base/critical_section.h"
|
#include "rtc_base/critical_section.h"
|
||||||
#include "rtc_base/event.h"
|
#include "rtc_base/event.h"
|
||||||
@ -496,7 +497,7 @@ AudioProcessingImplLockTest::AudioProcessingImplLockTest()
|
|||||||
this,
|
this,
|
||||||
"stats",
|
"stats",
|
||||||
rtc::kNormalPriority),
|
rtc::kNormalPriority),
|
||||||
apm_(AudioProcessingBuilder().Create()),
|
apm_(AudioProcessingBuilderForTesting().Create()),
|
||||||
render_thread_state_(kMaxFrameSize,
|
render_thread_state_(kMaxFrameSize,
|
||||||
&rand_gen_,
|
&rand_gen_,
|
||||||
&render_call_event_,
|
&render_call_event_,
|
||||||
|
|||||||
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
#include "api/scoped_refptr.h"
|
#include "api/scoped_refptr.h"
|
||||||
#include "modules/audio_processing/include/audio_processing.h"
|
#include "modules/audio_processing/include/audio_processing.h"
|
||||||
|
#include "modules/audio_processing/test/audio_processing_builder_for_testing.h"
|
||||||
#include "modules/audio_processing/test/echo_control_mock.h"
|
#include "modules/audio_processing/test/echo_control_mock.h"
|
||||||
#include "modules/audio_processing/test/test_utils.h"
|
#include "modules/audio_processing/test/test_utils.h"
|
||||||
#include "rtc_base/checks.h"
|
#include "rtc_base/checks.h"
|
||||||
@ -167,7 +168,8 @@ TEST(AudioProcessingImplTest, AudioParameterChangeTriggersInit) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(AudioProcessingImplTest, UpdateCapturePreGainRuntimeSetting) {
|
TEST(AudioProcessingImplTest, UpdateCapturePreGainRuntimeSetting) {
|
||||||
std::unique_ptr<AudioProcessing> apm(AudioProcessingBuilder().Create());
|
std::unique_ptr<AudioProcessing> apm(
|
||||||
|
AudioProcessingBuilderForTesting().Create());
|
||||||
webrtc::AudioProcessing::Config apm_config;
|
webrtc::AudioProcessing::Config apm_config;
|
||||||
apm_config.pre_amplifier.enabled = true;
|
apm_config.pre_amplifier.enabled = true;
|
||||||
apm_config.pre_amplifier.fixed_gain_factor = 1.f;
|
apm_config.pre_amplifier.fixed_gain_factor = 1.f;
|
||||||
@ -205,7 +207,7 @@ TEST(AudioProcessingImplTest,
|
|||||||
const auto* echo_control_factory_ptr = echo_control_factory.get();
|
const auto* echo_control_factory_ptr = echo_control_factory.get();
|
||||||
|
|
||||||
std::unique_ptr<AudioProcessing> apm(
|
std::unique_ptr<AudioProcessing> apm(
|
||||||
AudioProcessingBuilder()
|
AudioProcessingBuilderForTesting()
|
||||||
.SetEchoControlFactory(std::move(echo_control_factory))
|
.SetEchoControlFactory(std::move(echo_control_factory))
|
||||||
.Create());
|
.Create());
|
||||||
// Disable AGC.
|
// Disable AGC.
|
||||||
@ -248,7 +250,7 @@ TEST(AudioProcessingImplTest,
|
|||||||
const auto* echo_control_factory_ptr = echo_control_factory.get();
|
const auto* echo_control_factory_ptr = echo_control_factory.get();
|
||||||
|
|
||||||
std::unique_ptr<AudioProcessing> apm(
|
std::unique_ptr<AudioProcessing> apm(
|
||||||
AudioProcessingBuilder()
|
AudioProcessingBuilderForTesting()
|
||||||
.SetEchoControlFactory(std::move(echo_control_factory))
|
.SetEchoControlFactory(std::move(echo_control_factory))
|
||||||
.Create());
|
.Create());
|
||||||
webrtc::AudioProcessing::Config apm_config;
|
webrtc::AudioProcessing::Config apm_config;
|
||||||
@ -294,7 +296,7 @@ TEST(AudioProcessingImplTest, EchoControllerObservesPlayoutVolumeChange) {
|
|||||||
const auto* echo_control_factory_ptr = echo_control_factory.get();
|
const auto* echo_control_factory_ptr = echo_control_factory.get();
|
||||||
|
|
||||||
std::unique_ptr<AudioProcessing> apm(
|
std::unique_ptr<AudioProcessing> apm(
|
||||||
AudioProcessingBuilder()
|
AudioProcessingBuilderForTesting()
|
||||||
.SetEchoControlFactory(std::move(echo_control_factory))
|
.SetEchoControlFactory(std::move(echo_control_factory))
|
||||||
.Create());
|
.Create());
|
||||||
// Disable AGC.
|
// Disable AGC.
|
||||||
@ -353,7 +355,7 @@ TEST(AudioProcessingImplTest, RenderPreProcessorBeforeEchoDetector) {
|
|||||||
new TestRenderPreProcessor());
|
new TestRenderPreProcessor());
|
||||||
// Create APM injecting the test echo detector and render pre-processor.
|
// Create APM injecting the test echo detector and render pre-processor.
|
||||||
std::unique_ptr<AudioProcessing> apm(
|
std::unique_ptr<AudioProcessing> apm(
|
||||||
AudioProcessingBuilder()
|
AudioProcessingBuilderForTesting()
|
||||||
.SetEchoDetector(test_echo_detector)
|
.SetEchoDetector(test_echo_detector)
|
||||||
.SetRenderPreProcessing(std::move(test_render_pre_processor))
|
.SetRenderPreProcessing(std::move(test_render_pre_processor))
|
||||||
.Create());
|
.Create());
|
||||||
|
|||||||
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
#include "api/array_view.h"
|
#include "api/array_view.h"
|
||||||
#include "modules/audio_processing/audio_processing_impl.h"
|
#include "modules/audio_processing/audio_processing_impl.h"
|
||||||
|
#include "modules/audio_processing/test/audio_processing_builder_for_testing.h"
|
||||||
#include "modules/audio_processing/test/test_utils.h"
|
#include "modules/audio_processing/test/test_utils.h"
|
||||||
#include "rtc_base/atomic_ops.h"
|
#include "rtc_base/atomic_ops.h"
|
||||||
#include "rtc_base/event.h"
|
#include "rtc_base/event.h"
|
||||||
@ -486,28 +487,28 @@ class CallSimulator : public ::testing::TestWithParam<SimulationConfig> {
|
|||||||
int num_capture_channels = 1;
|
int num_capture_channels = 1;
|
||||||
switch (simulation_config_.simulation_settings) {
|
switch (simulation_config_.simulation_settings) {
|
||||||
case SettingsType::kDefaultApmMobile: {
|
case SettingsType::kDefaultApmMobile: {
|
||||||
apm_.reset(AudioProcessingBuilder().Create());
|
apm_.reset(AudioProcessingBuilderForTesting().Create());
|
||||||
ASSERT_TRUE(!!apm_);
|
ASSERT_TRUE(!!apm_);
|
||||||
set_default_mobile_apm_runtime_settings(apm_.get());
|
set_default_mobile_apm_runtime_settings(apm_.get());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SettingsType::kDefaultApmDesktop: {
|
case SettingsType::kDefaultApmDesktop: {
|
||||||
Config config;
|
Config config;
|
||||||
apm_.reset(AudioProcessingBuilder().Create(config));
|
apm_.reset(AudioProcessingBuilderForTesting().Create(config));
|
||||||
ASSERT_TRUE(!!apm_);
|
ASSERT_TRUE(!!apm_);
|
||||||
set_default_desktop_apm_runtime_settings(apm_.get());
|
set_default_desktop_apm_runtime_settings(apm_.get());
|
||||||
apm_->SetExtraOptions(config);
|
apm_->SetExtraOptions(config);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SettingsType::kAllSubmodulesTurnedOff: {
|
case SettingsType::kAllSubmodulesTurnedOff: {
|
||||||
apm_.reset(AudioProcessingBuilder().Create());
|
apm_.reset(AudioProcessingBuilderForTesting().Create());
|
||||||
ASSERT_TRUE(!!apm_);
|
ASSERT_TRUE(!!apm_);
|
||||||
turn_off_default_apm_runtime_settings(apm_.get());
|
turn_off_default_apm_runtime_settings(apm_.get());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SettingsType::kDefaultApmDesktopWithoutDelayAgnostic: {
|
case SettingsType::kDefaultApmDesktopWithoutDelayAgnostic: {
|
||||||
Config config;
|
Config config;
|
||||||
apm_.reset(AudioProcessingBuilder().Create(config));
|
apm_.reset(AudioProcessingBuilderForTesting().Create(config));
|
||||||
ASSERT_TRUE(!!apm_);
|
ASSERT_TRUE(!!apm_);
|
||||||
set_default_desktop_apm_runtime_settings(apm_.get());
|
set_default_desktop_apm_runtime_settings(apm_.get());
|
||||||
apm_->SetExtraOptions(config);
|
apm_->SetExtraOptions(config);
|
||||||
@ -515,7 +516,7 @@ class CallSimulator : public ::testing::TestWithParam<SimulationConfig> {
|
|||||||
}
|
}
|
||||||
case SettingsType::kDefaultApmDesktopWithoutExtendedFilter: {
|
case SettingsType::kDefaultApmDesktopWithoutExtendedFilter: {
|
||||||
Config config;
|
Config config;
|
||||||
apm_.reset(AudioProcessingBuilder().Create(config));
|
apm_.reset(AudioProcessingBuilderForTesting().Create(config));
|
||||||
ASSERT_TRUE(!!apm_);
|
ASSERT_TRUE(!!apm_);
|
||||||
set_default_desktop_apm_runtime_settings(apm_.get());
|
set_default_desktop_apm_runtime_settings(apm_.get());
|
||||||
apm_->SetExtraOptions(config);
|
apm_->SetExtraOptions(config);
|
||||||
|
|||||||
@ -28,6 +28,7 @@
|
|||||||
#include "modules/audio_processing/audio_processing_impl.h"
|
#include "modules/audio_processing/audio_processing_impl.h"
|
||||||
#include "modules/audio_processing/common.h"
|
#include "modules/audio_processing/common.h"
|
||||||
#include "modules/audio_processing/include/mock_audio_processing.h"
|
#include "modules/audio_processing/include/mock_audio_processing.h"
|
||||||
|
#include "modules/audio_processing/test/audio_processing_builder_for_testing.h"
|
||||||
#include "modules/audio_processing/test/protobuf_utils.h"
|
#include "modules/audio_processing/test/protobuf_utils.h"
|
||||||
#include "modules/audio_processing/test/test_utils.h"
|
#include "modules/audio_processing/test/test_utils.h"
|
||||||
#include "rtc_base/arraysize.h"
|
#include "rtc_base/arraysize.h"
|
||||||
@ -426,7 +427,7 @@ ApmTest::ApmTest()
|
|||||||
far_file_(NULL),
|
far_file_(NULL),
|
||||||
near_file_(NULL),
|
near_file_(NULL),
|
||||||
out_file_(NULL) {
|
out_file_(NULL) {
|
||||||
apm_.reset(AudioProcessingBuilder().Create());
|
apm_.reset(AudioProcessingBuilderForTesting().Create());
|
||||||
AudioProcessing::Config apm_config = apm_->GetConfig();
|
AudioProcessing::Config apm_config = apm_->GetConfig();
|
||||||
apm_config.gain_controller1.analog_gain_controller.enabled = false;
|
apm_config.gain_controller1.analog_gain_controller.enabled = false;
|
||||||
apm_config.pipeline.maximum_internal_processing_rate = 48000;
|
apm_config.pipeline.maximum_internal_processing_rate = 48000;
|
||||||
@ -1176,7 +1177,7 @@ TEST_F(ApmTest, NoProcessingWhenAllComponentsDisabledFloat) {
|
|||||||
auto src_channels = &src[0];
|
auto src_channels = &src[0];
|
||||||
auto dest_channels = &dest[0];
|
auto dest_channels = &dest[0];
|
||||||
|
|
||||||
apm_.reset(AudioProcessingBuilder().Create());
|
apm_.reset(AudioProcessingBuilderForTesting().Create());
|
||||||
EXPECT_NOERR(apm_->ProcessStream(&src_channels, StreamConfig(sample_rate, 1),
|
EXPECT_NOERR(apm_->ProcessStream(&src_channels, StreamConfig(sample_rate, 1),
|
||||||
StreamConfig(sample_rate, 1),
|
StreamConfig(sample_rate, 1),
|
||||||
&dest_channels));
|
&dest_channels));
|
||||||
@ -1637,7 +1638,7 @@ TEST_F(ApmTest, Process) {
|
|||||||
if (test->num_input_channels() != test->num_output_channels())
|
if (test->num_input_channels() != test->num_output_channels())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
apm_.reset(AudioProcessingBuilder().Create());
|
apm_.reset(AudioProcessingBuilderForTesting().Create());
|
||||||
AudioProcessing::Config apm_config = apm_->GetConfig();
|
AudioProcessing::Config apm_config = apm_->GetConfig();
|
||||||
apm_config.gain_controller1.analog_gain_controller.enabled = false;
|
apm_config.gain_controller1.analog_gain_controller.enabled = false;
|
||||||
apm_->ApplyConfig(apm_config);
|
apm_->ApplyConfig(apm_config);
|
||||||
@ -1806,7 +1807,8 @@ TEST_F(ApmTest, NoErrorsWithKeyboardChannel) {
|
|||||||
{AudioProcessing::kStereoAndKeyboard, AudioProcessing::kStereo},
|
{AudioProcessing::kStereoAndKeyboard, AudioProcessing::kStereo},
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<AudioProcessing> ap(AudioProcessingBuilder().Create());
|
std::unique_ptr<AudioProcessing> ap(
|
||||||
|
AudioProcessingBuilderForTesting().Create());
|
||||||
// Enable one component just to ensure some processing takes place.
|
// Enable one component just to ensure some processing takes place.
|
||||||
AudioProcessing::Config config;
|
AudioProcessing::Config config;
|
||||||
config.noise_suppression.enabled = true;
|
config.noise_suppression.enabled = true;
|
||||||
@ -1932,7 +1934,8 @@ class AudioProcessingTest
|
|||||||
size_t num_reverse_input_channels,
|
size_t num_reverse_input_channels,
|
||||||
size_t num_reverse_output_channels,
|
size_t num_reverse_output_channels,
|
||||||
const std::string& output_file_prefix) {
|
const std::string& output_file_prefix) {
|
||||||
std::unique_ptr<AudioProcessing> ap(AudioProcessingBuilder().Create());
|
std::unique_ptr<AudioProcessing> ap(
|
||||||
|
AudioProcessingBuilderForTesting().Create());
|
||||||
AudioProcessing::Config apm_config = ap->GetConfig();
|
AudioProcessing::Config apm_config = ap->GetConfig();
|
||||||
apm_config.gain_controller1.analog_gain_controller.enabled = false;
|
apm_config.gain_controller1.analog_gain_controller.enabled = false;
|
||||||
ap->ApplyConfig(apm_config);
|
ap->ApplyConfig(apm_config);
|
||||||
@ -2316,7 +2319,8 @@ void RunApmRateAndChannelTest(
|
|||||||
rtc::ArrayView<const int> sample_rates_hz,
|
rtc::ArrayView<const int> sample_rates_hz,
|
||||||
rtc::ArrayView<const int> render_channel_counts,
|
rtc::ArrayView<const int> render_channel_counts,
|
||||||
rtc::ArrayView<const int> capture_channel_counts) {
|
rtc::ArrayView<const int> capture_channel_counts) {
|
||||||
std::unique_ptr<AudioProcessing> apm(AudioProcessingBuilder().Create());
|
std::unique_ptr<AudioProcessing> apm(
|
||||||
|
AudioProcessingBuilderForTesting().Create());
|
||||||
webrtc::AudioProcessing::Config apm_config;
|
webrtc::AudioProcessing::Config apm_config;
|
||||||
apm_config.echo_canceller.enabled = true;
|
apm_config.echo_canceller.enabled = true;
|
||||||
apm->ApplyConfig(apm_config);
|
apm->ApplyConfig(apm_config);
|
||||||
@ -2455,7 +2459,7 @@ TEST(ApmConfiguration, EnablePostProcessing) {
|
|||||||
auto mock_post_processor =
|
auto mock_post_processor =
|
||||||
std::unique_ptr<CustomProcessing>(mock_post_processor_ptr);
|
std::unique_ptr<CustomProcessing>(mock_post_processor_ptr);
|
||||||
rtc::scoped_refptr<AudioProcessing> apm =
|
rtc::scoped_refptr<AudioProcessing> apm =
|
||||||
AudioProcessingBuilder()
|
AudioProcessingBuilderForTesting()
|
||||||
.SetCapturePostProcessing(std::move(mock_post_processor))
|
.SetCapturePostProcessing(std::move(mock_post_processor))
|
||||||
.Create();
|
.Create();
|
||||||
|
|
||||||
@ -2477,7 +2481,7 @@ TEST(ApmConfiguration, EnablePreProcessing) {
|
|||||||
auto mock_pre_processor =
|
auto mock_pre_processor =
|
||||||
std::unique_ptr<CustomProcessing>(mock_pre_processor_ptr);
|
std::unique_ptr<CustomProcessing>(mock_pre_processor_ptr);
|
||||||
rtc::scoped_refptr<AudioProcessing> apm =
|
rtc::scoped_refptr<AudioProcessing> apm =
|
||||||
AudioProcessingBuilder()
|
AudioProcessingBuilderForTesting()
|
||||||
.SetRenderPreProcessing(std::move(mock_pre_processor))
|
.SetRenderPreProcessing(std::move(mock_pre_processor))
|
||||||
.Create();
|
.Create();
|
||||||
|
|
||||||
@ -2499,7 +2503,7 @@ TEST(ApmConfiguration, EnableCaptureAnalyzer) {
|
|||||||
auto mock_capture_analyzer =
|
auto mock_capture_analyzer =
|
||||||
std::unique_ptr<CustomAudioAnalyzer>(mock_capture_analyzer_ptr);
|
std::unique_ptr<CustomAudioAnalyzer>(mock_capture_analyzer_ptr);
|
||||||
rtc::scoped_refptr<AudioProcessing> apm =
|
rtc::scoped_refptr<AudioProcessing> apm =
|
||||||
AudioProcessingBuilder()
|
AudioProcessingBuilderForTesting()
|
||||||
.SetCaptureAnalyzer(std::move(mock_capture_analyzer))
|
.SetCaptureAnalyzer(std::move(mock_capture_analyzer))
|
||||||
.Create();
|
.Create();
|
||||||
|
|
||||||
@ -2520,7 +2524,7 @@ TEST(ApmConfiguration, PreProcessingReceivesRuntimeSettings) {
|
|||||||
auto mock_pre_processor =
|
auto mock_pre_processor =
|
||||||
std::unique_ptr<CustomProcessing>(mock_pre_processor_ptr);
|
std::unique_ptr<CustomProcessing>(mock_pre_processor_ptr);
|
||||||
rtc::scoped_refptr<AudioProcessing> apm =
|
rtc::scoped_refptr<AudioProcessing> apm =
|
||||||
AudioProcessingBuilder()
|
AudioProcessingBuilderForTesting()
|
||||||
.SetRenderPreProcessing(std::move(mock_pre_processor))
|
.SetRenderPreProcessing(std::move(mock_pre_processor))
|
||||||
.Create();
|
.Create();
|
||||||
apm->SetRuntimeSetting(
|
apm->SetRuntimeSetting(
|
||||||
@ -2565,7 +2569,7 @@ TEST(ApmConfiguration, EchoControlInjection) {
|
|||||||
new MyEchoControlFactory());
|
new MyEchoControlFactory());
|
||||||
|
|
||||||
rtc::scoped_refptr<AudioProcessing> apm =
|
rtc::scoped_refptr<AudioProcessing> apm =
|
||||||
AudioProcessingBuilder()
|
AudioProcessingBuilderForTesting()
|
||||||
.SetEchoControlFactory(std::move(echo_control_factory))
|
.SetEchoControlFactory(std::move(echo_control_factory))
|
||||||
.Create(webrtc_config);
|
.Create(webrtc_config);
|
||||||
|
|
||||||
@ -2589,7 +2593,7 @@ TEST(ApmConfiguration, EchoControlInjection) {
|
|||||||
std::unique_ptr<AudioProcessing> CreateApm(bool mobile_aec) {
|
std::unique_ptr<AudioProcessing> CreateApm(bool mobile_aec) {
|
||||||
Config old_config;
|
Config old_config;
|
||||||
std::unique_ptr<AudioProcessing> apm(
|
std::unique_ptr<AudioProcessing> apm(
|
||||||
AudioProcessingBuilder().Create(old_config));
|
AudioProcessingBuilderForTesting().Create(old_config));
|
||||||
if (!apm) {
|
if (!apm) {
|
||||||
return apm;
|
return apm;
|
||||||
}
|
}
|
||||||
@ -2740,7 +2744,8 @@ TEST(ApmStatistics, ReportOutputRmsDbfs) {
|
|||||||
ptr[i] = 10000 * ((i % 3) - 1);
|
ptr[i] = 10000 * ((i % 3) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<AudioProcessing> apm(AudioProcessingBuilder().Create());
|
std::unique_ptr<AudioProcessing> apm(
|
||||||
|
AudioProcessingBuilderForTesting().Create());
|
||||||
apm->Initialize(processing_config);
|
apm->Initialize(processing_config);
|
||||||
|
|
||||||
// If not enabled, no metric should be reported.
|
// If not enabled, no metric should be reported.
|
||||||
@ -2793,7 +2798,8 @@ TEST(ApmStatistics, ReportHasVoice) {
|
|||||||
ptr[i] = 10000 * ((i % 3) - 1);
|
ptr[i] = 10000 * ((i % 3) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<AudioProcessing> apm(AudioProcessingBuilder().Create());
|
std::unique_ptr<AudioProcessing> apm(
|
||||||
|
AudioProcessingBuilderForTesting().Create());
|
||||||
apm->Initialize(processing_config);
|
apm->Initialize(processing_config);
|
||||||
|
|
||||||
// If not enabled, no metric should be reported.
|
// If not enabled, no metric should be reported.
|
||||||
|
|||||||
@ -685,19 +685,34 @@ class RTC_EXPORT AudioProcessingBuilder {
|
|||||||
~AudioProcessingBuilder();
|
~AudioProcessingBuilder();
|
||||||
// The AudioProcessingBuilder takes ownership of the echo_control_factory.
|
// The AudioProcessingBuilder takes ownership of the echo_control_factory.
|
||||||
AudioProcessingBuilder& SetEchoControlFactory(
|
AudioProcessingBuilder& SetEchoControlFactory(
|
||||||
std::unique_ptr<EchoControlFactory> echo_control_factory);
|
std::unique_ptr<EchoControlFactory> echo_control_factory) {
|
||||||
|
echo_control_factory_ = std::move(echo_control_factory);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
// The AudioProcessingBuilder takes ownership of the capture_post_processing.
|
// The AudioProcessingBuilder takes ownership of the capture_post_processing.
|
||||||
AudioProcessingBuilder& SetCapturePostProcessing(
|
AudioProcessingBuilder& SetCapturePostProcessing(
|
||||||
std::unique_ptr<CustomProcessing> capture_post_processing);
|
std::unique_ptr<CustomProcessing> capture_post_processing) {
|
||||||
|
capture_post_processing_ = std::move(capture_post_processing);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
// The AudioProcessingBuilder takes ownership of the render_pre_processing.
|
// The AudioProcessingBuilder takes ownership of the render_pre_processing.
|
||||||
AudioProcessingBuilder& SetRenderPreProcessing(
|
AudioProcessingBuilder& SetRenderPreProcessing(
|
||||||
std::unique_ptr<CustomProcessing> render_pre_processing);
|
std::unique_ptr<CustomProcessing> render_pre_processing) {
|
||||||
|
render_pre_processing_ = std::move(render_pre_processing);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
// The AudioProcessingBuilder takes ownership of the echo_detector.
|
// The AudioProcessingBuilder takes ownership of the echo_detector.
|
||||||
AudioProcessingBuilder& SetEchoDetector(
|
AudioProcessingBuilder& SetEchoDetector(
|
||||||
rtc::scoped_refptr<EchoDetector> echo_detector);
|
rtc::scoped_refptr<EchoDetector> echo_detector) {
|
||||||
|
echo_detector_ = std::move(echo_detector);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
// The AudioProcessingBuilder takes ownership of the capture_analyzer.
|
// The AudioProcessingBuilder takes ownership of the capture_analyzer.
|
||||||
AudioProcessingBuilder& SetCaptureAnalyzer(
|
AudioProcessingBuilder& SetCaptureAnalyzer(
|
||||||
std::unique_ptr<CustomAudioAnalyzer> capture_analyzer);
|
std::unique_ptr<CustomAudioAnalyzer> capture_analyzer) {
|
||||||
|
capture_analyzer_ = std::move(capture_analyzer);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
// This creates an APM instance using the previously set components. Calling
|
// This creates an APM instance using the previously set components. Calling
|
||||||
// the Create function resets the AudioProcessingBuilder to its initial state.
|
// the Create function resets the AudioProcessingBuilder to its initial state.
|
||||||
AudioProcessing* Create();
|
AudioProcessing* Create();
|
||||||
|
|||||||
@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "modules/audio_processing/test/audio_processing_builder_for_testing.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "modules/audio_processing/audio_processing_impl.h"
|
||||||
|
#include "rtc_base/ref_counted_object.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
AudioProcessingBuilderForTesting::AudioProcessingBuilderForTesting() = default;
|
||||||
|
AudioProcessingBuilderForTesting::~AudioProcessingBuilderForTesting() = default;
|
||||||
|
|
||||||
|
#ifdef WEBRTC_EXCLUDE_AUDIO_PROCESSING_MODULE
|
||||||
|
|
||||||
|
AudioProcessing* AudioProcessingBuilderForTesting::Create() {
|
||||||
|
webrtc::Config config;
|
||||||
|
return Create(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioProcessing* AudioProcessingBuilderForTesting::Create(
|
||||||
|
const webrtc::Config& config) {
|
||||||
|
AudioProcessingImpl* apm = new rtc::RefCountedObject<AudioProcessingImpl>(
|
||||||
|
config, std::move(capture_post_processing_),
|
||||||
|
std::move(render_pre_processing_), std::move(echo_control_factory_),
|
||||||
|
std::move(echo_detector_), std::move(capture_analyzer_));
|
||||||
|
int error = apm->Initialize();
|
||||||
|
RTC_CHECK_EQ(error, AudioProcessing::kNoError);
|
||||||
|
return apm;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
AudioProcessing* AudioProcessingBuilderForTesting::Create() {
|
||||||
|
AudioProcessingBuilder builder;
|
||||||
|
TransferOwnershipsToBuilder(&builder);
|
||||||
|
return builder.Create();
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioProcessing* AudioProcessingBuilderForTesting::Create(
|
||||||
|
const webrtc::Config& config) {
|
||||||
|
AudioProcessingBuilder builder;
|
||||||
|
TransferOwnershipsToBuilder(&builder);
|
||||||
|
return builder.Create(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void AudioProcessingBuilderForTesting::TransferOwnershipsToBuilder(
|
||||||
|
AudioProcessingBuilder* builder) {
|
||||||
|
builder->SetCapturePostProcessing(std::move(capture_post_processing_));
|
||||||
|
builder->SetRenderPreProcessing(std::move(render_pre_processing_));
|
||||||
|
builder->SetCaptureAnalyzer(std::move(capture_analyzer_));
|
||||||
|
builder->SetEchoControlFactory(std::move(echo_control_factory_));
|
||||||
|
builder->SetEchoDetector(std::move(echo_detector_));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace webrtc
|
||||||
@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020 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 MODULES_AUDIO_PROCESSING_TEST_AUDIO_PROCESSING_BUILDER_FOR_TESTING_H_
|
||||||
|
#define MODULES_AUDIO_PROCESSING_TEST_AUDIO_PROCESSING_BUILDER_FOR_TESTING_H_
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
#include <memory>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "modules/audio_processing/include/audio_processing.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
// Facilitates building of AudioProcessingImp for the tests.
|
||||||
|
class AudioProcessingBuilderForTesting {
|
||||||
|
public:
|
||||||
|
AudioProcessingBuilderForTesting();
|
||||||
|
~AudioProcessingBuilderForTesting();
|
||||||
|
// The AudioProcessingBuilderForTesting takes ownership of the
|
||||||
|
// echo_control_factory.
|
||||||
|
AudioProcessingBuilderForTesting& SetEchoControlFactory(
|
||||||
|
std::unique_ptr<EchoControlFactory> echo_control_factory) {
|
||||||
|
echo_control_factory_ = std::move(echo_control_factory);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
// The AudioProcessingBuilderForTesting takes ownership of the
|
||||||
|
// capture_post_processing.
|
||||||
|
AudioProcessingBuilderForTesting& SetCapturePostProcessing(
|
||||||
|
std::unique_ptr<CustomProcessing> capture_post_processing) {
|
||||||
|
capture_post_processing_ = std::move(capture_post_processing);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
// The AudioProcessingBuilderForTesting takes ownership of the
|
||||||
|
// render_pre_processing.
|
||||||
|
AudioProcessingBuilderForTesting& SetRenderPreProcessing(
|
||||||
|
std::unique_ptr<CustomProcessing> render_pre_processing) {
|
||||||
|
render_pre_processing_ = std::move(render_pre_processing);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
// The AudioProcessingBuilderForTesting takes ownership of the echo_detector.
|
||||||
|
AudioProcessingBuilderForTesting& SetEchoDetector(
|
||||||
|
rtc::scoped_refptr<EchoDetector> echo_detector) {
|
||||||
|
echo_detector_ = std::move(echo_detector);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
// The AudioProcessingBuilderForTesting takes ownership of the
|
||||||
|
// capture_analyzer.
|
||||||
|
AudioProcessingBuilderForTesting& SetCaptureAnalyzer(
|
||||||
|
std::unique_ptr<CustomAudioAnalyzer> capture_analyzer) {
|
||||||
|
capture_analyzer_ = std::move(capture_analyzer);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
// This creates an APM instance using the previously set components. Calling
|
||||||
|
// the Create function resets the AudioProcessingBuilderForTesting to its
|
||||||
|
// initial state.
|
||||||
|
AudioProcessing* Create();
|
||||||
|
AudioProcessing* Create(const webrtc::Config& config);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Transfers the ownership to a non-testing builder.
|
||||||
|
void TransferOwnershipsToBuilder(AudioProcessingBuilder* builder);
|
||||||
|
|
||||||
|
std::unique_ptr<EchoControlFactory> echo_control_factory_;
|
||||||
|
std::unique_ptr<CustomProcessing> capture_post_processing_;
|
||||||
|
std::unique_ptr<CustomProcessing> render_pre_processing_;
|
||||||
|
rtc::scoped_refptr<EchoDetector> echo_detector_;
|
||||||
|
std::unique_ptr<CustomAudioAnalyzer> capture_analyzer_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace webrtc
|
||||||
|
|
||||||
|
#endif // MODULES_AUDIO_PROCESSING_TEST_AUDIO_PROCESSING_BUILDER_FOR_TESTING_H_
|
||||||
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include "modules/audio_processing/test/debug_dump_replayer.h"
|
#include "modules/audio_processing/test/debug_dump_replayer.h"
|
||||||
|
|
||||||
|
#include "modules/audio_processing/test/audio_processing_builder_for_testing.h"
|
||||||
#include "modules/audio_processing/test/protobuf_utils.h"
|
#include "modules/audio_processing/test/protobuf_utils.h"
|
||||||
#include "modules/audio_processing/test/runtime_setting_util.h"
|
#include "modules/audio_processing/test/runtime_setting_util.h"
|
||||||
#include "rtc_base/checks.h"
|
#include "rtc_base/checks.h"
|
||||||
@ -185,7 +186,7 @@ void DebugDumpReplayer::MaybeRecreateApm(const audioproc::Config& msg) {
|
|||||||
// We only create APM once, since changes on these fields should not
|
// We only create APM once, since changes on these fields should not
|
||||||
// happen in current implementation.
|
// happen in current implementation.
|
||||||
if (!apm_.get()) {
|
if (!apm_.get()) {
|
||||||
apm_.reset(AudioProcessingBuilder().Create(config));
|
apm_.reset(AudioProcessingBuilderForTesting().Create(config));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -17,6 +17,7 @@
|
|||||||
#include "api/audio/echo_canceller3_factory.h"
|
#include "api/audio/echo_canceller3_factory.h"
|
||||||
#include "modules/audio_coding/neteq/tools/resample_input_audio_file.h"
|
#include "modules/audio_coding/neteq/tools/resample_input_audio_file.h"
|
||||||
#include "modules/audio_processing/aec_dump/aec_dump_factory.h"
|
#include "modules/audio_processing/aec_dump/aec_dump_factory.h"
|
||||||
|
#include "modules/audio_processing/test/audio_processing_builder_for_testing.h"
|
||||||
#include "modules/audio_processing/test/debug_dump_replayer.h"
|
#include "modules/audio_processing/test/debug_dump_replayer.h"
|
||||||
#include "modules/audio_processing/test/test_utils.h"
|
#include "modules/audio_processing/test/test_utils.h"
|
||||||
#include "rtc_base/task_queue_for_test.h"
|
#include "rtc_base/task_queue_for_test.h"
|
||||||
@ -141,7 +142,7 @@ DebugDumpGenerator::DebugDumpGenerator(const std::string& input_file_name,
|
|||||||
enable_pre_amplifier_(enable_pre_amplifier),
|
enable_pre_amplifier_(enable_pre_amplifier),
|
||||||
worker_queue_("debug_dump_generator_worker_queue"),
|
worker_queue_("debug_dump_generator_worker_queue"),
|
||||||
dump_file_name_(dump_file_name) {
|
dump_file_name_(dump_file_name) {
|
||||||
AudioProcessingBuilder apm_builder;
|
AudioProcessingBuilderForTesting apm_builder;
|
||||||
apm_.reset(apm_builder.Create(config));
|
apm_.reset(apm_builder.Create(config));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -587,6 +587,7 @@ if (rtc_include_tests) {
|
|||||||
"../media:rtc_media_engine_defaults",
|
"../media:rtc_media_engine_defaults",
|
||||||
"../modules/audio_device:audio_device_api",
|
"../modules/audio_device:audio_device_api",
|
||||||
"../modules/audio_processing:audio_processing_statistics",
|
"../modules/audio_processing:audio_processing_statistics",
|
||||||
|
"../modules/audio_processing:audioproc_test_utils",
|
||||||
"../modules/rtp_rtcp:rtp_rtcp_format",
|
"../modules/rtp_rtcp:rtp_rtcp_format",
|
||||||
"../p2p:fake_ice_transport",
|
"../p2p:fake_ice_transport",
|
||||||
"../p2p:fake_port_allocator",
|
"../p2p:fake_port_allocator",
|
||||||
|
|||||||
@ -36,6 +36,7 @@
|
|||||||
#include "media/engine/fake_webrtc_video_engine.h"
|
#include "media/engine/fake_webrtc_video_engine.h"
|
||||||
#include "media/engine/webrtc_media_engine.h"
|
#include "media/engine/webrtc_media_engine.h"
|
||||||
#include "media/engine/webrtc_media_engine_defaults.h"
|
#include "media/engine/webrtc_media_engine_defaults.h"
|
||||||
|
#include "modules/audio_processing/test/audio_processing_builder_for_testing.h"
|
||||||
#include "p2p/base/fake_ice_transport.h"
|
#include "p2p/base/fake_ice_transport.h"
|
||||||
#include "p2p/base/mock_async_resolver.h"
|
#include "p2p/base/mock_async_resolver.h"
|
||||||
#include "p2p/base/p2p_constants.h"
|
#include "p2p/base/p2p_constants.h"
|
||||||
@ -648,6 +649,12 @@ class PeerConnectionWrapper : public webrtc::PeerConnectionObserver,
|
|||||||
media_deps.video_decoder_factory.reset();
|
media_deps.video_decoder_factory.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!media_deps.audio_processing) {
|
||||||
|
// If the standard Creation method for APM returns a null pointer, instead
|
||||||
|
// use the builder for testing to create an APM object.
|
||||||
|
media_deps.audio_processing = AudioProcessingBuilderForTesting().Create();
|
||||||
|
}
|
||||||
|
|
||||||
pc_factory_dependencies.media_engine =
|
pc_factory_dependencies.media_engine =
|
||||||
cricket::CreateMediaEngine(std::move(media_deps));
|
cricket::CreateMediaEngine(std::move(media_deps));
|
||||||
pc_factory_dependencies.call_factory = webrtc::CreateCallFactory();
|
pc_factory_dependencies.call_factory = webrtc::CreateCallFactory();
|
||||||
|
|||||||
@ -453,6 +453,7 @@ webrtc_fuzzer_test("audio_processing_fuzzer") {
|
|||||||
"../../modules/audio_processing",
|
"../../modules/audio_processing",
|
||||||
"../../modules/audio_processing:api",
|
"../../modules/audio_processing:api",
|
||||||
"../../modules/audio_processing:audio_buffer",
|
"../../modules/audio_processing:audio_buffer",
|
||||||
|
"../../modules/audio_processing:audioproc_test_utils",
|
||||||
"../../modules/audio_processing/aec3",
|
"../../modules/audio_processing/aec3",
|
||||||
"../../modules/audio_processing/aec_dump",
|
"../../modules/audio_processing/aec_dump",
|
||||||
"../../modules/audio_processing/aec_dump:aec_dump_impl",
|
"../../modules/audio_processing/aec_dump:aec_dump_impl",
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
#include "api/task_queue/default_task_queue_factory.h"
|
#include "api/task_queue/default_task_queue_factory.h"
|
||||||
#include "modules/audio_processing/aec_dump/aec_dump_factory.h"
|
#include "modules/audio_processing/aec_dump/aec_dump_factory.h"
|
||||||
#include "modules/audio_processing/include/audio_processing.h"
|
#include "modules/audio_processing/include/audio_processing.h"
|
||||||
|
#include "modules/audio_processing/test/audio_processing_builder_for_testing.h"
|
||||||
#include "rtc_base/arraysize.h"
|
#include "rtc_base/arraysize.h"
|
||||||
#include "rtc_base/numerics/safe_minmax.h"
|
#include "rtc_base/numerics/safe_minmax.h"
|
||||||
#include "rtc_base/task_queue.h"
|
#include "rtc_base/task_queue.h"
|
||||||
@ -108,7 +109,7 @@ std::unique_ptr<AudioProcessing> CreateApm(test::FuzzDataHelper* fuzz_data,
|
|||||||
config.Set<ExperimentalNs>(new ExperimentalNs(exp_ns));
|
config.Set<ExperimentalNs>(new ExperimentalNs(exp_ns));
|
||||||
|
|
||||||
std::unique_ptr<AudioProcessing> apm(
|
std::unique_ptr<AudioProcessing> apm(
|
||||||
AudioProcessingBuilder()
|
AudioProcessingBuilderForTesting()
|
||||||
.SetEchoControlFactory(std::move(echo_control_factory))
|
.SetEchoControlFactory(std::move(echo_control_factory))
|
||||||
.Create(config));
|
.Create(config));
|
||||||
|
|
||||||
|
|||||||
@ -33,7 +33,11 @@ class TestPeer final : public PeerConnectionWrapper {
|
|||||||
return std::move(video_generators_[i]);
|
return std::move(video_generators_[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DetachAecDump() { audio_processing_->DetachAecDump(); }
|
void DetachAecDump() {
|
||||||
|
if (audio_processing_) {
|
||||||
|
audio_processing_->DetachAecDump();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Adds provided |candidates| to the owned peer connection.
|
// Adds provided |candidates| to the owned peer connection.
|
||||||
bool AddIceCandidates(
|
bool AddIceCandidates(
|
||||||
|
|||||||
@ -290,7 +290,7 @@ std::unique_ptr<TestPeer> TestPeerFactory::CreateTestPeer(
|
|||||||
// Create peer connection factory.
|
// Create peer connection factory.
|
||||||
rtc::scoped_refptr<AudioProcessing> audio_processing =
|
rtc::scoped_refptr<AudioProcessing> audio_processing =
|
||||||
webrtc::AudioProcessingBuilder().Create();
|
webrtc::AudioProcessingBuilder().Create();
|
||||||
if (params->aec_dump_path) {
|
if (params->aec_dump_path && audio_processing) {
|
||||||
audio_processing->AttachAecDump(
|
audio_processing->AttachAecDump(
|
||||||
AecDumpFactory::Create(*params->aec_dump_path, -1, task_queue));
|
AecDumpFactory::Create(*params->aec_dump_path, -1, task_queue));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -96,6 +96,9 @@ declare_args() {
|
|||||||
# should be generated.
|
# should be generated.
|
||||||
apm_debug_dump = false
|
apm_debug_dump = false
|
||||||
|
|
||||||
|
# Selects whether the audio processing module should be excluded.
|
||||||
|
rtc_exclude_audio_processing_module = false
|
||||||
|
|
||||||
# Set this to true to enable BWE test logging.
|
# Set this to true to enable BWE test logging.
|
||||||
rtc_enable_bwe_test_logging = false
|
rtc_enable_bwe_test_logging = false
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user