blob: 37c787fdd4c49944a21f98c8b010161bc6340992 [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#include <utility> // For std::pair, std::move.
13
14#include "webrtc/api/ortc/ortcfactoryinterface.h"
15#include "webrtc/base/criticalsection.h"
16#include "webrtc/base/fakenetwork.h"
17#include "webrtc/base/gunit.h"
18#include "webrtc/base/physicalsocketserver.h"
19#include "webrtc/base/virtualsocketserver.h"
20#include "webrtc/ortc/testrtpparameters.h"
21#include "webrtc/p2p/base/udptransport.h"
22#include "webrtc/pc/test/fakeaudiocapturemodule.h"
23#include "webrtc/pc/test/fakeperiodicvideocapturer.h"
24#include "webrtc/pc/test/fakevideotrackrenderer.h"
25
26namespace {
27
zhihuangd3501ad2017-03-03 14:39:06 -080028const int kDefaultTimeout = 10000; // 10 seconds.
29const int kReceivingDuration = 1000; // 1 second.
deadbeefe814a0d2017-02-25 18:15:09 -080030// Default number of audio/video frames to wait for before considering a test a
31// success.
32const int kDefaultNumFrames = 3;
33const rtc::IPAddress kIPv4LocalHostAddress =
34 rtc::IPAddress(0x7F000001); // 127.0.0.1
35
zhihuangd3501ad2017-03-03 14:39:06 -080036static const char kTestKeyParams1[] =
37 "inline:WVNfX19zZW1jdGwgKskgewkyMjA7fQp9CnVubGVz";
38static const char kTestKeyParams2[] =
39 "inline:PS1uQCVeeCFCanVmcjkpaywjNWhcYD0mXXtxaVBR";
40static const char kTestKeyParams3[] =
41 "inline:WVNfX19zZW1jdGwgKskgewkyMjA7fQp9CnVubGVa";
42static const char kTestKeyParams4[] =
43 "inline:WVNfX19zZW1jdGwgKskgewkyMjA7fQp9CnVubGVb";
44static const cricket::CryptoParams kTestCryptoParams1(1,
45 "AES_CM_128_HMAC_SHA1_80",
46 kTestKeyParams1,
47 "");
48static const cricket::CryptoParams kTestCryptoParams2(1,
49 "AES_CM_128_HMAC_SHA1_80",
50 kTestKeyParams2,
51 "");
52static const cricket::CryptoParams kTestCryptoParams3(1,
53 "AES_CM_128_HMAC_SHA1_80",
54 kTestKeyParams3,
55 "");
56static const cricket::CryptoParams kTestCryptoParams4(1,
57 "AES_CM_128_HMAC_SHA1_80",
58 kTestKeyParams4,
59 "");
deadbeefe814a0d2017-02-25 18:15:09 -080060} // namespace
61
62namespace webrtc {
63
64// Used to test that things work end-to-end when using the default
65// implementations of threads/etc. provided by OrtcFactory, with the exception
66// of using a virtual network.
67//
68// By default, the virtual network manager doesn't enumerate any networks, but
69// sockets can still be created in this state.
70class OrtcFactoryIntegrationTest : public testing::Test {
71 public:
72 OrtcFactoryIntegrationTest()
73 : virtual_socket_server_(&physical_socket_server_),
74 network_thread_(&virtual_socket_server_),
75 fake_audio_capture_module1_(FakeAudioCaptureModule::Create()),
76 fake_audio_capture_module2_(FakeAudioCaptureModule::Create()) {
77 // Sockets are bound to the ANY address, so this is needed to tell the
78 // virtual network which address to use in this case.
79 virtual_socket_server_.SetDefaultRoute(kIPv4LocalHostAddress);
80 network_thread_.Start();
81 // Need to create after network thread is started.
82 ortc_factory1_ = OrtcFactoryInterface::Create(
83 &network_thread_, nullptr, &fake_network_manager_,
84 nullptr, fake_audio_capture_module1_)
85 .MoveValue();
86 ortc_factory2_ = OrtcFactoryInterface::Create(
87 &network_thread_, nullptr, &fake_network_manager_,
88 nullptr, fake_audio_capture_module2_)
89 .MoveValue();
90 }
91
92 protected:
93 typedef std::pair<std::unique_ptr<UdpTransportInterface>,
94 std::unique_ptr<UdpTransportInterface>>
95 UdpTransportPair;
96 typedef std::pair<std::unique_ptr<RtpTransportInterface>,
97 std::unique_ptr<RtpTransportInterface>>
98 RtpTransportPair;
zhihuangd3501ad2017-03-03 14:39:06 -080099 typedef std::pair<std::unique_ptr<SrtpTransportInterface>,
100 std::unique_ptr<SrtpTransportInterface>>
101 SrtpTransportPair;
deadbeefe814a0d2017-02-25 18:15:09 -0800102 typedef std::pair<std::unique_ptr<RtpTransportControllerInterface>,
103 std::unique_ptr<RtpTransportControllerInterface>>
104 RtpTransportControllerPair;
105
106 // Helper function that creates one UDP transport each for |ortc_factory1_|
107 // and |ortc_factory2_|, and connects them.
108 UdpTransportPair CreateAndConnectUdpTransportPair() {
109 auto transport1 = ortc_factory1_->CreateUdpTransport(AF_INET).MoveValue();
110 auto transport2 = ortc_factory2_->CreateUdpTransport(AF_INET).MoveValue();
111 transport1->SetRemoteAddress(
112 rtc::SocketAddress(virtual_socket_server_.GetDefaultRoute(AF_INET),
113 transport2->GetLocalAddress().port()));
114 transport2->SetRemoteAddress(
115 rtc::SocketAddress(virtual_socket_server_.GetDefaultRoute(AF_INET),
116 transport1->GetLocalAddress().port()));
117 return {std::move(transport1), std::move(transport2)};
118 }
119
120 // Creates one transport controller each for |ortc_factory1_| and
121 // |ortc_factory2_|.
122 RtpTransportControllerPair CreateRtpTransportControllerPair() {
123 return {ortc_factory1_->CreateRtpTransportController().MoveValue(),
124 ortc_factory2_->CreateRtpTransportController().MoveValue()};
125 }
126
127 // Helper function that creates a pair of RtpTransports between
128 // |ortc_factory1_| and |ortc_factory2_|. Expected to be called with the
129 // result of CreateAndConnectUdpTransportPair. |rtcp_udp_transports| can be
130 // empty if RTCP muxing is used. |transport_controllers| can be empty if
131 // these transports are being created using a default transport controller.
132 RtpTransportPair CreateRtpTransportPair(
133 const RtcpParameters& rtcp_parameters,
134 const UdpTransportPair& rtp_udp_transports,
135 const UdpTransportPair& rtcp_udp_transports,
136 const RtpTransportControllerPair& transport_controllers) {
137 auto transport_result1 = ortc_factory1_->CreateRtpTransport(
138 rtcp_parameters, rtp_udp_transports.first.get(),
139 rtcp_udp_transports.first.get(), transport_controllers.first.get());
140 auto transport_result2 = ortc_factory2_->CreateRtpTransport(
141 rtcp_parameters, rtp_udp_transports.second.get(),
142 rtcp_udp_transports.second.get(), transport_controllers.second.get());
143 return {transport_result1.MoveValue(), transport_result2.MoveValue()};
144 }
145
zhihuangd3501ad2017-03-03 14:39:06 -0800146 SrtpTransportPair CreateSrtpTransportPair(
147 const RtcpParameters& rtcp_parameters,
148 const UdpTransportPair& rtp_udp_transports,
149 const UdpTransportPair& rtcp_udp_transports,
150 const RtpTransportControllerPair& transport_controllers) {
151 auto transport_result1 = ortc_factory1_->CreateSrtpTransport(
152 rtcp_parameters, rtp_udp_transports.first.get(),
153 rtcp_udp_transports.first.get(), transport_controllers.first.get());
154 auto transport_result2 = ortc_factory2_->CreateSrtpTransport(
155 rtcp_parameters, rtp_udp_transports.second.get(),
156 rtcp_udp_transports.second.get(), transport_controllers.second.get());
157 return {transport_result1.MoveValue(), transport_result2.MoveValue()};
158 }
159
deadbeefe814a0d2017-02-25 18:15:09 -0800160 // For convenience when |rtcp_udp_transports| and |transport_controllers|
161 // aren't needed.
162 RtpTransportPair CreateRtpTransportPair(
163 const RtcpParameters& rtcp_parameters,
164 const UdpTransportPair& rtp_udp_transports) {
165 return CreateRtpTransportPair(rtcp_parameters, rtp_udp_transports,
166 UdpTransportPair(),
167 RtpTransportControllerPair());
168 }
169
zhihuangd3501ad2017-03-03 14:39:06 -0800170 SrtpTransportPair CreateSrtpTransportPairAndSetKeys(
171 const RtcpParameters& rtcp_parameters,
172 const UdpTransportPair& rtp_udp_transports) {
173 SrtpTransportPair srtp_transports = CreateSrtpTransportPair(
174 rtcp_parameters, rtp_udp_transports, UdpTransportPair(),
175 RtpTransportControllerPair());
176 EXPECT_TRUE(srtp_transports.first->SetSrtpSendKey(kTestCryptoParams1).ok());
177 EXPECT_TRUE(
178 srtp_transports.first->SetSrtpReceiveKey(kTestCryptoParams2).ok());
179 EXPECT_TRUE(
180 srtp_transports.second->SetSrtpSendKey(kTestCryptoParams2).ok());
181 EXPECT_TRUE(
182 srtp_transports.second->SetSrtpReceiveKey(kTestCryptoParams1).ok());
183 return srtp_transports;
184 }
185
186 SrtpTransportPair CreateSrtpTransportPairAndSetMismatchingKeys(
187 const RtcpParameters& rtcp_parameters,
188 const UdpTransportPair& rtp_udp_transports) {
189 SrtpTransportPair srtp_transports = CreateSrtpTransportPair(
190 rtcp_parameters, rtp_udp_transports, UdpTransportPair(),
191 RtpTransportControllerPair());
192 EXPECT_TRUE(srtp_transports.first->SetSrtpSendKey(kTestCryptoParams1).ok());
193 EXPECT_TRUE(
194 srtp_transports.first->SetSrtpReceiveKey(kTestCryptoParams2).ok());
195 EXPECT_TRUE(
196 srtp_transports.second->SetSrtpSendKey(kTestCryptoParams1).ok());
197 EXPECT_TRUE(
198 srtp_transports.second->SetSrtpReceiveKey(kTestCryptoParams2).ok());
199 return srtp_transports;
200 }
201
deadbeefe814a0d2017-02-25 18:15:09 -0800202 // Ends up using fake audio capture module, which was passed into OrtcFactory
203 // on creation.
204 rtc::scoped_refptr<webrtc::AudioTrackInterface> CreateLocalAudioTrack(
205 const std::string& id,
206 OrtcFactoryInterface* ortc_factory) {
207 // Disable echo cancellation to make test more efficient.
208 cricket::AudioOptions options;
209 options.echo_cancellation.emplace(true);
210 rtc::scoped_refptr<webrtc::AudioSourceInterface> source =
211 ortc_factory->CreateAudioSource(options);
212 return ortc_factory->CreateAudioTrack(id, source);
213 }
214
215 // Stores created capturer in |fake_video_capturers_|.
216 rtc::scoped_refptr<webrtc::VideoTrackInterface>
217 CreateLocalVideoTrackAndFakeCapturer(const std::string& id,
218 OrtcFactoryInterface* ortc_factory) {
219 cricket::FakeVideoCapturer* fake_capturer =
220 new webrtc::FakePeriodicVideoCapturer();
221 fake_video_capturers_.push_back(fake_capturer);
222 rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> source =
223 ortc_factory->CreateVideoSource(
224 std::unique_ptr<cricket::VideoCapturer>(fake_capturer));
225 return rtc::scoped_refptr<webrtc::VideoTrackInterface>(
226 ortc_factory->CreateVideoTrack(id, source));
227 }
228
zhihuangd3501ad2017-03-03 14:39:06 -0800229 // Helper function used to test two way RTP senders and receivers with basic
230 // configurations.
231 // If |expect_success| is true, waits for kDefaultTimeout for
232 // kDefaultNumFrames frames to be received by all RtpReceivers.
233 // If |expect_success| is false, simply waits for |kReceivingDuration|, and
234 // stores the number of received frames in |received_audio_frame1_| etc.
235 void BasicTwoWayRtpSendersAndReceiversTest(RtpTransportPair srtp_transports,
236 bool expect_success) {
237 received_audio_frames1_ = 0;
238 received_audio_frames2_ = 0;
239 rendered_video_frames1_ = 0;
240 rendered_video_frames2_ = 0;
241 // Create all the senders and receivers (four per endpoint).
242 auto audio_sender_result1 = ortc_factory1_->CreateRtpSender(
243 cricket::MEDIA_TYPE_AUDIO, srtp_transports.first.get());
244 auto video_sender_result1 = ortc_factory1_->CreateRtpSender(
245 cricket::MEDIA_TYPE_VIDEO, srtp_transports.first.get());
246 auto audio_receiver_result1 = ortc_factory1_->CreateRtpReceiver(
247 cricket::MEDIA_TYPE_AUDIO, srtp_transports.first.get());
248 auto video_receiver_result1 = ortc_factory1_->CreateRtpReceiver(
249 cricket::MEDIA_TYPE_VIDEO, srtp_transports.first.get());
250 ASSERT_TRUE(audio_sender_result1.ok());
251 ASSERT_TRUE(video_sender_result1.ok());
252 ASSERT_TRUE(audio_receiver_result1.ok());
253 ASSERT_TRUE(video_receiver_result1.ok());
254 auto audio_sender1 = audio_sender_result1.MoveValue();
255 auto video_sender1 = video_sender_result1.MoveValue();
256 auto audio_receiver1 = audio_receiver_result1.MoveValue();
257 auto video_receiver1 = video_receiver_result1.MoveValue();
258
259 auto audio_sender_result2 = ortc_factory2_->CreateRtpSender(
260 cricket::MEDIA_TYPE_AUDIO, srtp_transports.second.get());
261 auto video_sender_result2 = ortc_factory2_->CreateRtpSender(
262 cricket::MEDIA_TYPE_VIDEO, srtp_transports.second.get());
263 auto audio_receiver_result2 = ortc_factory2_->CreateRtpReceiver(
264 cricket::MEDIA_TYPE_AUDIO, srtp_transports.second.get());
265 auto video_receiver_result2 = ortc_factory2_->CreateRtpReceiver(
266 cricket::MEDIA_TYPE_VIDEO, srtp_transports.second.get());
267 ASSERT_TRUE(audio_sender_result2.ok());
268 ASSERT_TRUE(video_sender_result2.ok());
269 ASSERT_TRUE(audio_receiver_result2.ok());
270 ASSERT_TRUE(video_receiver_result2.ok());
271 auto audio_sender2 = audio_sender_result2.MoveValue();
272 auto video_sender2 = video_sender_result2.MoveValue();
273 auto audio_receiver2 = audio_receiver_result2.MoveValue();
274 auto video_receiver2 = video_receiver_result2.MoveValue();
275
276 // Add fake tracks.
277 RTCError error = audio_sender1->SetTrack(
278 CreateLocalAudioTrack("audio", ortc_factory1_.get()));
279 EXPECT_TRUE(error.ok());
280 error = video_sender1->SetTrack(
281 CreateLocalVideoTrackAndFakeCapturer("video", ortc_factory1_.get()));
282 EXPECT_TRUE(error.ok());
283 error = audio_sender2->SetTrack(
284 CreateLocalAudioTrack("audio", ortc_factory2_.get()));
285 EXPECT_TRUE(error.ok());
286 error = video_sender2->SetTrack(
287 CreateLocalVideoTrackAndFakeCapturer("video", ortc_factory2_.get()));
288 EXPECT_TRUE(error.ok());
289
290 // "sent_X_parameters1" are the parameters that endpoint 1 sends with and
291 // endpoint 2 receives with.
292 RtpParameters sent_opus_parameters1 =
293 MakeMinimalOpusParametersWithSsrc(0xdeadbeef);
294 RtpParameters sent_vp8_parameters1 =
295 MakeMinimalVp8ParametersWithSsrc(0xbaadfeed);
296 RtpParameters sent_opus_parameters2 =
297 MakeMinimalOpusParametersWithSsrc(0x13333337);
298 RtpParameters sent_vp8_parameters2 =
299 MakeMinimalVp8ParametersWithSsrc(0x12345678);
300
301 // Configure the senders' and receivers' parameters.
302 EXPECT_TRUE(audio_receiver1->Receive(sent_opus_parameters2).ok());
303 EXPECT_TRUE(video_receiver1->Receive(sent_vp8_parameters2).ok());
304 EXPECT_TRUE(audio_receiver2->Receive(sent_opus_parameters1).ok());
305 EXPECT_TRUE(video_receiver2->Receive(sent_vp8_parameters1).ok());
306 EXPECT_TRUE(audio_sender1->Send(sent_opus_parameters1).ok());
307 EXPECT_TRUE(video_sender1->Send(sent_vp8_parameters1).ok());
308 EXPECT_TRUE(audio_sender2->Send(sent_opus_parameters2).ok());
309 EXPECT_TRUE(video_sender2->Send(sent_vp8_parameters2).ok());
310
311 FakeVideoTrackRenderer fake_video_renderer1(
312 static_cast<VideoTrackInterface*>(video_receiver1->GetTrack().get()));
313 FakeVideoTrackRenderer fake_video_renderer2(
314 static_cast<VideoTrackInterface*>(video_receiver2->GetTrack().get()));
315
316 if (expect_success) {
317 EXPECT_TRUE_WAIT(
318 fake_audio_capture_module1_->frames_received() > kDefaultNumFrames &&
319 fake_video_renderer1.num_rendered_frames() > kDefaultNumFrames &&
320 fake_audio_capture_module2_->frames_received() >
321 kDefaultNumFrames &&
322 fake_video_renderer1.num_rendered_frames() > kDefaultNumFrames,
323 kDefaultTimeout);
324 } else {
325 WAIT(false, kReceivingDuration);
326 rendered_video_frames1_ = fake_video_renderer1.num_rendered_frames();
327 rendered_video_frames2_ = fake_video_renderer2.num_rendered_frames();
328 received_audio_frames1_ = fake_audio_capture_module1_->frames_received();
329 received_audio_frames2_ = fake_audio_capture_module2_->frames_received();
330 }
331 }
332
deadbeefe814a0d2017-02-25 18:15:09 -0800333 rtc::PhysicalSocketServer physical_socket_server_;
334 rtc::VirtualSocketServer virtual_socket_server_;
335 rtc::Thread network_thread_;
336 rtc::FakeNetworkManager fake_network_manager_;
337 rtc::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module1_;
338 rtc::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module2_;
339 std::unique_ptr<OrtcFactoryInterface> ortc_factory1_;
340 std::unique_ptr<OrtcFactoryInterface> ortc_factory2_;
341 // Actually owned by video tracks.
342 std::vector<cricket::FakeVideoCapturer*> fake_video_capturers_;
zhihuangd3501ad2017-03-03 14:39:06 -0800343 int received_audio_frames1_ = 0;
344 int received_audio_frames2_ = 0;
345 int rendered_video_frames1_ = 0;
346 int rendered_video_frames2_ = 0;
deadbeefe814a0d2017-02-25 18:15:09 -0800347};
348
zhihuangacfb0172017-03-28 13:45:18 -0700349// Disable for TSan v2, see
350// https://bugs.chromium.org/p/webrtc/issues/detail?id=7366 for details.
351#if !defined(THREAD_SANITIZER)
352
deadbeefe814a0d2017-02-25 18:15:09 -0800353// Very basic end-to-end test with a single pair of audio RTP sender and
354// receiver.
355//
356// Uses muxed RTCP, and minimal parameters with a hard-coded config that's
357// known to work.
358TEST_F(OrtcFactoryIntegrationTest, BasicOneWayAudioRtpSenderAndReceiver) {
359 auto udp_transports = CreateAndConnectUdpTransportPair();
360 auto rtp_transports =
361 CreateRtpTransportPair(MakeRtcpMuxParameters(), udp_transports);
362
363 auto sender_result = ortc_factory1_->CreateRtpSender(
364 cricket::MEDIA_TYPE_AUDIO, rtp_transports.first.get());
365 auto receiver_result = ortc_factory2_->CreateRtpReceiver(
366 cricket::MEDIA_TYPE_AUDIO, rtp_transports.second.get());
367 ASSERT_TRUE(sender_result.ok());
368 ASSERT_TRUE(receiver_result.ok());
369 auto sender = sender_result.MoveValue();
370 auto receiver = receiver_result.MoveValue();
371
372 RTCError error =
373 sender->SetTrack(CreateLocalAudioTrack("audio", ortc_factory1_.get()));
374 EXPECT_TRUE(error.ok());
375
376 RtpParameters opus_parameters = MakeMinimalOpusParameters();
377 EXPECT_TRUE(receiver->Receive(opus_parameters).ok());
378 EXPECT_TRUE(sender->Send(opus_parameters).ok());
379 // Sender and receiver are connected and configured; audio frames should be
380 // able to flow at this point.
381 EXPECT_TRUE_WAIT(
382 fake_audio_capture_module2_->frames_received() > kDefaultNumFrames,
383 kDefaultTimeout);
384}
385
386// Very basic end-to-end test with a single pair of video RTP sender and
387// receiver.
388//
389// Uses muxed RTCP, and minimal parameters with a hard-coded config that's
390// known to work.
391TEST_F(OrtcFactoryIntegrationTest, BasicOneWayVideoRtpSenderAndReceiver) {
392 auto udp_transports = CreateAndConnectUdpTransportPair();
393 auto rtp_transports =
394 CreateRtpTransportPair(MakeRtcpMuxParameters(), udp_transports);
395
396 auto sender_result = ortc_factory1_->CreateRtpSender(
397 cricket::MEDIA_TYPE_VIDEO, rtp_transports.first.get());
398 auto receiver_result = ortc_factory2_->CreateRtpReceiver(
399 cricket::MEDIA_TYPE_VIDEO, rtp_transports.second.get());
400 ASSERT_TRUE(sender_result.ok());
401 ASSERT_TRUE(receiver_result.ok());
402 auto sender = sender_result.MoveValue();
403 auto receiver = receiver_result.MoveValue();
404
405 RTCError error = sender->SetTrack(
406 CreateLocalVideoTrackAndFakeCapturer("video", ortc_factory1_.get()));
407 EXPECT_TRUE(error.ok());
408
409 RtpParameters vp8_parameters = MakeMinimalVp8Parameters();
410 EXPECT_TRUE(receiver->Receive(vp8_parameters).ok());
411 EXPECT_TRUE(sender->Send(vp8_parameters).ok());
412 FakeVideoTrackRenderer fake_renderer(
413 static_cast<VideoTrackInterface*>(receiver->GetTrack().get()));
414 // Sender and receiver are connected and configured; video frames should be
415 // able to flow at this point.
416 EXPECT_TRUE_WAIT(fake_renderer.num_rendered_frames() > kDefaultNumFrames,
417 kDefaultTimeout);
418}
419
420// Test that if the track is changed while sending, the sender seamlessly
421// transitions to sending it and frames are received end-to-end.
422//
423// Only doing this for video, since given that audio is sourced from a single
424// fake audio capture module, the audio track is just a dummy object.
425// TODO(deadbeef): Change this when possible.
426TEST_F(OrtcFactoryIntegrationTest, SetTrackWhileSending) {
427 auto udp_transports = CreateAndConnectUdpTransportPair();
428 auto rtp_transports =
429 CreateRtpTransportPair(MakeRtcpMuxParameters(), udp_transports);
430
431 auto sender_result = ortc_factory1_->CreateRtpSender(
432 cricket::MEDIA_TYPE_VIDEO, rtp_transports.first.get());
433 auto receiver_result = ortc_factory2_->CreateRtpReceiver(
434 cricket::MEDIA_TYPE_VIDEO, rtp_transports.second.get());
435 ASSERT_TRUE(sender_result.ok());
436 ASSERT_TRUE(receiver_result.ok());
437 auto sender = sender_result.MoveValue();
438 auto receiver = receiver_result.MoveValue();
439
440 RTCError error = sender->SetTrack(
441 CreateLocalVideoTrackAndFakeCapturer("video_1", ortc_factory1_.get()));
442 EXPECT_TRUE(error.ok());
443 RtpParameters vp8_parameters = MakeMinimalVp8Parameters();
444 EXPECT_TRUE(receiver->Receive(vp8_parameters).ok());
445 EXPECT_TRUE(sender->Send(vp8_parameters).ok());
446 FakeVideoTrackRenderer fake_renderer(
447 static_cast<VideoTrackInterface*>(receiver->GetTrack().get()));
448 // Expect for some initial number of frames to be received.
449 EXPECT_TRUE_WAIT(fake_renderer.num_rendered_frames() > kDefaultNumFrames,
450 kDefaultTimeout);
451 // Stop the old capturer, set a new track, and verify new frames are received
452 // from the new track. Stopping the old capturer ensures that we aren't
453 // actually still getting frames from it.
454 fake_video_capturers_[0]->Stop();
455 int prev_num_frames = fake_renderer.num_rendered_frames();
456 error = sender->SetTrack(
457 CreateLocalVideoTrackAndFakeCapturer("video_2", ortc_factory1_.get()));
458 EXPECT_TRUE(error.ok());
459 EXPECT_TRUE_WAIT(
460 fake_renderer.num_rendered_frames() > kDefaultNumFrames + prev_num_frames,
461 kDefaultTimeout);
462}
463
464// End-to-end test with two pairs of RTP senders and receivers, for audio and
465// video.
466//
467// Uses muxed RTCP, and minimal parameters with hard-coded configs that are
468// known to work.
469TEST_F(OrtcFactoryIntegrationTest,
470 BasicTwoWayAudioVideoRtpSendersAndReceivers) {
471 auto udp_transports = CreateAndConnectUdpTransportPair();
472 auto rtp_transports =
473 CreateRtpTransportPair(MakeRtcpMuxParameters(), udp_transports);
zhihuangd3501ad2017-03-03 14:39:06 -0800474 bool expect_success = true;
475 BasicTwoWayRtpSendersAndReceiversTest(std::move(rtp_transports),
476 expect_success);
477}
deadbeefe814a0d2017-02-25 18:15:09 -0800478
zhihuangd3501ad2017-03-03 14:39:06 -0800479TEST_F(OrtcFactoryIntegrationTest,
480 BasicTwoWayAudioVideoSrtpSendersAndReceivers) {
481 auto udp_transports = CreateAndConnectUdpTransportPair();
482 auto srtp_transports = CreateSrtpTransportPairAndSetKeys(
483 MakeRtcpMuxParameters(), udp_transports);
484 bool expect_success = true;
485 BasicTwoWayRtpSendersAndReceiversTest(std::move(srtp_transports),
486 expect_success);
487}
deadbeefe814a0d2017-02-25 18:15:09 -0800488
zhihuangd3501ad2017-03-03 14:39:06 -0800489// Tests that the packets cannot be decoded if the keys are mismatched.
490TEST_F(OrtcFactoryIntegrationTest, SrtpSendersAndReceiversWithMismatchingKeys) {
491 auto udp_transports = CreateAndConnectUdpTransportPair();
492 auto srtp_transports = CreateSrtpTransportPairAndSetMismatchingKeys(
493 MakeRtcpMuxParameters(), udp_transports);
494 bool expect_success = false;
495 BasicTwoWayRtpSendersAndReceiversTest(std::move(srtp_transports),
496 expect_success);
497 // No frames are expected to be decoded.
498 EXPECT_TRUE(received_audio_frames1_ == 0 && received_audio_frames2_ == 0 &&
499 rendered_video_frames1_ == 0 && rendered_video_frames2_ == 0);
500}
deadbeefe814a0d2017-02-25 18:15:09 -0800501
zhihuangd3501ad2017-03-03 14:39:06 -0800502// Tests that the frames cannot be decoded if only one side uses SRTP.
503TEST_F(OrtcFactoryIntegrationTest, OneSideSrtpSenderAndReceiver) {
504 auto rtcp_parameters = MakeRtcpMuxParameters();
505 auto udp_transports = CreateAndConnectUdpTransportPair();
506 auto rtcp_udp_transports = UdpTransportPair();
507 auto transport_controllers = RtpTransportControllerPair();
508 auto transport_result1 = ortc_factory1_->CreateRtpTransport(
509 rtcp_parameters, udp_transports.first.get(),
510 rtcp_udp_transports.first.get(), transport_controllers.first.get());
511 auto transport_result2 = ortc_factory2_->CreateSrtpTransport(
512 rtcp_parameters, udp_transports.second.get(),
513 rtcp_udp_transports.second.get(), transport_controllers.second.get());
deadbeefe814a0d2017-02-25 18:15:09 -0800514
zhihuangd3501ad2017-03-03 14:39:06 -0800515 auto rtp_transport = transport_result1.MoveValue();
516 auto srtp_transport = transport_result2.MoveValue();
517 EXPECT_TRUE(srtp_transport->SetSrtpSendKey(kTestCryptoParams1).ok());
518 EXPECT_TRUE(srtp_transport->SetSrtpReceiveKey(kTestCryptoParams2).ok());
519 bool expect_success = false;
520 BasicTwoWayRtpSendersAndReceiversTest(
521 {std::move(rtp_transport), std::move(srtp_transport)}, expect_success);
deadbeefe814a0d2017-02-25 18:15:09 -0800522
zhihuangd3501ad2017-03-03 14:39:06 -0800523 // The SRTP side is not expected to decode any audio or video frames.
524 // The RTP side is not expected to decode any video frames while it is
525 // possible that the encrypted audio frames can be accidentally decoded which
526 // is why received_audio_frames1_ is not validated.
527 EXPECT_TRUE(received_audio_frames2_ == 0 && rendered_video_frames1_ == 0 &&
528 rendered_video_frames2_ == 0);
deadbeefe814a0d2017-02-25 18:15:09 -0800529}
530
531// End-to-end test with two pairs of RTP senders and receivers, for audio and
532// video. Unlike the test above, this attempts to make the parameters as
zhihuangd3501ad2017-03-03 14:39:06 -0800533// complex as possible. The senders and receivers use the SRTP transport with
534// different keys.
deadbeefe814a0d2017-02-25 18:15:09 -0800535//
536// Uses non-muxed RTCP, with separate audio/video transports, and a full set of
537// parameters, as would normally be used in a PeerConnection.
538//
539// TODO(deadbeef): Update this test as more audio/video features become
540// supported.
zhihuangd3501ad2017-03-03 14:39:06 -0800541TEST_F(OrtcFactoryIntegrationTest,
542 FullTwoWayAudioVideoSrtpSendersAndReceivers) {
deadbeefe814a0d2017-02-25 18:15:09 -0800543 // We want four pairs of UDP transports for this test, for audio/video and
544 // RTP/RTCP.
545 auto audio_rtp_udp_transports = CreateAndConnectUdpTransportPair();
546 auto audio_rtcp_udp_transports = CreateAndConnectUdpTransportPair();
547 auto video_rtp_udp_transports = CreateAndConnectUdpTransportPair();
548 auto video_rtcp_udp_transports = CreateAndConnectUdpTransportPair();
549
550 // Since we have multiple RTP transports on each side, we need an RTP
551 // transport controller.
552 auto transport_controllers = CreateRtpTransportControllerPair();
553
554 RtcpParameters audio_rtcp_parameters;
555 audio_rtcp_parameters.mux = false;
zhihuangd3501ad2017-03-03 14:39:06 -0800556 auto audio_srtp_transports =
557 CreateSrtpTransportPair(audio_rtcp_parameters, audio_rtp_udp_transports,
558 audio_rtcp_udp_transports, transport_controllers);
deadbeefe814a0d2017-02-25 18:15:09 -0800559
560 RtcpParameters video_rtcp_parameters;
561 video_rtcp_parameters.mux = false;
562 video_rtcp_parameters.reduced_size = true;
zhihuangd3501ad2017-03-03 14:39:06 -0800563 auto video_srtp_transports =
564 CreateSrtpTransportPair(video_rtcp_parameters, video_rtp_udp_transports,
565 video_rtcp_udp_transports, transport_controllers);
566
567 // Set keys for SRTP transports.
568 audio_srtp_transports.first->SetSrtpSendKey(kTestCryptoParams1);
569 audio_srtp_transports.first->SetSrtpReceiveKey(kTestCryptoParams2);
570 video_srtp_transports.first->SetSrtpSendKey(kTestCryptoParams3);
571 video_srtp_transports.first->SetSrtpReceiveKey(kTestCryptoParams4);
572
573 audio_srtp_transports.second->SetSrtpSendKey(kTestCryptoParams2);
574 audio_srtp_transports.second->SetSrtpReceiveKey(kTestCryptoParams1);
575 video_srtp_transports.second->SetSrtpSendKey(kTestCryptoParams4);
576 video_srtp_transports.second->SetSrtpReceiveKey(kTestCryptoParams3);
deadbeefe814a0d2017-02-25 18:15:09 -0800577
578 // Create all the senders and receivers (four per endpoint).
579 auto audio_sender_result1 = ortc_factory1_->CreateRtpSender(
zhihuangd3501ad2017-03-03 14:39:06 -0800580 cricket::MEDIA_TYPE_AUDIO, audio_srtp_transports.first.get());
deadbeefe814a0d2017-02-25 18:15:09 -0800581 auto video_sender_result1 = ortc_factory1_->CreateRtpSender(
zhihuangd3501ad2017-03-03 14:39:06 -0800582 cricket::MEDIA_TYPE_VIDEO, video_srtp_transports.first.get());
deadbeefe814a0d2017-02-25 18:15:09 -0800583 auto audio_receiver_result1 = ortc_factory1_->CreateRtpReceiver(
zhihuangd3501ad2017-03-03 14:39:06 -0800584 cricket::MEDIA_TYPE_AUDIO, audio_srtp_transports.first.get());
deadbeefe814a0d2017-02-25 18:15:09 -0800585 auto video_receiver_result1 = ortc_factory1_->CreateRtpReceiver(
zhihuangd3501ad2017-03-03 14:39:06 -0800586 cricket::MEDIA_TYPE_VIDEO, video_srtp_transports.first.get());
deadbeefe814a0d2017-02-25 18:15:09 -0800587 ASSERT_TRUE(audio_sender_result1.ok());
588 ASSERT_TRUE(video_sender_result1.ok());
589 ASSERT_TRUE(audio_receiver_result1.ok());
590 ASSERT_TRUE(video_receiver_result1.ok());
591 auto audio_sender1 = audio_sender_result1.MoveValue();
592 auto video_sender1 = video_sender_result1.MoveValue();
593 auto audio_receiver1 = audio_receiver_result1.MoveValue();
594 auto video_receiver1 = video_receiver_result1.MoveValue();
595
596 auto audio_sender_result2 = ortc_factory2_->CreateRtpSender(
zhihuangd3501ad2017-03-03 14:39:06 -0800597 cricket::MEDIA_TYPE_AUDIO, audio_srtp_transports.second.get());
deadbeefe814a0d2017-02-25 18:15:09 -0800598 auto video_sender_result2 = ortc_factory2_->CreateRtpSender(
zhihuangd3501ad2017-03-03 14:39:06 -0800599 cricket::MEDIA_TYPE_VIDEO, video_srtp_transports.second.get());
deadbeefe814a0d2017-02-25 18:15:09 -0800600 auto audio_receiver_result2 = ortc_factory2_->CreateRtpReceiver(
zhihuangd3501ad2017-03-03 14:39:06 -0800601 cricket::MEDIA_TYPE_AUDIO, audio_srtp_transports.second.get());
deadbeefe814a0d2017-02-25 18:15:09 -0800602 auto video_receiver_result2 = ortc_factory2_->CreateRtpReceiver(
zhihuangd3501ad2017-03-03 14:39:06 -0800603 cricket::MEDIA_TYPE_VIDEO, video_srtp_transports.second.get());
deadbeefe814a0d2017-02-25 18:15:09 -0800604 ASSERT_TRUE(audio_sender_result2.ok());
605 ASSERT_TRUE(video_sender_result2.ok());
606 ASSERT_TRUE(audio_receiver_result2.ok());
607 ASSERT_TRUE(video_receiver_result2.ok());
608 auto audio_sender2 = audio_sender_result2.MoveValue();
609 auto video_sender2 = video_sender_result2.MoveValue();
610 auto audio_receiver2 = audio_receiver_result2.MoveValue();
611 auto video_receiver2 = video_receiver_result2.MoveValue();
612
613 RTCError error = audio_sender1->SetTrack(
614 CreateLocalAudioTrack("audio", ortc_factory1_.get()));
615 EXPECT_TRUE(error.ok());
616 error = video_sender1->SetTrack(
617 CreateLocalVideoTrackAndFakeCapturer("video", ortc_factory1_.get()));
618 EXPECT_TRUE(error.ok());
619 error = audio_sender2->SetTrack(
620 CreateLocalAudioTrack("audio", ortc_factory2_.get()));
621 EXPECT_TRUE(error.ok());
622 error = video_sender2->SetTrack(
623 CreateLocalVideoTrackAndFakeCapturer("video", ortc_factory2_.get()));
624 EXPECT_TRUE(error.ok());
625
626 // Use different codecs in different directions for extra challenge.
627 RtpParameters opus_send_parameters = MakeFullOpusParameters();
628 RtpParameters isac_send_parameters = MakeFullIsacParameters();
629 RtpParameters vp8_send_parameters = MakeFullVp8Parameters();
630 RtpParameters vp9_send_parameters = MakeFullVp9Parameters();
631
632 // Remove "payload_type" from receive parameters. Receiver will need to
633 // discern the payload type from packets received.
634 RtpParameters opus_receive_parameters = opus_send_parameters;
635 RtpParameters isac_receive_parameters = isac_send_parameters;
636 RtpParameters vp8_receive_parameters = vp8_send_parameters;
637 RtpParameters vp9_receive_parameters = vp9_send_parameters;
638 opus_receive_parameters.encodings[0].codec_payload_type.reset();
639 isac_receive_parameters.encodings[0].codec_payload_type.reset();
640 vp8_receive_parameters.encodings[0].codec_payload_type.reset();
641 vp9_receive_parameters.encodings[0].codec_payload_type.reset();
642
643 // Configure the senders' and receivers' parameters.
644 //
645 // Note: Intentionally, the top codec in the receive parameters does not
646 // match the codec sent by the other side. If "Receive" is called with a list
647 // of codecs, the receiver should be prepared to receive any of them, not
648 // just the one on top.
649 EXPECT_TRUE(audio_receiver1->Receive(opus_receive_parameters).ok());
650 EXPECT_TRUE(video_receiver1->Receive(vp8_receive_parameters).ok());
651 EXPECT_TRUE(audio_receiver2->Receive(isac_receive_parameters).ok());
652 EXPECT_TRUE(video_receiver2->Receive(vp9_receive_parameters).ok());
653 EXPECT_TRUE(audio_sender1->Send(opus_send_parameters).ok());
654 EXPECT_TRUE(video_sender1->Send(vp8_send_parameters).ok());
655 EXPECT_TRUE(audio_sender2->Send(isac_send_parameters).ok());
656 EXPECT_TRUE(video_sender2->Send(vp9_send_parameters).ok());
657
658 FakeVideoTrackRenderer fake_video_renderer1(
659 static_cast<VideoTrackInterface*>(video_receiver1->GetTrack().get()));
660 FakeVideoTrackRenderer fake_video_renderer2(
661 static_cast<VideoTrackInterface*>(video_receiver2->GetTrack().get()));
662
663 // Senders and receivers are connected and configured; audio and video frames
664 // should be able to flow at this point.
665 EXPECT_TRUE_WAIT(
666 fake_audio_capture_module1_->frames_received() > kDefaultNumFrames &&
667 fake_video_renderer1.num_rendered_frames() > kDefaultNumFrames &&
668 fake_audio_capture_module2_->frames_received() > kDefaultNumFrames &&
669 fake_video_renderer2.num_rendered_frames() > kDefaultNumFrames,
670 kDefaultTimeout);
671}
672
673// TODO(deadbeef): End-to-end test for multiple senders/receivers of the same
674// media type, once that's supported. Currently, it is not because the
675// BaseChannel model relies on there being a single VoiceChannel and
676// VideoChannel, and these only support a single set of codecs/etc. per
677// send/receive direction.
678
679// TODO(deadbeef): End-to-end test for simulcast, once that's supported by this
680// API.
681
zhihuangacfb0172017-03-28 13:45:18 -0700682#endif // if !defined(THREAD_SANITIZER)
683
deadbeefe814a0d2017-02-25 18:15:09 -0800684} // namespace webrtc