blob: 9afcfda0a6ed89ba8be90c1b62067d44b354700d [file] [log] [blame]
solenbergc7a8b082015-10-16 21:35:071/*
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Jonas Olssona4d87372019-07-05 17:08:3311#include "audio/audio_send_stream.h"
12
Mirko Bonadei317a1f02019-09-17 15:06:1813#include <memory>
Fredrik Solenbergea073732015-12-01 10:26:3414#include <string>
Yves Gerey17048012019-07-26 15:49:5215#include <thread>
ossu20a4b3f2017-04-27 09:08:5216#include <utility>
Fredrik Solenbergea073732015-12-01 10:26:3417#include <vector>
18
Danil Chapovalov31660fd2019-03-22 11:59:4819#include "api/task_queue/default_task_queue_factory.h"
Benjamin Wright78410ad2018-10-25 16:52:5720#include "api/test/mock_frame_encryptor.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3121#include "audio/audio_state.h"
22#include "audio/conversion.h"
Fredrik Solenberga8b7c7f2018-01-17 10:18:3123#include "audio/mock_voe_channel_proxy.h"
Sebastian Janssonef9daee2018-02-22 13:49:0224#include "call/test/mock_rtp_transport_controller_send.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3125#include "logging/rtc_event_log/mock/mock_rtc_event_log.h"
Fredrik Solenberg2a877972017-12-15 15:42:1526#include "modules/audio_device/include/mock_audio_device.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3127#include "modules/audio_mixer/audio_mixer_impl.h"
Henrik Boströmd2c336f2019-07-03 15:11:1028#include "modules/audio_mixer/sine_wave_generator.h"
Ivo Creusen56d460902017-11-24 16:29:5929#include "modules/audio_processing/include/audio_processing_statistics.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3130#include "modules/audio_processing/include/mock_audio_processing.h"
Sebastian Janssonef9daee2018-02-22 13:49:0231#include "modules/rtp_rtcp/mocks/mock_rtcp_bandwidth_observer.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3132#include "modules/rtp_rtcp/mocks/mock_rtp_rtcp.h"
Sebastian Janssonda6806c2019-03-04 16:05:1233#include "system_wrappers/include/clock.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3134#include "test/gtest.h"
35#include "test/mock_audio_encoder.h"
36#include "test/mock_audio_encoder_factory.h"
Jonas Orelanda943e732022-03-16 12:50:5837#include "test/scoped_key_value_config.h"
Per Kjellander828ef912022-10-10 10:53:4138#include "test/time_controller/real_time_controller.h"
solenbergc7a8b082015-10-16 21:35:0739
40namespace webrtc {
solenberg85a04962015-10-27 10:35:2141namespace test {
Fredrik Solenberg0ccae132015-11-03 09:15:4942namespace {
43
Mirko Bonadei6a489f22019-04-09 13:11:1244using ::testing::_;
Henrik Boströmd2c336f2019-07-03 15:11:1045using ::testing::AnyNumber;
Mirko Bonadei6a489f22019-04-09 13:11:1246using ::testing::Eq;
47using ::testing::Field;
Jakob Ivarssonfde2b242020-08-20 14:48:4948using ::testing::InSequence;
Mirko Bonadei6a489f22019-04-09 13:11:1249using ::testing::Invoke;
50using ::testing::Ne;
Alex Konradic20baf62020-12-03 16:30:3451using ::testing::NiceMock;
Mirko Bonadei6a489f22019-04-09 13:11:1252using ::testing::Return;
53using ::testing::StrEq;
solenberg3a941542015-11-16 15:34:5054
Henrik Boströmd2c336f2019-07-03 15:11:1055static const float kTolerance = 0.0001f;
56
Fredrik Solenberg0ccae132015-11-03 09:15:4957const uint32_t kSsrc = 1234;
solenberg3a941542015-11-16 15:34:5058const char* kCName = "foo_name";
59const int kAudioLevelId = 2;
Stefan Holmerb86d4e42015-12-07 09:26:1860const int kTransportSequenceNumberId = 4;
Ivo Creusen56d460902017-11-24 16:29:5961const int32_t kEchoDelayMedian = 254;
62const int32_t kEchoDelayStdDev = -3;
63const double kDivergentFilterFraction = 0.2f;
64const double kEchoReturnLoss = -65;
65const double kEchoReturnLossEnhancement = 101;
66const double kResidualEchoLikelihood = -1.0f;
67const double kResidualEchoLikelihoodMax = 23.0f;
Niels Möllerac0a4cb2019-10-09 13:01:3368const CallSendStatistics kCallStats = {112, 12, 13456, 17890};
Danil Chapovalova9b9d4e2023-05-03 11:20:1169constexpr int kFractionLost = 123;
70constexpr int kCumulativeLost = 567;
71constexpr uint32_t kInterarrivalJitter = 132;
Fredrik Solenbergb5727682015-12-04 14:22:1972const int kTelephoneEventPayloadType = 123;
solenbergffbbcac2016-11-17 13:25:3773const int kTelephoneEventPayloadFrequency = 65432;
solenberg8842c3e2016-03-11 11:06:4174const int kTelephoneEventCode = 45;
75const int kTelephoneEventDuration = 6789;
ossu20a4b3f2017-04-27 09:08:5276constexpr int kIsacPayloadType = 103;
77const SdpAudioFormat kIsacFormat = {"isac", 16000, 1};
78const SdpAudioFormat kOpusFormat = {"opus", 48000, 2};
79const SdpAudioFormat kG722Format = {"g722", 8000, 1};
80const AudioCodecSpec kCodecSpecs[] = {
81 {kIsacFormat, {16000, 1, 32000, 10000, 32000}},
82 {kOpusFormat, {48000, 1, 32000, 6000, 510000}},
83 {kG722Format, {16000, 1, 64000}}};
solenberg566ef242015-11-06 23:34:4984
Daniel Lee93562522019-05-03 12:40:1385// TODO(dklee): This mirrors calculation in audio_send_stream.cc, which
86// should be made more precise in the future. This can be changed when that
87// logic is more accurate.
Danil Chapovalovcad3e0e2020-02-17 17:46:0788const DataSize kOverheadPerPacket = DataSize::Bytes(20 + 8 + 10 + 12);
Danil Chapovalov0c626af2020-02-10 10:16:0089const TimeDelta kMinFrameLength = TimeDelta::Millis(20);
90const TimeDelta kMaxFrameLength = TimeDelta::Millis(120);
Sebastian Jansson62aee932019-10-02 10:27:0691const DataRate kMinOverheadRate = kOverheadPerPacket / kMaxFrameLength;
92const DataRate kMaxOverheadRate = kOverheadPerPacket / kMinFrameLength;
Daniel Lee93562522019-05-03 12:40:1393
mflodman86cc6ff2016-07-26 11:44:0694class MockLimitObserver : public BitrateAllocator::LimitObserver {
95 public:
Danil Chapovalovf9c6b682020-05-15 09:40:4496 MOCK_METHOD(void,
97 OnAllocationLimitsChanged,
98 (BitrateAllocationLimits),
99 (override));
mflodman86cc6ff2016-07-26 11:44:06100};
101
ossu20a4b3f2017-04-27 09:08:52102std::unique_ptr<MockAudioEncoder> SetupAudioEncoderMock(
103 int payload_type,
104 const SdpAudioFormat& format) {
105 for (const auto& spec : kCodecSpecs) {
106 if (format == spec.format) {
Sebastian Jansson41f16be2018-02-22 10:09:56107 std::unique_ptr<MockAudioEncoder> encoder(
Mirko Bonadei6a489f22019-04-09 13:11:12108 new ::testing::NiceMock<MockAudioEncoder>());
ossu20a4b3f2017-04-27 09:08:52109 ON_CALL(*encoder.get(), SampleRateHz())
110 .WillByDefault(Return(spec.info.sample_rate_hz));
111 ON_CALL(*encoder.get(), NumChannels())
112 .WillByDefault(Return(spec.info.num_channels));
113 ON_CALL(*encoder.get(), RtpTimestampRateHz())
114 .WillByDefault(Return(spec.format.clockrate_hz));
Sebastian Jansson62aee932019-10-02 10:27:06115 ON_CALL(*encoder.get(), GetFrameLengthRange())
116 .WillByDefault(Return(absl::optional<std::pair<TimeDelta, TimeDelta>>{
Danil Chapovalov0c626af2020-02-10 10:16:00117 {TimeDelta::Millis(20), TimeDelta::Millis(120)}}));
ossu20a4b3f2017-04-27 09:08:52118 return encoder;
119 }
120 }
121 return nullptr;
122}
123
124rtc::scoped_refptr<MockAudioEncoderFactory> SetupEncoderFactoryMock() {
125 rtc::scoped_refptr<MockAudioEncoderFactory> factory =
Tomas Gunnarssonc1d58912021-04-22 17:21:43126 rtc::make_ref_counted<MockAudioEncoderFactory>();
ossu20a4b3f2017-04-27 09:08:52127 ON_CALL(*factory.get(), GetSupportedEncoders())
128 .WillByDefault(Return(std::vector<AudioCodecSpec>(
129 std::begin(kCodecSpecs), std::end(kCodecSpecs))));
130 ON_CALL(*factory.get(), QueryAudioEncoder(_))
Oskar Sundbom2707fb22017-11-16 09:57:35131 .WillByDefault(Invoke(
Danil Chapovalovb9b146c2018-06-15 10:28:07132 [](const SdpAudioFormat& format) -> absl::optional<AudioCodecInfo> {
Oskar Sundbom2707fb22017-11-16 09:57:35133 for (const auto& spec : kCodecSpecs) {
134 if (format == spec.format) {
135 return spec.info;
136 }
137 }
Danil Chapovalovb9b146c2018-06-15 10:28:07138 return absl::nullopt;
Oskar Sundbom2707fb22017-11-16 09:57:35139 }));
Karl Wibergd6fbf2a2018-02-27 12:37:31140 ON_CALL(*factory.get(), MakeAudioEncoderMock(_, _, _, _))
ossu20a4b3f2017-04-27 09:08:52141 .WillByDefault(Invoke([](int payload_type, const SdpAudioFormat& format,
Danil Chapovalovb9b146c2018-06-15 10:28:07142 absl::optional<AudioCodecPairId> codec_pair_id,
ossu20a4b3f2017-04-27 09:08:52143 std::unique_ptr<AudioEncoder>* return_value) {
144 *return_value = SetupAudioEncoderMock(payload_type, format);
145 }));
146 return factory;
147}
148
solenberg566ef242015-11-06 23:34:49149struct ConfigHelper {
Per Åhgrencc73ed32020-04-26 21:56:17150 ConfigHelper(bool audio_bwe_enabled,
151 bool expect_set_encoder_call,
152 bool use_null_audio_processing)
Per Kjellander828ef912022-10-10 10:53:41153 : stream_config_(/*send_transport=*/nullptr),
Per Åhgrencc73ed32020-04-26 21:56:17154 audio_processing_(
155 use_null_audio_processing
156 ? nullptr
Tomas Gunnarssonc1d58912021-04-22 17:21:43157 : rtc::make_ref_counted<NiceMock<MockAudioProcessing>>()),
Sebastian Jansson40de3cc2019-09-19 12:54:43158 bitrate_allocator_(&limit_observer_),
minyue-webrtc8de18262017-07-26 12:18:40159 audio_encoder_(nullptr) {
Mirko Bonadei6a489f22019-04-09 13:11:12160 using ::testing::Invoke;
solenberg3a941542015-11-16 15:34:50161
solenberg566ef242015-11-06 23:34:49162 AudioState::Config config;
aleloi10111bc2016-11-17 14:48:48163 config.audio_mixer = AudioMixerImpl::Create();
peaha9cc40b2017-06-29 15:32:09164 config.audio_processing = audio_processing_;
Tomas Gunnarssonc1d58912021-04-22 17:21:43165 config.audio_device_module = rtc::make_ref_counted<MockAudioDeviceModule>();
solenberg566ef242015-11-06 23:34:49166 audio_state_ = AudioState::Create(config);
solenberg3a941542015-11-16 15:34:50167
Niels Möllerdced9f62018-11-19 09:27:07168 SetupDefaultChannelSend(audio_bwe_enabled);
ossu20a4b3f2017-04-27 09:08:52169 SetupMockForSetupSendCodec(expect_set_encoder_call);
Jakob Ivarssond14525e2020-03-06 08:49:29170 SetupMockForCallEncoder();
minyue6b825df2016-10-31 11:08:32171
Artem Titovb0ea6372021-07-26 09:47:07172 // Use ISAC as default codec so as to prevent unnecessary `channel_proxy_`
ossu20a4b3f2017-04-27 09:08:52173 // calls from the default ctor behavior.
174 stream_config_.send_codec_spec =
Oskar Sundbom2707fb22017-11-16 09:57:35175 AudioSendStream::Config::SendCodecSpec(kIsacPayloadType, kIsacFormat);
solenberg566ef242015-11-06 23:34:49176 stream_config_.rtp.ssrc = kSsrc;
solenberg3a941542015-11-16 15:34:50177 stream_config_.rtp.c_name = kCName;
178 stream_config_.rtp.extensions.push_back(
isheriff6f8d6862016-05-26 18:24:55179 RtpExtension(RtpExtension::kAudioLevelUri, kAudioLevelId));
stefan7de8d642017-02-07 15:14:08180 if (audio_bwe_enabled) {
ossu1129df22017-06-30 08:38:56181 AddBweToConfig(&stream_config_);
stefan7de8d642017-02-07 15:14:08182 }
ossu20a4b3f2017-04-27 09:08:52183 stream_config_.encoder_factory = SetupEncoderFactoryMock();
minyue78b4d562016-11-30 12:47:39184 stream_config_.min_bitrate_bps = 10000;
185 stream_config_.max_bitrate_bps = 65000;
solenberg566ef242015-11-06 23:34:49186 }
187
Fredrik Solenberg8f5787a2018-01-11 12:52:30188 std::unique_ptr<internal::AudioSendStream> CreateAudioSendStream() {
189 return std::unique_ptr<internal::AudioSendStream>(
190 new internal::AudioSendStream(
Per Kjellander828ef912022-10-10 10:53:41191 time_controller_.GetClock(), stream_config_, audio_state_,
192 time_controller_.GetTaskQueueFactory(), &rtp_transport_,
193 &bitrate_allocator_, &event_log_, absl::nullopt,
Jonas Orelanda943e732022-03-16 12:50:58194 std::unique_ptr<voe::ChannelSendInterface>(channel_send_),
195 field_trials));
Fredrik Solenberg8f5787a2018-01-11 12:52:30196 }
197
solenberg566ef242015-11-06 23:34:49198 AudioSendStream::Config& config() { return stream_config_; }
ossu20a4b3f2017-04-27 09:08:52199 MockAudioEncoderFactory& mock_encoder_factory() {
200 return *static_cast<MockAudioEncoderFactory*>(
201 stream_config_.encoder_factory.get());
202 }
Tomas Gunnarssonf25761d2020-06-03 20:55:33203 MockRtpRtcpInterface* rtp_rtcp() { return &rtp_rtcp_; }
Niels Möllerdced9f62018-11-19 09:27:07204 MockChannelSend* channel_send() { return channel_send_; }
Sebastian Jansson1896cec2018-02-20 08:06:11205 RtpTransportControllerSendInterface* transport() { return &rtp_transport_; }
minyue7a973442016-10-20 10:27:12206
ossu1129df22017-06-30 08:38:56207 static void AddBweToConfig(AudioSendStream::Config* config) {
Yves Gerey665174f2018-06-19 13:03:05208 config->rtp.extensions.push_back(RtpExtension(
209 RtpExtension::kTransportSequenceNumberUri, kTransportSequenceNumberId));
ossu1129df22017-06-30 08:38:56210 config->send_codec_spec->transport_cc_enabled = true;
211 }
212
Niels Möllerdced9f62018-11-19 09:27:07213 void SetupDefaultChannelSend(bool audio_bwe_enabled) {
214 EXPECT_TRUE(channel_send_ == nullptr);
Mirko Bonadei6a489f22019-04-09 13:11:12215 channel_send_ = new ::testing::StrictMock<MockChannelSend>();
Niels Möllerdced9f62018-11-19 09:27:07216 EXPECT_CALL(*channel_send_, GetRtpRtcp()).WillRepeatedly(Invoke([this]() {
Niels Möller848d6d32018-08-08 08:49:16217 return &this->rtp_rtcp_;
218 }));
Erik Språng70efdde2019-08-21 11:36:20219 EXPECT_CALL(rtp_rtcp_, SSRC).WillRepeatedly(Return(kSsrc));
Niels Möllerdced9f62018-11-19 09:27:07220 EXPECT_CALL(*channel_send_, SetRTCP_CNAME(StrEq(kCName))).Times(1);
Niels Möllerdced9f62018-11-19 09:27:07221 EXPECT_CALL(*channel_send_, SetFrameEncryptor(_)).Times(1);
Marina Ciocead2aa8f92020-03-31 09:29:56222 EXPECT_CALL(*channel_send_, SetEncoderToPacketizerFrameTransformer(_))
223 .Times(1);
Sebastian Jansson6298b562020-01-14 16:55:19224 EXPECT_CALL(rtp_rtcp_, SetExtmapAllowMixed(false)).Times(1);
Niels Möllerdced9f62018-11-19 09:27:07225 EXPECT_CALL(*channel_send_,
minyue6b825df2016-10-31 11:08:32226 SetSendAudioLevelIndicationStatus(true, kAudioLevelId))
227 .Times(1);
Sebastian Janssonef9daee2018-02-22 13:49:02228 EXPECT_CALL(rtp_transport_, GetBandwidthObserver())
229 .WillRepeatedly(Return(&bandwidth_observer_));
stefan7de8d642017-02-07 15:14:08230 if (audio_bwe_enabled) {
Sebastian Jansson6298b562020-01-14 16:55:19231 EXPECT_CALL(rtp_rtcp_,
Danil Chapovalovd0321c52021-09-14 10:58:51232 RegisterRtpHeaderExtension(TransportSequenceNumber::Uri(),
Sebastian Jansson6298b562020-01-14 16:55:19233 kTransportSequenceNumberId))
stefan7de8d642017-02-07 15:14:08234 .Times(1);
stefan7de8d642017-02-07 15:14:08235 }
Danil Chapovalova2cf8ee2023-05-16 11:26:33236 EXPECT_CALL(*channel_send_,
237 RegisterSenderCongestionControlObjects(&rtp_transport_))
238 .Times(1);
Niels Möllerdced9f62018-11-19 09:27:07239 EXPECT_CALL(*channel_send_, ResetSenderCongestionControlObjects()).Times(1);
minyue6b825df2016-10-31 11:08:32240 }
241
ossu20a4b3f2017-04-27 09:08:52242 void SetupMockForSetupSendCodec(bool expect_set_encoder_call) {
243 if (expect_set_encoder_call) {
Danil Chapovalovf9c6b682020-05-15 09:40:44244 EXPECT_CALL(*channel_send_, SetEncoder)
245 .WillOnce(
246 [this](int payload_type, std::unique_ptr<AudioEncoder> encoder) {
247 this->audio_encoder_ = std::move(encoder);
minyue-webrtc8de18262017-07-26 12:18:40248 return true;
Danil Chapovalovf9c6b682020-05-15 09:40:44249 });
ossu20a4b3f2017-04-27 09:08:52250 }
minyue7a973442016-10-20 10:27:12251 }
ossu20a4b3f2017-04-27 09:08:52252
Sebastian Jansson14a7cf92019-02-13 14:11:42253 void SetupMockForCallEncoder() {
minyue-webrtc8de18262017-07-26 12:18:40254 // Let ModifyEncoder to invoke mock audio encoder.
Sebastian Jansson14a7cf92019-02-13 14:11:42255 EXPECT_CALL(*channel_send_, CallEncoder(_))
Artem Titove7d08df2019-01-16 13:49:44256 .WillRepeatedly(
Sebastian Jansson14a7cf92019-02-13 14:11:42257 [this](rtc::FunctionView<void(AudioEncoder*)> modifier) {
minyue-webrtc8de18262017-07-26 12:18:40258 if (this->audio_encoder_)
Sebastian Jansson14a7cf92019-02-13 14:11:42259 modifier(this->audio_encoder_.get());
Artem Titove7d08df2019-01-16 13:49:44260 });
minyue-webrtc8de18262017-07-26 12:18:40261 }
262
Fredrik Solenbergb5727682015-12-04 14:22:19263 void SetupMockForSendTelephoneEvent() {
Niels Möllerdced9f62018-11-19 09:27:07264 EXPECT_TRUE(channel_send_);
265 EXPECT_CALL(*channel_send_, SetSendTelephoneEventPayloadType(
266 kTelephoneEventPayloadType,
Niels Möller8fb1a6a2019-03-05 13:29:42267 kTelephoneEventPayloadFrequency));
Yves Gerey665174f2018-06-19 13:03:05268 EXPECT_CALL(
Niels Möllerdced9f62018-11-19 09:27:07269 *channel_send_,
Fredrik Solenbergb5727682015-12-04 14:22:19270 SendTelephoneEventOutband(kTelephoneEventCode, kTelephoneEventDuration))
Yves Gerey665174f2018-06-19 13:03:05271 .WillOnce(Return(true));
Fredrik Solenbergb5727682015-12-04 14:22:19272 }
273
Per Åhgrencc73ed32020-04-26 21:56:17274 void SetupMockForGetStats(bool use_null_audio_processing) {
Mirko Bonadei6a489f22019-04-09 13:11:12275 using ::testing::DoAll;
276 using ::testing::SetArgPointee;
277 using ::testing::SetArgReferee;
solenberg3a941542015-11-16 15:34:50278
Danil Chapovalova9b9d4e2023-05-03 11:20:11279 std::vector<ReportBlockData> report_blocks;
280 ReportBlockData block;
281 block.set_source_ssrc(780);
282 block.set_fraction_lost_raw(kFractionLost);
283 block.set_cumulative_lost(kCumulativeLost);
284 block.set_jitter(kInterarrivalJitter);
solenberg566ef242015-11-06 23:34:49285 report_blocks.push_back(block); // Has wrong SSRC.
Danil Chapovalova9b9d4e2023-05-03 11:20:11286 block.set_source_ssrc(kSsrc);
solenberg566ef242015-11-06 23:34:49287 report_blocks.push_back(block); // Correct block.
Danil Chapovalova9b9d4e2023-05-03 11:20:11288 block.set_fraction_lost_raw(0);
solenberg566ef242015-11-06 23:34:49289 report_blocks.push_back(block); // Duplicate SSRC, bad fraction_lost.
290
Niels Möllerdced9f62018-11-19 09:27:07291 EXPECT_TRUE(channel_send_);
292 EXPECT_CALL(*channel_send_, GetRTCPStatistics())
solenberg358057b2015-11-27 18:46:42293 .WillRepeatedly(Return(kCallStats));
Niels Möllerdced9f62018-11-19 09:27:07294 EXPECT_CALL(*channel_send_, GetRemoteRTCPReportBlocks())
solenberg358057b2015-11-27 18:46:42295 .WillRepeatedly(Return(report_blocks));
Niels Möllerdced9f62018-11-19 09:27:07296 EXPECT_CALL(*channel_send_, GetANAStatistics())
ivoce1198e02017-09-08 15:13:19297 .WillRepeatedly(Return(ANAStats()));
Jakob Ivarssonbf087452021-11-11 12:43:49298 EXPECT_CALL(*channel_send_, GetTargetBitrate()).WillRepeatedly(Return(0));
solenberg796b8f92017-03-02 01:02:23299
Ivo Creusen56d460902017-11-24 16:29:59300 audio_processing_stats_.echo_return_loss = kEchoReturnLoss;
301 audio_processing_stats_.echo_return_loss_enhancement =
302 kEchoReturnLossEnhancement;
303 audio_processing_stats_.delay_median_ms = kEchoDelayMedian;
304 audio_processing_stats_.delay_standard_deviation_ms = kEchoDelayStdDev;
305 audio_processing_stats_.divergent_filter_fraction =
306 kDivergentFilterFraction;
307 audio_processing_stats_.residual_echo_likelihood = kResidualEchoLikelihood;
308 audio_processing_stats_.residual_echo_likelihood_recent_max =
309 kResidualEchoLikelihoodMax;
Per Åhgrencc73ed32020-04-26 21:56:17310 if (!use_null_audio_processing) {
311 ASSERT_TRUE(audio_processing_);
312 EXPECT_CALL(*audio_processing_, GetStatistics(true))
313 .WillRepeatedly(Return(audio_processing_stats_));
314 }
solenberg566ef242015-11-06 23:34:49315 }
Per Åhgrencc73ed32020-04-26 21:56:17316
Jonas Orelanda943e732022-03-16 12:50:58317 test::ScopedKeyValueConfig field_trials;
318
solenberg566ef242015-11-06 23:34:49319 private:
Per Kjellander828ef912022-10-10 10:53:41320 RealTimeController time_controller_;
solenberg566ef242015-11-06 23:34:49321 rtc::scoped_refptr<AudioState> audio_state_;
322 AudioSendStream::Config stream_config_;
Mirko Bonadei6a489f22019-04-09 13:11:12323 ::testing::StrictMock<MockChannelSend>* channel_send_ = nullptr;
peaha9cc40b2017-06-29 15:32:09324 rtc::scoped_refptr<MockAudioProcessing> audio_processing_;
Ivo Creusen56d460902017-11-24 16:29:59325 AudioProcessingStats audio_processing_stats_;
Mirko Bonadei6a489f22019-04-09 13:11:12326 ::testing::StrictMock<MockRtcpBandwidthObserver> bandwidth_observer_;
327 ::testing::NiceMock<MockRtcEventLog> event_log_;
328 ::testing::NiceMock<MockRtpTransportControllerSend> rtp_transport_;
Tomas Gunnarssonf25761d2020-06-03 20:55:33329 ::testing::NiceMock<MockRtpRtcpInterface> rtp_rtcp_;
Mirko Bonadei6a489f22019-04-09 13:11:12330 ::testing::NiceMock<MockLimitObserver> limit_observer_;
mflodman86cc6ff2016-07-26 11:44:06331 BitrateAllocator bitrate_allocator_;
minyue-webrtc8de18262017-07-26 12:18:40332 std::unique_ptr<AudioEncoder> audio_encoder_;
solenberg566ef242015-11-06 23:34:49333};
Henrik Boströmd2c336f2019-07-03 15:11:10334
335// The audio level ranges linearly [0,32767].
336std::unique_ptr<AudioFrame> CreateAudioFrame1kHzSineWave(int16_t audio_level,
337 int duration_ms,
338 int sample_rate_hz,
339 size_t num_channels) {
340 size_t samples_per_channel = sample_rate_hz / (1000 / duration_ms);
341 std::vector<int16_t> audio_data(samples_per_channel * num_channels, 0);
Mirko Bonadei317a1f02019-09-17 15:06:18342 std::unique_ptr<AudioFrame> audio_frame = std::make_unique<AudioFrame>();
Henrik Boströmd2c336f2019-07-03 15:11:10343 audio_frame->UpdateFrame(0 /* RTP timestamp */, &audio_data[0],
344 samples_per_channel, sample_rate_hz,
345 AudioFrame::SpeechType::kNormalSpeech,
346 AudioFrame::VADActivity::kVadUnknown, num_channels);
347 SineWaveGenerator wave_generator(1000.0, audio_level);
348 wave_generator.GenerateNextFrame(audio_frame.get());
349 return audio_frame;
350}
351
Fredrik Solenberg0ccae132015-11-03 09:15:49352} // namespace
solenbergc7a8b082015-10-16 21:35:07353
354TEST(AudioSendStreamTest, ConfigToString) {
Bjorn A Mellem7a9a0922019-11-26 17:19:40355 AudioSendStream::Config config(/*send_transport=*/nullptr);
Fredrik Solenberg0ccae132015-11-03 09:15:49356 config.rtp.ssrc = kSsrc;
solenberg3a941542015-11-16 15:34:50357 config.rtp.c_name = kCName;
minyue10cbb462016-11-07 17:29:22358 config.min_bitrate_bps = 12000;
359 config.max_bitrate_bps = 34000;
Jakob Ivarssoned971162020-08-11 12:05:07360 config.has_dscp = true;
ossu20a4b3f2017-04-27 09:08:52361 config.send_codec_spec =
Oskar Sundbom2707fb22017-11-16 09:57:35362 AudioSendStream::Config::SendCodecSpec(kIsacPayloadType, kIsacFormat);
ossu20a4b3f2017-04-27 09:08:52363 config.send_codec_spec->nack_enabled = true;
364 config.send_codec_spec->transport_cc_enabled = false;
Oskar Sundbom2707fb22017-11-16 09:57:35365 config.send_codec_spec->cng_payload_type = 42;
Philipp Hanckeedcd9662020-06-24 10:52:42366 config.send_codec_spec->red_payload_type = 43;
ossu20a4b3f2017-04-27 09:08:52367 config.encoder_factory = MockAudioEncoderFactory::CreateUnusedFactory();
Johannes Kron9190b822018-10-29 10:22:05368 config.rtp.extmap_allow_mixed = true;
stefanb521aa72016-11-01 10:17:16369 config.rtp.extensions.push_back(
370 RtpExtension(RtpExtension::kAudioLevelUri, kAudioLevelId));
Jiawei Ou55718122018-11-09 21:17:39371 config.rtcp_report_interval_ms = 2500;
Fredrik Solenberg0ccae132015-11-03 09:15:49372 EXPECT_EQ(
Johannes Kron9190b822018-10-29 10:22:05373 "{rtp: {ssrc: 1234, extmap-allow-mixed: true, extensions: [{uri: "
Fredrik Solenbergc69a56e2018-11-21 08:21:23374 "urn:ietf:params:rtp-hdrext:ssrc-audio-level, id: 2}], "
375 "c_name: foo_name}, rtcp_report_interval_ms: 2500, "
Bjorn A Mellem7a9a0922019-11-26 17:19:40376 "send_transport: null, "
Jakob Ivarssoned971162020-08-11 12:05:07377 "min_bitrate_bps: 12000, max_bitrate_bps: 34000, has "
378 "audio_network_adaptor_config: false, has_dscp: true, "
solenberg940b6d62016-10-25 18:19:07379 "send_codec_spec: {nack_enabled: true, transport_cc_enabled: false, "
Ivo Creusen2562cf02021-09-03 14:51:22380 "enable_non_sender_rtt: false, cng_payload_type: 42, "
381 "red_payload_type: 43, payload_type: 103, "
ossu20a4b3f2017-04-27 09:08:52382 "format: {name: isac, clockrate_hz: 16000, num_channels: 1, "
383 "parameters: {}}}}",
solenberg85a04962015-10-27 10:35:21384 config.ToString());
solenbergc7a8b082015-10-16 21:35:07385}
386
387TEST(AudioSendStreamTest, ConstructDestruct) {
Per Åhgrencc73ed32020-04-26 21:56:17388 for (bool use_null_audio_processing : {false, true}) {
389 ConfigHelper helper(false, true, use_null_audio_processing);
390 auto send_stream = helper.CreateAudioSendStream();
391 }
solenbergc7a8b082015-10-16 21:35:07392}
solenberg85a04962015-10-27 10:35:21393
Fredrik Solenbergb5727682015-12-04 14:22:19394TEST(AudioSendStreamTest, SendTelephoneEvent) {
Per Åhgrencc73ed32020-04-26 21:56:17395 for (bool use_null_audio_processing : {false, true}) {
396 ConfigHelper helper(false, true, use_null_audio_processing);
397 auto send_stream = helper.CreateAudioSendStream();
398 helper.SetupMockForSendTelephoneEvent();
399 EXPECT_TRUE(send_stream->SendTelephoneEvent(
400 kTelephoneEventPayloadType, kTelephoneEventPayloadFrequency,
401 kTelephoneEventCode, kTelephoneEventDuration));
402 }
Fredrik Solenbergb5727682015-12-04 14:22:19403}
404
solenberg94218532016-06-16 17:53:22405TEST(AudioSendStreamTest, SetMuted) {
Per Åhgrencc73ed32020-04-26 21:56:17406 for (bool use_null_audio_processing : {false, true}) {
407 ConfigHelper helper(false, true, use_null_audio_processing);
408 auto send_stream = helper.CreateAudioSendStream();
409 EXPECT_CALL(*helper.channel_send(), SetInputMute(true));
410 send_stream->SetMuted(true);
411 }
solenberg94218532016-06-16 17:53:22412}
413
stefan7de8d642017-02-07 15:14:08414TEST(AudioSendStreamTest, AudioBweCorrectObjectsOnChannelProxy) {
Per Åhgrencc73ed32020-04-26 21:56:17415 for (bool use_null_audio_processing : {false, true}) {
416 ConfigHelper helper(true, true, use_null_audio_processing);
417 auto send_stream = helper.CreateAudioSendStream();
418 }
stefan7de8d642017-02-07 15:14:08419}
420
421TEST(AudioSendStreamTest, NoAudioBweCorrectObjectsOnChannelProxy) {
Per Åhgrencc73ed32020-04-26 21:56:17422 for (bool use_null_audio_processing : {false, true}) {
423 ConfigHelper helper(false, true, use_null_audio_processing);
424 auto send_stream = helper.CreateAudioSendStream();
425 }
stefan7de8d642017-02-07 15:14:08426}
427
solenberg85a04962015-10-27 10:35:21428TEST(AudioSendStreamTest, GetStats) {
Per Åhgrencc73ed32020-04-26 21:56:17429 for (bool use_null_audio_processing : {false, true}) {
430 ConfigHelper helper(false, true, use_null_audio_processing);
431 auto send_stream = helper.CreateAudioSendStream();
432 helper.SetupMockForGetStats(use_null_audio_processing);
433 AudioSendStream::Stats stats = send_stream->GetStats(true);
434 EXPECT_EQ(kSsrc, stats.local_ssrc);
435 EXPECT_EQ(kCallStats.payload_bytes_sent, stats.payload_bytes_sent);
436 EXPECT_EQ(kCallStats.header_and_padding_bytes_sent,
437 stats.header_and_padding_bytes_sent);
438 EXPECT_EQ(kCallStats.packetsSent, stats.packets_sent);
Danil Chapovalova9b9d4e2023-05-03 11:20:11439 EXPECT_EQ(stats.packets_lost, kCumulativeLost);
440 EXPECT_FLOAT_EQ(stats.fraction_lost, Q8ToFloat(kFractionLost));
Per Åhgrencc73ed32020-04-26 21:56:17441 EXPECT_EQ(kIsacFormat.name, stats.codec_name);
Danil Chapovalova9b9d4e2023-05-03 11:20:11442 EXPECT_EQ(stats.jitter_ms,
443 static_cast<int32_t>(kInterarrivalJitter /
444 (kIsacFormat.clockrate_hz / 1000)));
Per Åhgrencc73ed32020-04-26 21:56:17445 EXPECT_EQ(kCallStats.rttMs, stats.rtt_ms);
446 EXPECT_EQ(0, stats.audio_level);
447 EXPECT_EQ(0, stats.total_input_energy);
448 EXPECT_EQ(0, stats.total_input_duration);
449
450 if (!use_null_audio_processing) {
451 EXPECT_EQ(kEchoDelayMedian, stats.apm_statistics.delay_median_ms);
452 EXPECT_EQ(kEchoDelayStdDev,
453 stats.apm_statistics.delay_standard_deviation_ms);
454 EXPECT_EQ(kEchoReturnLoss, stats.apm_statistics.echo_return_loss);
455 EXPECT_EQ(kEchoReturnLossEnhancement,
456 stats.apm_statistics.echo_return_loss_enhancement);
457 EXPECT_EQ(kDivergentFilterFraction,
458 stats.apm_statistics.divergent_filter_fraction);
459 EXPECT_EQ(kResidualEchoLikelihood,
460 stats.apm_statistics.residual_echo_likelihood);
461 EXPECT_EQ(kResidualEchoLikelihoodMax,
462 stats.apm_statistics.residual_echo_likelihood_recent_max);
Per Åhgrencc73ed32020-04-26 21:56:17463 }
464 }
solenberg566ef242015-11-06 23:34:49465}
minyue7a973442016-10-20 10:27:12466
Henrik Boströmd2c336f2019-07-03 15:11:10467TEST(AudioSendStreamTest, GetStatsAudioLevel) {
Per Åhgrencc73ed32020-04-26 21:56:17468 for (bool use_null_audio_processing : {false, true}) {
469 ConfigHelper helper(false, true, use_null_audio_processing);
470 auto send_stream = helper.CreateAudioSendStream();
471 helper.SetupMockForGetStats(use_null_audio_processing);
Danil Chapovalovf9c6b682020-05-15 09:40:44472 EXPECT_CALL(*helper.channel_send(), ProcessAndEncodeAudio)
Per Åhgrencc73ed32020-04-26 21:56:17473 .Times(AnyNumber());
Henrik Boströmd2c336f2019-07-03 15:11:10474
Per Åhgrencc73ed32020-04-26 21:56:17475 constexpr int kSampleRateHz = 48000;
476 constexpr size_t kNumChannels = 1;
Henrik Boströmd2c336f2019-07-03 15:11:10477
Per Åhgrencc73ed32020-04-26 21:56:17478 constexpr int16_t kSilentAudioLevel = 0;
479 constexpr int16_t kMaxAudioLevel = 32767; // Audio level is [0,32767].
480 constexpr int kAudioFrameDurationMs = 10;
Henrik Boströmd2c336f2019-07-03 15:11:10481
Per Åhgrencc73ed32020-04-26 21:56:17482 // Process 10 audio frames (100 ms) of silence. After this, on the next
483 // (11-th) frame, the audio level will be updated with the maximum audio
484 // level of the first 11 frames. See AudioLevel.
485 for (size_t i = 0; i < 10; ++i) {
486 send_stream->SendAudioData(
487 CreateAudioFrame1kHzSineWave(kSilentAudioLevel, kAudioFrameDurationMs,
488 kSampleRateHz, kNumChannels));
489 }
490 AudioSendStream::Stats stats = send_stream->GetStats();
491 EXPECT_EQ(kSilentAudioLevel, stats.audio_level);
492 EXPECT_NEAR(0.0f, stats.total_input_energy, kTolerance);
493 EXPECT_NEAR(0.1f, stats.total_input_duration,
494 kTolerance); // 100 ms = 0.1 s
495
496 // Process 10 audio frames (100 ms) of maximum audio level.
497 // Note that AudioLevel updates the audio level every 11th frame, processing
498 // 10 frames above was needed to see a non-zero audio level here.
499 for (size_t i = 0; i < 10; ++i) {
500 send_stream->SendAudioData(CreateAudioFrame1kHzSineWave(
501 kMaxAudioLevel, kAudioFrameDurationMs, kSampleRateHz, kNumChannels));
502 }
503 stats = send_stream->GetStats();
504 EXPECT_EQ(kMaxAudioLevel, stats.audio_level);
505 // Energy increases by energy*duration, where energy is audio level in
506 // [0,1].
507 EXPECT_NEAR(0.1f, stats.total_input_energy, kTolerance); // 0.1 s of max
508 EXPECT_NEAR(0.2f, stats.total_input_duration,
509 kTolerance); // 200 ms = 0.2 s
Henrik Boströmd2c336f2019-07-03 15:11:10510 }
Henrik Boströmd2c336f2019-07-03 15:11:10511}
512
minyue-webrtc8de18262017-07-26 12:18:40513TEST(AudioSendStreamTest, SendCodecAppliesAudioNetworkAdaptor) {
Per Åhgrencc73ed32020-04-26 21:56:17514 for (bool use_null_audio_processing : {false, true}) {
Jakob Ivarsson47a03e82020-11-23 14:05:44515 ConfigHelper helper(true, true, use_null_audio_processing);
Per Åhgrencc73ed32020-04-26 21:56:17516 helper.config().send_codec_spec =
517 AudioSendStream::Config::SendCodecSpec(0, kOpusFormat);
518 const std::string kAnaConfigString = "abcde";
519 const std::string kAnaReconfigString = "12345";
minyue-webrtc8de18262017-07-26 12:18:40520
Per Åhgrencc73ed32020-04-26 21:56:17521 helper.config().audio_network_adaptor_config = kAnaConfigString;
ossu20a4b3f2017-04-27 09:08:52522
Per Åhgrencc73ed32020-04-26 21:56:17523 EXPECT_CALL(helper.mock_encoder_factory(), MakeAudioEncoderMock(_, _, _, _))
524 .WillOnce(Invoke([&kAnaConfigString, &kAnaReconfigString](
525 int payload_type, const SdpAudioFormat& format,
526 absl::optional<AudioCodecPairId> codec_pair_id,
527 std::unique_ptr<AudioEncoder>* return_value) {
528 auto mock_encoder = SetupAudioEncoderMock(payload_type, format);
529 EXPECT_CALL(*mock_encoder,
530 EnableAudioNetworkAdaptor(StrEq(kAnaConfigString), _))
531 .WillOnce(Return(true));
532 EXPECT_CALL(*mock_encoder,
533 EnableAudioNetworkAdaptor(StrEq(kAnaReconfigString), _))
534 .WillOnce(Return(true));
535 *return_value = std::move(mock_encoder);
536 }));
ossu20a4b3f2017-04-27 09:08:52537
Per Åhgrencc73ed32020-04-26 21:56:17538 auto send_stream = helper.CreateAudioSendStream();
minyue-webrtc8de18262017-07-26 12:18:40539
Per Åhgrencc73ed32020-04-26 21:56:17540 auto stream_config = helper.config();
541 stream_config.audio_network_adaptor_config = kAnaReconfigString;
minyue-webrtc8de18262017-07-26 12:18:40542
Florent Castelliacabb362022-10-18 15:05:16543 send_stream->Reconfigure(stream_config, nullptr);
Per Åhgrencc73ed32020-04-26 21:56:17544 }
minyue7a973442016-10-20 10:27:12545}
546
Jakob Ivarssonfde2b242020-08-20 14:48:49547TEST(AudioSendStreamTest, AudioNetworkAdaptorReceivesOverhead) {
548 for (bool use_null_audio_processing : {false, true}) {
Jakob Ivarsson47a03e82020-11-23 14:05:44549 ConfigHelper helper(true, true, use_null_audio_processing);
Jakob Ivarssonfde2b242020-08-20 14:48:49550 helper.config().send_codec_spec =
551 AudioSendStream::Config::SendCodecSpec(0, kOpusFormat);
552 const std::string kAnaConfigString = "abcde";
Jakob Ivarssonfde2b242020-08-20 14:48:49553
554 EXPECT_CALL(helper.mock_encoder_factory(), MakeAudioEncoderMock(_, _, _, _))
555 .WillOnce(Invoke(
556 [&kAnaConfigString](int payload_type, const SdpAudioFormat& format,
557 absl::optional<AudioCodecPairId> codec_pair_id,
558 std::unique_ptr<AudioEncoder>* return_value) {
559 auto mock_encoder = SetupAudioEncoderMock(payload_type, format);
560 InSequence s;
561 EXPECT_CALL(
562 *mock_encoder,
563 OnReceivedOverhead(Eq(kOverheadPerPacket.bytes<size_t>())))
564 .Times(2);
565 EXPECT_CALL(*mock_encoder,
566 EnableAudioNetworkAdaptor(StrEq(kAnaConfigString), _))
567 .WillOnce(Return(true));
568 // Note: Overhead is received AFTER ANA has been enabled.
569 EXPECT_CALL(
570 *mock_encoder,
571 OnReceivedOverhead(Eq(kOverheadPerPacket.bytes<size_t>())))
572 .WillOnce(Return());
573 *return_value = std::move(mock_encoder);
574 }));
575 EXPECT_CALL(*helper.rtp_rtcp(), ExpectedPerPacketOverhead)
576 .WillRepeatedly(Return(kOverheadPerPacket.bytes<size_t>()));
577
578 auto send_stream = helper.CreateAudioSendStream();
579
580 auto stream_config = helper.config();
581 stream_config.audio_network_adaptor_config = kAnaConfigString;
582
Florent Castelliacabb362022-10-18 15:05:16583 send_stream->Reconfigure(stream_config, nullptr);
Jakob Ivarssonfde2b242020-08-20 14:48:49584 }
585}
586
minyue7a973442016-10-20 10:27:12587// VAD is applied when codec is mono and the CNG frequency matches the codec
ossu20a4b3f2017-04-27 09:08:52588// clock rate.
minyue7a973442016-10-20 10:27:12589TEST(AudioSendStreamTest, SendCodecCanApplyVad) {
Per Åhgrencc73ed32020-04-26 21:56:17590 for (bool use_null_audio_processing : {false, true}) {
591 ConfigHelper helper(false, false, use_null_audio_processing);
592 helper.config().send_codec_spec =
593 AudioSendStream::Config::SendCodecSpec(9, kG722Format);
594 helper.config().send_codec_spec->cng_payload_type = 105;
Per Åhgrencc73ed32020-04-26 21:56:17595 std::unique_ptr<AudioEncoder> stolen_encoder;
Danil Chapovalovf9c6b682020-05-15 09:40:44596 EXPECT_CALL(*helper.channel_send(), SetEncoder)
597 .WillOnce([&stolen_encoder](int payload_type,
598 std::unique_ptr<AudioEncoder> encoder) {
599 stolen_encoder = std::move(encoder);
600 return true;
601 });
Per Åhgrencc73ed32020-04-26 21:56:17602 EXPECT_CALL(*helper.channel_send(), RegisterCngPayloadType(105, 8000));
ossu20a4b3f2017-04-27 09:08:52603
Per Åhgrencc73ed32020-04-26 21:56:17604 auto send_stream = helper.CreateAudioSendStream();
ossu20a4b3f2017-04-27 09:08:52605
Per Åhgrencc73ed32020-04-26 21:56:17606 // We cannot truly determine if the encoder created is an AudioEncoderCng.
607 // It is the only reasonable implementation that will return something from
608 // ReclaimContainedEncoders, though.
609 ASSERT_TRUE(stolen_encoder);
610 EXPECT_FALSE(stolen_encoder->ReclaimContainedEncoders().empty());
611 }
minyue7a973442016-10-20 10:27:12612}
613
minyue78b4d562016-11-30 12:47:39614TEST(AudioSendStreamTest, DoesNotPassHigherBitrateThanMaxBitrate) {
Per Åhgrencc73ed32020-04-26 21:56:17615 for (bool use_null_audio_processing : {false, true}) {
616 ConfigHelper helper(false, true, use_null_audio_processing);
617 auto send_stream = helper.CreateAudioSendStream();
618 EXPECT_CALL(
619 *helper.channel_send(),
620 OnBitrateAllocation(
621 Field(&BitrateAllocationUpdate::target_bitrate,
Danil Chapovalovcad3e0e2020-02-17 17:46:07622 Eq(DataRate::BitsPerSec(helper.config().max_bitrate_bps)))));
Per Åhgrencc73ed32020-04-26 21:56:17623 BitrateAllocationUpdate update;
624 update.target_bitrate =
625 DataRate::BitsPerSec(helper.config().max_bitrate_bps + 5000);
626 update.packet_loss_ratio = 0;
627 update.round_trip_time = TimeDelta::Millis(50);
628 update.bwe_period = TimeDelta::Millis(6000);
Per Kjellander50b0a762023-04-12 11:40:01629 send_stream->OnBitrateUpdated(update);
Per Åhgrencc73ed32020-04-26 21:56:17630 }
minyue78b4d562016-11-30 12:47:39631}
632
Daniel Lee93562522019-05-03 12:40:13633TEST(AudioSendStreamTest, SSBweTargetInRangeRespected) {
Per Åhgrencc73ed32020-04-26 21:56:17634 for (bool use_null_audio_processing : {false, true}) {
635 ConfigHelper helper(true, true, use_null_audio_processing);
636 auto send_stream = helper.CreateAudioSendStream();
637 EXPECT_CALL(
638 *helper.channel_send(),
639 OnBitrateAllocation(Field(
640 &BitrateAllocationUpdate::target_bitrate,
641 Eq(DataRate::BitsPerSec(helper.config().max_bitrate_bps - 5000)))));
642 BitrateAllocationUpdate update;
643 update.target_bitrate =
644 DataRate::BitsPerSec(helper.config().max_bitrate_bps - 5000);
Per Kjellander50b0a762023-04-12 11:40:01645 send_stream->OnBitrateUpdated(update);
Per Åhgrencc73ed32020-04-26 21:56:17646 }
Daniel Lee93562522019-05-03 12:40:13647}
648
649TEST(AudioSendStreamTest, SSBweFieldTrialMinRespected) {
Per Åhgrencc73ed32020-04-26 21:56:17650 for (bool use_null_audio_processing : {false, true}) {
651 ConfigHelper helper(true, true, use_null_audio_processing);
Jonas Orelanda943e732022-03-16 12:50:58652 ScopedKeyValueConfig field_trials(
653 helper.field_trials, "WebRTC-Audio-Allocation/min:6kbps,max:64kbps/");
Per Åhgrencc73ed32020-04-26 21:56:17654 auto send_stream = helper.CreateAudioSendStream();
655 EXPECT_CALL(
656 *helper.channel_send(),
657 OnBitrateAllocation(Field(&BitrateAllocationUpdate::target_bitrate,
658 Eq(DataRate::KilobitsPerSec(6)))));
659 BitrateAllocationUpdate update;
660 update.target_bitrate = DataRate::KilobitsPerSec(1);
Per Kjellander50b0a762023-04-12 11:40:01661 send_stream->OnBitrateUpdated(update);
Per Åhgrencc73ed32020-04-26 21:56:17662 }
Daniel Lee93562522019-05-03 12:40:13663}
664
665TEST(AudioSendStreamTest, SSBweFieldTrialMaxRespected) {
Per Åhgrencc73ed32020-04-26 21:56:17666 for (bool use_null_audio_processing : {false, true}) {
667 ConfigHelper helper(true, true, use_null_audio_processing);
Jonas Orelanda943e732022-03-16 12:50:58668 ScopedKeyValueConfig field_trials(
669 helper.field_trials, "WebRTC-Audio-Allocation/min:6kbps,max:64kbps/");
Per Åhgrencc73ed32020-04-26 21:56:17670 auto send_stream = helper.CreateAudioSendStream();
671 EXPECT_CALL(
672 *helper.channel_send(),
673 OnBitrateAllocation(Field(&BitrateAllocationUpdate::target_bitrate,
674 Eq(DataRate::KilobitsPerSec(64)))));
675 BitrateAllocationUpdate update;
676 update.target_bitrate = DataRate::KilobitsPerSec(128);
Per Kjellander50b0a762023-04-12 11:40:01677 send_stream->OnBitrateUpdated(update);
Per Åhgrencc73ed32020-04-26 21:56:17678 }
Daniel Lee93562522019-05-03 12:40:13679}
680
681TEST(AudioSendStreamTest, SSBweWithOverhead) {
Per Åhgrencc73ed32020-04-26 21:56:17682 for (bool use_null_audio_processing : {false, true}) {
683 ConfigHelper helper(true, true, use_null_audio_processing);
Jonas Orelanda943e732022-03-16 12:50:58684 ScopedKeyValueConfig field_trials(helper.field_trials,
685 "WebRTC-Audio-LegacyOverhead/Disabled/");
Erik Språng04e1bab2020-05-07 16:18:32686 EXPECT_CALL(*helper.rtp_rtcp(), ExpectedPerPacketOverhead)
687 .WillRepeatedly(Return(kOverheadPerPacket.bytes<size_t>()));
Per Åhgrencc73ed32020-04-26 21:56:17688 auto send_stream = helper.CreateAudioSendStream();
Per Åhgrencc73ed32020-04-26 21:56:17689 const DataRate bitrate =
690 DataRate::BitsPerSec(helper.config().max_bitrate_bps) +
691 kMaxOverheadRate;
692 EXPECT_CALL(*helper.channel_send(),
693 OnBitrateAllocation(Field(
694 &BitrateAllocationUpdate::target_bitrate, Eq(bitrate))));
695 BitrateAllocationUpdate update;
696 update.target_bitrate = bitrate;
Per Kjellander50b0a762023-04-12 11:40:01697 send_stream->OnBitrateUpdated(update);
Per Åhgrencc73ed32020-04-26 21:56:17698 }
Daniel Lee93562522019-05-03 12:40:13699}
700
701TEST(AudioSendStreamTest, SSBweWithOverheadMinRespected) {
Per Åhgrencc73ed32020-04-26 21:56:17702 for (bool use_null_audio_processing : {false, true}) {
703 ConfigHelper helper(true, true, use_null_audio_processing);
Jonas Orelanda943e732022-03-16 12:50:58704 ScopedKeyValueConfig field_trials(
705 helper.field_trials,
706 "WebRTC-Audio-LegacyOverhead/Disabled/"
707 "WebRTC-Audio-Allocation/min:6kbps,max:64kbps/");
Erik Språng04e1bab2020-05-07 16:18:32708 EXPECT_CALL(*helper.rtp_rtcp(), ExpectedPerPacketOverhead)
709 .WillRepeatedly(Return(kOverheadPerPacket.bytes<size_t>()));
Per Åhgrencc73ed32020-04-26 21:56:17710 auto send_stream = helper.CreateAudioSendStream();
Per Åhgrencc73ed32020-04-26 21:56:17711 const DataRate bitrate = DataRate::KilobitsPerSec(6) + kMinOverheadRate;
712 EXPECT_CALL(*helper.channel_send(),
713 OnBitrateAllocation(Field(
714 &BitrateAllocationUpdate::target_bitrate, Eq(bitrate))));
715 BitrateAllocationUpdate update;
716 update.target_bitrate = DataRate::KilobitsPerSec(1);
Per Kjellander50b0a762023-04-12 11:40:01717 send_stream->OnBitrateUpdated(update);
Per Åhgrencc73ed32020-04-26 21:56:17718 }
Daniel Lee93562522019-05-03 12:40:13719}
720
721TEST(AudioSendStreamTest, SSBweWithOverheadMaxRespected) {
Per Åhgrencc73ed32020-04-26 21:56:17722 for (bool use_null_audio_processing : {false, true}) {
723 ConfigHelper helper(true, true, use_null_audio_processing);
Jonas Orelanda943e732022-03-16 12:50:58724 ScopedKeyValueConfig field_trials(
725 helper.field_trials,
726 "WebRTC-Audio-LegacyOverhead/Disabled/"
727 "WebRTC-Audio-Allocation/min:6kbps,max:64kbps/");
Erik Språng04e1bab2020-05-07 16:18:32728 EXPECT_CALL(*helper.rtp_rtcp(), ExpectedPerPacketOverhead)
729 .WillRepeatedly(Return(kOverheadPerPacket.bytes<size_t>()));
Per Åhgrencc73ed32020-04-26 21:56:17730 auto send_stream = helper.CreateAudioSendStream();
Per Åhgrencc73ed32020-04-26 21:56:17731 const DataRate bitrate = DataRate::KilobitsPerSec(64) + kMaxOverheadRate;
732 EXPECT_CALL(*helper.channel_send(),
733 OnBitrateAllocation(Field(
734 &BitrateAllocationUpdate::target_bitrate, Eq(bitrate))));
735 BitrateAllocationUpdate update;
736 update.target_bitrate = DataRate::KilobitsPerSec(128);
Per Kjellander50b0a762023-04-12 11:40:01737 send_stream->OnBitrateUpdated(update);
Per Åhgrencc73ed32020-04-26 21:56:17738 }
Daniel Lee93562522019-05-03 12:40:13739}
740
minyue78b4d562016-11-30 12:47:39741TEST(AudioSendStreamTest, ProbingIntervalOnBitrateUpdated) {
Per Åhgrencc73ed32020-04-26 21:56:17742 for (bool use_null_audio_processing : {false, true}) {
743 ConfigHelper helper(false, true, use_null_audio_processing);
744 auto send_stream = helper.CreateAudioSendStream();
Sebastian Jansson254d8692018-11-21 18:19:00745
Per Åhgrencc73ed32020-04-26 21:56:17746 EXPECT_CALL(*helper.channel_send(),
747 OnBitrateAllocation(Field(&BitrateAllocationUpdate::bwe_period,
748 Eq(TimeDelta::Millis(5000)))));
749 BitrateAllocationUpdate update;
750 update.target_bitrate =
751 DataRate::BitsPerSec(helper.config().max_bitrate_bps + 5000);
752 update.packet_loss_ratio = 0;
753 update.round_trip_time = TimeDelta::Millis(50);
754 update.bwe_period = TimeDelta::Millis(5000);
Per Kjellander50b0a762023-04-12 11:40:01755 send_stream->OnBitrateUpdated(update);
Per Åhgrencc73ed32020-04-26 21:56:17756 }
minyue78b4d562016-11-30 12:47:39757}
758
ossu20a4b3f2017-04-27 09:08:52759// Test that AudioSendStream doesn't recreate the encoder unnecessarily.
760TEST(AudioSendStreamTest, DontRecreateEncoder) {
Per Åhgrencc73ed32020-04-26 21:56:17761 for (bool use_null_audio_processing : {false, true}) {
762 ConfigHelper helper(false, false, use_null_audio_processing);
763 // WillOnce is (currently) the default used by ConfigHelper if asked to set
764 // an expectation for SetEncoder. Since this behavior is essential for this
765 // test to be correct, it's instead set-up manually here. Otherwise a simple
766 // change to ConfigHelper (say to WillRepeatedly) would silently make this
767 // test useless.
Danil Chapovalovf9c6b682020-05-15 09:40:44768 EXPECT_CALL(*helper.channel_send(), SetEncoder).WillOnce(Return());
ossu20a4b3f2017-04-27 09:08:52769
Per Åhgrencc73ed32020-04-26 21:56:17770 EXPECT_CALL(*helper.channel_send(), RegisterCngPayloadType(105, 8000));
Niels Mölleree5ccbc2019-03-06 15:47:29771
Per Åhgrencc73ed32020-04-26 21:56:17772 helper.config().send_codec_spec =
773 AudioSendStream::Config::SendCodecSpec(9, kG722Format);
774 helper.config().send_codec_spec->cng_payload_type = 105;
775 auto send_stream = helper.CreateAudioSendStream();
Florent Castelliacabb362022-10-18 15:05:16776 send_stream->Reconfigure(helper.config(), nullptr);
Per Åhgrencc73ed32020-04-26 21:56:17777 }
ossu20a4b3f2017-04-27 09:08:52778}
779
ossu1129df22017-06-30 08:38:56780TEST(AudioSendStreamTest, ReconfigureTransportCcResetsFirst) {
Per Åhgrencc73ed32020-04-26 21:56:17781 for (bool use_null_audio_processing : {false, true}) {
782 ConfigHelper helper(false, true, use_null_audio_processing);
783 auto send_stream = helper.CreateAudioSendStream();
784 auto new_config = helper.config();
785 ConfigHelper::AddBweToConfig(&new_config);
Sebastian Jansson6298b562020-01-14 16:55:19786
Per Åhgrencc73ed32020-04-26 21:56:17787 EXPECT_CALL(*helper.rtp_rtcp(),
Danil Chapovalovd0321c52021-09-14 10:58:51788 RegisterRtpHeaderExtension(TransportSequenceNumber::Uri(),
Per Åhgrencc73ed32020-04-26 21:56:17789 kTransportSequenceNumberId))
ossu1129df22017-06-30 08:38:56790 .Times(1);
Per Åhgrencc73ed32020-04-26 21:56:17791 {
792 ::testing::InSequence seq;
793 EXPECT_CALL(*helper.channel_send(), ResetSenderCongestionControlObjects())
794 .Times(1);
795 EXPECT_CALL(*helper.channel_send(),
Danil Chapovalova2cf8ee2023-05-16 11:26:33796 RegisterSenderCongestionControlObjects(helper.transport()))
Per Åhgrencc73ed32020-04-26 21:56:17797 .Times(1);
798 }
799
Florent Castelliacabb362022-10-18 15:05:16800 send_stream->Reconfigure(new_config, nullptr);
ossu1129df22017-06-30 08:38:56801 }
ossu1129df22017-06-30 08:38:56802}
Sam Zackrisson06953ba2018-02-01 15:53:16803
Anton Sukhanov626015d2019-02-04 23:16:06804TEST(AudioSendStreamTest, OnTransportOverheadChanged) {
Per Åhgrencc73ed32020-04-26 21:56:17805 for (bool use_null_audio_processing : {false, true}) {
806 ConfigHelper helper(false, true, use_null_audio_processing);
807 auto send_stream = helper.CreateAudioSendStream();
808 auto new_config = helper.config();
Anton Sukhanov626015d2019-02-04 23:16:06809
Per Åhgrencc73ed32020-04-26 21:56:17810 // CallEncoder will be called on overhead change.
Erik Språngcf6544a2020-05-13 12:43:11811 EXPECT_CALL(*helper.channel_send(), CallEncoder);
Anton Sukhanov626015d2019-02-04 23:16:06812
Per Åhgrencc73ed32020-04-26 21:56:17813 const size_t transport_overhead_per_packet_bytes = 333;
814 send_stream->SetTransportOverhead(transport_overhead_per_packet_bytes);
Anton Sukhanov626015d2019-02-04 23:16:06815
Per Åhgrencc73ed32020-04-26 21:56:17816 EXPECT_EQ(transport_overhead_per_packet_bytes,
817 send_stream->TestOnlyGetPerPacketOverheadBytes());
818 }
Anton Sukhanov626015d2019-02-04 23:16:06819}
820
Erik Språngcf6544a2020-05-13 12:43:11821TEST(AudioSendStreamTest, DoesntCallEncoderWhenOverheadUnchanged) {
822 for (bool use_null_audio_processing : {false, true}) {
823 ConfigHelper helper(false, true, use_null_audio_processing);
824 auto send_stream = helper.CreateAudioSendStream();
825 auto new_config = helper.config();
826
827 // CallEncoder will be called on overhead change.
828 EXPECT_CALL(*helper.channel_send(), CallEncoder);
829 const size_t transport_overhead_per_packet_bytes = 333;
830 send_stream->SetTransportOverhead(transport_overhead_per_packet_bytes);
831
832 // Set the same overhead again, CallEncoder should not be called again.
833 EXPECT_CALL(*helper.channel_send(), CallEncoder).Times(0);
834 send_stream->SetTransportOverhead(transport_overhead_per_packet_bytes);
835
836 // New overhead, call CallEncoder again
837 EXPECT_CALL(*helper.channel_send(), CallEncoder);
838 send_stream->SetTransportOverhead(transport_overhead_per_packet_bytes + 1);
839 }
840}
841
Erik Språng04e1bab2020-05-07 16:18:32842TEST(AudioSendStreamTest, AudioOverheadChanged) {
Per Åhgrencc73ed32020-04-26 21:56:17843 for (bool use_null_audio_processing : {false, true}) {
844 ConfigHelper helper(false, true, use_null_audio_processing);
Erik Språng04e1bab2020-05-07 16:18:32845 const size_t audio_overhead_per_packet_bytes = 555;
846 EXPECT_CALL(*helper.rtp_rtcp(), ExpectedPerPacketOverhead)
847 .WillRepeatedly(Return(audio_overhead_per_packet_bytes));
Per Åhgrencc73ed32020-04-26 21:56:17848 auto send_stream = helper.CreateAudioSendStream();
849 auto new_config = helper.config();
Anton Sukhanov626015d2019-02-04 23:16:06850
Erik Språng04e1bab2020-05-07 16:18:32851 BitrateAllocationUpdate update;
852 update.target_bitrate =
853 DataRate::BitsPerSec(helper.config().max_bitrate_bps) +
854 kMaxOverheadRate;
855 EXPECT_CALL(*helper.channel_send(), OnBitrateAllocation);
Per Kjellander50b0a762023-04-12 11:40:01856 send_stream->OnBitrateUpdated(update);
Anton Sukhanov626015d2019-02-04 23:16:06857
Per Åhgrencc73ed32020-04-26 21:56:17858 EXPECT_EQ(audio_overhead_per_packet_bytes,
859 send_stream->TestOnlyGetPerPacketOverheadBytes());
Erik Språng04e1bab2020-05-07 16:18:32860
861 EXPECT_CALL(*helper.rtp_rtcp(), ExpectedPerPacketOverhead)
862 .WillRepeatedly(Return(audio_overhead_per_packet_bytes + 20));
863 EXPECT_CALL(*helper.channel_send(), OnBitrateAllocation);
Per Kjellander50b0a762023-04-12 11:40:01864 send_stream->OnBitrateUpdated(update);
Erik Språng04e1bab2020-05-07 16:18:32865
866 EXPECT_EQ(audio_overhead_per_packet_bytes + 20,
867 send_stream->TestOnlyGetPerPacketOverheadBytes());
Per Åhgrencc73ed32020-04-26 21:56:17868 }
Anton Sukhanov626015d2019-02-04 23:16:06869}
870
871TEST(AudioSendStreamTest, OnAudioAndTransportOverheadChanged) {
Per Åhgrencc73ed32020-04-26 21:56:17872 for (bool use_null_audio_processing : {false, true}) {
873 ConfigHelper helper(false, true, use_null_audio_processing);
Erik Språng04e1bab2020-05-07 16:18:32874 const size_t audio_overhead_per_packet_bytes = 555;
875 EXPECT_CALL(*helper.rtp_rtcp(), ExpectedPerPacketOverhead)
876 .WillRepeatedly(Return(audio_overhead_per_packet_bytes));
Per Åhgrencc73ed32020-04-26 21:56:17877 auto send_stream = helper.CreateAudioSendStream();
878 auto new_config = helper.config();
Anton Sukhanov626015d2019-02-04 23:16:06879
Per Åhgrencc73ed32020-04-26 21:56:17880 const size_t transport_overhead_per_packet_bytes = 333;
881 send_stream->SetTransportOverhead(transport_overhead_per_packet_bytes);
Anton Sukhanov626015d2019-02-04 23:16:06882
Erik Språng04e1bab2020-05-07 16:18:32883 BitrateAllocationUpdate update;
884 update.target_bitrate =
885 DataRate::BitsPerSec(helper.config().max_bitrate_bps) +
886 kMaxOverheadRate;
887 EXPECT_CALL(*helper.channel_send(), OnBitrateAllocation);
Per Kjellander50b0a762023-04-12 11:40:01888 send_stream->OnBitrateUpdated(update);
Anton Sukhanov626015d2019-02-04 23:16:06889
Per Åhgrencc73ed32020-04-26 21:56:17890 EXPECT_EQ(
891 transport_overhead_per_packet_bytes + audio_overhead_per_packet_bytes,
892 send_stream->TestOnlyGetPerPacketOverheadBytes());
893 }
Anton Sukhanov626015d2019-02-04 23:16:06894}
895
Benjamin Wright78410ad2018-10-25 16:52:57896// Validates that reconfiguring the AudioSendStream with a Frame encryptor
897// correctly reconfigures on the object without crashing.
898TEST(AudioSendStreamTest, ReconfigureWithFrameEncryptor) {
Per Åhgrencc73ed32020-04-26 21:56:17899 for (bool use_null_audio_processing : {false, true}) {
900 ConfigHelper helper(false, true, use_null_audio_processing);
901 auto send_stream = helper.CreateAudioSendStream();
902 auto new_config = helper.config();
Benjamin Wright78410ad2018-10-25 16:52:57903
Per Åhgrencc73ed32020-04-26 21:56:17904 rtc::scoped_refptr<FrameEncryptorInterface> mock_frame_encryptor_0(
Tomas Gunnarssonc1d58912021-04-22 17:21:43905 rtc::make_ref_counted<MockFrameEncryptor>());
Per Åhgrencc73ed32020-04-26 21:56:17906 new_config.frame_encryptor = mock_frame_encryptor_0;
907 EXPECT_CALL(*helper.channel_send(), SetFrameEncryptor(Ne(nullptr)))
908 .Times(1);
Florent Castelliacabb362022-10-18 15:05:16909 send_stream->Reconfigure(new_config, nullptr);
Benjamin Wright78410ad2018-10-25 16:52:57910
Per Åhgrencc73ed32020-04-26 21:56:17911 // Not updating the frame encryptor shouldn't force it to reconfigure.
912 EXPECT_CALL(*helper.channel_send(), SetFrameEncryptor(_)).Times(0);
Florent Castelliacabb362022-10-18 15:05:16913 send_stream->Reconfigure(new_config, nullptr);
Benjamin Wright78410ad2018-10-25 16:52:57914
Per Åhgrencc73ed32020-04-26 21:56:17915 // Updating frame encryptor to a new object should force a call to the
916 // proxy.
917 rtc::scoped_refptr<FrameEncryptorInterface> mock_frame_encryptor_1(
Tomas Gunnarssonc1d58912021-04-22 17:21:43918 rtc::make_ref_counted<MockFrameEncryptor>());
Per Åhgrencc73ed32020-04-26 21:56:17919 new_config.frame_encryptor = mock_frame_encryptor_1;
920 new_config.crypto_options.sframe.require_frame_encryption = true;
921 EXPECT_CALL(*helper.channel_send(), SetFrameEncryptor(Ne(nullptr)))
922 .Times(1);
Florent Castelliacabb362022-10-18 15:05:16923 send_stream->Reconfigure(new_config, nullptr);
Per Åhgrencc73ed32020-04-26 21:56:17924 }
Benjamin Wright78410ad2018-10-25 16:52:57925}
solenberg85a04962015-10-27 10:35:21926} // namespace test
solenbergc7a8b082015-10-16 21:35:07927} // namespace webrtc