1 /*
2 * Copyright (c) 2017 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 <string>
12 #include <utility>
13 #include <vector>
14
15 #include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
16 #include "modules/rtp_rtcp/source/rtp_header_extensions.h"
17 #include "modules/rtp_rtcp/source/rtp_packet.h"
18 #include "test/call_test.h"
19 #include "test/field_trial.h"
20 #include "test/gtest.h"
21 #include "test/rtcp_packet_parser.h"
22
23 namespace webrtc {
24 namespace test {
25 namespace {
26
27 enum : int { // The first valid value is 1.
28 kAudioLevelExtensionId = 1,
29 kTransportSequenceNumberExtensionId,
30 };
31
32 class AudioSendTest : public SendTest {
33 public:
AudioSendTest()34 AudioSendTest() : SendTest(CallTest::kDefaultTimeout) {}
35
GetNumVideoStreams() const36 size_t GetNumVideoStreams() const override { return 0; }
GetNumAudioStreams() const37 size_t GetNumAudioStreams() const override { return 1; }
GetNumFlexfecStreams() const38 size_t GetNumFlexfecStreams() const override { return 0; }
39 };
40 } // namespace
41
42 using AudioSendStreamCallTest = CallTest;
43
TEST_F(AudioSendStreamCallTest,SupportsCName)44 TEST_F(AudioSendStreamCallTest, SupportsCName) {
45 static std::string kCName = "PjqatC14dGfbVwGPUOA9IH7RlsFDbWl4AhXEiDsBizo=";
46 class CNameObserver : public AudioSendTest {
47 public:
48 CNameObserver() = default;
49
50 private:
51 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
52 RtcpPacketParser parser;
53 EXPECT_TRUE(parser.Parse(packet, length));
54 if (parser.sdes()->num_packets() > 0) {
55 EXPECT_EQ(1u, parser.sdes()->chunks().size());
56 EXPECT_EQ(kCName, parser.sdes()->chunks()[0].cname);
57
58 observation_complete_.Set();
59 }
60
61 return SEND_PACKET;
62 }
63
64 void ModifyAudioConfigs(AudioSendStream::Config* send_config,
65 std::vector<AudioReceiveStreamInterface::Config>*
66 receive_configs) override {
67 send_config->rtp.c_name = kCName;
68 }
69
70 void PerformTest() override {
71 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP with CNAME.";
72 }
73 } test;
74
75 RunBaseTest(&test);
76 }
77
TEST_F(AudioSendStreamCallTest,NoExtensionsByDefault)78 TEST_F(AudioSendStreamCallTest, NoExtensionsByDefault) {
79 class NoExtensionsObserver : public AudioSendTest {
80 public:
81 NoExtensionsObserver() = default;
82
83 private:
84 Action OnSendRtp(const uint8_t* packet, size_t length) override {
85 RtpPacket rtp_packet;
86 EXPECT_TRUE(rtp_packet.Parse(packet, length)); // rtp packet is valid.
87 EXPECT_EQ(packet[0] & 0b0001'0000, 0); // extension bit not set.
88
89 observation_complete_.Set();
90 return SEND_PACKET;
91 }
92
93 void ModifyAudioConfigs(AudioSendStream::Config* send_config,
94 std::vector<AudioReceiveStreamInterface::Config>*
95 receive_configs) override {
96 send_config->rtp.extensions.clear();
97 }
98
99 void PerformTest() override {
100 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
101 }
102 } test;
103
104 RunBaseTest(&test);
105 }
106
TEST_F(AudioSendStreamCallTest,SupportsAudioLevel)107 TEST_F(AudioSendStreamCallTest, SupportsAudioLevel) {
108 class AudioLevelObserver : public AudioSendTest {
109 public:
110 AudioLevelObserver() : AudioSendTest() {
111 extensions_.Register<AudioLevel>(kAudioLevelExtensionId);
112 }
113
114 Action OnSendRtp(const uint8_t* packet, size_t length) override {
115 RtpPacket rtp_packet(&extensions_);
116 EXPECT_TRUE(rtp_packet.Parse(packet, length));
117
118 uint8_t audio_level = 0;
119 bool voice = false;
120 EXPECT_TRUE(rtp_packet.GetExtension<AudioLevel>(&voice, &audio_level));
121 if (audio_level != 0) {
122 // Wait for at least one packet with a non-zero level.
123 observation_complete_.Set();
124 } else {
125 RTC_LOG(LS_WARNING) << "Got a packet with zero audioLevel - waiting"
126 " for another packet...";
127 }
128
129 return SEND_PACKET;
130 }
131
132 void ModifyAudioConfigs(AudioSendStream::Config* send_config,
133 std::vector<AudioReceiveStreamInterface::Config>*
134 receive_configs) override {
135 send_config->rtp.extensions.clear();
136 send_config->rtp.extensions.push_back(
137 RtpExtension(RtpExtension::kAudioLevelUri, kAudioLevelExtensionId));
138 }
139
140 void PerformTest() override {
141 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
142 }
143
144 private:
145 RtpHeaderExtensionMap extensions_;
146 } test;
147
148 RunBaseTest(&test);
149 }
150
151 class TransportWideSequenceNumberObserver : public AudioSendTest {
152 public:
TransportWideSequenceNumberObserver(bool expect_sequence_number)153 explicit TransportWideSequenceNumberObserver(bool expect_sequence_number)
154 : AudioSendTest(), expect_sequence_number_(expect_sequence_number) {
155 extensions_.Register<TransportSequenceNumber>(
156 kTransportSequenceNumberExtensionId);
157 }
158
159 private:
OnSendRtp(const uint8_t * packet,size_t length)160 Action OnSendRtp(const uint8_t* packet, size_t length) override {
161 RtpPacket rtp_packet(&extensions_);
162 EXPECT_TRUE(rtp_packet.Parse(packet, length));
163
164 EXPECT_EQ(rtp_packet.HasExtension<TransportSequenceNumber>(),
165 expect_sequence_number_);
166 EXPECT_FALSE(rtp_packet.HasExtension<TransmissionOffset>());
167 EXPECT_FALSE(rtp_packet.HasExtension<AbsoluteSendTime>());
168
169 observation_complete_.Set();
170
171 return SEND_PACKET;
172 }
173
ModifyAudioConfigs(AudioSendStream::Config * send_config,std::vector<AudioReceiveStreamInterface::Config> * receive_configs)174 void ModifyAudioConfigs(AudioSendStream::Config* send_config,
175 std::vector<AudioReceiveStreamInterface::Config>*
176 receive_configs) override {
177 send_config->rtp.extensions.clear();
178 send_config->rtp.extensions.push_back(
179 RtpExtension(RtpExtension::kTransportSequenceNumberUri,
180 kTransportSequenceNumberExtensionId));
181 }
182
PerformTest()183 void PerformTest() override {
184 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
185 }
186 const bool expect_sequence_number_;
187 RtpHeaderExtensionMap extensions_;
188 };
189
TEST_F(AudioSendStreamCallTest,SendsTransportWideSequenceNumbersInFieldTrial)190 TEST_F(AudioSendStreamCallTest, SendsTransportWideSequenceNumbersInFieldTrial) {
191 TransportWideSequenceNumberObserver test(/*expect_sequence_number=*/true);
192 RunBaseTest(&test);
193 }
194
TEST_F(AudioSendStreamCallTest,SendDtmf)195 TEST_F(AudioSendStreamCallTest, SendDtmf) {
196 static const uint8_t kDtmfPayloadType = 120;
197 static const int kDtmfPayloadFrequency = 8000;
198 static const int kDtmfEventFirst = 12;
199 static const int kDtmfEventLast = 31;
200 static const int kDtmfDuration = 50;
201 class DtmfObserver : public AudioSendTest {
202 public:
203 DtmfObserver() = default;
204
205 private:
206 Action OnSendRtp(const uint8_t* packet, size_t length) override {
207 RtpPacket rtp_packet;
208 EXPECT_TRUE(rtp_packet.Parse(packet, length));
209
210 if (rtp_packet.PayloadType() == kDtmfPayloadType) {
211 EXPECT_EQ(rtp_packet.headers_size(), 12u);
212 EXPECT_EQ(rtp_packet.size(), 16u);
213 const int event = rtp_packet.payload()[0];
214 if (event != expected_dtmf_event_) {
215 ++expected_dtmf_event_;
216 EXPECT_EQ(event, expected_dtmf_event_);
217 if (expected_dtmf_event_ == kDtmfEventLast) {
218 observation_complete_.Set();
219 }
220 }
221 }
222
223 return SEND_PACKET;
224 }
225
226 void OnAudioStreamsCreated(AudioSendStream* send_stream,
227 const std::vector<AudioReceiveStreamInterface*>&
228 receive_streams) override {
229 // Need to start stream here, else DTMF events are dropped.
230 send_stream->Start();
231 for (int event = kDtmfEventFirst; event <= kDtmfEventLast; ++event) {
232 send_stream->SendTelephoneEvent(kDtmfPayloadType, kDtmfPayloadFrequency,
233 event, kDtmfDuration);
234 }
235 }
236
237 void PerformTest() override {
238 EXPECT_TRUE(Wait()) << "Timed out while waiting for DTMF stream.";
239 }
240
241 int expected_dtmf_event_ = kDtmfEventFirst;
242 } test;
243
244 RunBaseTest(&test);
245 }
246
247 } // namespace test
248 } // namespace webrtc
249