1 /*
2 * Copyright (c) 2020 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/voip/audio_channel.h"
12
13 #include "absl/functional/any_invocable.h"
14 #include "api/audio_codecs/builtin_audio_decoder_factory.h"
15 #include "api/audio_codecs/builtin_audio_encoder_factory.h"
16 #include "api/call/transport.h"
17 #include "api/task_queue/task_queue_factory.h"
18 #include "audio/voip/test/mock_task_queue.h"
19 #include "modules/audio_mixer/audio_mixer_impl.h"
20 #include "modules/audio_mixer/sine_wave_generator.h"
21 #include "modules/rtp_rtcp/source/rtp_packet_received.h"
22 #include "rtc_base/logging.h"
23 #include "test/gmock.h"
24 #include "test/gtest.h"
25 #include "test/mock_transport.h"
26
27 namespace webrtc {
28 namespace {
29
30 using ::testing::Invoke;
31 using ::testing::NiceMock;
32 using ::testing::Return;
33 using ::testing::Unused;
34
35 constexpr uint64_t kStartTime = 123456789;
36 constexpr uint32_t kLocalSsrc = 0xdeadc0de;
37 constexpr int16_t kAudioLevel = 3004; // used for sine wave level
38 constexpr int kPcmuPayload = 0;
39
40 class AudioChannelTest : public ::testing::Test {
41 public:
42 const SdpAudioFormat kPcmuFormat = {"pcmu", 8000, 1};
43
AudioChannelTest()44 AudioChannelTest()
45 : fake_clock_(kStartTime), wave_generator_(1000.0, kAudioLevel) {
46 task_queue_factory_ = std::make_unique<MockTaskQueueFactory>(&task_queue_);
47 audio_mixer_ = AudioMixerImpl::Create();
48 encoder_factory_ = CreateBuiltinAudioEncoderFactory();
49 decoder_factory_ = CreateBuiltinAudioDecoderFactory();
50
51 // By default, run the queued task immediately.
52 ON_CALL(task_queue_, PostTask)
53 .WillByDefault(
54 [](absl::AnyInvocable<void() &&> task) { std::move(task)(); });
55 }
56
SetUp()57 void SetUp() override { audio_channel_ = CreateAudioChannel(kLocalSsrc); }
58
TearDown()59 void TearDown() override { audio_channel_ = nullptr; }
60
CreateAudioChannel(uint32_t ssrc)61 rtc::scoped_refptr<AudioChannel> CreateAudioChannel(uint32_t ssrc) {
62 // Use same audio mixer here for simplicity sake as we are not checking
63 // audio activity of RTP in our testcases. If we need to do test on audio
64 // signal activity then we need to assign audio mixer for each channel.
65 // Also this uses the same transport object for different audio channel to
66 // simplify network routing logic.
67 rtc::scoped_refptr<AudioChannel> audio_channel =
68 rtc::make_ref_counted<AudioChannel>(
69 &transport_, ssrc, task_queue_factory_.get(), audio_mixer_.get(),
70 decoder_factory_);
71 audio_channel->SetEncoder(kPcmuPayload, kPcmuFormat,
72 encoder_factory_->MakeAudioEncoder(
73 kPcmuPayload, kPcmuFormat, absl::nullopt));
74 audio_channel->SetReceiveCodecs({{kPcmuPayload, kPcmuFormat}});
75 audio_channel->StartSend();
76 audio_channel->StartPlay();
77 return audio_channel;
78 }
79
GetAudioFrame(int order)80 std::unique_ptr<AudioFrame> GetAudioFrame(int order) {
81 auto frame = std::make_unique<AudioFrame>();
82 frame->sample_rate_hz_ = kPcmuFormat.clockrate_hz;
83 frame->samples_per_channel_ = kPcmuFormat.clockrate_hz / 100; // 10 ms.
84 frame->num_channels_ = kPcmuFormat.num_channels;
85 frame->timestamp_ = frame->samples_per_channel_ * order;
86 wave_generator_.GenerateNextFrame(frame.get());
87 return frame;
88 }
89
90 SimulatedClock fake_clock_;
91 SineWaveGenerator wave_generator_;
92 NiceMock<MockTransport> transport_;
93 NiceMock<MockTaskQueue> task_queue_;
94 std::unique_ptr<TaskQueueFactory> task_queue_factory_;
95 rtc::scoped_refptr<AudioMixer> audio_mixer_;
96 rtc::scoped_refptr<AudioDecoderFactory> decoder_factory_;
97 rtc::scoped_refptr<AudioEncoderFactory> encoder_factory_;
98 rtc::scoped_refptr<AudioChannel> audio_channel_;
99 };
100
101 // Validate RTP packet generation by feeding audio frames with sine wave.
102 // Resulted RTP packet is looped back into AudioChannel and gets decoded into
103 // audio frame to see if it has some signal to indicate its validity.
TEST_F(AudioChannelTest,PlayRtpByLocalLoop)104 TEST_F(AudioChannelTest, PlayRtpByLocalLoop) {
105 auto loop_rtp = [&](const uint8_t* packet, size_t length, Unused) {
106 audio_channel_->ReceivedRTPPacket(
107 rtc::ArrayView<const uint8_t>(packet, length));
108 return true;
109 };
110 EXPECT_CALL(transport_, SendRtp).WillOnce(Invoke(loop_rtp));
111
112 auto audio_sender = audio_channel_->GetAudioSender();
113 audio_sender->SendAudioData(GetAudioFrame(0));
114 audio_sender->SendAudioData(GetAudioFrame(1));
115
116 AudioFrame empty_frame, audio_frame;
117 empty_frame.Mute();
118 empty_frame.mutable_data(); // This will zero out the data.
119 audio_frame.CopyFrom(empty_frame);
120 audio_mixer_->Mix(/*number_of_channels*/ 1, &audio_frame);
121
122 // We expect now audio frame to pick up something.
123 EXPECT_NE(memcmp(empty_frame.data(), audio_frame.data(),
124 AudioFrame::kMaxDataSizeBytes),
125 0);
126 }
127
128 // Validate assigned local SSRC is resulted in RTP packet.
TEST_F(AudioChannelTest,VerifyLocalSsrcAsAssigned)129 TEST_F(AudioChannelTest, VerifyLocalSsrcAsAssigned) {
130 RtpPacketReceived rtp;
131 auto loop_rtp = [&](const uint8_t* packet, size_t length, Unused) {
132 rtp.Parse(packet, length);
133 return true;
134 };
135 EXPECT_CALL(transport_, SendRtp).WillOnce(Invoke(loop_rtp));
136
137 auto audio_sender = audio_channel_->GetAudioSender();
138 audio_sender->SendAudioData(GetAudioFrame(0));
139 audio_sender->SendAudioData(GetAudioFrame(1));
140
141 EXPECT_EQ(rtp.Ssrc(), kLocalSsrc);
142 }
143
144 // Check metrics after processing an RTP packet.
TEST_F(AudioChannelTest,TestIngressStatistics)145 TEST_F(AudioChannelTest, TestIngressStatistics) {
146 auto loop_rtp = [&](const uint8_t* packet, size_t length, Unused) {
147 audio_channel_->ReceivedRTPPacket(
148 rtc::ArrayView<const uint8_t>(packet, length));
149 return true;
150 };
151 EXPECT_CALL(transport_, SendRtp).WillRepeatedly(Invoke(loop_rtp));
152
153 auto audio_sender = audio_channel_->GetAudioSender();
154 audio_sender->SendAudioData(GetAudioFrame(0));
155 audio_sender->SendAudioData(GetAudioFrame(1));
156
157 AudioFrame audio_frame;
158 audio_mixer_->Mix(/*number_of_channels=*/1, &audio_frame);
159 audio_mixer_->Mix(/*number_of_channels=*/1, &audio_frame);
160
161 absl::optional<IngressStatistics> ingress_stats =
162 audio_channel_->GetIngressStatistics();
163 EXPECT_TRUE(ingress_stats);
164 EXPECT_EQ(ingress_stats->neteq_stats.total_samples_received, 160ULL);
165 EXPECT_EQ(ingress_stats->neteq_stats.concealed_samples, 0ULL);
166 EXPECT_EQ(ingress_stats->neteq_stats.concealment_events, 0ULL);
167 EXPECT_EQ(ingress_stats->neteq_stats.inserted_samples_for_deceleration, 0ULL);
168 EXPECT_EQ(ingress_stats->neteq_stats.removed_samples_for_acceleration, 0ULL);
169 EXPECT_EQ(ingress_stats->neteq_stats.silent_concealed_samples, 0ULL);
170 // To extract the jitter buffer length in millisecond, jitter_buffer_delay_ms
171 // needs to be divided by jitter_buffer_emitted_count (number of samples).
172 EXPECT_EQ(ingress_stats->neteq_stats.jitter_buffer_delay_ms, 1600ULL);
173 EXPECT_EQ(ingress_stats->neteq_stats.jitter_buffer_emitted_count, 160ULL);
174 EXPECT_GT(ingress_stats->neteq_stats.jitter_buffer_target_delay_ms, 0ULL);
175 EXPECT_EQ(ingress_stats->neteq_stats.interruption_count, 0);
176 EXPECT_EQ(ingress_stats->neteq_stats.total_interruption_duration_ms, 0);
177 EXPECT_DOUBLE_EQ(ingress_stats->total_duration, 0.02);
178
179 // Now without any RTP pending in jitter buffer pull more.
180 audio_mixer_->Mix(/*number_of_channels=*/1, &audio_frame);
181 audio_mixer_->Mix(/*number_of_channels=*/1, &audio_frame);
182
183 // Send another RTP packet to intentionally break PLC.
184 audio_sender->SendAudioData(GetAudioFrame(2));
185 audio_sender->SendAudioData(GetAudioFrame(3));
186
187 ingress_stats = audio_channel_->GetIngressStatistics();
188 EXPECT_TRUE(ingress_stats);
189 EXPECT_EQ(ingress_stats->neteq_stats.total_samples_received, 320ULL);
190 EXPECT_EQ(ingress_stats->neteq_stats.concealed_samples, 168ULL);
191 EXPECT_EQ(ingress_stats->neteq_stats.concealment_events, 1ULL);
192 EXPECT_EQ(ingress_stats->neteq_stats.inserted_samples_for_deceleration, 0ULL);
193 EXPECT_EQ(ingress_stats->neteq_stats.removed_samples_for_acceleration, 0ULL);
194 EXPECT_EQ(ingress_stats->neteq_stats.silent_concealed_samples, 0ULL);
195 EXPECT_EQ(ingress_stats->neteq_stats.jitter_buffer_delay_ms, 1600ULL);
196 EXPECT_EQ(ingress_stats->neteq_stats.jitter_buffer_emitted_count, 160ULL);
197 EXPECT_GT(ingress_stats->neteq_stats.jitter_buffer_target_delay_ms, 0ULL);
198 EXPECT_EQ(ingress_stats->neteq_stats.interruption_count, 0);
199 EXPECT_EQ(ingress_stats->neteq_stats.total_interruption_duration_ms, 0);
200 EXPECT_DOUBLE_EQ(ingress_stats->total_duration, 0.04);
201
202 // Pull the last RTP packet.
203 audio_mixer_->Mix(/*number_of_channels=*/1, &audio_frame);
204 audio_mixer_->Mix(/*number_of_channels=*/1, &audio_frame);
205
206 ingress_stats = audio_channel_->GetIngressStatistics();
207 EXPECT_TRUE(ingress_stats);
208 EXPECT_EQ(ingress_stats->neteq_stats.total_samples_received, 480ULL);
209 EXPECT_EQ(ingress_stats->neteq_stats.concealed_samples, 168ULL);
210 EXPECT_EQ(ingress_stats->neteq_stats.concealment_events, 1ULL);
211 EXPECT_EQ(ingress_stats->neteq_stats.inserted_samples_for_deceleration, 0ULL);
212 EXPECT_EQ(ingress_stats->neteq_stats.removed_samples_for_acceleration, 0ULL);
213 EXPECT_EQ(ingress_stats->neteq_stats.silent_concealed_samples, 0ULL);
214 EXPECT_EQ(ingress_stats->neteq_stats.jitter_buffer_delay_ms, 3200ULL);
215 EXPECT_EQ(ingress_stats->neteq_stats.jitter_buffer_emitted_count, 320ULL);
216 EXPECT_GT(ingress_stats->neteq_stats.jitter_buffer_target_delay_ms, 0ULL);
217 EXPECT_EQ(ingress_stats->neteq_stats.interruption_count, 0);
218 EXPECT_EQ(ingress_stats->neteq_stats.total_interruption_duration_ms, 0);
219 EXPECT_DOUBLE_EQ(ingress_stats->total_duration, 0.06);
220 }
221
222 // Check ChannelStatistics metric after processing RTP and RTCP packets.
TEST_F(AudioChannelTest,TestChannelStatistics)223 TEST_F(AudioChannelTest, TestChannelStatistics) {
224 auto loop_rtp = [&](const uint8_t* packet, size_t length, Unused) {
225 audio_channel_->ReceivedRTPPacket(
226 rtc::ArrayView<const uint8_t>(packet, length));
227 return true;
228 };
229 auto loop_rtcp = [&](const uint8_t* packet, size_t length) {
230 audio_channel_->ReceivedRTCPPacket(
231 rtc::ArrayView<const uint8_t>(packet, length));
232 return true;
233 };
234 EXPECT_CALL(transport_, SendRtp).WillRepeatedly(Invoke(loop_rtp));
235 EXPECT_CALL(transport_, SendRtcp).WillRepeatedly(Invoke(loop_rtcp));
236
237 // Simulate microphone giving audio frame (10 ms). This will trigger tranport
238 // to send RTP as handled in loop_rtp above.
239 auto audio_sender = audio_channel_->GetAudioSender();
240 audio_sender->SendAudioData(GetAudioFrame(0));
241 audio_sender->SendAudioData(GetAudioFrame(1));
242
243 // Simulate speaker requesting audio frame (10 ms). This will trigger VoIP
244 // engine to fetch audio samples from RTP packets stored in jitter buffer.
245 AudioFrame audio_frame;
246 audio_mixer_->Mix(/*number_of_channels=*/1, &audio_frame);
247 audio_mixer_->Mix(/*number_of_channels=*/1, &audio_frame);
248
249 // Force sending RTCP SR report in order to have remote_rtcp field available
250 // in channel statistics. This will trigger tranport to send RTCP as handled
251 // in loop_rtcp above.
252 audio_channel_->SendRTCPReportForTesting(kRtcpSr);
253
254 absl::optional<ChannelStatistics> channel_stats =
255 audio_channel_->GetChannelStatistics();
256 EXPECT_TRUE(channel_stats);
257
258 EXPECT_EQ(channel_stats->packets_sent, 1ULL);
259 EXPECT_EQ(channel_stats->bytes_sent, 160ULL);
260
261 EXPECT_EQ(channel_stats->packets_received, 1ULL);
262 EXPECT_EQ(channel_stats->bytes_received, 160ULL);
263 EXPECT_EQ(channel_stats->jitter, 0);
264 EXPECT_EQ(channel_stats->packets_lost, 0);
265 EXPECT_EQ(channel_stats->remote_ssrc.value(), kLocalSsrc);
266
267 EXPECT_TRUE(channel_stats->remote_rtcp.has_value());
268
269 EXPECT_EQ(channel_stats->remote_rtcp->jitter, 0);
270 EXPECT_EQ(channel_stats->remote_rtcp->packets_lost, 0);
271 EXPECT_EQ(channel_stats->remote_rtcp->fraction_lost, 0);
272 EXPECT_GT(channel_stats->remote_rtcp->last_report_received_timestamp_ms, 0);
273 EXPECT_FALSE(channel_stats->remote_rtcp->round_trip_time.has_value());
274 }
275
276 // Check ChannelStatistics RTT metric after processing RTP and RTCP packets
277 // using three audio channels where each represents media endpoint.
278 //
279 // 1) AC1 <- RTP/RTCP -> AC2
280 // 2) AC1 <- RTP/RTCP -> AC3
281 //
282 // During step 1), AC1 should be able to check RTT from AC2's SSRC.
283 // During step 2), AC1 should be able to check RTT from AC3's SSRC.
TEST_F(AudioChannelTest,RttIsAvailableAfterChangeOfRemoteSsrc)284 TEST_F(AudioChannelTest, RttIsAvailableAfterChangeOfRemoteSsrc) {
285 // Create AC2 and AC3.
286 constexpr uint32_t kAc2Ssrc = 0xdeadbeef;
287 constexpr uint32_t kAc3Ssrc = 0xdeafbeef;
288
289 auto ac_2 = CreateAudioChannel(kAc2Ssrc);
290 auto ac_3 = CreateAudioChannel(kAc3Ssrc);
291
292 auto send_recv_rtp = [&](rtc::scoped_refptr<AudioChannel> rtp_sender,
293 rtc::scoped_refptr<AudioChannel> rtp_receiver) {
294 // Setup routing logic via transport_.
295 auto route_rtp = [&](const uint8_t* packet, size_t length, Unused) {
296 rtp_receiver->ReceivedRTPPacket(rtc::MakeArrayView(packet, length));
297 return true;
298 };
299 ON_CALL(transport_, SendRtp).WillByDefault(route_rtp);
300
301 // This will trigger route_rtp callback via transport_.
302 rtp_sender->GetAudioSender()->SendAudioData(GetAudioFrame(0));
303 rtp_sender->GetAudioSender()->SendAudioData(GetAudioFrame(1));
304
305 // Process received RTP in receiver.
306 AudioFrame audio_frame;
307 audio_mixer_->Mix(/*number_of_channels=*/1, &audio_frame);
308 audio_mixer_->Mix(/*number_of_channels=*/1, &audio_frame);
309
310 // Revert to default to avoid using reference in route_rtp lambda.
311 ON_CALL(transport_, SendRtp).WillByDefault(Return(true));
312 };
313
314 auto send_recv_rtcp = [&](rtc::scoped_refptr<AudioChannel> rtcp_sender,
315 rtc::scoped_refptr<AudioChannel> rtcp_receiver) {
316 // Setup routing logic via transport_.
317 auto route_rtcp = [&](const uint8_t* packet, size_t length) {
318 rtcp_receiver->ReceivedRTCPPacket(rtc::MakeArrayView(packet, length));
319 return true;
320 };
321 ON_CALL(transport_, SendRtcp).WillByDefault(route_rtcp);
322
323 // This will trigger route_rtcp callback via transport_.
324 rtcp_sender->SendRTCPReportForTesting(kRtcpSr);
325
326 // Revert to default to avoid using reference in route_rtcp lambda.
327 ON_CALL(transport_, SendRtcp).WillByDefault(Return(true));
328 };
329
330 // AC1 <-- RTP/RTCP --> AC2
331 send_recv_rtp(audio_channel_, ac_2);
332 send_recv_rtp(ac_2, audio_channel_);
333 send_recv_rtcp(audio_channel_, ac_2);
334 send_recv_rtcp(ac_2, audio_channel_);
335
336 absl::optional<ChannelStatistics> channel_stats =
337 audio_channel_->GetChannelStatistics();
338 ASSERT_TRUE(channel_stats);
339 EXPECT_EQ(channel_stats->remote_ssrc, kAc2Ssrc);
340 ASSERT_TRUE(channel_stats->remote_rtcp);
341 EXPECT_GT(channel_stats->remote_rtcp->round_trip_time, 0.0);
342
343 // AC1 <-- RTP/RTCP --> AC3
344 send_recv_rtp(audio_channel_, ac_3);
345 send_recv_rtp(ac_3, audio_channel_);
346 send_recv_rtcp(audio_channel_, ac_3);
347 send_recv_rtcp(ac_3, audio_channel_);
348
349 channel_stats = audio_channel_->GetChannelStatistics();
350 ASSERT_TRUE(channel_stats);
351 EXPECT_EQ(channel_stats->remote_ssrc, kAc3Ssrc);
352 ASSERT_TRUE(channel_stats->remote_rtcp);
353 EXPECT_GT(channel_stats->remote_rtcp->round_trip_time, 0.0);
354 }
355
356 } // namespace
357 } // namespace webrtc
358