1 /*
2 * Copyright 2022 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 // Integration tests for PeerConnection.
12 // These tests exercise a full stack for the SVC extension.
13
14 #include <stdint.h>
15
16 #include <vector>
17
18 #include "api/rtc_error.h"
19 #include "api/rtp_parameters.h"
20 #include "api/rtp_transceiver_interface.h"
21 #include "api/scoped_refptr.h"
22 #include "pc/test/integration_test_helpers.h"
23 #include "rtc_base/gunit.h"
24 #include "rtc_base/helpers.h"
25 #include "test/gtest.h"
26
27 namespace webrtc {
28
29 namespace {
30
31 class PeerConnectionSVCIntegrationTest
32 : public PeerConnectionIntegrationBaseTest {
33 protected:
PeerConnectionSVCIntegrationTest()34 PeerConnectionSVCIntegrationTest()
35 : PeerConnectionIntegrationBaseTest(SdpSemantics::kUnifiedPlan) {}
36
SetCodecPreferences(rtc::scoped_refptr<webrtc::RtpTransceiverInterface> transceiver,absl::string_view codec_name)37 RTCError SetCodecPreferences(
38 rtc::scoped_refptr<webrtc::RtpTransceiverInterface> transceiver,
39 absl::string_view codec_name) {
40 webrtc::RtpCapabilities capabilities =
41 caller()->pc_factory()->GetRtpSenderCapabilities(
42 cricket::MEDIA_TYPE_VIDEO);
43 std::vector<RtpCodecCapability> codecs;
44 for (const webrtc::RtpCodecCapability& codec_capability :
45 capabilities.codecs) {
46 if (codec_capability.name == codec_name)
47 codecs.push_back(codec_capability);
48 }
49 return transceiver->SetCodecPreferences(codecs);
50 }
51 };
52
TEST_F(PeerConnectionSVCIntegrationTest,AddTransceiverAcceptsL1T1)53 TEST_F(PeerConnectionSVCIntegrationTest, AddTransceiverAcceptsL1T1) {
54 ASSERT_TRUE(CreatePeerConnectionWrappers());
55 ConnectFakeSignaling();
56 webrtc::RtpTransceiverInit init;
57 webrtc::RtpEncodingParameters encoding_parameters;
58 encoding_parameters.scalability_mode = "L1T1";
59 init.send_encodings.push_back(encoding_parameters);
60 auto transceiver_or_error =
61 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack(), init);
62 EXPECT_TRUE(transceiver_or_error.ok());
63 }
64
TEST_F(PeerConnectionSVCIntegrationTest,AddTransceiverAcceptsL3T3)65 TEST_F(PeerConnectionSVCIntegrationTest, AddTransceiverAcceptsL3T3) {
66 ASSERT_TRUE(CreatePeerConnectionWrappers());
67 ConnectFakeSignaling();
68 webrtc::RtpTransceiverInit init;
69 webrtc::RtpEncodingParameters encoding_parameters;
70 encoding_parameters.scalability_mode = "L3T3";
71 init.send_encodings.push_back(encoding_parameters);
72 auto transceiver_or_error =
73 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack(), init);
74 EXPECT_TRUE(transceiver_or_error.ok());
75 }
76
TEST_F(PeerConnectionSVCIntegrationTest,AddTransceiverRejectsUnknownScalabilityMode)77 TEST_F(PeerConnectionSVCIntegrationTest,
78 AddTransceiverRejectsUnknownScalabilityMode) {
79 ASSERT_TRUE(CreatePeerConnectionWrappers());
80 ConnectFakeSignaling();
81 webrtc::RtpTransceiverInit init;
82 webrtc::RtpEncodingParameters encoding_parameters;
83 encoding_parameters.scalability_mode = "FOOBAR";
84 init.send_encodings.push_back(encoding_parameters);
85 auto transceiver_or_error =
86 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack(), init);
87 EXPECT_FALSE(transceiver_or_error.ok());
88 EXPECT_EQ(transceiver_or_error.error().type(),
89 webrtc::RTCErrorType::UNSUPPORTED_OPERATION);
90 }
91
TEST_F(PeerConnectionSVCIntegrationTest,SetParametersAcceptsL1T3WithVP8)92 TEST_F(PeerConnectionSVCIntegrationTest, SetParametersAcceptsL1T3WithVP8) {
93 ASSERT_TRUE(CreatePeerConnectionWrappers());
94 ConnectFakeSignaling();
95
96 webrtc::RtpCapabilities capabilities =
97 caller()->pc_factory()->GetRtpSenderCapabilities(
98 cricket::MEDIA_TYPE_VIDEO);
99 std::vector<RtpCodecCapability> vp8_codec;
100 for (const webrtc::RtpCodecCapability& codec_capability :
101 capabilities.codecs) {
102 if (codec_capability.name == cricket::kVp8CodecName)
103 vp8_codec.push_back(codec_capability);
104 }
105
106 webrtc::RtpTransceiverInit init;
107 webrtc::RtpEncodingParameters encoding_parameters;
108 init.send_encodings.push_back(encoding_parameters);
109 auto transceiver_or_error =
110 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack(), init);
111 ASSERT_TRUE(transceiver_or_error.ok());
112 auto transceiver = transceiver_or_error.MoveValue();
113 EXPECT_TRUE(transceiver->SetCodecPreferences(vp8_codec).ok());
114
115 webrtc::RtpParameters parameters = transceiver->sender()->GetParameters();
116 ASSERT_EQ(parameters.encodings.size(), 1u);
117 parameters.encodings[0].scalability_mode = "L1T3";
118 auto result = transceiver->sender()->SetParameters(parameters);
119 EXPECT_TRUE(result.ok());
120 }
121
TEST_F(PeerConnectionSVCIntegrationTest,SetParametersRejectsL3T3WithVP8)122 TEST_F(PeerConnectionSVCIntegrationTest, SetParametersRejectsL3T3WithVP8) {
123 ASSERT_TRUE(CreatePeerConnectionWrappers());
124 ConnectFakeSignaling();
125
126 webrtc::RtpTransceiverInit init;
127 webrtc::RtpEncodingParameters encoding_parameters;
128 init.send_encodings.push_back(encoding_parameters);
129 auto transceiver_or_error =
130 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack(), init);
131 ASSERT_TRUE(transceiver_or_error.ok());
132 auto transceiver = transceiver_or_error.MoveValue();
133 EXPECT_TRUE(SetCodecPreferences(transceiver, cricket::kVp8CodecName).ok());
134
135 webrtc::RtpParameters parameters = transceiver->sender()->GetParameters();
136 ASSERT_EQ(parameters.encodings.size(), 1u);
137 parameters.encodings[0].scalability_mode = "L3T3";
138 auto result = transceiver->sender()->SetParameters(parameters);
139 EXPECT_FALSE(result.ok());
140 EXPECT_EQ(result.type(), webrtc::RTCErrorType::UNSUPPORTED_OPERATION);
141 }
142
TEST_F(PeerConnectionSVCIntegrationTest,SetParametersAcceptsL1T3WithVP8AfterNegotiation)143 TEST_F(PeerConnectionSVCIntegrationTest,
144 SetParametersAcceptsL1T3WithVP8AfterNegotiation) {
145 ASSERT_TRUE(CreatePeerConnectionWrappers());
146 ConnectFakeSignaling();
147
148 webrtc::RtpTransceiverInit init;
149 webrtc::RtpEncodingParameters encoding_parameters;
150 init.send_encodings.push_back(encoding_parameters);
151 auto transceiver_or_error =
152 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack(), init);
153 ASSERT_TRUE(transceiver_or_error.ok());
154 auto transceiver = transceiver_or_error.MoveValue();
155 EXPECT_TRUE(SetCodecPreferences(transceiver, cricket::kVp8CodecName).ok());
156
157 caller()->CreateAndSetAndSignalOffer();
158 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
159
160 webrtc::RtpParameters parameters = transceiver->sender()->GetParameters();
161 ASSERT_EQ(parameters.encodings.size(), 1u);
162 parameters.encodings[0].scalability_mode = "L1T3";
163 auto result = transceiver->sender()->SetParameters(parameters);
164 EXPECT_TRUE(result.ok());
165 }
166
TEST_F(PeerConnectionSVCIntegrationTest,SetParametersAcceptsL3T3WithVP9AfterNegotiation)167 TEST_F(PeerConnectionSVCIntegrationTest,
168 SetParametersAcceptsL3T3WithVP9AfterNegotiation) {
169 ASSERT_TRUE(CreatePeerConnectionWrappers());
170 ConnectFakeSignaling();
171
172 webrtc::RtpTransceiverInit init;
173 webrtc::RtpEncodingParameters encoding_parameters;
174 init.send_encodings.push_back(encoding_parameters);
175 auto transceiver_or_error =
176 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack(), init);
177 ASSERT_TRUE(transceiver_or_error.ok());
178 auto transceiver = transceiver_or_error.MoveValue();
179 EXPECT_TRUE(SetCodecPreferences(transceiver, cricket::kVp9CodecName).ok());
180
181 caller()->CreateAndSetAndSignalOffer();
182 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
183
184 webrtc::RtpParameters parameters = transceiver->sender()->GetParameters();
185 ASSERT_EQ(parameters.encodings.size(), 1u);
186 parameters.encodings[0].scalability_mode = "L3T3";
187 auto result = transceiver->sender()->SetParameters(parameters);
188 EXPECT_TRUE(result.ok());
189 }
190
TEST_F(PeerConnectionSVCIntegrationTest,SetParametersRejectsL3T3WithVP8AfterNegotiation)191 TEST_F(PeerConnectionSVCIntegrationTest,
192 SetParametersRejectsL3T3WithVP8AfterNegotiation) {
193 ASSERT_TRUE(CreatePeerConnectionWrappers());
194 ConnectFakeSignaling();
195
196 webrtc::RtpTransceiverInit init;
197 webrtc::RtpEncodingParameters encoding_parameters;
198 init.send_encodings.push_back(encoding_parameters);
199 auto transceiver_or_error =
200 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack(), init);
201 ASSERT_TRUE(transceiver_or_error.ok());
202 auto transceiver = transceiver_or_error.MoveValue();
203 EXPECT_TRUE(SetCodecPreferences(transceiver, cricket::kVp8CodecName).ok());
204
205 caller()->CreateAndSetAndSignalOffer();
206 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
207
208 webrtc::RtpParameters parameters = transceiver->sender()->GetParameters();
209 ASSERT_EQ(parameters.encodings.size(), 1u);
210 parameters.encodings[0].scalability_mode = "L3T3";
211 auto result = transceiver->sender()->SetParameters(parameters);
212 EXPECT_FALSE(result.ok());
213 EXPECT_EQ(result.type(), webrtc::RTCErrorType::UNSUPPORTED_OPERATION);
214 }
215
TEST_F(PeerConnectionSVCIntegrationTest,SetParametersRejectsInvalidModeWithVP9AfterNegotiation)216 TEST_F(PeerConnectionSVCIntegrationTest,
217 SetParametersRejectsInvalidModeWithVP9AfterNegotiation) {
218 ASSERT_TRUE(CreatePeerConnectionWrappers());
219 ConnectFakeSignaling();
220
221 webrtc::RtpTransceiverInit init;
222 webrtc::RtpEncodingParameters encoding_parameters;
223 init.send_encodings.push_back(encoding_parameters);
224 auto transceiver_or_error =
225 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack(), init);
226 ASSERT_TRUE(transceiver_or_error.ok());
227 auto transceiver = transceiver_or_error.MoveValue();
228 EXPECT_TRUE(SetCodecPreferences(transceiver, cricket::kVp9CodecName).ok());
229
230 caller()->CreateAndSetAndSignalOffer();
231 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
232
233 webrtc::RtpParameters parameters = transceiver->sender()->GetParameters();
234 ASSERT_EQ(parameters.encodings.size(), 1u);
235 parameters.encodings[0].scalability_mode = "FOOBAR";
236 auto result = transceiver->sender()->SetParameters(parameters);
237 EXPECT_FALSE(result.ok());
238 EXPECT_EQ(result.type(), webrtc::RTCErrorType::UNSUPPORTED_OPERATION);
239 }
240
241 } // namespace
242
243 } // namespace webrtc
244