• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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