blob: 92ad43fab3edee70405ba5521d915dfb59309b8a [file] [log] [blame]
deadbeefe814a0d2017-02-25 18:15:09 -08001/*
2 * Copyright 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 <memory>
12
Karl Wiberg3e9e5b32017-11-06 05:01:56 +010013#include "api/audio_codecs/builtin_audio_decoder_factory.h"
14#include "api/audio_codecs/builtin_audio_encoder_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "media/base/fakemediaengine.h"
16#include "ortc/ortcfactory.h"
17#include "ortc/testrtpparameters.h"
18#include "p2p/base/fakepackettransport.h"
19#include "rtc_base/gunit.h"
deadbeefe814a0d2017-02-25 18:15:09 -080020
21namespace webrtc {
22
23// This test uses fake packet transports and a fake media engine, in order to
24// test the RtpTransport at only an API level. Any end-to-end test should go in
25// ortcfactory_integrationtest.cc instead.
26class RtpTransportTest : public testing::Test {
27 public:
28 RtpTransportTest() {
29 fake_media_engine_ = new cricket::FakeMediaEngine();
30 // Note: This doesn't need to use fake network classes, since it uses
31 // FakePacketTransports.
32 auto result = OrtcFactory::Create(
33 nullptr, nullptr, nullptr, nullptr, nullptr,
Karl Wiberg3e9e5b32017-11-06 05:01:56 +010034 std::unique_ptr<cricket::MediaEngineInterface>(fake_media_engine_),
35 CreateBuiltinAudioEncoderFactory(), CreateBuiltinAudioDecoderFactory());
deadbeefe814a0d2017-02-25 18:15:09 -080036 ortc_factory_ = result.MoveValue();
37 }
38
39 protected:
40 // Owned by |ortc_factory_|.
41 cricket::FakeMediaEngine* fake_media_engine_;
42 std::unique_ptr<OrtcFactoryInterface> ortc_factory_;
43};
44
45// Test GetRtpPacketTransport and GetRtcpPacketTransport, with and without RTCP
46// muxing.
47TEST_F(RtpTransportTest, GetPacketTransports) {
48 rtc::FakePacketTransport rtp("rtp");
49 rtc::FakePacketTransport rtcp("rtcp");
50 // With muxed RTCP.
sprangdb2a9fc2017-08-09 06:42:32 -070051 RtpTransportParameters parameters;
52 parameters.rtcp.mux = true;
53 auto result =
54 ortc_factory_->CreateRtpTransport(parameters, &rtp, nullptr, nullptr);
deadbeefe814a0d2017-02-25 18:15:09 -080055 ASSERT_TRUE(result.ok());
56 EXPECT_EQ(&rtp, result.value()->GetRtpPacketTransport());
57 EXPECT_EQ(nullptr, result.value()->GetRtcpPacketTransport());
58 result.MoveValue().reset();
59 // With non-muxed RTCP.
sprangdb2a9fc2017-08-09 06:42:32 -070060 parameters.rtcp.mux = false;
61 result = ortc_factory_->CreateRtpTransport(parameters, &rtp, &rtcp, nullptr);
deadbeefe814a0d2017-02-25 18:15:09 -080062 ASSERT_TRUE(result.ok());
63 EXPECT_EQ(&rtp, result.value()->GetRtpPacketTransport());
64 EXPECT_EQ(&rtcp, result.value()->GetRtcpPacketTransport());
65}
66
67// If an RtpTransport starts out un-muxed and then starts muxing, the RTCP
68// packet transport should be forgotten and GetRtcpPacketTransport should
69// return null.
70TEST_F(RtpTransportTest, EnablingRtcpMuxingUnsetsRtcpTransport) {
71 rtc::FakePacketTransport rtp("rtp");
72 rtc::FakePacketTransport rtcp("rtcp");
73
74 // Create non-muxed.
sprangdb2a9fc2017-08-09 06:42:32 -070075 RtpTransportParameters parameters;
76 parameters.rtcp.mux = false;
deadbeefe814a0d2017-02-25 18:15:09 -080077 auto result =
sprangdb2a9fc2017-08-09 06:42:32 -070078 ortc_factory_->CreateRtpTransport(parameters, &rtp, &rtcp, nullptr);
deadbeefe814a0d2017-02-25 18:15:09 -080079 ASSERT_TRUE(result.ok());
80 auto rtp_transport = result.MoveValue();
81
82 // Enable muxing.
sprangdb2a9fc2017-08-09 06:42:32 -070083 parameters.rtcp.mux = true;
84 EXPECT_TRUE(rtp_transport->SetParameters(parameters).ok());
deadbeefe814a0d2017-02-25 18:15:09 -080085 EXPECT_EQ(nullptr, rtp_transport->GetRtcpPacketTransport());
86}
87
88TEST_F(RtpTransportTest, GetAndSetRtcpParameters) {
89 rtc::FakePacketTransport rtp("rtp");
90 rtc::FakePacketTransport rtcp("rtcp");
91 // Start with non-muxed RTCP.
sprangdb2a9fc2017-08-09 06:42:32 -070092 RtpTransportParameters parameters;
93 parameters.rtcp.mux = false;
94 parameters.rtcp.cname = "teST";
95 parameters.rtcp.reduced_size = false;
deadbeefe814a0d2017-02-25 18:15:09 -080096 auto result =
sprangdb2a9fc2017-08-09 06:42:32 -070097 ortc_factory_->CreateRtpTransport(parameters, &rtp, &rtcp, nullptr);
deadbeefe814a0d2017-02-25 18:15:09 -080098 ASSERT_TRUE(result.ok());
99 auto transport = result.MoveValue();
sprangdb2a9fc2017-08-09 06:42:32 -0700100 EXPECT_EQ(parameters, transport->GetParameters());
deadbeefe814a0d2017-02-25 18:15:09 -0800101
102 // Changing the CNAME is currently unsupported.
sprangdb2a9fc2017-08-09 06:42:32 -0700103 parameters.rtcp.cname = "different";
deadbeefe814a0d2017-02-25 18:15:09 -0800104 EXPECT_EQ(RTCErrorType::UNSUPPORTED_OPERATION,
sprangdb2a9fc2017-08-09 06:42:32 -0700105 transport->SetParameters(parameters).type());
106 parameters.rtcp.cname = "teST";
deadbeefe814a0d2017-02-25 18:15:09 -0800107
108 // Enable RTCP muxing and reduced-size RTCP.
sprangdb2a9fc2017-08-09 06:42:32 -0700109 parameters.rtcp.mux = true;
110 parameters.rtcp.reduced_size = true;
111 EXPECT_TRUE(transport->SetParameters(parameters).ok());
112 EXPECT_EQ(parameters, transport->GetParameters());
deadbeefe814a0d2017-02-25 18:15:09 -0800113
114 // Empty CNAME should result in the existing CNAME being used.
sprangdb2a9fc2017-08-09 06:42:32 -0700115 parameters.rtcp.cname.clear();
116 EXPECT_TRUE(transport->SetParameters(parameters).ok());
117 EXPECT_EQ("teST", transport->GetParameters().rtcp.cname);
deadbeefe814a0d2017-02-25 18:15:09 -0800118
119 // Disabling RTCP muxing after enabling shouldn't be allowed, since enabling
120 // muxing should have made the RTP transport forget about the RTCP packet
121 // transport initially passed into it.
sprangdb2a9fc2017-08-09 06:42:32 -0700122 parameters.rtcp.mux = false;
deadbeefe814a0d2017-02-25 18:15:09 -0800123 EXPECT_EQ(RTCErrorType::INVALID_STATE,
sprangdb2a9fc2017-08-09 06:42:32 -0700124 transport->SetParameters(parameters).type());
deadbeefe814a0d2017-02-25 18:15:09 -0800125}
126
127// When Send or Receive is called on a sender or receiver, the RTCP parameters
128// from the RtpTransport underneath the sender should be applied to the created
129// media stream. The only relevant parameters (currently) are |cname| and
130// |reduced_size|.
131TEST_F(RtpTransportTest, SendAndReceiveApplyRtcpParametersToMediaEngine) {
132 // First, create video transport with reduced-size RTCP.
133 rtc::FakePacketTransport fake_packet_transport1("1");
sprangdb2a9fc2017-08-09 06:42:32 -0700134 RtpTransportParameters parameters;
135 parameters.rtcp.mux = true;
136 parameters.rtcp.reduced_size = true;
137 parameters.rtcp.cname = "foo";
deadbeefe814a0d2017-02-25 18:15:09 -0800138 auto rtp_transport_result = ortc_factory_->CreateRtpTransport(
sprangdb2a9fc2017-08-09 06:42:32 -0700139 parameters, &fake_packet_transport1, nullptr, nullptr);
deadbeefe814a0d2017-02-25 18:15:09 -0800140 auto video_transport = rtp_transport_result.MoveValue();
141
142 // Create video sender and call Send, expecting parameters to be applied.
143 auto sender_result = ortc_factory_->CreateRtpSender(cricket::MEDIA_TYPE_VIDEO,
144 video_transport.get());
145 auto video_sender = sender_result.MoveValue();
146 EXPECT_TRUE(video_sender->Send(MakeMinimalVp8Parameters()).ok());
147 cricket::FakeVideoMediaChannel* fake_video_channel =
148 fake_media_engine_->GetVideoChannel(0);
149 ASSERT_NE(nullptr, fake_video_channel);
150 EXPECT_TRUE(fake_video_channel->send_rtcp_parameters().reduced_size);
151 ASSERT_EQ(1u, fake_video_channel->send_streams().size());
152 const cricket::StreamParams& video_send_stream =
153 fake_video_channel->send_streams()[0];
154 EXPECT_EQ("foo", video_send_stream.cname);
155
156 // Create video receiver and call Receive, expecting parameters to be applied
157 // (minus |cname|, since that's the sent cname, not received).
158 auto receiver_result = ortc_factory_->CreateRtpReceiver(
159 cricket::MEDIA_TYPE_VIDEO, video_transport.get());
160 auto video_receiver = receiver_result.MoveValue();
161 EXPECT_TRUE(
162 video_receiver->Receive(MakeMinimalVp8ParametersWithSsrc(0xdeadbeef))
163 .ok());
164 EXPECT_TRUE(fake_video_channel->recv_rtcp_parameters().reduced_size);
165
166 // Create audio transport with non-reduced size RTCP.
167 rtc::FakePacketTransport fake_packet_transport2("2");
sprangdb2a9fc2017-08-09 06:42:32 -0700168 parameters.rtcp.reduced_size = false;
169 parameters.rtcp.cname = "bar";
deadbeefe814a0d2017-02-25 18:15:09 -0800170 rtp_transport_result = ortc_factory_->CreateRtpTransport(
sprangdb2a9fc2017-08-09 06:42:32 -0700171 parameters, &fake_packet_transport2, nullptr, nullptr);
deadbeefe814a0d2017-02-25 18:15:09 -0800172 auto audio_transport = rtp_transport_result.MoveValue();
173
174 // Create audio sender and call Send, expecting parameters to be applied.
175 sender_result = ortc_factory_->CreateRtpSender(cricket::MEDIA_TYPE_AUDIO,
176 audio_transport.get());
177 auto audio_sender = sender_result.MoveValue();
178 EXPECT_TRUE(audio_sender->Send(MakeMinimalIsacParameters()).ok());
179
180 cricket::FakeVoiceMediaChannel* fake_voice_channel =
181 fake_media_engine_->GetVoiceChannel(0);
182 ASSERT_NE(nullptr, fake_voice_channel);
183 EXPECT_FALSE(fake_voice_channel->send_rtcp_parameters().reduced_size);
184 ASSERT_EQ(1u, fake_voice_channel->send_streams().size());
185 const cricket::StreamParams& audio_send_stream =
186 fake_voice_channel->send_streams()[0];
187 EXPECT_EQ("bar", audio_send_stream.cname);
188
189 // Create audio receiver and call Receive, expecting parameters to be applied
190 // (minus |cname|, since that's the sent cname, not received).
191 receiver_result = ortc_factory_->CreateRtpReceiver(cricket::MEDIA_TYPE_AUDIO,
192 audio_transport.get());
193 auto audio_receiver = receiver_result.MoveValue();
194 EXPECT_TRUE(
195 audio_receiver->Receive(MakeMinimalOpusParametersWithSsrc(0xbaadf00d))
196 .ok());
197 EXPECT_FALSE(fake_voice_channel->recv_rtcp_parameters().reduced_size);
198}
199
sprangdb2a9fc2017-08-09 06:42:32 -0700200// When SetParameters is called, the modified parameters should be applied
deadbeefe814a0d2017-02-25 18:15:09 -0800201// to the media engine.
202// TODO(deadbeef): Once the implementation supports changing the CNAME,
203// test that here.
204TEST_F(RtpTransportTest, SetRtcpParametersAppliesParametersToMediaEngine) {
205 rtc::FakePacketTransport fake_packet_transport("fake");
sprangdb2a9fc2017-08-09 06:42:32 -0700206 RtpTransportParameters parameters;
207 parameters.rtcp.mux = true;
208 parameters.rtcp.reduced_size = false;
deadbeefe814a0d2017-02-25 18:15:09 -0800209 auto rtp_transport_result = ortc_factory_->CreateRtpTransport(
sprangdb2a9fc2017-08-09 06:42:32 -0700210 parameters, &fake_packet_transport, nullptr, nullptr);
deadbeefe814a0d2017-02-25 18:15:09 -0800211 auto rtp_transport = rtp_transport_result.MoveValue();
212
213 // Create video sender and call Send, applying an initial set of parameters.
214 auto sender_result = ortc_factory_->CreateRtpSender(cricket::MEDIA_TYPE_VIDEO,
215 rtp_transport.get());
216 auto sender = sender_result.MoveValue();
217 EXPECT_TRUE(sender->Send(MakeMinimalVp8Parameters()).ok());
218
219 // Modify parameters and expect them to be changed at the media engine level.
sprangdb2a9fc2017-08-09 06:42:32 -0700220 parameters.rtcp.reduced_size = true;
221 EXPECT_TRUE(rtp_transport->SetParameters(parameters).ok());
deadbeefe814a0d2017-02-25 18:15:09 -0800222
223 cricket::FakeVideoMediaChannel* fake_video_channel =
224 fake_media_engine_->GetVideoChannel(0);
225 ASSERT_NE(nullptr, fake_video_channel);
226 EXPECT_TRUE(fake_video_channel->send_rtcp_parameters().reduced_size);
227}
228
sprangdb2a9fc2017-08-09 06:42:32 -0700229// SetParameters should set keepalive for all RTP transports.
230// It is impossible to modify keepalive parameters if any streams are created.
231// Note: This is an implementation detail for current way of configuring the
232// keep-alive. It may change in the future.
233TEST_F(RtpTransportTest, CantChangeKeepAliveAfterCreatedSendStreams) {
234 rtc::FakePacketTransport fake_packet_transport("fake");
235 RtpTransportParameters parameters;
236 parameters.keepalive.timeout_interval_ms = 100;
237 auto rtp_transport_result = ortc_factory_->CreateRtpTransport(
238 parameters, &fake_packet_transport, nullptr, nullptr);
239 ASSERT_TRUE(rtp_transport_result.ok());
240 std::unique_ptr<RtpTransportInterface> rtp_transport =
241 rtp_transport_result.MoveValue();
242
243 // Updating keepalive parameters is ok, since no rtp sender created.
244 parameters.keepalive.timeout_interval_ms = 200;
245 EXPECT_TRUE(rtp_transport->SetParameters(parameters).ok());
246
247 // Create video sender. Note: |sender_result| scope must extend past the
248 // SetParameters() call below.
249 auto sender_result = ortc_factory_->CreateRtpSender(cricket::MEDIA_TYPE_VIDEO,
250 rtp_transport.get());
251 EXPECT_TRUE(sender_result.ok());
252
253 // Modify parameters second time after video send stream created.
254 parameters.keepalive.timeout_interval_ms = 10;
255 EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION,
256 rtp_transport->SetParameters(parameters).type());
257}
258
259// Note: This is an implementation detail for current way of configuring the
260// keep-alive. It may change in the future.
261TEST_F(RtpTransportTest, KeepAliveMustBeSameAcrossTransportController) {
262 rtc::FakePacketTransport fake_packet_transport("fake");
263 RtpTransportParameters parameters;
264 parameters.keepalive.timeout_interval_ms = 100;
265
266 // Manually create a controller, that can be shared by multiple transports.
267 auto controller_result = ortc_factory_->CreateRtpTransportController();
268 ASSERT_TRUE(controller_result.ok());
269 std::unique_ptr<RtpTransportControllerInterface> controller =
270 controller_result.MoveValue();
271
272 // Create a first transport.
273 auto first_transport_result = ortc_factory_->CreateRtpTransport(
274 parameters, &fake_packet_transport, nullptr, controller.get());
275 ASSERT_TRUE(first_transport_result.ok());
276
277 // Update the parameters, and create another transport for the same
278 // controller.
279 parameters.keepalive.timeout_interval_ms = 10;
280 auto seconds_transport_result = ortc_factory_->CreateRtpTransport(
281 parameters, &fake_packet_transport, nullptr, controller.get());
282 EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION,
283 seconds_transport_result.error().type());
284}
285
deadbeefe814a0d2017-02-25 18:15:09 -0800286} // namespace webrtc