• 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::kDefaultTimeoutMs) {}
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(
65         AudioSendStream::Config* send_config,
66         std::vector<AudioReceiveStream::Config>* 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(
94         AudioSendStream::Config* send_config,
95         std::vector<AudioReceiveStream::Config>* 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(
133         AudioSendStream::Config* send_config,
134         std::vector<AudioReceiveStream::Config>* 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<AudioReceiveStream::Config> * receive_configs)174   void ModifyAudioConfigs(
175       AudioSendStream::Config* send_config,
176       std::vector<AudioReceiveStream::Config>* 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   ScopedFieldTrials field_trials("WebRTC-Audio-SendSideBwe/Enabled/");
192   TransportWideSequenceNumberObserver test(/*expect_sequence_number=*/true);
193   RunBaseTest(&test);
194 }
195 
TEST_F(AudioSendStreamCallTest,DoesNotSendTransportWideSequenceNumbersPerDefault)196 TEST_F(AudioSendStreamCallTest,
197        DoesNotSendTransportWideSequenceNumbersPerDefault) {
198   TransportWideSequenceNumberObserver test(/*expect_sequence_number=*/false);
199   RunBaseTest(&test);
200 }
201 
TEST_F(AudioSendStreamCallTest,SendDtmf)202 TEST_F(AudioSendStreamCallTest, SendDtmf) {
203   static const uint8_t kDtmfPayloadType = 120;
204   static const int kDtmfPayloadFrequency = 8000;
205   static const int kDtmfEventFirst = 12;
206   static const int kDtmfEventLast = 31;
207   static const int kDtmfDuration = 50;
208   class DtmfObserver : public AudioSendTest {
209    public:
210     DtmfObserver() = default;
211 
212    private:
213     Action OnSendRtp(const uint8_t* packet, size_t length) override {
214       RtpPacket rtp_packet;
215       EXPECT_TRUE(rtp_packet.Parse(packet, length));
216 
217       if (rtp_packet.PayloadType() == kDtmfPayloadType) {
218         EXPECT_EQ(rtp_packet.headers_size(), 12u);
219         EXPECT_EQ(rtp_packet.size(), 16u);
220         const int event = rtp_packet.payload()[0];
221         if (event != expected_dtmf_event_) {
222           ++expected_dtmf_event_;
223           EXPECT_EQ(event, expected_dtmf_event_);
224           if (expected_dtmf_event_ == kDtmfEventLast) {
225             observation_complete_.Set();
226           }
227         }
228       }
229 
230       return SEND_PACKET;
231     }
232 
233     void OnAudioStreamsCreated(
234         AudioSendStream* send_stream,
235         const std::vector<AudioReceiveStream*>& receive_streams) override {
236       // Need to start stream here, else DTMF events are dropped.
237       send_stream->Start();
238       for (int event = kDtmfEventFirst; event <= kDtmfEventLast; ++event) {
239         send_stream->SendTelephoneEvent(kDtmfPayloadType, kDtmfPayloadFrequency,
240                                         event, kDtmfDuration);
241       }
242     }
243 
244     void PerformTest() override {
245       EXPECT_TRUE(Wait()) << "Timed out while waiting for DTMF stream.";
246     }
247 
248     int expected_dtmf_event_ = kDtmfEventFirst;
249   } test;
250 
251   RunBaseTest(&test);
252 }
253 
254 }  // namespace test
255 }  // namespace webrtc
256