xref: /aosp_15_r20/external/webrtc/audio/voip/test/audio_channel_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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