1 /*
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
11 #include "audio/audio_receive_stream.h"
12
13 #include <map>
14 #include <string>
15 #include <utility>
16 #include <vector>
17
18 #include "api/test/mock_audio_mixer.h"
19 #include "api/test/mock_frame_decryptor.h"
20 #include "audio/conversion.h"
21 #include "audio/mock_voe_channel_proxy.h"
22 #include "call/rtp_stream_receiver_controller.h"
23 #include "logging/rtc_event_log/mock/mock_rtc_event_log.h"
24 #include "modules/audio_device/include/mock_audio_device.h"
25 #include "modules/audio_processing/include/mock_audio_processing.h"
26 #include "modules/pacing/packet_router.h"
27 #include "modules/rtp_rtcp/source/byte_io.h"
28 #include "rtc_base/time_utils.h"
29 #include "test/gtest.h"
30 #include "test/mock_audio_decoder_factory.h"
31 #include "test/mock_transport.h"
32
33 namespace webrtc {
34 namespace test {
35 namespace {
36
37 using ::testing::_;
38 using ::testing::FloatEq;
39 using ::testing::Return;
40
MakeAudioDecodeStatsForTest()41 AudioDecodingCallStats MakeAudioDecodeStatsForTest() {
42 AudioDecodingCallStats audio_decode_stats;
43 audio_decode_stats.calls_to_silence_generator = 234;
44 audio_decode_stats.calls_to_neteq = 567;
45 audio_decode_stats.decoded_normal = 890;
46 audio_decode_stats.decoded_neteq_plc = 123;
47 audio_decode_stats.decoded_codec_plc = 124;
48 audio_decode_stats.decoded_cng = 456;
49 audio_decode_stats.decoded_plc_cng = 789;
50 audio_decode_stats.decoded_muted_output = 987;
51 return audio_decode_stats;
52 }
53
54 const uint32_t kRemoteSsrc = 1234;
55 const uint32_t kLocalSsrc = 5678;
56 const size_t kOneByteExtensionHeaderLength = 4;
57 const size_t kOneByteExtensionLength = 4;
58 const int kAudioLevelId = 3;
59 const int kTransportSequenceNumberId = 4;
60 const int kJitterBufferDelay = -7;
61 const int kPlayoutBufferDelay = 302;
62 const unsigned int kSpeechOutputLevel = 99;
63 const double kTotalOutputEnergy = 0.25;
64 const double kTotalOutputDuration = 0.5;
65 const int64_t kPlayoutNtpTimestampMs = 5678;
66
67 const CallReceiveStatistics kCallStats = {678, 234, -12, 567, 78, 890, 123};
68 const std::pair<int, SdpAudioFormat> kReceiveCodec = {
69 123,
70 {"codec_name_recv", 96000, 0}};
71 const NetworkStatistics kNetworkStats = {
72 123, 456, false, 789012, 3456, 123, 456, 789, 543, 123,
73 432, 321, 123, 101, 0, {}, 789, 12, 345, 678,
74 901, 0, -1, -1, -1, -1, 0, 0, 0, 0};
75 const AudioDecodingCallStats kAudioDecodeStats = MakeAudioDecodeStatsForTest();
76
77 struct ConfigHelper {
ConfigHelperwebrtc::test::__anonddcb09660111::ConfigHelper78 explicit ConfigHelper(bool use_null_audio_processing)
79 : ConfigHelper(new rtc::RefCountedObject<MockAudioMixer>(),
80 use_null_audio_processing) {}
81
ConfigHelperwebrtc::test::__anonddcb09660111::ConfigHelper82 ConfigHelper(rtc::scoped_refptr<MockAudioMixer> audio_mixer,
83 bool use_null_audio_processing)
84 : audio_mixer_(audio_mixer) {
85 using ::testing::Invoke;
86
87 AudioState::Config config;
88 config.audio_mixer = audio_mixer_;
89 config.audio_processing =
90 use_null_audio_processing
91 ? nullptr
92 : new rtc::RefCountedObject<MockAudioProcessing>();
93 config.audio_device_module =
94 new rtc::RefCountedObject<testing::NiceMock<MockAudioDeviceModule>>();
95 audio_state_ = AudioState::Create(config);
96
97 channel_receive_ = new ::testing::StrictMock<MockChannelReceive>();
98 EXPECT_CALL(*channel_receive_, SetNACKStatus(true, 15)).Times(1);
99 EXPECT_CALL(*channel_receive_,
100 RegisterReceiverCongestionControlObjects(&packet_router_))
101 .Times(1);
102 EXPECT_CALL(*channel_receive_, ResetReceiverCongestionControlObjects())
103 .Times(1);
104 EXPECT_CALL(*channel_receive_, SetAssociatedSendChannel(nullptr)).Times(1);
105 EXPECT_CALL(*channel_receive_, SetReceiveCodecs(_))
106 .WillRepeatedly(Invoke([](const std::map<int, SdpAudioFormat>& codecs) {
107 EXPECT_THAT(codecs, ::testing::IsEmpty());
108 }));
109 EXPECT_CALL(*channel_receive_, SetDepacketizerToDecoderFrameTransformer(_))
110 .Times(1);
111
112 stream_config_.rtp.local_ssrc = kLocalSsrc;
113 stream_config_.rtp.remote_ssrc = kRemoteSsrc;
114 stream_config_.rtp.nack.rtp_history_ms = 300;
115 stream_config_.rtp.extensions.push_back(
116 RtpExtension(RtpExtension::kAudioLevelUri, kAudioLevelId));
117 stream_config_.rtp.extensions.push_back(RtpExtension(
118 RtpExtension::kTransportSequenceNumberUri, kTransportSequenceNumberId));
119 stream_config_.rtcp_send_transport = &rtcp_send_transport_;
120 stream_config_.decoder_factory =
121 new rtc::RefCountedObject<MockAudioDecoderFactory>;
122 }
123
CreateAudioReceiveStreamwebrtc::test::__anonddcb09660111::ConfigHelper124 std::unique_ptr<internal::AudioReceiveStream> CreateAudioReceiveStream() {
125 return std::unique_ptr<internal::AudioReceiveStream>(
126 new internal::AudioReceiveStream(
127 Clock::GetRealTimeClock(), &rtp_stream_receiver_controller_,
128 &packet_router_, stream_config_, audio_state_, &event_log_,
129 std::unique_ptr<voe::ChannelReceiveInterface>(channel_receive_)));
130 }
131
configwebrtc::test::__anonddcb09660111::ConfigHelper132 AudioReceiveStream::Config& config() { return stream_config_; }
audio_mixerwebrtc::test::__anonddcb09660111::ConfigHelper133 rtc::scoped_refptr<MockAudioMixer> audio_mixer() { return audio_mixer_; }
channel_receivewebrtc::test::__anonddcb09660111::ConfigHelper134 MockChannelReceive* channel_receive() { return channel_receive_; }
135
SetupMockForGetStatswebrtc::test::__anonddcb09660111::ConfigHelper136 void SetupMockForGetStats() {
137 using ::testing::DoAll;
138 using ::testing::SetArgPointee;
139
140 ASSERT_TRUE(channel_receive_);
141 EXPECT_CALL(*channel_receive_, GetRTCPStatistics())
142 .WillOnce(Return(kCallStats));
143 EXPECT_CALL(*channel_receive_, GetDelayEstimate())
144 .WillOnce(Return(kJitterBufferDelay + kPlayoutBufferDelay));
145 EXPECT_CALL(*channel_receive_, GetSpeechOutputLevelFullRange())
146 .WillOnce(Return(kSpeechOutputLevel));
147 EXPECT_CALL(*channel_receive_, GetTotalOutputEnergy())
148 .WillOnce(Return(kTotalOutputEnergy));
149 EXPECT_CALL(*channel_receive_, GetTotalOutputDuration())
150 .WillOnce(Return(kTotalOutputDuration));
151 EXPECT_CALL(*channel_receive_, GetNetworkStatistics())
152 .WillOnce(Return(kNetworkStats));
153 EXPECT_CALL(*channel_receive_, GetDecodingCallStatistics())
154 .WillOnce(Return(kAudioDecodeStats));
155 EXPECT_CALL(*channel_receive_, GetReceiveCodec())
156 .WillOnce(Return(kReceiveCodec));
157 EXPECT_CALL(*channel_receive_, GetCurrentEstimatedPlayoutNtpTimestampMs(_))
158 .WillOnce(Return(kPlayoutNtpTimestampMs));
159 }
160
161 private:
162 PacketRouter packet_router_;
163 MockRtcEventLog event_log_;
164 rtc::scoped_refptr<AudioState> audio_state_;
165 rtc::scoped_refptr<MockAudioMixer> audio_mixer_;
166 AudioReceiveStream::Config stream_config_;
167 ::testing::StrictMock<MockChannelReceive>* channel_receive_ = nullptr;
168 RtpStreamReceiverController rtp_stream_receiver_controller_;
169 MockTransport rtcp_send_transport_;
170 };
171
BuildOneByteExtension(std::vector<uint8_t>::iterator it,int id,uint32_t extension_value,size_t value_length)172 void BuildOneByteExtension(std::vector<uint8_t>::iterator it,
173 int id,
174 uint32_t extension_value,
175 size_t value_length) {
176 const uint16_t kRtpOneByteHeaderExtensionId = 0xBEDE;
177 ByteWriter<uint16_t>::WriteBigEndian(&(*it), kRtpOneByteHeaderExtensionId);
178 it += 2;
179
180 ByteWriter<uint16_t>::WriteBigEndian(&(*it), kOneByteExtensionLength / 4);
181 it += 2;
182 const size_t kExtensionDataLength = kOneByteExtensionLength - 1;
183 uint32_t shifted_value = extension_value
184 << (8 * (kExtensionDataLength - value_length));
185 *it = (id << 4) + (static_cast<uint8_t>(value_length) - 1);
186 ++it;
187 ByteWriter<uint32_t, kExtensionDataLength>::WriteBigEndian(&(*it),
188 shifted_value);
189 }
190
CreateRtpHeaderWithOneByteExtension(int extension_id,uint32_t extension_value,size_t value_length)191 const std::vector<uint8_t> CreateRtpHeaderWithOneByteExtension(
192 int extension_id,
193 uint32_t extension_value,
194 size_t value_length) {
195 std::vector<uint8_t> header;
196 header.resize(webrtc::kRtpHeaderSize + kOneByteExtensionHeaderLength +
197 kOneByteExtensionLength);
198 header[0] = 0x80; // Version 2.
199 header[0] |= 0x10; // Set extension bit.
200 header[1] = 100; // Payload type.
201 header[1] |= 0x80; // Marker bit is set.
202 ByteWriter<uint16_t>::WriteBigEndian(&header[2], 0x1234); // Sequence number.
203 ByteWriter<uint32_t>::WriteBigEndian(&header[4], 0x5678); // Timestamp.
204 ByteWriter<uint32_t>::WriteBigEndian(&header[8], 0x4321); // SSRC.
205
206 BuildOneByteExtension(header.begin() + webrtc::kRtpHeaderSize, extension_id,
207 extension_value, value_length);
208 return header;
209 }
210
CreateRtcpSenderReport()211 const std::vector<uint8_t> CreateRtcpSenderReport() {
212 std::vector<uint8_t> packet;
213 const size_t kRtcpSrLength = 28; // In bytes.
214 packet.resize(kRtcpSrLength);
215 packet[0] = 0x80; // Version 2.
216 packet[1] = 0xc8; // PT = 200, SR.
217 // Length in number of 32-bit words - 1.
218 ByteWriter<uint16_t>::WriteBigEndian(&packet[2], 6);
219 ByteWriter<uint32_t>::WriteBigEndian(&packet[4], kLocalSsrc);
220 return packet;
221 }
222 } // namespace
223
TEST(AudioReceiveStreamTest,ConfigToString)224 TEST(AudioReceiveStreamTest, ConfigToString) {
225 AudioReceiveStream::Config config;
226 config.rtp.remote_ssrc = kRemoteSsrc;
227 config.rtp.local_ssrc = kLocalSsrc;
228 config.rtp.extensions.push_back(
229 RtpExtension(RtpExtension::kAudioLevelUri, kAudioLevelId));
230 EXPECT_EQ(
231 "{rtp: {remote_ssrc: 1234, local_ssrc: 5678, transport_cc: off, nack: "
232 "{rtp_history_ms: 0}, extensions: [{uri: "
233 "urn:ietf:params:rtp-hdrext:ssrc-audio-level, id: 3}]}, "
234 "rtcp_send_transport: null}",
235 config.ToString());
236 }
237
TEST(AudioReceiveStreamTest,ConstructDestruct)238 TEST(AudioReceiveStreamTest, ConstructDestruct) {
239 for (bool use_null_audio_processing : {false, true}) {
240 ConfigHelper helper(use_null_audio_processing);
241 auto recv_stream = helper.CreateAudioReceiveStream();
242 }
243 }
244
TEST(AudioReceiveStreamTest,ReceiveRtpPacket)245 TEST(AudioReceiveStreamTest, ReceiveRtpPacket) {
246 for (bool use_null_audio_processing : {false, true}) {
247 ConfigHelper helper(use_null_audio_processing);
248 helper.config().rtp.transport_cc = true;
249 auto recv_stream = helper.CreateAudioReceiveStream();
250 const int kTransportSequenceNumberValue = 1234;
251 std::vector<uint8_t> rtp_packet = CreateRtpHeaderWithOneByteExtension(
252 kTransportSequenceNumberId, kTransportSequenceNumberValue, 2);
253 constexpr int64_t packet_time_us = 5678000;
254
255 RtpPacketReceived parsed_packet;
256 ASSERT_TRUE(parsed_packet.Parse(&rtp_packet[0], rtp_packet.size()));
257 parsed_packet.set_arrival_time_ms((packet_time_us + 500) / 1000);
258
259 EXPECT_CALL(*helper.channel_receive(),
260 OnRtpPacket(::testing::Ref(parsed_packet)));
261
262 recv_stream->OnRtpPacket(parsed_packet);
263 }
264 }
265
TEST(AudioReceiveStreamTest,ReceiveRtcpPacket)266 TEST(AudioReceiveStreamTest, ReceiveRtcpPacket) {
267 for (bool use_null_audio_processing : {false, true}) {
268 ConfigHelper helper(use_null_audio_processing);
269 helper.config().rtp.transport_cc = true;
270 auto recv_stream = helper.CreateAudioReceiveStream();
271 std::vector<uint8_t> rtcp_packet = CreateRtcpSenderReport();
272 EXPECT_CALL(*helper.channel_receive(),
273 ReceivedRTCPPacket(&rtcp_packet[0], rtcp_packet.size()))
274 .WillOnce(Return());
275 recv_stream->DeliverRtcp(&rtcp_packet[0], rtcp_packet.size());
276 }
277 }
278
TEST(AudioReceiveStreamTest,GetStats)279 TEST(AudioReceiveStreamTest, GetStats) {
280 for (bool use_null_audio_processing : {false, true}) {
281 ConfigHelper helper(use_null_audio_processing);
282 auto recv_stream = helper.CreateAudioReceiveStream();
283 helper.SetupMockForGetStats();
284 AudioReceiveStream::Stats stats = recv_stream->GetStats();
285 EXPECT_EQ(kRemoteSsrc, stats.remote_ssrc);
286 EXPECT_EQ(kCallStats.payload_bytes_rcvd, stats.payload_bytes_rcvd);
287 EXPECT_EQ(kCallStats.header_and_padding_bytes_rcvd,
288 stats.header_and_padding_bytes_rcvd);
289 EXPECT_EQ(static_cast<uint32_t>(kCallStats.packetsReceived),
290 stats.packets_rcvd);
291 EXPECT_EQ(kCallStats.cumulativeLost, stats.packets_lost);
292 EXPECT_EQ(kReceiveCodec.second.name, stats.codec_name);
293 EXPECT_EQ(
294 kCallStats.jitterSamples / (kReceiveCodec.second.clockrate_hz / 1000),
295 stats.jitter_ms);
296 EXPECT_EQ(kNetworkStats.currentBufferSize, stats.jitter_buffer_ms);
297 EXPECT_EQ(kNetworkStats.preferredBufferSize,
298 stats.jitter_buffer_preferred_ms);
299 EXPECT_EQ(static_cast<uint32_t>(kJitterBufferDelay + kPlayoutBufferDelay),
300 stats.delay_estimate_ms);
301 EXPECT_EQ(static_cast<int32_t>(kSpeechOutputLevel), stats.audio_level);
302 EXPECT_EQ(kTotalOutputEnergy, stats.total_output_energy);
303 EXPECT_EQ(kNetworkStats.totalSamplesReceived, stats.total_samples_received);
304 EXPECT_EQ(kTotalOutputDuration, stats.total_output_duration);
305 EXPECT_EQ(kNetworkStats.concealedSamples, stats.concealed_samples);
306 EXPECT_EQ(kNetworkStats.concealmentEvents, stats.concealment_events);
307 EXPECT_EQ(static_cast<double>(kNetworkStats.jitterBufferDelayMs) /
308 static_cast<double>(rtc::kNumMillisecsPerSec),
309 stats.jitter_buffer_delay_seconds);
310 EXPECT_EQ(kNetworkStats.jitterBufferEmittedCount,
311 stats.jitter_buffer_emitted_count);
312 EXPECT_EQ(static_cast<double>(kNetworkStats.jitterBufferTargetDelayMs) /
313 static_cast<double>(rtc::kNumMillisecsPerSec),
314 stats.jitter_buffer_target_delay_seconds);
315 EXPECT_EQ(Q14ToFloat(kNetworkStats.currentExpandRate), stats.expand_rate);
316 EXPECT_EQ(Q14ToFloat(kNetworkStats.currentSpeechExpandRate),
317 stats.speech_expand_rate);
318 EXPECT_EQ(Q14ToFloat(kNetworkStats.currentSecondaryDecodedRate),
319 stats.secondary_decoded_rate);
320 EXPECT_EQ(Q14ToFloat(kNetworkStats.currentSecondaryDiscardedRate),
321 stats.secondary_discarded_rate);
322 EXPECT_EQ(Q14ToFloat(kNetworkStats.currentAccelerateRate),
323 stats.accelerate_rate);
324 EXPECT_EQ(Q14ToFloat(kNetworkStats.currentPreemptiveRate),
325 stats.preemptive_expand_rate);
326 EXPECT_EQ(kAudioDecodeStats.calls_to_silence_generator,
327 stats.decoding_calls_to_silence_generator);
328 EXPECT_EQ(kAudioDecodeStats.calls_to_neteq, stats.decoding_calls_to_neteq);
329 EXPECT_EQ(kAudioDecodeStats.decoded_normal, stats.decoding_normal);
330 EXPECT_EQ(kAudioDecodeStats.decoded_neteq_plc, stats.decoding_plc);
331 EXPECT_EQ(kAudioDecodeStats.decoded_codec_plc, stats.decoding_codec_plc);
332 EXPECT_EQ(kAudioDecodeStats.decoded_cng, stats.decoding_cng);
333 EXPECT_EQ(kAudioDecodeStats.decoded_plc_cng, stats.decoding_plc_cng);
334 EXPECT_EQ(kAudioDecodeStats.decoded_muted_output,
335 stats.decoding_muted_output);
336 EXPECT_EQ(kCallStats.capture_start_ntp_time_ms_,
337 stats.capture_start_ntp_time_ms);
338 EXPECT_EQ(kPlayoutNtpTimestampMs, stats.estimated_playout_ntp_timestamp_ms);
339 }
340 }
341
TEST(AudioReceiveStreamTest,SetGain)342 TEST(AudioReceiveStreamTest, SetGain) {
343 for (bool use_null_audio_processing : {false, true}) {
344 ConfigHelper helper(use_null_audio_processing);
345 auto recv_stream = helper.CreateAudioReceiveStream();
346 EXPECT_CALL(*helper.channel_receive(),
347 SetChannelOutputVolumeScaling(FloatEq(0.765f)));
348 recv_stream->SetGain(0.765f);
349 }
350 }
351
TEST(AudioReceiveStreamTest,StreamsShouldBeAddedToMixerOnceOnStart)352 TEST(AudioReceiveStreamTest, StreamsShouldBeAddedToMixerOnceOnStart) {
353 for (bool use_null_audio_processing : {false, true}) {
354 ConfigHelper helper1(use_null_audio_processing);
355 ConfigHelper helper2(helper1.audio_mixer(), use_null_audio_processing);
356 auto recv_stream1 = helper1.CreateAudioReceiveStream();
357 auto recv_stream2 = helper2.CreateAudioReceiveStream();
358
359 EXPECT_CALL(*helper1.channel_receive(), StartPlayout()).Times(1);
360 EXPECT_CALL(*helper2.channel_receive(), StartPlayout()).Times(1);
361 EXPECT_CALL(*helper1.channel_receive(), StopPlayout()).Times(1);
362 EXPECT_CALL(*helper2.channel_receive(), StopPlayout()).Times(1);
363 EXPECT_CALL(*helper1.audio_mixer(), AddSource(recv_stream1.get()))
364 .WillOnce(Return(true));
365 EXPECT_CALL(*helper1.audio_mixer(), AddSource(recv_stream2.get()))
366 .WillOnce(Return(true));
367 EXPECT_CALL(*helper1.audio_mixer(), RemoveSource(recv_stream1.get()))
368 .Times(1);
369 EXPECT_CALL(*helper1.audio_mixer(), RemoveSource(recv_stream2.get()))
370 .Times(1);
371
372 recv_stream1->Start();
373 recv_stream2->Start();
374
375 // One more should not result in any more mixer sources added.
376 recv_stream1->Start();
377
378 // Stop stream before it is being destructed.
379 recv_stream2->Stop();
380 }
381 }
382
TEST(AudioReceiveStreamTest,ReconfigureWithSameConfig)383 TEST(AudioReceiveStreamTest, ReconfigureWithSameConfig) {
384 for (bool use_null_audio_processing : {false, true}) {
385 ConfigHelper helper(use_null_audio_processing);
386 auto recv_stream = helper.CreateAudioReceiveStream();
387 recv_stream->Reconfigure(helper.config());
388 }
389 }
390
TEST(AudioReceiveStreamTest,ReconfigureWithUpdatedConfig)391 TEST(AudioReceiveStreamTest, ReconfigureWithUpdatedConfig) {
392 for (bool use_null_audio_processing : {false, true}) {
393 ConfigHelper helper(use_null_audio_processing);
394 auto recv_stream = helper.CreateAudioReceiveStream();
395
396 auto new_config = helper.config();
397 new_config.rtp.nack.rtp_history_ms = 300 + 20;
398 new_config.rtp.extensions.clear();
399 new_config.rtp.extensions.push_back(
400 RtpExtension(RtpExtension::kAudioLevelUri, kAudioLevelId + 1));
401 new_config.rtp.extensions.push_back(
402 RtpExtension(RtpExtension::kTransportSequenceNumberUri,
403 kTransportSequenceNumberId + 1));
404 new_config.decoder_map.emplace(1, SdpAudioFormat("foo", 8000, 1));
405
406 MockChannelReceive& channel_receive = *helper.channel_receive();
407 EXPECT_CALL(channel_receive, SetNACKStatus(true, 15 + 1)).Times(1);
408 EXPECT_CALL(channel_receive, SetReceiveCodecs(new_config.decoder_map));
409
410 recv_stream->Reconfigure(new_config);
411 }
412 }
413
TEST(AudioReceiveStreamTest,ReconfigureWithFrameDecryptor)414 TEST(AudioReceiveStreamTest, ReconfigureWithFrameDecryptor) {
415 for (bool use_null_audio_processing : {false, true}) {
416 ConfigHelper helper(use_null_audio_processing);
417 auto recv_stream = helper.CreateAudioReceiveStream();
418
419 auto new_config_0 = helper.config();
420 rtc::scoped_refptr<FrameDecryptorInterface> mock_frame_decryptor_0(
421 new rtc::RefCountedObject<MockFrameDecryptor>());
422 new_config_0.frame_decryptor = mock_frame_decryptor_0;
423
424 recv_stream->Reconfigure(new_config_0);
425
426 auto new_config_1 = helper.config();
427 rtc::scoped_refptr<FrameDecryptorInterface> mock_frame_decryptor_1(
428 new rtc::RefCountedObject<MockFrameDecryptor>());
429 new_config_1.frame_decryptor = mock_frame_decryptor_1;
430 new_config_1.crypto_options.sframe.require_frame_encryption = true;
431 recv_stream->Reconfigure(new_config_1);
432 }
433 }
434
435 } // namespace test
436 } // namespace webrtc
437