blob: 2ec7229bfbc8fa5be8a64fed2be9b841c473f2f5 [file] [log] [blame]
solenberg18f54272017-09-15 09:56:08 -07001/*
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
Elad Alond8d32482019-02-18 23:45:57 +010011#include <string>
12#include <utility>
13#include <vector>
14
Danil Chapovalov1b4e4bf2019-12-06 12:34:57 +010015#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"
solenberg18f54272017-09-15 09:56:08 -070018#include "test/call_test.h"
Per Kjellander914351d2019-02-15 10:54:55 +010019#include "test/field_trial.h"
solenberg18f54272017-09-15 09:56:08 -070020#include "test/gtest.h"
21#include "test/rtcp_packet_parser.h"
22
23namespace webrtc {
24namespace test {
25namespace {
26
Elad Alond8d32482019-02-18 23:45:57 +010027enum : int { // The first valid value is 1.
28 kAudioLevelExtensionId = 1,
29 kTransportSequenceNumberExtensionId,
30};
31
solenberg18f54272017-09-15 09:56:08 -070032class AudioSendTest : public SendTest {
33 public:
Markus Handellf4f22872022-08-16 11:02:45 +000034 AudioSendTest() : SendTest(CallTest::kDefaultTimeout) {}
solenberg18f54272017-09-15 09:56:08 -070035
Yves Gerey665174f2018-06-19 15:03:05 +020036 size_t GetNumVideoStreams() const override { return 0; }
37 size_t GetNumAudioStreams() const override { return 1; }
38 size_t GetNumFlexfecStreams() const override { return 0; }
solenberg18f54272017-09-15 09:56:08 -070039};
40} // namespace
41
42using AudioSendStreamCallTest = CallTest;
43
44TEST_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
Tommi3176ef72022-05-22 20:47:28 +020064 void ModifyAudioConfigs(AudioSendStream::Config* send_config,
65 std::vector<AudioReceiveStreamInterface::Config>*
66 receive_configs) override {
solenberg18f54272017-09-15 09:56:08 -070067 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
78TEST_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 {
Danil Chapovalov1b4e4bf2019-12-06 12:34:57 +010085 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.
solenberg18f54272017-09-15 09:56:08 -070088
solenberg18f54272017-09-15 09:56:08 -070089 observation_complete_.Set();
solenberg18f54272017-09-15 09:56:08 -070090 return SEND_PACKET;
91 }
92
Tommi3176ef72022-05-22 20:47:28 +020093 void ModifyAudioConfigs(AudioSendStream::Config* send_config,
94 std::vector<AudioReceiveStreamInterface::Config>*
95 receive_configs) override {
solenberg18f54272017-09-15 09:56:08 -070096 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
107TEST_F(AudioSendStreamCallTest, SupportsAudioLevel) {
108 class AudioLevelObserver : public AudioSendTest {
109 public:
110 AudioLevelObserver() : AudioSendTest() {
Danil Chapovalov1b4e4bf2019-12-06 12:34:57 +0100111 extensions_.Register<AudioLevel>(kAudioLevelExtensionId);
solenberg18f54272017-09-15 09:56:08 -0700112 }
113
114 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Danil Chapovalov1b4e4bf2019-12-06 12:34:57 +0100115 RtpPacket rtp_packet(&extensions_);
116 EXPECT_TRUE(rtp_packet.Parse(packet, length));
solenberg18f54272017-09-15 09:56:08 -0700117
Danil Chapovalov1b4e4bf2019-12-06 12:34:57 +0100118 uint8_t audio_level = 0;
119 bool voice = false;
120 EXPECT_TRUE(rtp_packet.GetExtension<AudioLevel>(&voice, &audio_level));
121 if (audio_level != 0) {
solenberg18f54272017-09-15 09:56:08 -0700122 // Wait for at least one packet with a non-zero level.
123 observation_complete_.Set();
124 } else {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100125 RTC_LOG(LS_WARNING) << "Got a packet with zero audioLevel - waiting"
126 " for another packet...";
solenberg18f54272017-09-15 09:56:08 -0700127 }
128
129 return SEND_PACKET;
130 }
131
Tommi3176ef72022-05-22 20:47:28 +0200132 void ModifyAudioConfigs(AudioSendStream::Config* send_config,
133 std::vector<AudioReceiveStreamInterface::Config>*
134 receive_configs) override {
solenberg18f54272017-09-15 09:56:08 -0700135 send_config->rtp.extensions.clear();
Elad Alond8d32482019-02-18 23:45:57 +0100136 send_config->rtp.extensions.push_back(
137 RtpExtension(RtpExtension::kAudioLevelUri, kAudioLevelExtensionId));
solenberg18f54272017-09-15 09:56:08 -0700138 }
139
140 void PerformTest() override {
141 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
142 }
Danil Chapovalov1b4e4bf2019-12-06 12:34:57 +0100143
144 private:
145 RtpHeaderExtensionMap extensions_;
solenberg18f54272017-09-15 09:56:08 -0700146 } test;
147
148 RunBaseTest(&test);
149}
150
Per Kjellander914351d2019-02-15 10:54:55 +0100151class TransportWideSequenceNumberObserver : public AudioSendTest {
152 public:
153 explicit TransportWideSequenceNumberObserver(bool expect_sequence_number)
154 : AudioSendTest(), expect_sequence_number_(expect_sequence_number) {
Danil Chapovalov1b4e4bf2019-12-06 12:34:57 +0100155 extensions_.Register<TransportSequenceNumber>(
156 kTransportSequenceNumberExtensionId);
Per Kjellander914351d2019-02-15 10:54:55 +0100157 }
solenberg18f54272017-09-15 09:56:08 -0700158
Per Kjellander914351d2019-02-15 10:54:55 +0100159 private:
160 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Danil Chapovalov1b4e4bf2019-12-06 12:34:57 +0100161 RtpPacket rtp_packet(&extensions_);
162 EXPECT_TRUE(rtp_packet.Parse(packet, length));
solenberg18f54272017-09-15 09:56:08 -0700163
Danil Chapovalov1b4e4bf2019-12-06 12:34:57 +0100164 EXPECT_EQ(rtp_packet.HasExtension<TransportSequenceNumber>(),
Per Kjellander914351d2019-02-15 10:54:55 +0100165 expect_sequence_number_);
Danil Chapovalov1b4e4bf2019-12-06 12:34:57 +0100166 EXPECT_FALSE(rtp_packet.HasExtension<TransmissionOffset>());
167 EXPECT_FALSE(rtp_packet.HasExtension<AbsoluteSendTime>());
solenberg18f54272017-09-15 09:56:08 -0700168
Per Kjellander914351d2019-02-15 10:54:55 +0100169 observation_complete_.Set();
solenberg18f54272017-09-15 09:56:08 -0700170
Per Kjellander914351d2019-02-15 10:54:55 +0100171 return SEND_PACKET;
172 }
solenberg18f54272017-09-15 09:56:08 -0700173
Tommi3176ef72022-05-22 20:47:28 +0200174 void ModifyAudioConfigs(AudioSendStream::Config* send_config,
175 std::vector<AudioReceiveStreamInterface::Config>*
176 receive_configs) override {
Per Kjellander914351d2019-02-15 10:54:55 +0100177 send_config->rtp.extensions.clear();
178 send_config->rtp.extensions.push_back(
179 RtpExtension(RtpExtension::kTransportSequenceNumberUri,
180 kTransportSequenceNumberExtensionId));
181 }
solenberg18f54272017-09-15 09:56:08 -0700182
Per Kjellander914351d2019-02-15 10:54:55 +0100183 void PerformTest() override {
184 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
185 }
186 const bool expect_sequence_number_;
Danil Chapovalov1b4e4bf2019-12-06 12:34:57 +0100187 RtpHeaderExtensionMap extensions_;
Per Kjellander914351d2019-02-15 10:54:55 +0100188};
solenberg18f54272017-09-15 09:56:08 -0700189
Per Kjellander914351d2019-02-15 10:54:55 +0100190TEST_F(AudioSendStreamCallTest, SendsTransportWideSequenceNumbersInFieldTrial) {
Per Kjellander914351d2019-02-15 10:54:55 +0100191 TransportWideSequenceNumberObserver test(/*expect_sequence_number=*/true);
192 RunBaseTest(&test);
193}
194
solenberg18f54272017-09-15 09:56:08 -0700195TEST_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 {
Danil Chapovalov1b4e4bf2019-12-06 12:34:57 +0100207 RtpPacket rtp_packet;
208 EXPECT_TRUE(rtp_packet.Parse(packet, length));
solenberg18f54272017-09-15 09:56:08 -0700209
Danil Chapovalov1b4e4bf2019-12-06 12:34:57 +0100210 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];
solenberg18f54272017-09-15 09:56:08 -0700214 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
Tommi3176ef72022-05-22 20:47:28 +0200226 void OnAudioStreamsCreated(AudioSendStream* send_stream,
227 const std::vector<AudioReceiveStreamInterface*>&
228 receive_streams) override {
solenberg18f54272017-09-15 09:56:08 -0700229 // 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