blob: d53085bdbff0a287fa5c6f9106c6a1beb9dae306 [file] [log] [blame]
Stefan Holmer8bffba72015-09-23 13:53:521/*
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_receive_stream.h"
12
Jakob Ivarsson75dc9c92025-01-10 12:29:0013#include <cstddef>
14#include <cstdint>
kwiberg1c07c702017-03-27 14:15:4915#include <map>
Jakob Ivarsson75dc9c92025-01-10 12:29:0016#include <memory>
Fredrik Solenbergf693bfa2018-12-11 11:22:1017#include <utility>
stefan3313ec92016-01-21 14:32:4318#include <vector>
Fredrik Solenbergea073732015-12-01 10:26:3419
Jakob Ivarsson75dc9c92025-01-10 12:29:0020#include "api/audio_codecs/audio_format.h"
21#include "api/crypto/frame_decryptor_interface.h"
Danil Chapovalov3732b842024-07-18 16:24:3222#include "api/environment/environment_factory.h"
Jakob Ivarsson75dc9c92025-01-10 12:29:0023#include "api/make_ref_counted.h"
24#include "api/rtp_headers.h"
25#include "api/scoped_refptr.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3126#include "api/test/mock_audio_mixer.h"
Benjamin Wright78410ad2018-10-25 16:52:5727#include "api/test/mock_frame_decryptor.h"
Jakob Ivarsson75dc9c92025-01-10 12:29:0028#include "audio/channel_receive.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3129#include "audio/conversion.h"
Fredrik Solenberga8b7c7f2018-01-17 10:18:3130#include "audio/mock_voe_channel_proxy.h"
Jakob Ivarsson75dc9c92025-01-10 12:29:0031#include "call/audio_receive_stream.h"
32#include "call/audio_state.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3133#include "call/rtp_stream_receiver_controller.h"
Jakob Ivarsson75dc9c92025-01-10 12:29:0034#include "modules/audio_coding/include/audio_coding_module_typedefs.h"
Fredrik Solenberg2a877972017-12-15 15:42:1535#include "modules/audio_device/include/mock_audio_device.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3136#include "modules/audio_processing/include/mock_audio_processing.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3137#include "modules/pacing/packet_router.h"
38#include "modules/rtp_rtcp/source/byte_io.h"
Bjorn Terelius5c2f1f02019-01-16 16:45:0539#include "rtc_base/time_utils.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3140#include "test/gtest.h"
41#include "test/mock_audio_decoder_factory.h"
Niels Möllerae4237e2018-10-05 09:28:3842#include "test/mock_transport.h"
Tommicde4b672023-04-25 06:53:4243#include "test/run_loop.h"
Stefan Holmer8bffba72015-09-23 13:53:5244
Fredrik Solenberg0ccae132015-11-03 09:15:4945namespace webrtc {
46namespace test {
Fredrik Solenberg4f4ec0a2015-10-22 08:49:2747namespace {
48
Mirko Bonadei6a489f22019-04-09 13:11:1249using ::testing::_;
50using ::testing::FloatEq;
Alex Konradic20baf62020-12-03 16:30:3451using ::testing::NiceMock;
Mirko Bonadei6a489f22019-04-09 13:11:1252using ::testing::Return;
solenberg3a941542015-11-16 15:34:5053
solenberg566ef242015-11-06 23:34:4954AudioDecodingCallStats MakeAudioDecodeStatsForTest() {
55 AudioDecodingCallStats audio_decode_stats;
56 audio_decode_stats.calls_to_silence_generator = 234;
57 audio_decode_stats.calls_to_neteq = 567;
58 audio_decode_stats.decoded_normal = 890;
Alex Narest5b5d97c2019-08-07 16:15:0859 audio_decode_stats.decoded_neteq_plc = 123;
60 audio_decode_stats.decoded_codec_plc = 124;
solenberg566ef242015-11-06 23:34:4961 audio_decode_stats.decoded_cng = 456;
62 audio_decode_stats.decoded_plc_cng = 789;
henrik.lundin63489782016-09-20 08:47:1263 audio_decode_stats.decoded_muted_output = 987;
solenberg566ef242015-11-06 23:34:4964 return audio_decode_stats;
65}
66
Fredrik Solenberg0ccae132015-11-03 09:15:4967const uint32_t kRemoteSsrc = 1234;
68const uint32_t kLocalSsrc = 5678;
solenberg566ef242015-11-06 23:34:4969const int kJitterBufferDelay = -7;
70const int kPlayoutBufferDelay = 302;
71const unsigned int kSpeechOutputLevel = 99;
zsteine76bd3a2017-07-14 19:17:4972const double kTotalOutputEnergy = 0.25;
73const double kTotalOutputDuration = 0.5;
Åsa Perssonfcf79cc2019-10-22 13:23:4474const int64_t kPlayoutNtpTimestampMs = 5678;
zsteine76bd3a2017-07-14 19:17:4975
Niels Möllerac0a4cb2019-10-09 13:01:3376const CallReceiveStatistics kCallStats = {678, 234, -12, 567, 78, 890, 123};
Benjamin Wright17b050f2019-03-14 00:35:4677const std::pair<int, SdpAudioFormat> kReceiveCodec = {
78 123,
79 {"codec_name_recv", 96000, 0}};
Gustaf Ullbergb0a02072017-10-02 10:00:3480const NetworkStatistics kNetworkStats = {
Minyue Li28a2c632021-07-07 13:53:3881 /*currentBufferSize=*/123,
82 /*preferredBufferSize=*/456,
83 /*jitterPeaksFound=*/false,
84 /*totalSamplesReceived=*/789012,
85 /*concealedSamples=*/3456,
86 /*silentConcealedSamples=*/123,
87 /*concealmentEvents=*/456,
88 /*jitterBufferDelayMs=*/789,
89 /*jitterBufferEmittedCount=*/543,
90 /*jitterBufferTargetDelayMs=*/123,
Ivo Creusen1a84b562022-07-19 14:33:1091 /*jitterBufferMinimumDelayMs=*/222,
Minyue Li28a2c632021-07-07 13:53:3892 /*insertedSamplesForDeceleration=*/432,
93 /*removedSamplesForAcceleration=*/321,
94 /*fecPacketsReceived=*/123,
95 /*fecPacketsDiscarded=*/101,
Jesús de Vicente Peñafc6df052024-06-04 08:05:3196 /*totalProcessingDelayMs=*/154,
Minyue Li28a2c632021-07-07 13:53:3897 /*packetsDiscarded=*/989,
98 /*currentExpandRate=*/789,
99 /*currentSpeechExpandRate=*/12,
100 /*currentPreemptiveRate=*/345,
101 /*currentAccelerateRate =*/678,
102 /*currentSecondaryDecodedRate=*/901,
103 /*currentSecondaryDiscardedRate=*/0,
104 /*meanWaitingTimeMs=*/-1,
105 /*maxWaitingTimeMs=*/-1,
106 /*packetBufferFlushes=*/0,
107 /*delayedPacketOutageSamples=*/0,
108 /*relativePacketArrivalDelayMs=*/135,
109 /*interruptionCount=*/-1,
110 /*totalInterruptionDurationMs=*/-1};
solenberg566ef242015-11-06 23:34:49111const AudioDecodingCallStats kAudioDecodeStats = MakeAudioDecodeStatsForTest();
112
113struct ConfigHelper {
Per Åhgrencc73ed32020-04-26 21:56:17114 explicit ConfigHelper(bool use_null_audio_processing)
Tomas Gunnarssonc1d58912021-04-22 17:21:43115 : ConfigHelper(rtc::make_ref_counted<MockAudioMixer>(),
Per Åhgrencc73ed32020-04-26 21:56:17116 use_null_audio_processing) {}
Fredrik Solenberg8f5787a2018-01-11 12:52:30117
Per Åhgrencc73ed32020-04-26 21:56:17118 ConfigHelper(rtc::scoped_refptr<MockAudioMixer> audio_mixer,
119 bool use_null_audio_processing)
Fredrik Solenberg8f5787a2018-01-11 12:52:30120 : audio_mixer_(audio_mixer) {
Mirko Bonadei6a489f22019-04-09 13:11:12121 using ::testing::Invoke;
solenberg13725082015-11-25 16:16:52122
solenberg566ef242015-11-06 23:34:49123 AudioState::Config config;
aleloi04c07222016-11-22 14:42:53124 config.audio_mixer = audio_mixer_;
Per Åhgrencc73ed32020-04-26 21:56:17125 config.audio_processing =
126 use_null_audio_processing
127 ? nullptr
Tomas Gunnarssonc1d58912021-04-22 17:21:43128 : rtc::make_ref_counted<NiceMock<MockAudioProcessing>>();
Fredrik Solenberg2a877972017-12-15 15:42:15129 config.audio_device_module =
Tomas Gunnarssonc1d58912021-04-22 17:21:43130 rtc::make_ref_counted<testing::NiceMock<MockAudioDeviceModule>>();
solenberg566ef242015-11-06 23:34:49131 audio_state_ = AudioState::Create(config);
solenberg7add0582015-11-20 17:59:34132
Mirko Bonadei6a489f22019-04-09 13:11:12133 channel_receive_ = new ::testing::StrictMock<MockChannelReceive>();
Niels Möller349ade32018-11-16 08:50:42134 EXPECT_CALL(*channel_receive_, SetNACKStatus(true, 15)).Times(1);
Philipp Hanckebad99ab2024-05-13 15:49:42135 EXPECT_CALL(*channel_receive_, SetRtcpMode(_)).Times(1);
Niels Möller349ade32018-11-16 08:50:42136 EXPECT_CALL(*channel_receive_,
Yves Gerey665174f2018-06-19 13:03:05137 RegisterReceiverCongestionControlObjects(&packet_router_))
138 .Times(1);
Niels Möller349ade32018-11-16 08:50:42139 EXPECT_CALL(*channel_receive_, ResetReceiverCongestionControlObjects())
Fredrik Solenberg8f5787a2018-01-11 12:52:30140 .Times(1);
Niels Möller349ade32018-11-16 08:50:42141 EXPECT_CALL(*channel_receive_, SetReceiveCodecs(_))
Yves Gerey665174f2018-06-19 13:03:05142 .WillRepeatedly(Invoke([](const std::map<int, SdpAudioFormat>& codecs) {
Mirko Bonadei6a489f22019-04-09 13:11:12143 EXPECT_THAT(codecs, ::testing::IsEmpty());
Yves Gerey665174f2018-06-19 13:03:05144 }));
Tommicc50b042022-05-09 10:22:48145 EXPECT_CALL(*channel_receive_, GetLocalSsrc())
146 .WillRepeatedly(Return(kLocalSsrc));
Fredrik Solenberg8f5787a2018-01-11 12:52:30147
solenberg566ef242015-11-06 23:34:49148 stream_config_.rtp.local_ssrc = kLocalSsrc;
149 stream_config_.rtp.remote_ssrc = kRemoteSsrc;
solenberg8189b022016-06-14 19:13:00150 stream_config_.rtp.nack.rtp_history_ms = 300;
Niels Möllerae4237e2018-10-05 09:28:38151 stream_config_.rtcp_send_transport = &rtcp_send_transport_;
Fredrik Solenberg8f5787a2018-01-11 12:52:30152 stream_config_.decoder_factory =
Tomas Gunnarssonc1d58912021-04-22 17:21:43153 rtc::make_ref_counted<MockAudioDecoderFactory>();
solenberg13725082015-11-25 16:16:52154 }
solenberg566ef242015-11-06 23:34:49155
Tommidddbbeb2022-05-20 13:21:33156 std::unique_ptr<AudioReceiveStreamImpl> CreateAudioReceiveStream() {
157 auto ret = std::make_unique<AudioReceiveStreamImpl>(
Danil Chapovalov3732b842024-07-18 16:24:32158 CreateEnvironment(), &packet_router_, stream_config_, audio_state_,
Tommi02df2eb2021-05-31 10:57:53159 std::unique_ptr<voe::ChannelReceiveInterface>(channel_receive_));
160 ret->RegisterWithTransport(&rtp_stream_receiver_controller_);
161 return ret;
nisse0f15f922017-06-21 08:05:22162 }
solenberg566ef242015-11-06 23:34:49163
Tommi3176ef72022-05-22 18:47:28164 AudioReceiveStreamInterface::Config& config() { return stream_config_; }
Fredrik Solenberg8f5787a2018-01-11 12:52:30165 rtc::scoped_refptr<MockAudioMixer> audio_mixer() { return audio_mixer_; }
Niels Möller349ade32018-11-16 08:50:42166 MockChannelReceive* channel_receive() { return channel_receive_; }
Fredrik Solenberg8f5787a2018-01-11 12:52:30167
solenberg566ef242015-11-06 23:34:49168 void SetupMockForGetStats() {
Mirko Bonadei6a489f22019-04-09 13:11:12169 using ::testing::DoAll;
170 using ::testing::SetArgPointee;
solenberg13725082015-11-25 16:16:52171
Niels Möller349ade32018-11-16 08:50:42172 ASSERT_TRUE(channel_receive_);
173 EXPECT_CALL(*channel_receive_, GetRTCPStatistics())
solenberg358057b2015-11-27 18:46:42174 .WillOnce(Return(kCallStats));
Niels Möller349ade32018-11-16 08:50:42175 EXPECT_CALL(*channel_receive_, GetDelayEstimate())
solenberg358057b2015-11-27 18:46:42176 .WillOnce(Return(kJitterBufferDelay + kPlayoutBufferDelay));
Niels Möller349ade32018-11-16 08:50:42177 EXPECT_CALL(*channel_receive_, GetSpeechOutputLevelFullRange())
solenberg358057b2015-11-27 18:46:42178 .WillOnce(Return(kSpeechOutputLevel));
Niels Möller349ade32018-11-16 08:50:42179 EXPECT_CALL(*channel_receive_, GetTotalOutputEnergy())
zsteine76bd3a2017-07-14 19:17:49180 .WillOnce(Return(kTotalOutputEnergy));
Niels Möller349ade32018-11-16 08:50:42181 EXPECT_CALL(*channel_receive_, GetTotalOutputDuration())
zsteine76bd3a2017-07-14 19:17:49182 .WillOnce(Return(kTotalOutputDuration));
Niels Möller6b4d9622020-09-14 08:47:50183 EXPECT_CALL(*channel_receive_, GetNetworkStatistics(_))
solenberg358057b2015-11-27 18:46:42184 .WillOnce(Return(kNetworkStats));
Niels Möller349ade32018-11-16 08:50:42185 EXPECT_CALL(*channel_receive_, GetDecodingCallStatistics())
solenberg358057b2015-11-27 18:46:42186 .WillOnce(Return(kAudioDecodeStats));
Fredrik Solenbergf693bfa2018-12-11 11:22:10187 EXPECT_CALL(*channel_receive_, GetReceiveCodec())
188 .WillOnce(Return(kReceiveCodec));
Åsa Perssonfcf79cc2019-10-22 13:23:44189 EXPECT_CALL(*channel_receive_, GetCurrentEstimatedPlayoutNtpTimestampMs(_))
190 .WillOnce(Return(kPlayoutNtpTimestampMs));
solenberg566ef242015-11-06 23:34:49191 }
192
193 private:
Stefan Holmer3842c5c2016-01-12 12:55:00194 PacketRouter packet_router_;
solenberg566ef242015-11-06 23:34:49195 rtc::scoped_refptr<AudioState> audio_state_;
aleloi04c07222016-11-22 14:42:53196 rtc::scoped_refptr<MockAudioMixer> audio_mixer_;
Tommi3176ef72022-05-22 18:47:28197 AudioReceiveStreamInterface::Config stream_config_;
Mirko Bonadei6a489f22019-04-09 13:11:12198 ::testing::StrictMock<MockChannelReceive>* channel_receive_ = nullptr;
nisse0f15f922017-06-21 08:05:22199 RtpStreamReceiverController rtp_stream_receiver_controller_;
Niels Möllerae4237e2018-10-05 09:28:38200 MockTransport rtcp_send_transport_;
solenberg566ef242015-11-06 23:34:49201};
Stefan Holmer8bffba72015-09-23 13:53:52202
Jakob Ivarsson75dc9c92025-01-10 12:29:00203std::vector<uint8_t> CreateRtcpSenderReport() {
mflodman3d7db262016-04-29 07:57:13204 std::vector<uint8_t> packet;
205 const size_t kRtcpSrLength = 28; // In bytes.
206 packet.resize(kRtcpSrLength);
207 packet[0] = 0x80; // Version 2.
208 packet[1] = 0xc8; // PT = 200, SR.
209 // Length in number of 32-bit words - 1.
210 ByteWriter<uint16_t>::WriteBigEndian(&packet[2], 6);
211 ByteWriter<uint32_t>::WriteBigEndian(&packet[4], kLocalSsrc);
212 return packet;
213}
Fredrik Solenberg4f4ec0a2015-10-22 08:49:27214} // namespace
215
solenberg85a04962015-10-27 10:35:21216TEST(AudioReceiveStreamTest, ConfigToString) {
Tommi3176ef72022-05-22 18:47:28217 AudioReceiveStreamInterface::Config config;
Fredrik Solenberg0ccae132015-11-03 09:15:49218 config.rtp.remote_ssrc = kRemoteSsrc;
219 config.rtp.local_ssrc = kLocalSsrc;
Philipp Hanckebad99ab2024-05-13 15:49:42220 config.rtp.rtcp_mode = RtcpMode::kOff;
Fredrik Solenberg0ccae132015-11-03 09:15:49221 EXPECT_EQ(
Per K92532402023-01-02 15:57:18222 "{rtp: {remote_ssrc: 1234, local_ssrc: 5678, nack: "
Philipp Hanckebad99ab2024-05-13 15:49:42223 "{rtp_history_ms: 0}, rtcp: off}, "
Bjorn A Mellem7a9a0922019-11-26 17:19:40224 "rtcp_send_transport: null}",
Fredrik Solenberg0ccae132015-11-03 09:15:49225 config.ToString());
solenberg85a04962015-10-27 10:35:21226}
227
228TEST(AudioReceiveStreamTest, ConstructDestruct) {
Tommicde4b672023-04-25 06:53:42229 test::RunLoop loop;
Per Åhgrencc73ed32020-04-26 21:56:17230 for (bool use_null_audio_processing : {false, true}) {
231 ConfigHelper helper(use_null_audio_processing);
232 auto recv_stream = helper.CreateAudioReceiveStream();
Tommi02df2eb2021-05-31 10:57:53233 recv_stream->UnregisterFromTransport();
Per Åhgrencc73ed32020-04-26 21:56:17234 }
Stefan Holmer3842c5c2016-01-12 12:55:00235}
236
mflodman3d7db262016-04-29 07:57:13237TEST(AudioReceiveStreamTest, ReceiveRtcpPacket) {
Tommicde4b672023-04-25 06:53:42238 test::RunLoop loop;
Per Åhgrencc73ed32020-04-26 21:56:17239 for (bool use_null_audio_processing : {false, true}) {
240 ConfigHelper helper(use_null_audio_processing);
Per Åhgrencc73ed32020-04-26 21:56:17241 auto recv_stream = helper.CreateAudioReceiveStream();
242 std::vector<uint8_t> rtcp_packet = CreateRtcpSenderReport();
243 EXPECT_CALL(*helper.channel_receive(),
244 ReceivedRTCPPacket(&rtcp_packet[0], rtcp_packet.size()))
245 .WillOnce(Return());
246 recv_stream->DeliverRtcp(&rtcp_packet[0], rtcp_packet.size());
Tommi02df2eb2021-05-31 10:57:53247 recv_stream->UnregisterFromTransport();
Per Åhgrencc73ed32020-04-26 21:56:17248 }
mflodman3d7db262016-04-29 07:57:13249}
250
Fredrik Solenberg4f4ec0a2015-10-22 08:49:27251TEST(AudioReceiveStreamTest, GetStats) {
Tommicde4b672023-04-25 06:53:42252 test::RunLoop loop;
Per Åhgrencc73ed32020-04-26 21:56:17253 for (bool use_null_audio_processing : {false, true}) {
254 ConfigHelper helper(use_null_audio_processing);
255 auto recv_stream = helper.CreateAudioReceiveStream();
256 helper.SetupMockForGetStats();
Tommi3176ef72022-05-22 18:47:28257 AudioReceiveStreamInterface::Stats stats =
Niels Möller6b4d9622020-09-14 08:47:50258 recv_stream->GetStats(/*get_and_clear_legacy_stats=*/true);
Per Åhgrencc73ed32020-04-26 21:56:17259 EXPECT_EQ(kRemoteSsrc, stats.remote_ssrc);
Philipp Hancke6a7bf102023-04-21 17:32:42260 EXPECT_EQ(kCallStats.payload_bytes_received, stats.payload_bytes_received);
261 EXPECT_EQ(kCallStats.header_and_padding_bytes_received,
262 stats.header_and_padding_bytes_received);
Jakob Ivarsson8da15c42024-11-21 15:35:46263 EXPECT_EQ(static_cast<uint32_t>(kCallStats.packets_received),
Philipp Hancke6a7bf102023-04-21 17:32:42264 stats.packets_received);
Jakob Ivarsson8da15c42024-11-21 15:35:46265 EXPECT_EQ(kCallStats.packets_lost, stats.packets_lost);
Per Åhgrencc73ed32020-04-26 21:56:17266 EXPECT_EQ(kReceiveCodec.second.name, stats.codec_name);
Jakob Ivarsson8da15c42024-11-21 15:35:46267 EXPECT_EQ(kCallStats.jitter_ms, stats.jitter_ms);
Per Åhgrencc73ed32020-04-26 21:56:17268 EXPECT_EQ(kNetworkStats.currentBufferSize, stats.jitter_buffer_ms);
269 EXPECT_EQ(kNetworkStats.preferredBufferSize,
270 stats.jitter_buffer_preferred_ms);
271 EXPECT_EQ(static_cast<uint32_t>(kJitterBufferDelay + kPlayoutBufferDelay),
272 stats.delay_estimate_ms);
273 EXPECT_EQ(static_cast<int32_t>(kSpeechOutputLevel), stats.audio_level);
274 EXPECT_EQ(kTotalOutputEnergy, stats.total_output_energy);
275 EXPECT_EQ(kNetworkStats.totalSamplesReceived, stats.total_samples_received);
276 EXPECT_EQ(kTotalOutputDuration, stats.total_output_duration);
277 EXPECT_EQ(kNetworkStats.concealedSamples, stats.concealed_samples);
278 EXPECT_EQ(kNetworkStats.concealmentEvents, stats.concealment_events);
279 EXPECT_EQ(static_cast<double>(kNetworkStats.jitterBufferDelayMs) /
280 static_cast<double>(rtc::kNumMillisecsPerSec),
281 stats.jitter_buffer_delay_seconds);
282 EXPECT_EQ(kNetworkStats.jitterBufferEmittedCount,
283 stats.jitter_buffer_emitted_count);
284 EXPECT_EQ(static_cast<double>(kNetworkStats.jitterBufferTargetDelayMs) /
285 static_cast<double>(rtc::kNumMillisecsPerSec),
286 stats.jitter_buffer_target_delay_seconds);
Ivo Creusen1a84b562022-07-19 14:33:10287 EXPECT_EQ(static_cast<double>(kNetworkStats.jitterBufferMinimumDelayMs) /
288 static_cast<double>(rtc::kNumMillisecsPerSec),
289 stats.jitter_buffer_minimum_delay_seconds);
Minyue Li28a2c632021-07-07 13:53:38290 EXPECT_EQ(kNetworkStats.insertedSamplesForDeceleration,
291 stats.inserted_samples_for_deceleration);
292 EXPECT_EQ(kNetworkStats.removedSamplesForAcceleration,
293 stats.removed_samples_for_acceleration);
294 EXPECT_EQ(kNetworkStats.fecPacketsReceived, stats.fec_packets_received);
295 EXPECT_EQ(kNetworkStats.fecPacketsDiscarded, stats.fec_packets_discarded);
Jesús de Vicente Peñafc6df052024-06-04 08:05:31296 EXPECT_EQ(static_cast<double>(kNetworkStats.totalProcessingDelayUs) /
297 static_cast<double>(rtc::kNumMicrosecsPerSec),
298 stats.total_processing_delay_seconds);
Minyue Li28a2c632021-07-07 13:53:38299 EXPECT_EQ(kNetworkStats.packetsDiscarded, stats.packets_discarded);
Per Åhgrencc73ed32020-04-26 21:56:17300 EXPECT_EQ(Q14ToFloat(kNetworkStats.currentExpandRate), stats.expand_rate);
301 EXPECT_EQ(Q14ToFloat(kNetworkStats.currentSpeechExpandRate),
302 stats.speech_expand_rate);
303 EXPECT_EQ(Q14ToFloat(kNetworkStats.currentSecondaryDecodedRate),
304 stats.secondary_decoded_rate);
305 EXPECT_EQ(Q14ToFloat(kNetworkStats.currentSecondaryDiscardedRate),
306 stats.secondary_discarded_rate);
307 EXPECT_EQ(Q14ToFloat(kNetworkStats.currentAccelerateRate),
308 stats.accelerate_rate);
309 EXPECT_EQ(Q14ToFloat(kNetworkStats.currentPreemptiveRate),
310 stats.preemptive_expand_rate);
Minyue Li28a2c632021-07-07 13:53:38311 EXPECT_EQ(kNetworkStats.packetBufferFlushes, stats.jitter_buffer_flushes);
312 EXPECT_EQ(kNetworkStats.delayedPacketOutageSamples,
313 stats.delayed_packet_outage_samples);
314 EXPECT_EQ(static_cast<double>(kNetworkStats.relativePacketArrivalDelayMs) /
315 static_cast<double>(rtc::kNumMillisecsPerSec),
316 stats.relative_packet_arrival_delay_seconds);
317 EXPECT_EQ(kNetworkStats.interruptionCount, stats.interruption_count);
318 EXPECT_EQ(kNetworkStats.totalInterruptionDurationMs,
319 stats.total_interruption_duration_ms);
320
Per Åhgrencc73ed32020-04-26 21:56:17321 EXPECT_EQ(kAudioDecodeStats.calls_to_silence_generator,
322 stats.decoding_calls_to_silence_generator);
323 EXPECT_EQ(kAudioDecodeStats.calls_to_neteq, stats.decoding_calls_to_neteq);
324 EXPECT_EQ(kAudioDecodeStats.decoded_normal, stats.decoding_normal);
325 EXPECT_EQ(kAudioDecodeStats.decoded_neteq_plc, stats.decoding_plc);
326 EXPECT_EQ(kAudioDecodeStats.decoded_codec_plc, stats.decoding_codec_plc);
327 EXPECT_EQ(kAudioDecodeStats.decoded_cng, stats.decoding_cng);
328 EXPECT_EQ(kAudioDecodeStats.decoded_plc_cng, stats.decoding_plc_cng);
329 EXPECT_EQ(kAudioDecodeStats.decoded_muted_output,
330 stats.decoding_muted_output);
Jakob Ivarsson8da15c42024-11-21 15:35:46331 EXPECT_EQ(kCallStats.capture_start_ntp_time_ms,
Per Åhgrencc73ed32020-04-26 21:56:17332 stats.capture_start_ntp_time_ms);
333 EXPECT_EQ(kPlayoutNtpTimestampMs, stats.estimated_playout_ntp_timestamp_ms);
Tommi02df2eb2021-05-31 10:57:53334 recv_stream->UnregisterFromTransport();
Per Åhgrencc73ed32020-04-26 21:56:17335 }
Fredrik Solenberg4f4ec0a2015-10-22 08:49:27336}
solenberg217fb662016-06-17 15:30:54337
338TEST(AudioReceiveStreamTest, SetGain) {
Tommicde4b672023-04-25 06:53:42339 test::RunLoop loop;
Per Åhgrencc73ed32020-04-26 21:56:17340 for (bool use_null_audio_processing : {false, true}) {
341 ConfigHelper helper(use_null_audio_processing);
342 auto recv_stream = helper.CreateAudioReceiveStream();
343 EXPECT_CALL(*helper.channel_receive(),
344 SetChannelOutputVolumeScaling(FloatEq(0.765f)));
345 recv_stream->SetGain(0.765f);
Tommi02df2eb2021-05-31 10:57:53346 recv_stream->UnregisterFromTransport();
Per Åhgrencc73ed32020-04-26 21:56:17347 }
solenberg217fb662016-06-17 15:30:54348}
aleloi04c07222016-11-22 14:42:53349
Fredrik Solenbergd5247512017-12-18 21:41:03350TEST(AudioReceiveStreamTest, StreamsShouldBeAddedToMixerOnceOnStart) {
Tommicde4b672023-04-25 06:53:42351 test::RunLoop loop;
Per Åhgrencc73ed32020-04-26 21:56:17352 for (bool use_null_audio_processing : {false, true}) {
353 ConfigHelper helper1(use_null_audio_processing);
354 ConfigHelper helper2(helper1.audio_mixer(), use_null_audio_processing);
355 auto recv_stream1 = helper1.CreateAudioReceiveStream();
356 auto recv_stream2 = helper2.CreateAudioReceiveStream();
aleloi04c07222016-11-22 14:42:53357
Per Åhgrencc73ed32020-04-26 21:56:17358 EXPECT_CALL(*helper1.channel_receive(), StartPlayout()).Times(1);
359 EXPECT_CALL(*helper2.channel_receive(), StartPlayout()).Times(1);
360 EXPECT_CALL(*helper1.channel_receive(), StopPlayout()).Times(1);
361 EXPECT_CALL(*helper2.channel_receive(), StopPlayout()).Times(1);
362 EXPECT_CALL(*helper1.audio_mixer(), AddSource(recv_stream1.get()))
363 .WillOnce(Return(true));
364 EXPECT_CALL(*helper1.audio_mixer(), AddSource(recv_stream2.get()))
365 .WillOnce(Return(true));
366 EXPECT_CALL(*helper1.audio_mixer(), RemoveSource(recv_stream1.get()))
367 .Times(1);
368 EXPECT_CALL(*helper1.audio_mixer(), RemoveSource(recv_stream2.get()))
369 .Times(1);
aleloi04c07222016-11-22 14:42:53370
Per Åhgrencc73ed32020-04-26 21:56:17371 recv_stream1->Start();
372 recv_stream2->Start();
Fredrik Solenbergd5247512017-12-18 21:41:03373
Per Åhgrencc73ed32020-04-26 21:56:17374 // One more should not result in any more mixer sources added.
375 recv_stream1->Start();
Fredrik Solenbergd5247512017-12-18 21:41:03376
Per Åhgrencc73ed32020-04-26 21:56:17377 // Stop stream before it is being destructed.
378 recv_stream2->Stop();
Tommi02df2eb2021-05-31 10:57:53379
380 recv_stream1->UnregisterFromTransport();
381 recv_stream2->UnregisterFromTransport();
Per Åhgrencc73ed32020-04-26 21:56:17382 }
aleloi04c07222016-11-22 14:42:53383}
Fredrik Solenberg3b903d02018-01-10 14:17:10384
Fredrik Solenberg3b903d02018-01-10 14:17:10385TEST(AudioReceiveStreamTest, ReconfigureWithUpdatedConfig) {
Tommicde4b672023-04-25 06:53:42386 test::RunLoop loop;
Per Åhgrencc73ed32020-04-26 21:56:17387 for (bool use_null_audio_processing : {false, true}) {
388 ConfigHelper helper(use_null_audio_processing);
389 auto recv_stream = helper.CreateAudioReceiveStream();
Fredrik Solenberg3b903d02018-01-10 14:17:10390
Per Åhgrencc73ed32020-04-26 21:56:17391 auto new_config = helper.config();
Tommi6eda26c2021-06-09 11:46:28392
Per Åhgrencc73ed32020-04-26 21:56:17393 MockChannelReceive& channel_receive = *helper.channel_receive();
Tommie2561e12021-06-08 14:55:47394
Tommi6eda26c2021-06-09 11:46:28395 // TODO(tommi, nisse): This applies new extensions to the internal config,
396 // but there's nothing that actually verifies that the changes take effect.
397 // In fact Call manages the extensions separately in Call::ReceiveRtpConfig
398 // and changing this config value (there seem to be a few copies), doesn't
399 // affect that logic.
400 recv_stream->ReconfigureForTesting(new_config);
401
402 new_config.decoder_map.emplace(1, SdpAudioFormat("foo", 8000, 1));
403 EXPECT_CALL(channel_receive, SetReceiveCodecs(new_config.decoder_map));
404 recv_stream->SetDecoderMap(new_config.decoder_map);
405
406 EXPECT_CALL(channel_receive, SetNACKStatus(true, 15 + 1)).Times(1);
Tommia136ed42022-05-30 13:08:13407 recv_stream->SetNackHistory(300 + 20);
Tommi6eda26c2021-06-09 11:46:28408
Tommi02df2eb2021-05-31 10:57:53409 recv_stream->UnregisterFromTransport();
Per Åhgrencc73ed32020-04-26 21:56:17410 }
Fredrik Solenberg3b903d02018-01-10 14:17:10411}
Benjamin Wright78410ad2018-10-25 16:52:57412
413TEST(AudioReceiveStreamTest, ReconfigureWithFrameDecryptor) {
Tommicde4b672023-04-25 06:53:42414 test::RunLoop loop;
Per Åhgrencc73ed32020-04-26 21:56:17415 for (bool use_null_audio_processing : {false, true}) {
416 ConfigHelper helper(use_null_audio_processing);
417 auto recv_stream = helper.CreateAudioReceiveStream();
Benjamin Wright78410ad2018-10-25 16:52:57418
Per Åhgrencc73ed32020-04-26 21:56:17419 auto new_config_0 = helper.config();
420 rtc::scoped_refptr<FrameDecryptorInterface> mock_frame_decryptor_0(
Tomas Gunnarssonc1d58912021-04-22 17:21:43421 rtc::make_ref_counted<MockFrameDecryptor>());
Per Åhgrencc73ed32020-04-26 21:56:17422 new_config_0.frame_decryptor = mock_frame_decryptor_0;
Benjamin Wright78410ad2018-10-25 16:52:57423
Tommi6eda26c2021-06-09 11:46:28424 // TODO(tommi): While this changes the internal config value, it doesn't
425 // actually change what frame_decryptor is used. WebRtcAudioReceiveStream
426 // recreates the whole instance in order to change this value.
427 // So, it's not clear if changing this post initialization needs to be
428 // supported.
429 recv_stream->ReconfigureForTesting(new_config_0);
Benjamin Wright78410ad2018-10-25 16:52:57430
Per Åhgrencc73ed32020-04-26 21:56:17431 auto new_config_1 = helper.config();
432 rtc::scoped_refptr<FrameDecryptorInterface> mock_frame_decryptor_1(
Tomas Gunnarssonc1d58912021-04-22 17:21:43433 rtc::make_ref_counted<MockFrameDecryptor>());
Per Åhgrencc73ed32020-04-26 21:56:17434 new_config_1.frame_decryptor = mock_frame_decryptor_1;
435 new_config_1.crypto_options.sframe.require_frame_encryption = true;
Tommi6eda26c2021-06-09 11:46:28436 recv_stream->ReconfigureForTesting(new_config_1);
Tommi02df2eb2021-05-31 10:57:53437 recv_stream->UnregisterFromTransport();
Per Åhgrencc73ed32020-04-26 21:56:17438 }
Benjamin Wright78410ad2018-10-25 16:52:57439}
440
Fredrik Solenberg4f4ec0a2015-10-22 08:49:27441} // namespace test
Stefan Holmer8bffba72015-09-23 13:53:52442} // namespace webrtc