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}
diff --git a/audio/audio_send_stream_unittest.cc b/audio/audio_send_stream_unittest.cc
index de1f2fe..8f33d29 100644
--- a/audio/audio_send_stream_unittest.cc
+++ b/audio/audio_send_stream_unittest.cc
@@ -141,11 +141,16 @@
}
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),
task_queue_factory_(CreateDefaultTaskQueueFactory()),
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_),
worker_queue_(task_queue_factory_->CreateTaskQueue(
"ConfigHelper_worker_queue",
@@ -273,7 +278,7 @@
.WillOnce(Return(true));
}
- void SetupMockForGetStats() {
+ void SetupMockForGetStats(bool use_null_audio_processing) {
using ::testing::DoAll;
using ::testing::SetArgPointee;
using ::testing::SetArgReferee;
@@ -305,10 +310,13 @@
audio_processing_stats_.residual_echo_likelihood = kResidualEchoLikelihood;
audio_processing_stats_.residual_echo_likelihood_recent_max =
kResidualEchoLikelihoodMax;
-
- EXPECT_CALL(*audio_processing_, GetStatistics(true))
- .WillRepeatedly(Return(audio_processing_stats_));
+ if (!use_null_audio_processing) {
+ ASSERT_TRUE(audio_processing_);
+ EXPECT_CALL(*audio_processing_, GetStatistics(true))
+ .WillRepeatedly(Return(audio_processing_stats_));
+ }
}
+
TaskQueueForTest* worker() { return &worker_queue_; }
private:
@@ -381,235 +389,270 @@
}
TEST(AudioSendStreamTest, ConstructDestruct) {
- ConfigHelper helper(false, true);
- auto send_stream = helper.CreateAudioSendStream();
+ for (bool use_null_audio_processing : {false, true}) {
+ ConfigHelper helper(false, true, use_null_audio_processing);
+ auto send_stream = helper.CreateAudioSendStream();
+ }
}
TEST(AudioSendStreamTest, SendTelephoneEvent) {
- ConfigHelper helper(false, true);
- auto send_stream = helper.CreateAudioSendStream();
- helper.SetupMockForSendTelephoneEvent();
- EXPECT_TRUE(send_stream->SendTelephoneEvent(
- kTelephoneEventPayloadType, kTelephoneEventPayloadFrequency,
- kTelephoneEventCode, kTelephoneEventDuration));
+ for (bool use_null_audio_processing : {false, true}) {
+ ConfigHelper helper(false, true, use_null_audio_processing);
+ auto send_stream = helper.CreateAudioSendStream();
+ helper.SetupMockForSendTelephoneEvent();
+ EXPECT_TRUE(send_stream->SendTelephoneEvent(
+ kTelephoneEventPayloadType, kTelephoneEventPayloadFrequency,
+ kTelephoneEventCode, kTelephoneEventDuration));
+ }
}
TEST(AudioSendStreamTest, SetMuted) {
- ConfigHelper helper(false, true);
- auto send_stream = helper.CreateAudioSendStream();
- EXPECT_CALL(*helper.channel_send(), SetInputMute(true));
- send_stream->SetMuted(true);
+ for (bool use_null_audio_processing : {false, true}) {
+ ConfigHelper helper(false, true, use_null_audio_processing);
+ auto send_stream = helper.CreateAudioSendStream();
+ EXPECT_CALL(*helper.channel_send(), SetInputMute(true));
+ send_stream->SetMuted(true);
+ }
}
TEST(AudioSendStreamTest, AudioBweCorrectObjectsOnChannelProxy) {
ScopedFieldTrials field_trials("WebRTC-Audio-SendSideBwe/Enabled/");
- ConfigHelper helper(true, true);
- auto send_stream = helper.CreateAudioSendStream();
+ for (bool use_null_audio_processing : {false, true}) {
+ ConfigHelper helper(true, true, use_null_audio_processing);
+ auto send_stream = helper.CreateAudioSendStream();
+ }
}
TEST(AudioSendStreamTest, NoAudioBweCorrectObjectsOnChannelProxy) {
- ConfigHelper helper(false, true);
- auto send_stream = helper.CreateAudioSendStream();
+ for (bool use_null_audio_processing : {false, true}) {
+ ConfigHelper helper(false, true, use_null_audio_processing);
+ auto send_stream = helper.CreateAudioSendStream();
+ }
}
TEST(AudioSendStreamTest, GetStats) {
- ConfigHelper helper(false, true);
- auto send_stream = helper.CreateAudioSendStream();
- helper.SetupMockForGetStats();
- AudioSendStream::Stats stats = send_stream->GetStats(true);
- EXPECT_EQ(kSsrc, stats.local_ssrc);
- EXPECT_EQ(kCallStats.payload_bytes_sent, stats.payload_bytes_sent);
- EXPECT_EQ(kCallStats.header_and_padding_bytes_sent,
- stats.header_and_padding_bytes_sent);
- EXPECT_EQ(kCallStats.packetsSent, stats.packets_sent);
- EXPECT_EQ(kReportBlock.cumulative_num_packets_lost, stats.packets_lost);
- EXPECT_EQ(Q8ToFloat(kReportBlock.fraction_lost), stats.fraction_lost);
- EXPECT_EQ(kIsacFormat.name, stats.codec_name);
- EXPECT_EQ(static_cast<int32_t>(kReportBlock.interarrival_jitter /
- (kIsacFormat.clockrate_hz / 1000)),
- stats.jitter_ms);
- EXPECT_EQ(kCallStats.rttMs, stats.rtt_ms);
- EXPECT_EQ(0, stats.audio_level);
- EXPECT_EQ(0, stats.total_input_energy);
- EXPECT_EQ(0, stats.total_input_duration);
- EXPECT_EQ(kEchoDelayMedian, stats.apm_statistics.delay_median_ms);
- EXPECT_EQ(kEchoDelayStdDev, stats.apm_statistics.delay_standard_deviation_ms);
- EXPECT_EQ(kEchoReturnLoss, stats.apm_statistics.echo_return_loss);
- EXPECT_EQ(kEchoReturnLossEnhancement,
- stats.apm_statistics.echo_return_loss_enhancement);
- EXPECT_EQ(kDivergentFilterFraction,
- stats.apm_statistics.divergent_filter_fraction);
- EXPECT_EQ(kResidualEchoLikelihood,
- stats.apm_statistics.residual_echo_likelihood);
- EXPECT_EQ(kResidualEchoLikelihoodMax,
- stats.apm_statistics.residual_echo_likelihood_recent_max);
- EXPECT_FALSE(stats.typing_noise_detected);
+ for (bool use_null_audio_processing : {false, true}) {
+ ConfigHelper helper(false, true, use_null_audio_processing);
+ auto send_stream = helper.CreateAudioSendStream();
+ helper.SetupMockForGetStats(use_null_audio_processing);
+ AudioSendStream::Stats stats = send_stream->GetStats(true);
+ EXPECT_EQ(kSsrc, stats.local_ssrc);
+ EXPECT_EQ(kCallStats.payload_bytes_sent, stats.payload_bytes_sent);
+ EXPECT_EQ(kCallStats.header_and_padding_bytes_sent,
+ stats.header_and_padding_bytes_sent);
+ EXPECT_EQ(kCallStats.packetsSent, stats.packets_sent);
+ EXPECT_EQ(kReportBlock.cumulative_num_packets_lost, stats.packets_lost);
+ EXPECT_EQ(Q8ToFloat(kReportBlock.fraction_lost), stats.fraction_lost);
+ EXPECT_EQ(kIsacFormat.name, stats.codec_name);
+ EXPECT_EQ(static_cast<int32_t>(kReportBlock.interarrival_jitter /
+ (kIsacFormat.clockrate_hz / 1000)),
+ stats.jitter_ms);
+ EXPECT_EQ(kCallStats.rttMs, stats.rtt_ms);
+ EXPECT_EQ(0, stats.audio_level);
+ EXPECT_EQ(0, stats.total_input_energy);
+ EXPECT_EQ(0, stats.total_input_duration);
+
+ if (!use_null_audio_processing) {
+ EXPECT_EQ(kEchoDelayMedian, stats.apm_statistics.delay_median_ms);
+ EXPECT_EQ(kEchoDelayStdDev,
+ stats.apm_statistics.delay_standard_deviation_ms);
+ EXPECT_EQ(kEchoReturnLoss, stats.apm_statistics.echo_return_loss);
+ EXPECT_EQ(kEchoReturnLossEnhancement,
+ stats.apm_statistics.echo_return_loss_enhancement);
+ EXPECT_EQ(kDivergentFilterFraction,
+ stats.apm_statistics.divergent_filter_fraction);
+ EXPECT_EQ(kResidualEchoLikelihood,
+ stats.apm_statistics.residual_echo_likelihood);
+ EXPECT_EQ(kResidualEchoLikelihoodMax,
+ stats.apm_statistics.residual_echo_likelihood_recent_max);
+ EXPECT_FALSE(stats.typing_noise_detected);
+ }
+ }
}
TEST(AudioSendStreamTest, GetStatsAudioLevel) {
- ConfigHelper helper(false, true);
- auto send_stream = helper.CreateAudioSendStream();
- helper.SetupMockForGetStats();
- EXPECT_CALL(*helper.channel_send(), ProcessAndEncodeAudioForMock(_))
- .Times(AnyNumber());
+ for (bool use_null_audio_processing : {false, true}) {
+ ConfigHelper helper(false, true, use_null_audio_processing);
+ auto send_stream = helper.CreateAudioSendStream();
+ helper.SetupMockForGetStats(use_null_audio_processing);
+ EXPECT_CALL(*helper.channel_send(), ProcessAndEncodeAudioForMock(_))
+ .Times(AnyNumber());
- constexpr int kSampleRateHz = 48000;
- constexpr size_t kNumChannels = 1;
+ constexpr int kSampleRateHz = 48000;
+ constexpr size_t kNumChannels = 1;
- constexpr int16_t kSilentAudioLevel = 0;
- constexpr int16_t kMaxAudioLevel = 32767; // Audio level is [0,32767].
- constexpr int kAudioFrameDurationMs = 10;
+ constexpr int16_t kSilentAudioLevel = 0;
+ constexpr int16_t kMaxAudioLevel = 32767; // Audio level is [0,32767].
+ constexpr int kAudioFrameDurationMs = 10;
- // 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
- // of the first 11 frames. See AudioLevel.
- for (size_t i = 0; i < 10; ++i) {
- send_stream->SendAudioData(CreateAudioFrame1kHzSineWave(
- kSilentAudioLevel, kAudioFrameDurationMs, kSampleRateHz, kNumChannels));
+ // 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 of the first 11 frames. See AudioLevel.
+ for (size_t i = 0; i < 10; ++i) {
+ send_stream->SendAudioData(
+ CreateAudioFrame1kHzSineWave(kSilentAudioLevel, kAudioFrameDurationMs,
+ kSampleRateHz, kNumChannels));
+ }
+ AudioSendStream::Stats stats = send_stream->GetStats();
+ EXPECT_EQ(kSilentAudioLevel, stats.audio_level);
+ EXPECT_NEAR(0.0f, stats.total_input_energy, kTolerance);
+ EXPECT_NEAR(0.1f, stats.total_input_duration,
+ kTolerance); // 100 ms = 0.1 s
+
+ // Process 10 audio frames (100 ms) of maximum audio level.
+ // Note that AudioLevel updates the audio level every 11th frame, processing
+ // 10 frames above was needed to see a non-zero audio level here.
+ for (size_t i = 0; i < 10; ++i) {
+ send_stream->SendAudioData(CreateAudioFrame1kHzSineWave(
+ kMaxAudioLevel, kAudioFrameDurationMs, kSampleRateHz, kNumChannels));
+ }
+ stats = send_stream->GetStats();
+ EXPECT_EQ(kMaxAudioLevel, stats.audio_level);
+ // 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.2f, stats.total_input_duration,
+ kTolerance); // 200 ms = 0.2 s
}
- AudioSendStream::Stats stats = send_stream->GetStats();
- EXPECT_EQ(kSilentAudioLevel, stats.audio_level);
- EXPECT_NEAR(0.0f, stats.total_input_energy, kTolerance);
- EXPECT_NEAR(0.1f, stats.total_input_duration, kTolerance); // 100 ms = 0.1 s
-
- // Process 10 audio frames (100 ms) of maximum audio level.
- // Note that AudioLevel updates the audio level every 11th frame, processing
- // 10 frames above was needed to see a non-zero audio level here.
- for (size_t i = 0; i < 10; ++i) {
- send_stream->SendAudioData(CreateAudioFrame1kHzSineWave(
- kMaxAudioLevel, kAudioFrameDurationMs, kSampleRateHz, kNumChannels));
- }
- stats = send_stream->GetStats();
- EXPECT_EQ(kMaxAudioLevel, stats.audio_level);
- // 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.2f, stats.total_input_duration, kTolerance); // 200 ms = 0.2 s
}
TEST(AudioSendStreamTest, SendCodecAppliesAudioNetworkAdaptor) {
- ConfigHelper helper(false, true);
- helper.config().send_codec_spec =
- AudioSendStream::Config::SendCodecSpec(0, kOpusFormat);
- const std::string kAnaConfigString = "abcde";
- const std::string kAnaReconfigString = "12345";
+ for (bool use_null_audio_processing : {false, true}) {
+ ConfigHelper helper(false, true, use_null_audio_processing);
+ helper.config().send_codec_spec =
+ AudioSendStream::Config::SendCodecSpec(0, kOpusFormat);
+ const std::string kAnaConfigString = "abcde";
+ const std::string kAnaReconfigString = "12345";
- helper.config().rtp.extensions.push_back(RtpExtension(
- RtpExtension::kTransportSequenceNumberUri, kTransportSequenceNumberId));
- helper.config().audio_network_adaptor_config = kAnaConfigString;
+ helper.config().rtp.extensions.push_back(RtpExtension(
+ RtpExtension::kTransportSequenceNumberUri, kTransportSequenceNumberId));
+ helper.config().audio_network_adaptor_config = kAnaConfigString;
- EXPECT_CALL(helper.mock_encoder_factory(), MakeAudioEncoderMock(_, _, _, _))
- .WillOnce(Invoke([&kAnaConfigString, &kAnaReconfigString](
- int payload_type, const SdpAudioFormat& format,
- absl::optional<AudioCodecPairId> codec_pair_id,
- std::unique_ptr<AudioEncoder>* return_value) {
- auto mock_encoder = SetupAudioEncoderMock(payload_type, format);
- EXPECT_CALL(*mock_encoder,
- EnableAudioNetworkAdaptor(StrEq(kAnaConfigString), _))
- .WillOnce(Return(true));
- EXPECT_CALL(*mock_encoder,
- EnableAudioNetworkAdaptor(StrEq(kAnaReconfigString), _))
- .WillOnce(Return(true));
- *return_value = std::move(mock_encoder);
- }));
+ EXPECT_CALL(helper.mock_encoder_factory(), MakeAudioEncoderMock(_, _, _, _))
+ .WillOnce(Invoke([&kAnaConfigString, &kAnaReconfigString](
+ int payload_type, const SdpAudioFormat& format,
+ absl::optional<AudioCodecPairId> codec_pair_id,
+ std::unique_ptr<AudioEncoder>* return_value) {
+ auto mock_encoder = SetupAudioEncoderMock(payload_type, format);
+ EXPECT_CALL(*mock_encoder,
+ EnableAudioNetworkAdaptor(StrEq(kAnaConfigString), _))
+ .WillOnce(Return(true));
+ EXPECT_CALL(*mock_encoder,
+ EnableAudioNetworkAdaptor(StrEq(kAnaReconfigString), _))
+ .WillOnce(Return(true));
+ *return_value = std::move(mock_encoder);
+ }));
- auto send_stream = helper.CreateAudioSendStream();
+ auto send_stream = helper.CreateAudioSendStream();
- auto stream_config = helper.config();
- stream_config.audio_network_adaptor_config = kAnaReconfigString;
+ auto stream_config = helper.config();
+ stream_config.audio_network_adaptor_config = kAnaReconfigString;
- send_stream->Reconfigure(stream_config);
+ send_stream->Reconfigure(stream_config);
+ }
}
// VAD is applied when codec is mono and the CNG frequency matches the codec
// clock rate.
TEST(AudioSendStreamTest, SendCodecCanApplyVad) {
- ConfigHelper helper(false, false);
- helper.config().send_codec_spec =
- AudioSendStream::Config::SendCodecSpec(9, kG722Format);
- helper.config().send_codec_spec->cng_payload_type = 105;
- using ::testing::Invoke;
- std::unique_ptr<AudioEncoder> stolen_encoder;
- EXPECT_CALL(*helper.channel_send(), SetEncoderForMock(_, _))
- .WillOnce(
- Invoke([&stolen_encoder](int payload_type,
- std::unique_ptr<AudioEncoder>* encoder) {
- stolen_encoder = std::move(*encoder);
- return true;
- }));
- EXPECT_CALL(*helper.channel_send(), RegisterCngPayloadType(105, 8000));
+ for (bool use_null_audio_processing : {false, true}) {
+ ConfigHelper helper(false, false, use_null_audio_processing);
+ helper.config().send_codec_spec =
+ AudioSendStream::Config::SendCodecSpec(9, kG722Format);
+ helper.config().send_codec_spec->cng_payload_type = 105;
+ using ::testing::Invoke;
+ std::unique_ptr<AudioEncoder> stolen_encoder;
+ EXPECT_CALL(*helper.channel_send(), SetEncoderForMock(_, _))
+ .WillOnce(
+ Invoke([&stolen_encoder](int payload_type,
+ std::unique_ptr<AudioEncoder>* encoder) {
+ stolen_encoder = std::move(*encoder);
+ return true;
+ }));
+ EXPECT_CALL(*helper.channel_send(), RegisterCngPayloadType(105, 8000));
- auto send_stream = helper.CreateAudioSendStream();
+ auto send_stream = helper.CreateAudioSendStream();
- // We cannot truly determine if the encoder created is an AudioEncoderCng. It
- // is the only reasonable implementation that will return something from
- // ReclaimContainedEncoders, though.
- ASSERT_TRUE(stolen_encoder);
- EXPECT_FALSE(stolen_encoder->ReclaimContainedEncoders().empty());
+ // We cannot truly determine if the encoder created is an AudioEncoderCng.
+ // It is the only reasonable implementation that will return something from
+ // ReclaimContainedEncoders, though.
+ ASSERT_TRUE(stolen_encoder);
+ EXPECT_FALSE(stolen_encoder->ReclaimContainedEncoders().empty());
+ }
}
TEST(AudioSendStreamTest, DoesNotPassHigherBitrateThanMaxBitrate) {
- ConfigHelper helper(false, true);
- auto send_stream = helper.CreateAudioSendStream();
- EXPECT_CALL(*helper.channel_send(),
- OnBitrateAllocation(Field(
- &BitrateAllocationUpdate::target_bitrate,
+ for (bool use_null_audio_processing : {false, true}) {
+ ConfigHelper helper(false, true, use_null_audio_processing);
+ auto send_stream = helper.CreateAudioSendStream();
+ EXPECT_CALL(
+ *helper.channel_send(),
+ OnBitrateAllocation(
+ Field(&BitrateAllocationUpdate::target_bitrate,
Eq(DataRate::BitsPerSec(helper.config().max_bitrate_bps)))));
- BitrateAllocationUpdate update;
- update.target_bitrate =
- DataRate::BitsPerSec(helper.config().max_bitrate_bps + 5000);
- update.packet_loss_ratio = 0;
- update.round_trip_time = TimeDelta::Millis(50);
- update.bwe_period = TimeDelta::Millis(6000);
- helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
- RTC_FROM_HERE);
+ BitrateAllocationUpdate update;
+ update.target_bitrate =
+ DataRate::BitsPerSec(helper.config().max_bitrate_bps + 5000);
+ update.packet_loss_ratio = 0;
+ update.round_trip_time = TimeDelta::Millis(50);
+ update.bwe_period = TimeDelta::Millis(6000);
+ helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
+ RTC_FROM_HERE);
+ }
}
TEST(AudioSendStreamTest, SSBweTargetInRangeRespected) {
ScopedFieldTrials field_trials("WebRTC-Audio-SendSideBwe/Enabled/");
- ConfigHelper helper(true, true);
- auto send_stream = helper.CreateAudioSendStream();
- EXPECT_CALL(
- *helper.channel_send(),
- OnBitrateAllocation(Field(
- &BitrateAllocationUpdate::target_bitrate,
- Eq(DataRate::BitsPerSec(helper.config().max_bitrate_bps - 5000)))));
- BitrateAllocationUpdate update;
- update.target_bitrate =
- DataRate::BitsPerSec(helper.config().max_bitrate_bps - 5000);
- helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
- RTC_FROM_HERE);
+ for (bool use_null_audio_processing : {false, true}) {
+ ConfigHelper helper(true, true, use_null_audio_processing);
+ auto send_stream = helper.CreateAudioSendStream();
+ EXPECT_CALL(
+ *helper.channel_send(),
+ OnBitrateAllocation(Field(
+ &BitrateAllocationUpdate::target_bitrate,
+ Eq(DataRate::BitsPerSec(helper.config().max_bitrate_bps - 5000)))));
+ BitrateAllocationUpdate update;
+ update.target_bitrate =
+ DataRate::BitsPerSec(helper.config().max_bitrate_bps - 5000);
+ helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
+ RTC_FROM_HERE);
+ }
}
TEST(AudioSendStreamTest, SSBweFieldTrialMinRespected) {
ScopedFieldTrials field_trials(
"WebRTC-Audio-SendSideBwe/Enabled/"
"WebRTC-Audio-Allocation/min:6kbps,max:64kbps/");
- ConfigHelper helper(true, true);
- auto send_stream = helper.CreateAudioSendStream();
- EXPECT_CALL(
- *helper.channel_send(),
- OnBitrateAllocation(Field(&BitrateAllocationUpdate::target_bitrate,
- Eq(DataRate::KilobitsPerSec(6)))));
- BitrateAllocationUpdate update;
- update.target_bitrate = DataRate::KilobitsPerSec(1);
- helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
- RTC_FROM_HERE);
+ for (bool use_null_audio_processing : {false, true}) {
+ ConfigHelper helper(true, true, use_null_audio_processing);
+ auto send_stream = helper.CreateAudioSendStream();
+ EXPECT_CALL(
+ *helper.channel_send(),
+ OnBitrateAllocation(Field(&BitrateAllocationUpdate::target_bitrate,
+ Eq(DataRate::KilobitsPerSec(6)))));
+ BitrateAllocationUpdate update;
+ update.target_bitrate = DataRate::KilobitsPerSec(1);
+ helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
+ RTC_FROM_HERE);
+ }
}
TEST(AudioSendStreamTest, SSBweFieldTrialMaxRespected) {
ScopedFieldTrials field_trials(
"WebRTC-Audio-SendSideBwe/Enabled/"
"WebRTC-Audio-Allocation/min:6kbps,max:64kbps/");
- ConfigHelper helper(true, true);
- auto send_stream = helper.CreateAudioSendStream();
- EXPECT_CALL(
- *helper.channel_send(),
- OnBitrateAllocation(Field(&BitrateAllocationUpdate::target_bitrate,
- Eq(DataRate::KilobitsPerSec(64)))));
- BitrateAllocationUpdate update;
- update.target_bitrate = DataRate::KilobitsPerSec(128);
- helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
- RTC_FROM_HERE);
+ for (bool use_null_audio_processing : {false, true}) {
+ ConfigHelper helper(true, true, use_null_audio_processing);
+ auto send_stream = helper.CreateAudioSendStream();
+ EXPECT_CALL(
+ *helper.channel_send(),
+ OnBitrateAllocation(Field(&BitrateAllocationUpdate::target_bitrate,
+ Eq(DataRate::KilobitsPerSec(64)))));
+ BitrateAllocationUpdate update;
+ update.target_bitrate = DataRate::KilobitsPerSec(128);
+ helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
+ RTC_FROM_HERE);
+ }
}
TEST(AudioSendStreamTest, SSBweWithOverhead) {
@@ -617,19 +660,22 @@
"WebRTC-Audio-SendSideBwe/Enabled/"
"WebRTC-SendSideBwe-WithOverhead/Enabled/"
"WebRTC-Audio-LegacyOverhead/Disabled/");
- ConfigHelper helper(true, true);
- auto send_stream = helper.CreateAudioSendStream();
- EXPECT_CALL(*helper.channel_send(), CallEncoder(_)).Times(1);
- send_stream->OnOverheadChanged(kOverheadPerPacket.bytes<size_t>());
- const DataRate bitrate =
- DataRate::BitsPerSec(helper.config().max_bitrate_bps) + kMaxOverheadRate;
- EXPECT_CALL(*helper.channel_send(),
- OnBitrateAllocation(Field(
- &BitrateAllocationUpdate::target_bitrate, Eq(bitrate))));
- BitrateAllocationUpdate update;
- update.target_bitrate = bitrate;
- helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
- RTC_FROM_HERE);
+ for (bool use_null_audio_processing : {false, true}) {
+ ConfigHelper helper(true, true, use_null_audio_processing);
+ auto send_stream = helper.CreateAudioSendStream();
+ EXPECT_CALL(*helper.channel_send(), CallEncoder(_)).Times(1);
+ send_stream->OnOverheadChanged(kOverheadPerPacket.bytes<size_t>());
+ const DataRate bitrate =
+ DataRate::BitsPerSec(helper.config().max_bitrate_bps) +
+ kMaxOverheadRate;
+ EXPECT_CALL(*helper.channel_send(),
+ OnBitrateAllocation(Field(
+ &BitrateAllocationUpdate::target_bitrate, Eq(bitrate))));
+ BitrateAllocationUpdate update;
+ update.target_bitrate = bitrate;
+ helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
+ RTC_FROM_HERE);
+ }
}
TEST(AudioSendStreamTest, SSBweWithOverheadMinRespected) {
@@ -638,18 +684,20 @@
"WebRTC-SendSideBwe-WithOverhead/Enabled/"
"WebRTC-Audio-LegacyOverhead/Disabled/"
"WebRTC-Audio-Allocation/min:6kbps,max:64kbps/");
- ConfigHelper helper(true, true);
- auto send_stream = helper.CreateAudioSendStream();
- EXPECT_CALL(*helper.channel_send(), CallEncoder(_)).Times(1);
- send_stream->OnOverheadChanged(kOverheadPerPacket.bytes<size_t>());
- const DataRate bitrate = DataRate::KilobitsPerSec(6) + kMinOverheadRate;
- EXPECT_CALL(*helper.channel_send(),
- OnBitrateAllocation(Field(
- &BitrateAllocationUpdate::target_bitrate, Eq(bitrate))));
- BitrateAllocationUpdate update;
- update.target_bitrate = DataRate::KilobitsPerSec(1);
- helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
- RTC_FROM_HERE);
+ for (bool use_null_audio_processing : {false, true}) {
+ ConfigHelper helper(true, true, use_null_audio_processing);
+ auto send_stream = helper.CreateAudioSendStream();
+ EXPECT_CALL(*helper.channel_send(), CallEncoder(_)).Times(1);
+ send_stream->OnOverheadChanged(kOverheadPerPacket.bytes<size_t>());
+ const DataRate bitrate = DataRate::KilobitsPerSec(6) + kMinOverheadRate;
+ EXPECT_CALL(*helper.channel_send(),
+ OnBitrateAllocation(Field(
+ &BitrateAllocationUpdate::target_bitrate, Eq(bitrate))));
+ BitrateAllocationUpdate update;
+ update.target_bitrate = DataRate::KilobitsPerSec(1);
+ helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
+ RTC_FROM_HERE);
+ }
}
TEST(AudioSendStreamTest, SSBweWithOverheadMaxRespected) {
@@ -658,152 +706,172 @@
"WebRTC-SendSideBwe-WithOverhead/Enabled/"
"WebRTC-Audio-LegacyOverhead/Disabled/"
"WebRTC-Audio-Allocation/min:6kbps,max:64kbps/");
- ConfigHelper helper(true, true);
- auto send_stream = helper.CreateAudioSendStream();
- EXPECT_CALL(*helper.channel_send(), CallEncoder(_)).Times(1);
- send_stream->OnOverheadChanged(kOverheadPerPacket.bytes<size_t>());
- const DataRate bitrate = DataRate::KilobitsPerSec(64) + kMaxOverheadRate;
- EXPECT_CALL(*helper.channel_send(),
- OnBitrateAllocation(Field(
- &BitrateAllocationUpdate::target_bitrate, Eq(bitrate))));
- BitrateAllocationUpdate update;
- update.target_bitrate = DataRate::KilobitsPerSec(128);
- helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
- RTC_FROM_HERE);
+ for (bool use_null_audio_processing : {false, true}) {
+ ConfigHelper helper(true, true, use_null_audio_processing);
+ auto send_stream = helper.CreateAudioSendStream();
+ EXPECT_CALL(*helper.channel_send(), CallEncoder(_)).Times(1);
+ send_stream->OnOverheadChanged(kOverheadPerPacket.bytes<size_t>());
+ const DataRate bitrate = DataRate::KilobitsPerSec(64) + kMaxOverheadRate;
+ EXPECT_CALL(*helper.channel_send(),
+ OnBitrateAllocation(Field(
+ &BitrateAllocationUpdate::target_bitrate, Eq(bitrate))));
+ BitrateAllocationUpdate update;
+ update.target_bitrate = DataRate::KilobitsPerSec(128);
+ helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
+ RTC_FROM_HERE);
+ }
}
TEST(AudioSendStreamTest, ProbingIntervalOnBitrateUpdated) {
- ConfigHelper helper(false, true);
- auto send_stream = helper.CreateAudioSendStream();
+ for (bool use_null_audio_processing : {false, true}) {
+ ConfigHelper helper(false, true, use_null_audio_processing);
+ auto send_stream = helper.CreateAudioSendStream();
- EXPECT_CALL(*helper.channel_send(),
- OnBitrateAllocation(Field(&BitrateAllocationUpdate::bwe_period,
- Eq(TimeDelta::Millis(5000)))));
- BitrateAllocationUpdate update;
- update.target_bitrate =
- DataRate::BitsPerSec(helper.config().max_bitrate_bps + 5000);
- update.packet_loss_ratio = 0;
- update.round_trip_time = TimeDelta::Millis(50);
- update.bwe_period = TimeDelta::Millis(5000);
- helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
- RTC_FROM_HERE);
+ EXPECT_CALL(*helper.channel_send(),
+ OnBitrateAllocation(Field(&BitrateAllocationUpdate::bwe_period,
+ Eq(TimeDelta::Millis(5000)))));
+ BitrateAllocationUpdate update;
+ update.target_bitrate =
+ DataRate::BitsPerSec(helper.config().max_bitrate_bps + 5000);
+ update.packet_loss_ratio = 0;
+ update.round_trip_time = TimeDelta::Millis(50);
+ update.bwe_period = TimeDelta::Millis(5000);
+ helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
+ RTC_FROM_HERE);
+ }
}
// Test that AudioSendStream doesn't recreate the encoder unnecessarily.
TEST(AudioSendStreamTest, DontRecreateEncoder) {
- ConfigHelper helper(false, false);
- // WillOnce is (currently) the default used by ConfigHelper if asked to set an
- // expectation for SetEncoder. Since this behavior is essential for this test
- // to be correct, it's instead set-up manually here. Otherwise a simple change
- // to ConfigHelper (say to WillRepeatedly) would silently make this test
- // useless.
- EXPECT_CALL(*helper.channel_send(), SetEncoderForMock(_, _))
- .WillOnce(Return());
+ for (bool use_null_audio_processing : {false, true}) {
+ ConfigHelper helper(false, false, use_null_audio_processing);
+ // WillOnce is (currently) the default used by ConfigHelper if asked to set
+ // an expectation for SetEncoder. Since this behavior is essential for this
+ // test to be correct, it's instead set-up manually here. Otherwise a simple
+ // change to ConfigHelper (say to WillRepeatedly) would silently make this
+ // test useless.
+ EXPECT_CALL(*helper.channel_send(), SetEncoderForMock(_, _))
+ .WillOnce(Return());
- EXPECT_CALL(*helper.channel_send(), RegisterCngPayloadType(105, 8000));
+ EXPECT_CALL(*helper.channel_send(), RegisterCngPayloadType(105, 8000));
- helper.config().send_codec_spec =
- AudioSendStream::Config::SendCodecSpec(9, kG722Format);
- helper.config().send_codec_spec->cng_payload_type = 105;
- auto send_stream = helper.CreateAudioSendStream();
- send_stream->Reconfigure(helper.config());
+ helper.config().send_codec_spec =
+ AudioSendStream::Config::SendCodecSpec(9, kG722Format);
+ helper.config().send_codec_spec->cng_payload_type = 105;
+ auto send_stream = helper.CreateAudioSendStream();
+ send_stream->Reconfigure(helper.config());
+ }
}
TEST(AudioSendStreamTest, ReconfigureTransportCcResetsFirst) {
ScopedFieldTrials field_trials("WebRTC-Audio-SendSideBwe/Enabled/");
- ConfigHelper helper(false, true);
- auto send_stream = helper.CreateAudioSendStream();
- auto new_config = helper.config();
- ConfigHelper::AddBweToConfig(&new_config);
+ for (bool use_null_audio_processing : {false, true}) {
+ ConfigHelper helper(false, true, use_null_audio_processing);
+ auto send_stream = helper.CreateAudioSendStream();
+ auto new_config = helper.config();
+ ConfigHelper::AddBweToConfig(&new_config);
- EXPECT_CALL(*helper.rtp_rtcp(),
- RegisterRtpHeaderExtension(TransportSequenceNumber::kUri,
- kTransportSequenceNumberId))
- .Times(1);
- {
- ::testing::InSequence seq;
- EXPECT_CALL(*helper.channel_send(), ResetSenderCongestionControlObjects())
+ EXPECT_CALL(*helper.rtp_rtcp(),
+ RegisterRtpHeaderExtension(TransportSequenceNumber::kUri,
+ kTransportSequenceNumberId))
.Times(1);
- EXPECT_CALL(*helper.channel_send(), RegisterSenderCongestionControlObjects(
- helper.transport(), Ne(nullptr)))
- .Times(1);
+ {
+ ::testing::InSequence seq;
+ EXPECT_CALL(*helper.channel_send(), ResetSenderCongestionControlObjects())
+ .Times(1);
+ EXPECT_CALL(*helper.channel_send(),
+ RegisterSenderCongestionControlObjects(helper.transport(),
+ Ne(nullptr)))
+ .Times(1);
+ }
+
+ send_stream->Reconfigure(new_config);
}
-
- send_stream->Reconfigure(new_config);
}
TEST(AudioSendStreamTest, OnTransportOverheadChanged) {
- ConfigHelper helper(false, true);
- auto send_stream = helper.CreateAudioSendStream();
- auto new_config = helper.config();
+ for (bool use_null_audio_processing : {false, true}) {
+ ConfigHelper helper(false, true, use_null_audio_processing);
+ auto send_stream = helper.CreateAudioSendStream();
+ auto new_config = helper.config();
- // CallEncoder will be called on overhead change.
- EXPECT_CALL(*helper.channel_send(), CallEncoder(::testing::_)).Times(1);
+ // CallEncoder will be called on overhead change.
+ EXPECT_CALL(*helper.channel_send(), CallEncoder(::testing::_)).Times(1);
- const size_t transport_overhead_per_packet_bytes = 333;
- send_stream->SetTransportOverhead(transport_overhead_per_packet_bytes);
+ const size_t transport_overhead_per_packet_bytes = 333;
+ send_stream->SetTransportOverhead(transport_overhead_per_packet_bytes);
- EXPECT_EQ(transport_overhead_per_packet_bytes,
- send_stream->TestOnlyGetPerPacketOverheadBytes());
+ EXPECT_EQ(transport_overhead_per_packet_bytes,
+ send_stream->TestOnlyGetPerPacketOverheadBytes());
+ }
}
TEST(AudioSendStreamTest, OnAudioOverheadChanged) {
- ConfigHelper helper(false, true);
- auto send_stream = helper.CreateAudioSendStream();
- auto new_config = helper.config();
+ for (bool use_null_audio_processing : {false, true}) {
+ ConfigHelper helper(false, true, use_null_audio_processing);
+ auto send_stream = helper.CreateAudioSendStream();
+ auto new_config = helper.config();
- // CallEncoder will be called on overhead change.
- EXPECT_CALL(*helper.channel_send(), CallEncoder(::testing::_)).Times(1);
+ // CallEncoder will be called on overhead change.
+ EXPECT_CALL(*helper.channel_send(), CallEncoder(::testing::_)).Times(1);
- const size_t audio_overhead_per_packet_bytes = 555;
- send_stream->OnOverheadChanged(audio_overhead_per_packet_bytes);
- EXPECT_EQ(audio_overhead_per_packet_bytes,
- send_stream->TestOnlyGetPerPacketOverheadBytes());
+ const size_t audio_overhead_per_packet_bytes = 555;
+ send_stream->OnOverheadChanged(audio_overhead_per_packet_bytes);
+ EXPECT_EQ(audio_overhead_per_packet_bytes,
+ send_stream->TestOnlyGetPerPacketOverheadBytes());
+ }
}
TEST(AudioSendStreamTest, OnAudioAndTransportOverheadChanged) {
- ConfigHelper helper(false, true);
- auto send_stream = helper.CreateAudioSendStream();
- auto new_config = helper.config();
+ for (bool use_null_audio_processing : {false, true}) {
+ ConfigHelper helper(false, true, use_null_audio_processing);
+ auto send_stream = helper.CreateAudioSendStream();
+ auto new_config = helper.config();
- // CallEncoder will be called when each of overhead changes.
- EXPECT_CALL(*helper.channel_send(), CallEncoder(::testing::_)).Times(2);
+ // CallEncoder will be called when each of overhead changes.
+ EXPECT_CALL(*helper.channel_send(), CallEncoder(::testing::_)).Times(2);
- const size_t transport_overhead_per_packet_bytes = 333;
- send_stream->SetTransportOverhead(transport_overhead_per_packet_bytes);
+ const size_t transport_overhead_per_packet_bytes = 333;
+ send_stream->SetTransportOverhead(transport_overhead_per_packet_bytes);
- const size_t audio_overhead_per_packet_bytes = 555;
- send_stream->OnOverheadChanged(audio_overhead_per_packet_bytes);
+ const size_t audio_overhead_per_packet_bytes = 555;
+ send_stream->OnOverheadChanged(audio_overhead_per_packet_bytes);
- EXPECT_EQ(
- transport_overhead_per_packet_bytes + audio_overhead_per_packet_bytes,
- send_stream->TestOnlyGetPerPacketOverheadBytes());
+ EXPECT_EQ(
+ transport_overhead_per_packet_bytes + audio_overhead_per_packet_bytes,
+ send_stream->TestOnlyGetPerPacketOverheadBytes());
+ }
}
// Validates that reconfiguring the AudioSendStream with a Frame encryptor
// correctly reconfigures on the object without crashing.
TEST(AudioSendStreamTest, ReconfigureWithFrameEncryptor) {
- ConfigHelper helper(false, true);
- auto send_stream = helper.CreateAudioSendStream();
- auto new_config = helper.config();
+ for (bool use_null_audio_processing : {false, true}) {
+ ConfigHelper helper(false, true, use_null_audio_processing);
+ auto send_stream = helper.CreateAudioSendStream();
+ auto new_config = helper.config();
- rtc::scoped_refptr<FrameEncryptorInterface> mock_frame_encryptor_0(
- new rtc::RefCountedObject<MockFrameEncryptor>());
- new_config.frame_encryptor = mock_frame_encryptor_0;
- EXPECT_CALL(*helper.channel_send(), SetFrameEncryptor(Ne(nullptr))).Times(1);
- send_stream->Reconfigure(new_config);
+ rtc::scoped_refptr<FrameEncryptorInterface> mock_frame_encryptor_0(
+ new rtc::RefCountedObject<MockFrameEncryptor>());
+ new_config.frame_encryptor = mock_frame_encryptor_0;
+ EXPECT_CALL(*helper.channel_send(), SetFrameEncryptor(Ne(nullptr)))
+ .Times(1);
+ send_stream->Reconfigure(new_config);
- // Not updating the frame encryptor shouldn't force it to reconfigure.
- EXPECT_CALL(*helper.channel_send(), SetFrameEncryptor(_)).Times(0);
- send_stream->Reconfigure(new_config);
+ // Not updating the frame encryptor shouldn't force it to reconfigure.
+ EXPECT_CALL(*helper.channel_send(), SetFrameEncryptor(_)).Times(0);
+ send_stream->Reconfigure(new_config);
- // Updating frame encryptor to a new object should force a call to the proxy.
- rtc::scoped_refptr<FrameEncryptorInterface> mock_frame_encryptor_1(
- new rtc::RefCountedObject<MockFrameEncryptor>());
- new_config.frame_encryptor = mock_frame_encryptor_1;
- new_config.crypto_options.sframe.require_frame_encryption = true;
- EXPECT_CALL(*helper.channel_send(), SetFrameEncryptor(Ne(nullptr))).Times(1);
- send_stream->Reconfigure(new_config);
+ // Updating frame encryptor to a new object should force a call to the
+ // proxy.
+ rtc::scoped_refptr<FrameEncryptorInterface> mock_frame_encryptor_1(
+ new rtc::RefCountedObject<MockFrameEncryptor>());
+ new_config.frame_encryptor = mock_frame_encryptor_1;
+ new_config.crypto_options.sframe.require_frame_encryption = true;
+ EXPECT_CALL(*helper.channel_send(), SetFrameEncryptor(Ne(nullptr)))
+ .Times(1);
+ send_stream->Reconfigure(new_config);
+ }
}
} // namespace test
} // namespace webrtc