xref: /aosp_15_r20/external/webrtc/modules/rtp_rtcp/source/rtp_sender_audio_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright (c) 2019 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 "modules/rtp_rtcp/source/rtp_sender_audio.h"
12 
13 #include <memory>
14 #include <vector>
15 
16 #include "api/transport/field_trial_based_config.h"
17 #include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
18 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
19 #include "modules/rtp_rtcp/source/rtp_header_extensions.h"
20 #include "modules/rtp_rtcp/source/rtp_packet_received.h"
21 #include "modules/rtp_rtcp/source/rtp_rtcp_impl2.h"
22 #include "rtc_base/thread.h"
23 #include "test/field_trial.h"
24 #include "test/gmock.h"
25 #include "test/gtest.h"
26 
27 namespace webrtc {
28 
29 namespace {
30 enum : int {  // The first valid value is 1.
31   kAudioLevelExtensionId = 1,
32   kAbsoluteCaptureTimeExtensionId = 2,
33 };
34 
35 const uint16_t kSeqNum = 33;
36 const uint32_t kSsrc = 725242;
37 const uint8_t kAudioLevel = 0x5a;
38 const uint64_t kStartTime = 123456789;
39 
40 using ::testing::ElementsAreArray;
41 
42 class LoopbackTransportTest : public webrtc::Transport {
43  public:
LoopbackTransportTest()44   LoopbackTransportTest() {
45     receivers_extensions_.Register<AudioLevel>(kAudioLevelExtensionId);
46     receivers_extensions_.Register<AbsoluteCaptureTimeExtension>(
47         kAbsoluteCaptureTimeExtensionId);
48   }
49 
SendRtp(const uint8_t * data,size_t len,const PacketOptions &)50   bool SendRtp(const uint8_t* data,
51                size_t len,
52                const PacketOptions& /*options*/) override {
53     sent_packets_.push_back(RtpPacketReceived(&receivers_extensions_));
54     EXPECT_TRUE(sent_packets_.back().Parse(data, len));
55     return true;
56   }
SendRtcp(const uint8_t * data,size_t len)57   bool SendRtcp(const uint8_t* data, size_t len) override { return false; }
last_sent_packet()58   const RtpPacketReceived& last_sent_packet() { return sent_packets_.back(); }
packets_sent()59   int packets_sent() { return sent_packets_.size(); }
60 
61  private:
62   RtpHeaderExtensionMap receivers_extensions_;
63   std::vector<RtpPacketReceived> sent_packets_;
64 };
65 
66 }  // namespace
67 
68 class RtpSenderAudioTest : public ::testing::Test {
69  public:
RtpSenderAudioTest()70   RtpSenderAudioTest()
71       : fake_clock_(kStartTime),
72         rtp_module_(ModuleRtpRtcpImpl2::Create([&] {
73           RtpRtcpInterface::Configuration config;
74           config.audio = true;
75           config.clock = &fake_clock_;
76           config.outgoing_transport = &transport_;
77           config.local_media_ssrc = kSsrc;
78           return config;
79         }())),
80         rtp_sender_audio_(
81             std::make_unique<RTPSenderAudio>(&fake_clock_,
82                                              rtp_module_->RtpSender())) {
83     rtp_module_->SetSequenceNumber(kSeqNum);
84   }
85 
86   rtc::AutoThread main_thread_;
87   SimulatedClock fake_clock_;
88   LoopbackTransportTest transport_;
89   std::unique_ptr<ModuleRtpRtcpImpl2> rtp_module_;
90   std::unique_ptr<RTPSenderAudio> rtp_sender_audio_;
91 };
92 
TEST_F(RtpSenderAudioTest,SendAudio)93 TEST_F(RtpSenderAudioTest, SendAudio) {
94   const char payload_name[] = "PAYLOAD_NAME";
95   const uint8_t payload_type = 127;
96   ASSERT_EQ(0, rtp_sender_audio_->RegisterAudioPayload(
97                    payload_name, payload_type, 48000, 0, 1500));
98   uint8_t payload[] = {47, 11, 32, 93, 89};
99 
100   ASSERT_TRUE(
101       rtp_sender_audio_->SendAudio(AudioFrameType::kAudioFrameCN, payload_type,
102                                    4321, payload, sizeof(payload),
103                                    /*absolute_capture_timestamp_ms=*/0));
104 
105   auto sent_payload = transport_.last_sent_packet().payload();
106   EXPECT_THAT(sent_payload, ElementsAreArray(payload));
107 }
108 
TEST_F(RtpSenderAudioTest,SendAudioWithAudioLevelExtension)109 TEST_F(RtpSenderAudioTest, SendAudioWithAudioLevelExtension) {
110   EXPECT_EQ(0, rtp_sender_audio_->SetAudioLevel(kAudioLevel));
111   rtp_module_->RegisterRtpHeaderExtension(AudioLevel::Uri(),
112                                           kAudioLevelExtensionId);
113 
114   const char payload_name[] = "PAYLOAD_NAME";
115   const uint8_t payload_type = 127;
116   ASSERT_EQ(0, rtp_sender_audio_->RegisterAudioPayload(
117                    payload_name, payload_type, 48000, 0, 1500));
118 
119   uint8_t payload[] = {47, 11, 32, 93, 89};
120 
121   ASSERT_TRUE(
122       rtp_sender_audio_->SendAudio(AudioFrameType::kAudioFrameCN, payload_type,
123                                    4321, payload, sizeof(payload),
124                                    /*absolute_capture_timestamp_ms=*/0));
125 
126   auto sent_payload = transport_.last_sent_packet().payload();
127   EXPECT_THAT(sent_payload, ElementsAreArray(payload));
128   // Verify AudioLevel extension.
129   bool voice_activity;
130   uint8_t audio_level;
131   EXPECT_TRUE(transport_.last_sent_packet().GetExtension<AudioLevel>(
132       &voice_activity, &audio_level));
133   EXPECT_EQ(kAudioLevel, audio_level);
134   EXPECT_FALSE(voice_activity);
135 }
136 
TEST_F(RtpSenderAudioTest,SendAudioWithoutAbsoluteCaptureTime)137 TEST_F(RtpSenderAudioTest, SendAudioWithoutAbsoluteCaptureTime) {
138   constexpr uint32_t kAbsoluteCaptureTimestampMs = 521;
139   const char payload_name[] = "audio";
140   const uint8_t payload_type = 127;
141   ASSERT_EQ(0, rtp_sender_audio_->RegisterAudioPayload(
142                    payload_name, payload_type, 48000, 0, 1500));
143   uint8_t payload[] = {47, 11, 32, 93, 89};
144 
145   ASSERT_TRUE(rtp_sender_audio_->SendAudio(
146       AudioFrameType::kAudioFrameCN, payload_type, 4321, payload,
147       sizeof(payload), kAbsoluteCaptureTimestampMs));
148 
149   EXPECT_FALSE(transport_.last_sent_packet()
150                    .HasExtension<AbsoluteCaptureTimeExtension>());
151 }
152 
153 // Essentially the same test as
154 // SendAudioWithAbsoluteCaptureTimeWithCaptureClockOffset but with a field
155 // trial. We will remove this test eventually.
TEST_F(RtpSenderAudioTest,SendAudioWithAbsoluteCaptureTime)156 TEST_F(RtpSenderAudioTest, SendAudioWithAbsoluteCaptureTime) {
157   // Recreate rtp_sender_audio_ with new field trial.
158   test::ScopedFieldTrials field_trial(
159       "WebRTC-IncludeCaptureClockOffset/Disabled/");
160   rtp_sender_audio_ =
161       std::make_unique<RTPSenderAudio>(&fake_clock_, rtp_module_->RtpSender());
162 
163   rtp_module_->RegisterRtpHeaderExtension(AbsoluteCaptureTimeExtension::Uri(),
164                                           kAbsoluteCaptureTimeExtensionId);
165   constexpr uint32_t kAbsoluteCaptureTimestampMs = 521;
166   const char payload_name[] = "audio";
167   const uint8_t payload_type = 127;
168   ASSERT_EQ(0, rtp_sender_audio_->RegisterAudioPayload(
169                    payload_name, payload_type, 48000, 0, 1500));
170   uint8_t payload[] = {47, 11, 32, 93, 89};
171 
172   ASSERT_TRUE(rtp_sender_audio_->SendAudio(
173       AudioFrameType::kAudioFrameCN, payload_type, 4321, payload,
174       sizeof(payload), kAbsoluteCaptureTimestampMs));
175 
176   auto absolute_capture_time =
177       transport_.last_sent_packet()
178           .GetExtension<AbsoluteCaptureTimeExtension>();
179   EXPECT_TRUE(absolute_capture_time);
180   EXPECT_EQ(
181       absolute_capture_time->absolute_capture_timestamp,
182       Int64MsToUQ32x32(fake_clock_.ConvertTimestampToNtpTimeInMilliseconds(
183           kAbsoluteCaptureTimestampMs)));
184   EXPECT_FALSE(
185       absolute_capture_time->estimated_capture_clock_offset.has_value());
186 }
187 
TEST_F(RtpSenderAudioTest,SendAudioWithAbsoluteCaptureTimeWithCaptureClockOffset)188 TEST_F(RtpSenderAudioTest,
189        SendAudioWithAbsoluteCaptureTimeWithCaptureClockOffset) {
190   rtp_module_->RegisterRtpHeaderExtension(AbsoluteCaptureTimeExtension::Uri(),
191                                           kAbsoluteCaptureTimeExtensionId);
192   constexpr uint32_t kAbsoluteCaptureTimestampMs = 521;
193   const char payload_name[] = "audio";
194   const uint8_t payload_type = 127;
195   ASSERT_EQ(0, rtp_sender_audio_->RegisterAudioPayload(
196                    payload_name, payload_type, 48000, 0, 1500));
197   uint8_t payload[] = {47, 11, 32, 93, 89};
198 
199   ASSERT_TRUE(rtp_sender_audio_->SendAudio(
200       AudioFrameType::kAudioFrameCN, payload_type, 4321, payload,
201       sizeof(payload), kAbsoluteCaptureTimestampMs));
202 
203   auto absolute_capture_time =
204       transport_.last_sent_packet()
205           .GetExtension<AbsoluteCaptureTimeExtension>();
206   EXPECT_TRUE(absolute_capture_time);
207   EXPECT_EQ(
208       absolute_capture_time->absolute_capture_timestamp,
209       Int64MsToUQ32x32(fake_clock_.ConvertTimestampToNtpTimeInMilliseconds(
210           kAbsoluteCaptureTimestampMs)));
211   EXPECT_TRUE(
212       absolute_capture_time->estimated_capture_clock_offset.has_value());
213   EXPECT_EQ(0, *absolute_capture_time->estimated_capture_clock_offset);
214 }
215 
216 // As RFC4733, named telephone events are carried as part of the audio stream
217 // and must use the same sequence number and timestamp base as the regular
218 // audio channel.
219 // This test checks the marker bit for the first packet and the consequent
220 // packets of the same telephone event. Since it is specifically for DTMF
221 // events, ignoring audio packets and sending kEmptyFrame instead of those.
TEST_F(RtpSenderAudioTest,CheckMarkerBitForTelephoneEvents)222 TEST_F(RtpSenderAudioTest, CheckMarkerBitForTelephoneEvents) {
223   const char* kDtmfPayloadName = "telephone-event";
224   const uint32_t kPayloadFrequency = 8000;
225   const uint8_t kPayloadType = 126;
226   ASSERT_EQ(0, rtp_sender_audio_->RegisterAudioPayload(
227                    kDtmfPayloadName, kPayloadType, kPayloadFrequency, 0, 0));
228   // For Telephone events, payload is not added to the registered payload list,
229   // it will register only the payload used for audio stream.
230   // Registering the payload again for audio stream with different payload name.
231   const char* kPayloadName = "payload_name";
232   ASSERT_EQ(0, rtp_sender_audio_->RegisterAudioPayload(
233                    kPayloadName, kPayloadType, kPayloadFrequency, 1, 0));
234   // Start time is arbitrary.
235   uint32_t capture_timestamp = fake_clock_.TimeInMilliseconds();
236   // DTMF event key=9, duration=500 and attenuationdB=10
237   rtp_sender_audio_->SendTelephoneEvent(9, 500, 10);
238   // During start, it takes the starting timestamp as last sent timestamp.
239   // The duration is calculated as the difference of current and last sent
240   // timestamp. So for first call it will skip since the duration is zero.
241   ASSERT_TRUE(rtp_sender_audio_->SendAudio(
242       AudioFrameType::kEmptyFrame, kPayloadType, capture_timestamp, nullptr, 0,
243       /*absolute_capture_time_ms=0*/ 0));
244 
245   // DTMF Sample Length is (Frequency/1000) * Duration.
246   // So in this case, it is (8000/1000) * 500 = 4000.
247   // Sending it as two packets.
248   ASSERT_TRUE(rtp_sender_audio_->SendAudio(AudioFrameType::kEmptyFrame,
249                                            kPayloadType,
250                                            capture_timestamp + 2000, nullptr, 0,
251                                            /*absolute_capture_time_ms=0*/ 0));
252 
253   // Marker Bit should be set to 1 for first packet.
254   EXPECT_TRUE(transport_.last_sent_packet().Marker());
255 
256   ASSERT_TRUE(rtp_sender_audio_->SendAudio(AudioFrameType::kEmptyFrame,
257                                            kPayloadType,
258                                            capture_timestamp + 4000, nullptr, 0,
259                                            /*absolute_capture_time_ms=0*/ 0));
260   // Marker Bit should be set to 0 for rest of the packets.
261   EXPECT_FALSE(transport_.last_sent_packet().Marker());
262 }
263 
264 }  // namespace webrtc
265