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