blob: d556fb1dc9bb6b68cdd60ebadda5fa7cfffe6456 [file] [log] [blame]
deadbeefe814a0d2017-02-26 02:15:091/*
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
Karl Wiberg3e9e5b32017-11-06 04:01:5614#include "api/audio_codecs/builtin_audio_decoder_factory.h"
15#include "api/audio_codecs/builtin_audio_encoder_factory.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3116#include "api/ortc/ortcfactoryinterface.h"
17#include "ortc/testrtpparameters.h"
18#include "p2p/base/udptransport.h"
19#include "pc/test/fakeaudiocapturemodule.h"
Niels Möller48cca022018-03-21 08:20:2120#include "pc/test/fakeperiodicvideosource.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3121#include "pc/test/fakevideotrackrenderer.h"
Niels Möller48cca022018-03-21 08:20:2122#include "pc/videotracksource.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3123#include "rtc_base/criticalsection.h"
24#include "rtc_base/fakenetwork.h"
25#include "rtc_base/gunit.h"
26#include "rtc_base/virtualsocketserver.h"
deadbeefe814a0d2017-02-26 02:15:0927
28namespace {
29
zhihuangd3501ad2017-03-03 22:39:0630const int kDefaultTimeout = 10000; // 10 seconds.
31const int kReceivingDuration = 1000; // 1 second.
Niels Möller48cca022018-03-21 08:20:2132
deadbeefe814a0d2017-02-26 02:15:0933// Default number of audio/video frames to wait for before considering a test a
34// success.
35const int kDefaultNumFrames = 3;
36const rtc::IPAddress kIPv4LocalHostAddress =
37 rtc::IPAddress(0x7F000001); // 127.0.0.1
38
zhihuangd3501ad2017-03-03 22:39:0639static const char kTestKeyParams1[] =
40 "inline:WVNfX19zZW1jdGwgKskgewkyMjA7fQp9CnVubGVz";
41static const char kTestKeyParams2[] =
42 "inline:PS1uQCVeeCFCanVmcjkpaywjNWhcYD0mXXtxaVBR";
43static const char kTestKeyParams3[] =
44 "inline:WVNfX19zZW1jdGwgKskgewkyMjA7fQp9CnVubGVa";
45static const char kTestKeyParams4[] =
46 "inline:WVNfX19zZW1jdGwgKskgewkyMjA7fQp9CnVubGVb";
47static const cricket::CryptoParams kTestCryptoParams1(1,
48 "AES_CM_128_HMAC_SHA1_80",
49 kTestKeyParams1,
50 "");
51static const cricket::CryptoParams kTestCryptoParams2(1,
52 "AES_CM_128_HMAC_SHA1_80",
53 kTestKeyParams2,
54 "");
55static const cricket::CryptoParams kTestCryptoParams3(1,
56 "AES_CM_128_HMAC_SHA1_80",
57 kTestKeyParams3,
58 "");
59static const cricket::CryptoParams kTestCryptoParams4(1,
60 "AES_CM_128_HMAC_SHA1_80",
61 kTestKeyParams4,
62 "");
deadbeefe814a0d2017-02-26 02:15:0963} // namespace
64
65namespace webrtc {
66
67// Used to test that things work end-to-end when using the default
68// implementations of threads/etc. provided by OrtcFactory, with the exception
69// of using a virtual network.
70//
71// By default, the virtual network manager doesn't enumerate any networks, but
72// sockets can still be created in this state.
73class OrtcFactoryIntegrationTest : public testing::Test {
74 public:
75 OrtcFactoryIntegrationTest()
deadbeef98e186c2017-05-17 01:00:0676 : network_thread_(&virtual_socket_server_),
deadbeefe814a0d2017-02-26 02:15:0977 fake_audio_capture_module1_(FakeAudioCaptureModule::Create()),
78 fake_audio_capture_module2_(FakeAudioCaptureModule::Create()) {
79 // Sockets are bound to the ANY address, so this is needed to tell the
80 // virtual network which address to use in this case.
81 virtual_socket_server_.SetDefaultRoute(kIPv4LocalHostAddress);
Tommi8b0ebb92018-02-07 20:09:1182 network_thread_.SetName("TestNetworkThread", this);
deadbeefe814a0d2017-02-26 02:15:0983 network_thread_.Start();
84 // Need to create after network thread is started.
Karl Wiberg3e9e5b32017-11-06 04:01:5685 ortc_factory1_ =
86 OrtcFactoryInterface::Create(
87 &network_thread_, nullptr, &fake_network_manager_, nullptr,
88 fake_audio_capture_module1_, CreateBuiltinAudioEncoderFactory(),
89 CreateBuiltinAudioDecoderFactory())
90 .MoveValue();
91 ortc_factory2_ =
92 OrtcFactoryInterface::Create(
93 &network_thread_, nullptr, &fake_network_manager_, nullptr,
94 fake_audio_capture_module2_, CreateBuiltinAudioEncoderFactory(),
95 CreateBuiltinAudioDecoderFactory())
96 .MoveValue();
deadbeefe814a0d2017-02-26 02:15:0997 }
98
99 protected:
100 typedef std::pair<std::unique_ptr<UdpTransportInterface>,
101 std::unique_ptr<UdpTransportInterface>>
102 UdpTransportPair;
103 typedef std::pair<std::unique_ptr<RtpTransportInterface>,
104 std::unique_ptr<RtpTransportInterface>>
105 RtpTransportPair;
zhihuangd3501ad2017-03-03 22:39:06106 typedef std::pair<std::unique_ptr<SrtpTransportInterface>,
107 std::unique_ptr<SrtpTransportInterface>>
108 SrtpTransportPair;
deadbeefe814a0d2017-02-26 02:15:09109 typedef std::pair<std::unique_ptr<RtpTransportControllerInterface>,
110 std::unique_ptr<RtpTransportControllerInterface>>
111 RtpTransportControllerPair;
112
113 // Helper function that creates one UDP transport each for |ortc_factory1_|
114 // and |ortc_factory2_|, and connects them.
115 UdpTransportPair CreateAndConnectUdpTransportPair() {
116 auto transport1 = ortc_factory1_->CreateUdpTransport(AF_INET).MoveValue();
117 auto transport2 = ortc_factory2_->CreateUdpTransport(AF_INET).MoveValue();
118 transport1->SetRemoteAddress(
119 rtc::SocketAddress(virtual_socket_server_.GetDefaultRoute(AF_INET),
120 transport2->GetLocalAddress().port()));
121 transport2->SetRemoteAddress(
122 rtc::SocketAddress(virtual_socket_server_.GetDefaultRoute(AF_INET),
123 transport1->GetLocalAddress().port()));
124 return {std::move(transport1), std::move(transport2)};
125 }
126
127 // Creates one transport controller each for |ortc_factory1_| and
128 // |ortc_factory2_|.
129 RtpTransportControllerPair CreateRtpTransportControllerPair() {
130 return {ortc_factory1_->CreateRtpTransportController().MoveValue(),
131 ortc_factory2_->CreateRtpTransportController().MoveValue()};
132 }
133
134 // Helper function that creates a pair of RtpTransports between
135 // |ortc_factory1_| and |ortc_factory2_|. Expected to be called with the
136 // result of CreateAndConnectUdpTransportPair. |rtcp_udp_transports| can be
137 // empty if RTCP muxing is used. |transport_controllers| can be empty if
138 // these transports are being created using a default transport controller.
139 RtpTransportPair CreateRtpTransportPair(
sprangdb2a9fc2017-08-09 13:42:32140 const RtpTransportParameters& parameters,
deadbeefe814a0d2017-02-26 02:15:09141 const UdpTransportPair& rtp_udp_transports,
142 const UdpTransportPair& rtcp_udp_transports,
143 const RtpTransportControllerPair& transport_controllers) {
144 auto transport_result1 = ortc_factory1_->CreateRtpTransport(
sprangdb2a9fc2017-08-09 13:42:32145 parameters, rtp_udp_transports.first.get(),
deadbeefe814a0d2017-02-26 02:15:09146 rtcp_udp_transports.first.get(), transport_controllers.first.get());
147 auto transport_result2 = ortc_factory2_->CreateRtpTransport(
sprangdb2a9fc2017-08-09 13:42:32148 parameters, rtp_udp_transports.second.get(),
deadbeefe814a0d2017-02-26 02:15:09149 rtcp_udp_transports.second.get(), transport_controllers.second.get());
150 return {transport_result1.MoveValue(), transport_result2.MoveValue()};
151 }
152
zhihuangd3501ad2017-03-03 22:39:06153 SrtpTransportPair CreateSrtpTransportPair(
sprangdb2a9fc2017-08-09 13:42:32154 const RtpTransportParameters& parameters,
zhihuangd3501ad2017-03-03 22:39:06155 const UdpTransportPair& rtp_udp_transports,
156 const UdpTransportPair& rtcp_udp_transports,
157 const RtpTransportControllerPair& transport_controllers) {
158 auto transport_result1 = ortc_factory1_->CreateSrtpTransport(
sprangdb2a9fc2017-08-09 13:42:32159 parameters, rtp_udp_transports.first.get(),
zhihuangd3501ad2017-03-03 22:39:06160 rtcp_udp_transports.first.get(), transport_controllers.first.get());
161 auto transport_result2 = ortc_factory2_->CreateSrtpTransport(
sprangdb2a9fc2017-08-09 13:42:32162 parameters, rtp_udp_transports.second.get(),
zhihuangd3501ad2017-03-03 22:39:06163 rtcp_udp_transports.second.get(), transport_controllers.second.get());
164 return {transport_result1.MoveValue(), transport_result2.MoveValue()};
165 }
166
deadbeefe814a0d2017-02-26 02:15:09167 // For convenience when |rtcp_udp_transports| and |transport_controllers|
168 // aren't needed.
169 RtpTransportPair CreateRtpTransportPair(
sprangdb2a9fc2017-08-09 13:42:32170 const RtpTransportParameters& parameters,
deadbeefe814a0d2017-02-26 02:15:09171 const UdpTransportPair& rtp_udp_transports) {
sprangdb2a9fc2017-08-09 13:42:32172 return CreateRtpTransportPair(parameters, rtp_udp_transports,
deadbeefe814a0d2017-02-26 02:15:09173 UdpTransportPair(),
174 RtpTransportControllerPair());
175 }
176
zhihuangd3501ad2017-03-03 22:39:06177 SrtpTransportPair CreateSrtpTransportPairAndSetKeys(
sprangdb2a9fc2017-08-09 13:42:32178 const RtpTransportParameters& parameters,
zhihuangd3501ad2017-03-03 22:39:06179 const UdpTransportPair& rtp_udp_transports) {
180 SrtpTransportPair srtp_transports = CreateSrtpTransportPair(
sprangdb2a9fc2017-08-09 13:42:32181 parameters, rtp_udp_transports, UdpTransportPair(),
zhihuangd3501ad2017-03-03 22:39:06182 RtpTransportControllerPair());
183 EXPECT_TRUE(srtp_transports.first->SetSrtpSendKey(kTestCryptoParams1).ok());
184 EXPECT_TRUE(
185 srtp_transports.first->SetSrtpReceiveKey(kTestCryptoParams2).ok());
186 EXPECT_TRUE(
187 srtp_transports.second->SetSrtpSendKey(kTestCryptoParams2).ok());
188 EXPECT_TRUE(
189 srtp_transports.second->SetSrtpReceiveKey(kTestCryptoParams1).ok());
190 return srtp_transports;
191 }
192
193 SrtpTransportPair CreateSrtpTransportPairAndSetMismatchingKeys(
sprangdb2a9fc2017-08-09 13:42:32194 const RtpTransportParameters& parameters,
zhihuangd3501ad2017-03-03 22:39:06195 const UdpTransportPair& rtp_udp_transports) {
196 SrtpTransportPair srtp_transports = CreateSrtpTransportPair(
sprangdb2a9fc2017-08-09 13:42:32197 parameters, rtp_udp_transports, UdpTransportPair(),
zhihuangd3501ad2017-03-03 22:39:06198 RtpTransportControllerPair());
199 EXPECT_TRUE(srtp_transports.first->SetSrtpSendKey(kTestCryptoParams1).ok());
200 EXPECT_TRUE(
201 srtp_transports.first->SetSrtpReceiveKey(kTestCryptoParams2).ok());
202 EXPECT_TRUE(
203 srtp_transports.second->SetSrtpSendKey(kTestCryptoParams1).ok());
204 EXPECT_TRUE(
205 srtp_transports.second->SetSrtpReceiveKey(kTestCryptoParams2).ok());
206 return srtp_transports;
207 }
208
deadbeefe814a0d2017-02-26 02:15:09209 // Ends up using fake audio capture module, which was passed into OrtcFactory
210 // on creation.
211 rtc::scoped_refptr<webrtc::AudioTrackInterface> CreateLocalAudioTrack(
212 const std::string& id,
213 OrtcFactoryInterface* ortc_factory) {
214 // Disable echo cancellation to make test more efficient.
215 cricket::AudioOptions options;
216 options.echo_cancellation.emplace(true);
217 rtc::scoped_refptr<webrtc::AudioSourceInterface> source =
218 ortc_factory->CreateAudioSource(options);
219 return ortc_factory->CreateAudioTrack(id, source);
220 }
221
Niels Möller48cca022018-03-21 08:20:21222 // Stores created video source in |fake_video_sources_|.
deadbeefe814a0d2017-02-26 02:15:09223 rtc::scoped_refptr<webrtc::VideoTrackInterface>
Niels Möller48cca022018-03-21 08:20:21224 CreateLocalVideoTrackAndFakeSource(const std::string& id,
225 OrtcFactoryInterface* ortc_factory) {
226 fake_video_sources_.emplace_back(
227 rtc::MakeUnique<FakePeriodicVideoSource>());
228 fake_video_track_sources_.emplace_back(
229 new rtc::RefCountedObject<VideoTrackSource>(
230 fake_video_sources_.back().get(), false /* remote */));
231 return rtc::scoped_refptr<VideoTrackInterface>(
232 ortc_factory->CreateVideoTrack(
233 id, fake_video_track_sources_.back()));
deadbeefe814a0d2017-02-26 02:15:09234 }
235
zhihuangd3501ad2017-03-03 22:39:06236 // Helper function used to test two way RTP senders and receivers with basic
237 // configurations.
238 // If |expect_success| is true, waits for kDefaultTimeout for
239 // kDefaultNumFrames frames to be received by all RtpReceivers.
240 // If |expect_success| is false, simply waits for |kReceivingDuration|, and
241 // stores the number of received frames in |received_audio_frame1_| etc.
242 void BasicTwoWayRtpSendersAndReceiversTest(RtpTransportPair srtp_transports,
243 bool expect_success) {
244 received_audio_frames1_ = 0;
245 received_audio_frames2_ = 0;
246 rendered_video_frames1_ = 0;
247 rendered_video_frames2_ = 0;
248 // Create all the senders and receivers (four per endpoint).
249 auto audio_sender_result1 = ortc_factory1_->CreateRtpSender(
250 cricket::MEDIA_TYPE_AUDIO, srtp_transports.first.get());
251 auto video_sender_result1 = ortc_factory1_->CreateRtpSender(
252 cricket::MEDIA_TYPE_VIDEO, srtp_transports.first.get());
253 auto audio_receiver_result1 = ortc_factory1_->CreateRtpReceiver(
254 cricket::MEDIA_TYPE_AUDIO, srtp_transports.first.get());
255 auto video_receiver_result1 = ortc_factory1_->CreateRtpReceiver(
256 cricket::MEDIA_TYPE_VIDEO, srtp_transports.first.get());
257 ASSERT_TRUE(audio_sender_result1.ok());
258 ASSERT_TRUE(video_sender_result1.ok());
259 ASSERT_TRUE(audio_receiver_result1.ok());
260 ASSERT_TRUE(video_receiver_result1.ok());
261 auto audio_sender1 = audio_sender_result1.MoveValue();
262 auto video_sender1 = video_sender_result1.MoveValue();
263 auto audio_receiver1 = audio_receiver_result1.MoveValue();
264 auto video_receiver1 = video_receiver_result1.MoveValue();
265
266 auto audio_sender_result2 = ortc_factory2_->CreateRtpSender(
267 cricket::MEDIA_TYPE_AUDIO, srtp_transports.second.get());
268 auto video_sender_result2 = ortc_factory2_->CreateRtpSender(
269 cricket::MEDIA_TYPE_VIDEO, srtp_transports.second.get());
270 auto audio_receiver_result2 = ortc_factory2_->CreateRtpReceiver(
271 cricket::MEDIA_TYPE_AUDIO, srtp_transports.second.get());
272 auto video_receiver_result2 = ortc_factory2_->CreateRtpReceiver(
273 cricket::MEDIA_TYPE_VIDEO, srtp_transports.second.get());
274 ASSERT_TRUE(audio_sender_result2.ok());
275 ASSERT_TRUE(video_sender_result2.ok());
276 ASSERT_TRUE(audio_receiver_result2.ok());
277 ASSERT_TRUE(video_receiver_result2.ok());
278 auto audio_sender2 = audio_sender_result2.MoveValue();
279 auto video_sender2 = video_sender_result2.MoveValue();
280 auto audio_receiver2 = audio_receiver_result2.MoveValue();
281 auto video_receiver2 = video_receiver_result2.MoveValue();
282
283 // Add fake tracks.
284 RTCError error = audio_sender1->SetTrack(
285 CreateLocalAudioTrack("audio", ortc_factory1_.get()));
286 EXPECT_TRUE(error.ok());
287 error = video_sender1->SetTrack(
Niels Möller48cca022018-03-21 08:20:21288 CreateLocalVideoTrackAndFakeSource("video", ortc_factory1_.get()));
zhihuangd3501ad2017-03-03 22:39:06289 EXPECT_TRUE(error.ok());
290 error = audio_sender2->SetTrack(
291 CreateLocalAudioTrack("audio", ortc_factory2_.get()));
292 EXPECT_TRUE(error.ok());
293 error = video_sender2->SetTrack(
Niels Möller48cca022018-03-21 08:20:21294 CreateLocalVideoTrackAndFakeSource("video", ortc_factory2_.get()));
zhihuangd3501ad2017-03-03 22:39:06295 EXPECT_TRUE(error.ok());
296
297 // "sent_X_parameters1" are the parameters that endpoint 1 sends with and
298 // endpoint 2 receives with.
299 RtpParameters sent_opus_parameters1 =
300 MakeMinimalOpusParametersWithSsrc(0xdeadbeef);
301 RtpParameters sent_vp8_parameters1 =
302 MakeMinimalVp8ParametersWithSsrc(0xbaadfeed);
303 RtpParameters sent_opus_parameters2 =
304 MakeMinimalOpusParametersWithSsrc(0x13333337);
305 RtpParameters sent_vp8_parameters2 =
306 MakeMinimalVp8ParametersWithSsrc(0x12345678);
307
308 // Configure the senders' and receivers' parameters.
309 EXPECT_TRUE(audio_receiver1->Receive(sent_opus_parameters2).ok());
310 EXPECT_TRUE(video_receiver1->Receive(sent_vp8_parameters2).ok());
311 EXPECT_TRUE(audio_receiver2->Receive(sent_opus_parameters1).ok());
312 EXPECT_TRUE(video_receiver2->Receive(sent_vp8_parameters1).ok());
313 EXPECT_TRUE(audio_sender1->Send(sent_opus_parameters1).ok());
314 EXPECT_TRUE(video_sender1->Send(sent_vp8_parameters1).ok());
315 EXPECT_TRUE(audio_sender2->Send(sent_opus_parameters2).ok());
316 EXPECT_TRUE(video_sender2->Send(sent_vp8_parameters2).ok());
317
318 FakeVideoTrackRenderer fake_video_renderer1(
319 static_cast<VideoTrackInterface*>(video_receiver1->GetTrack().get()));
320 FakeVideoTrackRenderer fake_video_renderer2(
321 static_cast<VideoTrackInterface*>(video_receiver2->GetTrack().get()));
322
323 if (expect_success) {
324 EXPECT_TRUE_WAIT(
325 fake_audio_capture_module1_->frames_received() > kDefaultNumFrames &&
326 fake_video_renderer1.num_rendered_frames() > kDefaultNumFrames &&
327 fake_audio_capture_module2_->frames_received() >
328 kDefaultNumFrames &&
minyue-webrtcc453b082017-07-10 09:56:05329 fake_video_renderer2.num_rendered_frames() > kDefaultNumFrames,
330 kDefaultTimeout) << "Audio capture module 1 received "
331 << fake_audio_capture_module1_->frames_received()
332 << " frames, Video renderer 1 rendered "
333 << fake_video_renderer1.num_rendered_frames()
334 << " frames, Audio capture module 2 received "
335 << fake_audio_capture_module2_->frames_received()
336 << " frames, Video renderer 2 rendered "
337 << fake_video_renderer2.num_rendered_frames()
338 << " frames.";
zhihuangd3501ad2017-03-03 22:39:06339 } else {
340 WAIT(false, kReceivingDuration);
341 rendered_video_frames1_ = fake_video_renderer1.num_rendered_frames();
342 rendered_video_frames2_ = fake_video_renderer2.num_rendered_frames();
343 received_audio_frames1_ = fake_audio_capture_module1_->frames_received();
344 received_audio_frames2_ = fake_audio_capture_module2_->frames_received();
345 }
346 }
347
deadbeefe814a0d2017-02-26 02:15:09348 rtc::VirtualSocketServer virtual_socket_server_;
349 rtc::Thread network_thread_;
350 rtc::FakeNetworkManager fake_network_manager_;
351 rtc::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module1_;
352 rtc::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module2_;
353 std::unique_ptr<OrtcFactoryInterface> ortc_factory1_;
354 std::unique_ptr<OrtcFactoryInterface> ortc_factory2_;
Niels Möller48cca022018-03-21 08:20:21355 std::vector<std::unique_ptr<FakePeriodicVideoSource>> fake_video_sources_;
356 std::vector<rtc::scoped_refptr<VideoTrackSource>> fake_video_track_sources_;
zhihuangd3501ad2017-03-03 22:39:06357 int received_audio_frames1_ = 0;
358 int received_audio_frames2_ = 0;
359 int rendered_video_frames1_ = 0;
360 int rendered_video_frames2_ = 0;
deadbeefe814a0d2017-02-26 02:15:09361};
362
zhihuangacfb0172017-03-28 20:45:18363// Disable for TSan v2, see
364// https://bugs.chromium.org/p/webrtc/issues/detail?id=7366 for details.
365#if !defined(THREAD_SANITIZER)
366
deadbeefe814a0d2017-02-26 02:15:09367// Very basic end-to-end test with a single pair of audio RTP sender and
368// receiver.
369//
370// Uses muxed RTCP, and minimal parameters with a hard-coded config that's
371// known to work.
372TEST_F(OrtcFactoryIntegrationTest, BasicOneWayAudioRtpSenderAndReceiver) {
373 auto udp_transports = CreateAndConnectUdpTransportPair();
374 auto rtp_transports =
375 CreateRtpTransportPair(MakeRtcpMuxParameters(), udp_transports);
376
377 auto sender_result = ortc_factory1_->CreateRtpSender(
378 cricket::MEDIA_TYPE_AUDIO, rtp_transports.first.get());
379 auto receiver_result = ortc_factory2_->CreateRtpReceiver(
380 cricket::MEDIA_TYPE_AUDIO, rtp_transports.second.get());
381 ASSERT_TRUE(sender_result.ok());
382 ASSERT_TRUE(receiver_result.ok());
383 auto sender = sender_result.MoveValue();
384 auto receiver = receiver_result.MoveValue();
385
386 RTCError error =
387 sender->SetTrack(CreateLocalAudioTrack("audio", ortc_factory1_.get()));
388 EXPECT_TRUE(error.ok());
389
390 RtpParameters opus_parameters = MakeMinimalOpusParameters();
391 EXPECT_TRUE(receiver->Receive(opus_parameters).ok());
392 EXPECT_TRUE(sender->Send(opus_parameters).ok());
393 // Sender and receiver are connected and configured; audio frames should be
394 // able to flow at this point.
395 EXPECT_TRUE_WAIT(
396 fake_audio_capture_module2_->frames_received() > kDefaultNumFrames,
397 kDefaultTimeout);
398}
399
400// Very basic end-to-end test with a single pair of video RTP sender and
401// receiver.
402//
403// Uses muxed RTCP, and minimal parameters with a hard-coded config that's
404// known to work.
405TEST_F(OrtcFactoryIntegrationTest, BasicOneWayVideoRtpSenderAndReceiver) {
406 auto udp_transports = CreateAndConnectUdpTransportPair();
407 auto rtp_transports =
408 CreateRtpTransportPair(MakeRtcpMuxParameters(), udp_transports);
409
410 auto sender_result = ortc_factory1_->CreateRtpSender(
411 cricket::MEDIA_TYPE_VIDEO, rtp_transports.first.get());
412 auto receiver_result = ortc_factory2_->CreateRtpReceiver(
413 cricket::MEDIA_TYPE_VIDEO, rtp_transports.second.get());
414 ASSERT_TRUE(sender_result.ok());
415 ASSERT_TRUE(receiver_result.ok());
416 auto sender = sender_result.MoveValue();
417 auto receiver = receiver_result.MoveValue();
418
419 RTCError error = sender->SetTrack(
Niels Möller48cca022018-03-21 08:20:21420 CreateLocalVideoTrackAndFakeSource("video", ortc_factory1_.get()));
deadbeefe814a0d2017-02-26 02:15:09421 EXPECT_TRUE(error.ok());
422
423 RtpParameters vp8_parameters = MakeMinimalVp8Parameters();
424 EXPECT_TRUE(receiver->Receive(vp8_parameters).ok());
425 EXPECT_TRUE(sender->Send(vp8_parameters).ok());
426 FakeVideoTrackRenderer fake_renderer(
427 static_cast<VideoTrackInterface*>(receiver->GetTrack().get()));
428 // Sender and receiver are connected and configured; video frames should be
429 // able to flow at this point.
430 EXPECT_TRUE_WAIT(fake_renderer.num_rendered_frames() > kDefaultNumFrames,
431 kDefaultTimeout);
432}
433
434// Test that if the track is changed while sending, the sender seamlessly
435// transitions to sending it and frames are received end-to-end.
436//
437// Only doing this for video, since given that audio is sourced from a single
438// fake audio capture module, the audio track is just a dummy object.
439// TODO(deadbeef): Change this when possible.
440TEST_F(OrtcFactoryIntegrationTest, SetTrackWhileSending) {
441 auto udp_transports = CreateAndConnectUdpTransportPair();
442 auto rtp_transports =
443 CreateRtpTransportPair(MakeRtcpMuxParameters(), udp_transports);
444
445 auto sender_result = ortc_factory1_->CreateRtpSender(
446 cricket::MEDIA_TYPE_VIDEO, rtp_transports.first.get());
447 auto receiver_result = ortc_factory2_->CreateRtpReceiver(
448 cricket::MEDIA_TYPE_VIDEO, rtp_transports.second.get());
449 ASSERT_TRUE(sender_result.ok());
450 ASSERT_TRUE(receiver_result.ok());
451 auto sender = sender_result.MoveValue();
452 auto receiver = receiver_result.MoveValue();
453
454 RTCError error = sender->SetTrack(
Niels Möller48cca022018-03-21 08:20:21455 CreateLocalVideoTrackAndFakeSource("video_1", ortc_factory1_.get()));
deadbeefe814a0d2017-02-26 02:15:09456 EXPECT_TRUE(error.ok());
457 RtpParameters vp8_parameters = MakeMinimalVp8Parameters();
458 EXPECT_TRUE(receiver->Receive(vp8_parameters).ok());
459 EXPECT_TRUE(sender->Send(vp8_parameters).ok());
460 FakeVideoTrackRenderer fake_renderer(
461 static_cast<VideoTrackInterface*>(receiver->GetTrack().get()));
462 // Expect for some initial number of frames to be received.
463 EXPECT_TRUE_WAIT(fake_renderer.num_rendered_frames() > kDefaultNumFrames,
464 kDefaultTimeout);
Niels Möller48cca022018-03-21 08:20:21465 // Destroy old source, set a new track, and verify new frames are received
466 // from the new track. The VideoTrackSource is reference counted and may live
467 // a little longer, so tell it that its source is going away now.
468 fake_video_track_sources_[0]->OnSourceDestroyed();
469 fake_video_track_sources_[0] = nullptr;
470 fake_video_sources_[0].reset();
deadbeefe814a0d2017-02-26 02:15:09471 int prev_num_frames = fake_renderer.num_rendered_frames();
472 error = sender->SetTrack(
Niels Möller48cca022018-03-21 08:20:21473 CreateLocalVideoTrackAndFakeSource("video_2", ortc_factory1_.get()));
deadbeefe814a0d2017-02-26 02:15:09474 EXPECT_TRUE(error.ok());
475 EXPECT_TRUE_WAIT(
476 fake_renderer.num_rendered_frames() > kDefaultNumFrames + prev_num_frames,
477 kDefaultTimeout);
478}
479
480// End-to-end test with two pairs of RTP senders and receivers, for audio and
481// video.
482//
483// Uses muxed RTCP, and minimal parameters with hard-coded configs that are
484// known to work.
Alex Loikoa354e262017-09-27 09:10:04485#if !(defined(WEBRTC_IOS) && defined(WEBRTC_ARCH_64_BITS) && !defined(NDEBUG))
deadbeefe814a0d2017-02-26 02:15:09486TEST_F(OrtcFactoryIntegrationTest,
487 BasicTwoWayAudioVideoRtpSendersAndReceivers) {
488 auto udp_transports = CreateAndConnectUdpTransportPair();
489 auto rtp_transports =
490 CreateRtpTransportPair(MakeRtcpMuxParameters(), udp_transports);
zhihuangd3501ad2017-03-03 22:39:06491 bool expect_success = true;
492 BasicTwoWayRtpSendersAndReceiversTest(std::move(rtp_transports),
493 expect_success);
494}
deadbeefe814a0d2017-02-26 02:15:09495
zhihuangd3501ad2017-03-03 22:39:06496TEST_F(OrtcFactoryIntegrationTest,
497 BasicTwoWayAudioVideoSrtpSendersAndReceivers) {
498 auto udp_transports = CreateAndConnectUdpTransportPair();
499 auto srtp_transports = CreateSrtpTransportPairAndSetKeys(
500 MakeRtcpMuxParameters(), udp_transports);
501 bool expect_success = true;
502 BasicTwoWayRtpSendersAndReceiversTest(std::move(srtp_transports),
503 expect_success);
504}
mbonadeif904d132017-07-14 22:19:03505#endif
deadbeefe814a0d2017-02-26 02:15:09506
zhihuangd3501ad2017-03-03 22:39:06507// Tests that the packets cannot be decoded if the keys are mismatched.
508TEST_F(OrtcFactoryIntegrationTest, SrtpSendersAndReceiversWithMismatchingKeys) {
509 auto udp_transports = CreateAndConnectUdpTransportPair();
510 auto srtp_transports = CreateSrtpTransportPairAndSetMismatchingKeys(
511 MakeRtcpMuxParameters(), udp_transports);
512 bool expect_success = false;
513 BasicTwoWayRtpSendersAndReceiversTest(std::move(srtp_transports),
514 expect_success);
515 // No frames are expected to be decoded.
516 EXPECT_TRUE(received_audio_frames1_ == 0 && received_audio_frames2_ == 0 &&
517 rendered_video_frames1_ == 0 && rendered_video_frames2_ == 0);
518}
deadbeefe814a0d2017-02-26 02:15:09519
zhihuangd3501ad2017-03-03 22:39:06520// Tests that the frames cannot be decoded if only one side uses SRTP.
521TEST_F(OrtcFactoryIntegrationTest, OneSideSrtpSenderAndReceiver) {
522 auto rtcp_parameters = MakeRtcpMuxParameters();
523 auto udp_transports = CreateAndConnectUdpTransportPair();
524 auto rtcp_udp_transports = UdpTransportPair();
525 auto transport_controllers = RtpTransportControllerPair();
526 auto transport_result1 = ortc_factory1_->CreateRtpTransport(
527 rtcp_parameters, udp_transports.first.get(),
528 rtcp_udp_transports.first.get(), transport_controllers.first.get());
529 auto transport_result2 = ortc_factory2_->CreateSrtpTransport(
530 rtcp_parameters, udp_transports.second.get(),
531 rtcp_udp_transports.second.get(), transport_controllers.second.get());
deadbeefe814a0d2017-02-26 02:15:09532
zhihuangd3501ad2017-03-03 22:39:06533 auto rtp_transport = transport_result1.MoveValue();
534 auto srtp_transport = transport_result2.MoveValue();
535 EXPECT_TRUE(srtp_transport->SetSrtpSendKey(kTestCryptoParams1).ok());
536 EXPECT_TRUE(srtp_transport->SetSrtpReceiveKey(kTestCryptoParams2).ok());
537 bool expect_success = false;
538 BasicTwoWayRtpSendersAndReceiversTest(
539 {std::move(rtp_transport), std::move(srtp_transport)}, expect_success);
deadbeefe814a0d2017-02-26 02:15:09540
zhihuangd3501ad2017-03-03 22:39:06541 // The SRTP side is not expected to decode any audio or video frames.
542 // The RTP side is not expected to decode any video frames while it is
543 // possible that the encrypted audio frames can be accidentally decoded which
544 // is why received_audio_frames1_ is not validated.
545 EXPECT_TRUE(received_audio_frames2_ == 0 && rendered_video_frames1_ == 0 &&
546 rendered_video_frames2_ == 0);
deadbeefe814a0d2017-02-26 02:15:09547}
548
549// End-to-end test with two pairs of RTP senders and receivers, for audio and
550// video. Unlike the test above, this attempts to make the parameters as
zhihuangd3501ad2017-03-03 22:39:06551// complex as possible. The senders and receivers use the SRTP transport with
552// different keys.
deadbeefe814a0d2017-02-26 02:15:09553//
554// Uses non-muxed RTCP, with separate audio/video transports, and a full set of
555// parameters, as would normally be used in a PeerConnection.
556//
557// TODO(deadbeef): Update this test as more audio/video features become
558// supported.
zhihuangd3501ad2017-03-03 22:39:06559TEST_F(OrtcFactoryIntegrationTest,
560 FullTwoWayAudioVideoSrtpSendersAndReceivers) {
deadbeefe814a0d2017-02-26 02:15:09561 // We want four pairs of UDP transports for this test, for audio/video and
562 // RTP/RTCP.
563 auto audio_rtp_udp_transports = CreateAndConnectUdpTransportPair();
564 auto audio_rtcp_udp_transports = CreateAndConnectUdpTransportPair();
565 auto video_rtp_udp_transports = CreateAndConnectUdpTransportPair();
566 auto video_rtcp_udp_transports = CreateAndConnectUdpTransportPair();
567
568 // Since we have multiple RTP transports on each side, we need an RTP
569 // transport controller.
570 auto transport_controllers = CreateRtpTransportControllerPair();
571
sprangdb2a9fc2017-08-09 13:42:32572 RtpTransportParameters audio_rtp_transport_parameters;
573 audio_rtp_transport_parameters.rtcp.mux = false;
574 auto audio_srtp_transports = CreateSrtpTransportPair(
575 audio_rtp_transport_parameters, audio_rtp_udp_transports,
576 audio_rtcp_udp_transports, transport_controllers);
deadbeefe814a0d2017-02-26 02:15:09577
sprangdb2a9fc2017-08-09 13:42:32578 RtpTransportParameters video_rtp_transport_parameters;
579 video_rtp_transport_parameters.rtcp.mux = false;
580 video_rtp_transport_parameters.rtcp.reduced_size = true;
581 auto video_srtp_transports = CreateSrtpTransportPair(
582 video_rtp_transport_parameters, video_rtp_udp_transports,
583 video_rtcp_udp_transports, transport_controllers);
zhihuangd3501ad2017-03-03 22:39:06584
585 // Set keys for SRTP transports.
586 audio_srtp_transports.first->SetSrtpSendKey(kTestCryptoParams1);
587 audio_srtp_transports.first->SetSrtpReceiveKey(kTestCryptoParams2);
588 video_srtp_transports.first->SetSrtpSendKey(kTestCryptoParams3);
589 video_srtp_transports.first->SetSrtpReceiveKey(kTestCryptoParams4);
590
591 audio_srtp_transports.second->SetSrtpSendKey(kTestCryptoParams2);
592 audio_srtp_transports.second->SetSrtpReceiveKey(kTestCryptoParams1);
593 video_srtp_transports.second->SetSrtpSendKey(kTestCryptoParams4);
594 video_srtp_transports.second->SetSrtpReceiveKey(kTestCryptoParams3);
deadbeefe814a0d2017-02-26 02:15:09595
596 // Create all the senders and receivers (four per endpoint).
597 auto audio_sender_result1 = ortc_factory1_->CreateRtpSender(
zhihuangd3501ad2017-03-03 22:39:06598 cricket::MEDIA_TYPE_AUDIO, audio_srtp_transports.first.get());
deadbeefe814a0d2017-02-26 02:15:09599 auto video_sender_result1 = ortc_factory1_->CreateRtpSender(
zhihuangd3501ad2017-03-03 22:39:06600 cricket::MEDIA_TYPE_VIDEO, video_srtp_transports.first.get());
deadbeefe814a0d2017-02-26 02:15:09601 auto audio_receiver_result1 = ortc_factory1_->CreateRtpReceiver(
zhihuangd3501ad2017-03-03 22:39:06602 cricket::MEDIA_TYPE_AUDIO, audio_srtp_transports.first.get());
deadbeefe814a0d2017-02-26 02:15:09603 auto video_receiver_result1 = ortc_factory1_->CreateRtpReceiver(
zhihuangd3501ad2017-03-03 22:39:06604 cricket::MEDIA_TYPE_VIDEO, video_srtp_transports.first.get());
deadbeefe814a0d2017-02-26 02:15:09605 ASSERT_TRUE(audio_sender_result1.ok());
606 ASSERT_TRUE(video_sender_result1.ok());
607 ASSERT_TRUE(audio_receiver_result1.ok());
608 ASSERT_TRUE(video_receiver_result1.ok());
609 auto audio_sender1 = audio_sender_result1.MoveValue();
610 auto video_sender1 = video_sender_result1.MoveValue();
611 auto audio_receiver1 = audio_receiver_result1.MoveValue();
612 auto video_receiver1 = video_receiver_result1.MoveValue();
613
614 auto audio_sender_result2 = ortc_factory2_->CreateRtpSender(
zhihuangd3501ad2017-03-03 22:39:06615 cricket::MEDIA_TYPE_AUDIO, audio_srtp_transports.second.get());
deadbeefe814a0d2017-02-26 02:15:09616 auto video_sender_result2 = ortc_factory2_->CreateRtpSender(
zhihuangd3501ad2017-03-03 22:39:06617 cricket::MEDIA_TYPE_VIDEO, video_srtp_transports.second.get());
deadbeefe814a0d2017-02-26 02:15:09618 auto audio_receiver_result2 = ortc_factory2_->CreateRtpReceiver(
zhihuangd3501ad2017-03-03 22:39:06619 cricket::MEDIA_TYPE_AUDIO, audio_srtp_transports.second.get());
deadbeefe814a0d2017-02-26 02:15:09620 auto video_receiver_result2 = ortc_factory2_->CreateRtpReceiver(
zhihuangd3501ad2017-03-03 22:39:06621 cricket::MEDIA_TYPE_VIDEO, video_srtp_transports.second.get());
deadbeefe814a0d2017-02-26 02:15:09622 ASSERT_TRUE(audio_sender_result2.ok());
623 ASSERT_TRUE(video_sender_result2.ok());
624 ASSERT_TRUE(audio_receiver_result2.ok());
625 ASSERT_TRUE(video_receiver_result2.ok());
626 auto audio_sender2 = audio_sender_result2.MoveValue();
627 auto video_sender2 = video_sender_result2.MoveValue();
628 auto audio_receiver2 = audio_receiver_result2.MoveValue();
629 auto video_receiver2 = video_receiver_result2.MoveValue();
630
631 RTCError error = audio_sender1->SetTrack(
632 CreateLocalAudioTrack("audio", ortc_factory1_.get()));
633 EXPECT_TRUE(error.ok());
634 error = video_sender1->SetTrack(
Niels Möller48cca022018-03-21 08:20:21635 CreateLocalVideoTrackAndFakeSource("video", ortc_factory1_.get()));
deadbeefe814a0d2017-02-26 02:15:09636 EXPECT_TRUE(error.ok());
637 error = audio_sender2->SetTrack(
638 CreateLocalAudioTrack("audio", ortc_factory2_.get()));
639 EXPECT_TRUE(error.ok());
640 error = video_sender2->SetTrack(
Niels Möller48cca022018-03-21 08:20:21641 CreateLocalVideoTrackAndFakeSource("video", ortc_factory2_.get()));
deadbeefe814a0d2017-02-26 02:15:09642 EXPECT_TRUE(error.ok());
643
644 // Use different codecs in different directions for extra challenge.
645 RtpParameters opus_send_parameters = MakeFullOpusParameters();
646 RtpParameters isac_send_parameters = MakeFullIsacParameters();
647 RtpParameters vp8_send_parameters = MakeFullVp8Parameters();
648 RtpParameters vp9_send_parameters = MakeFullVp9Parameters();
649
650 // Remove "payload_type" from receive parameters. Receiver will need to
651 // discern the payload type from packets received.
652 RtpParameters opus_receive_parameters = opus_send_parameters;
653 RtpParameters isac_receive_parameters = isac_send_parameters;
654 RtpParameters vp8_receive_parameters = vp8_send_parameters;
655 RtpParameters vp9_receive_parameters = vp9_send_parameters;
656 opus_receive_parameters.encodings[0].codec_payload_type.reset();
657 isac_receive_parameters.encodings[0].codec_payload_type.reset();
658 vp8_receive_parameters.encodings[0].codec_payload_type.reset();
659 vp9_receive_parameters.encodings[0].codec_payload_type.reset();
660
661 // Configure the senders' and receivers' parameters.
662 //
663 // Note: Intentionally, the top codec in the receive parameters does not
664 // match the codec sent by the other side. If "Receive" is called with a list
665 // of codecs, the receiver should be prepared to receive any of them, not
666 // just the one on top.
667 EXPECT_TRUE(audio_receiver1->Receive(opus_receive_parameters).ok());
668 EXPECT_TRUE(video_receiver1->Receive(vp8_receive_parameters).ok());
669 EXPECT_TRUE(audio_receiver2->Receive(isac_receive_parameters).ok());
670 EXPECT_TRUE(video_receiver2->Receive(vp9_receive_parameters).ok());
671 EXPECT_TRUE(audio_sender1->Send(opus_send_parameters).ok());
672 EXPECT_TRUE(video_sender1->Send(vp8_send_parameters).ok());
673 EXPECT_TRUE(audio_sender2->Send(isac_send_parameters).ok());
674 EXPECT_TRUE(video_sender2->Send(vp9_send_parameters).ok());
675
676 FakeVideoTrackRenderer fake_video_renderer1(
677 static_cast<VideoTrackInterface*>(video_receiver1->GetTrack().get()));
678 FakeVideoTrackRenderer fake_video_renderer2(
679 static_cast<VideoTrackInterface*>(video_receiver2->GetTrack().get()));
680
681 // Senders and receivers are connected and configured; audio and video frames
682 // should be able to flow at this point.
683 EXPECT_TRUE_WAIT(
684 fake_audio_capture_module1_->frames_received() > kDefaultNumFrames &&
685 fake_video_renderer1.num_rendered_frames() > kDefaultNumFrames &&
686 fake_audio_capture_module2_->frames_received() > kDefaultNumFrames &&
687 fake_video_renderer2.num_rendered_frames() > kDefaultNumFrames,
688 kDefaultTimeout);
689}
690
691// TODO(deadbeef): End-to-end test for multiple senders/receivers of the same
692// media type, once that's supported. Currently, it is not because the
693// BaseChannel model relies on there being a single VoiceChannel and
694// VideoChannel, and these only support a single set of codecs/etc. per
695// send/receive direction.
696
697// TODO(deadbeef): End-to-end test for simulcast, once that's supported by this
698// API.
699
zhihuangacfb0172017-03-28 20:45:18700#endif // if !defined(THREAD_SANITIZER)
701
deadbeefe814a0d2017-02-26 02:15:09702} // namespace webrtc