Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(262)

Unified Diff: webrtc/ortc/ortcfactory_integrationtest.cc

Issue 2675173003: Adding "adapter" ORTC objects on top of ChannelManager/BaseChannel/etc. (Closed)
Patch Set: Add memcheck suppression for end-to-end tests. Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webrtc/ortc/ortcfactory.cc ('k') | webrtc/ortc/ortcfactory_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webrtc/ortc/ortcfactory_integrationtest.cc
diff --git a/webrtc/ortc/ortcfactory_integrationtest.cc b/webrtc/ortc/ortcfactory_integrationtest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..e935f068a319caebdedd47a2e50056363d1344ed
--- /dev/null
+++ b/webrtc/ortc/ortcfactory_integrationtest.cc
@@ -0,0 +1,512 @@
+/*
+ * Copyright 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include <memory>
+#include <utility> // For std::pair, std::move.
+
+#include "webrtc/api/ortc/ortcfactoryinterface.h"
+#include "webrtc/base/criticalsection.h"
+#include "webrtc/base/fakenetwork.h"
+#include "webrtc/base/gunit.h"
+#include "webrtc/base/physicalsocketserver.h"
+#include "webrtc/base/virtualsocketserver.h"
+#include "webrtc/ortc/testrtpparameters.h"
+#include "webrtc/p2p/base/udptransport.h"
+#include "webrtc/pc/test/fakeaudiocapturemodule.h"
+#include "webrtc/pc/test/fakeperiodicvideocapturer.h"
+#include "webrtc/pc/test/fakevideotrackrenderer.h"
+
+namespace {
+
+const int kDefaultTimeout = 10000; // 10 seconds.
+// Default number of audio/video frames to wait for before considering a test a
+// success.
+const int kDefaultNumFrames = 3;
+const rtc::IPAddress kIPv4LocalHostAddress =
+ rtc::IPAddress(0x7F000001); // 127.0.0.1
+
+} // namespace
+
+namespace webrtc {
+
+// Used to test that things work end-to-end when using the default
+// implementations of threads/etc. provided by OrtcFactory, with the exception
+// of using a virtual network.
+//
+// By default, the virtual network manager doesn't enumerate any networks, but
+// sockets can still be created in this state.
+class OrtcFactoryIntegrationTest : public testing::Test {
+ public:
+ OrtcFactoryIntegrationTest()
+ : virtual_socket_server_(&physical_socket_server_),
+ network_thread_(&virtual_socket_server_),
+ fake_audio_capture_module1_(FakeAudioCaptureModule::Create()),
+ fake_audio_capture_module2_(FakeAudioCaptureModule::Create()) {
+ // Sockets are bound to the ANY address, so this is needed to tell the
+ // virtual network which address to use in this case.
+ virtual_socket_server_.SetDefaultRoute(kIPv4LocalHostAddress);
+ network_thread_.Start();
+ // Need to create after network thread is started.
+ ortc_factory1_ = OrtcFactoryInterface::Create(
+ &network_thread_, nullptr, &fake_network_manager_,
+ nullptr, fake_audio_capture_module1_)
+ .MoveValue();
+ ortc_factory2_ = OrtcFactoryInterface::Create(
+ &network_thread_, nullptr, &fake_network_manager_,
+ nullptr, fake_audio_capture_module2_)
+ .MoveValue();
+ }
+
+ protected:
+ typedef std::pair<std::unique_ptr<UdpTransportInterface>,
+ std::unique_ptr<UdpTransportInterface>>
+ UdpTransportPair;
+ typedef std::pair<std::unique_ptr<RtpTransportInterface>,
+ std::unique_ptr<RtpTransportInterface>>
+ RtpTransportPair;
+ typedef std::pair<std::unique_ptr<RtpTransportControllerInterface>,
+ std::unique_ptr<RtpTransportControllerInterface>>
+ RtpTransportControllerPair;
+
+ // Helper function that creates one UDP transport each for |ortc_factory1_|
+ // and |ortc_factory2_|, and connects them.
+ UdpTransportPair CreateAndConnectUdpTransportPair() {
+ auto transport1 = ortc_factory1_->CreateUdpTransport(AF_INET).MoveValue();
+ auto transport2 = ortc_factory2_->CreateUdpTransport(AF_INET).MoveValue();
+ transport1->SetRemoteAddress(
+ rtc::SocketAddress(virtual_socket_server_.GetDefaultRoute(AF_INET),
+ transport2->GetLocalAddress().port()));
+ transport2->SetRemoteAddress(
+ rtc::SocketAddress(virtual_socket_server_.GetDefaultRoute(AF_INET),
+ transport1->GetLocalAddress().port()));
+ return {std::move(transport1), std::move(transport2)};
+ }
+
+ // Creates one transport controller each for |ortc_factory1_| and
+ // |ortc_factory2_|.
+ RtpTransportControllerPair CreateRtpTransportControllerPair() {
+ return {ortc_factory1_->CreateRtpTransportController().MoveValue(),
+ ortc_factory2_->CreateRtpTransportController().MoveValue()};
+ }
+
+ // Helper function that creates a pair of RtpTransports between
+ // |ortc_factory1_| and |ortc_factory2_|. Expected to be called with the
+ // result of CreateAndConnectUdpTransportPair. |rtcp_udp_transports| can be
+ // empty if RTCP muxing is used. |transport_controllers| can be empty if
+ // these transports are being created using a default transport controller.
+ RtpTransportPair CreateRtpTransportPair(
+ const RtcpParameters& rtcp_parameters,
+ const UdpTransportPair& rtp_udp_transports,
+ const UdpTransportPair& rtcp_udp_transports,
+ const RtpTransportControllerPair& transport_controllers) {
+ auto transport_result1 = ortc_factory1_->CreateRtpTransport(
+ rtcp_parameters, rtp_udp_transports.first.get(),
+ rtcp_udp_transports.first.get(), transport_controllers.first.get());
+ auto transport_result2 = ortc_factory2_->CreateRtpTransport(
+ rtcp_parameters, rtp_udp_transports.second.get(),
+ rtcp_udp_transports.second.get(), transport_controllers.second.get());
+ return {transport_result1.MoveValue(), transport_result2.MoveValue()};
+ }
+
+ // For convenience when |rtcp_udp_transports| and |transport_controllers|
+ // aren't needed.
+ RtpTransportPair CreateRtpTransportPair(
+ const RtcpParameters& rtcp_parameters,
+ const UdpTransportPair& rtp_udp_transports) {
+ return CreateRtpTransportPair(rtcp_parameters, rtp_udp_transports,
+ UdpTransportPair(),
+ RtpTransportControllerPair());
+ }
+
+ // Ends up using fake audio capture module, which was passed into OrtcFactory
+ // on creation.
+ rtc::scoped_refptr<webrtc::AudioTrackInterface> CreateLocalAudioTrack(
+ const std::string& id,
+ OrtcFactoryInterface* ortc_factory) {
+ // Disable echo cancellation to make test more efficient.
+ cricket::AudioOptions options;
+ options.echo_cancellation.emplace(true);
+ rtc::scoped_refptr<webrtc::AudioSourceInterface> source =
+ ortc_factory->CreateAudioSource(options);
+ return ortc_factory->CreateAudioTrack(id, source);
+ }
+
+ // Stores created capturer in |fake_video_capturers_|.
+ rtc::scoped_refptr<webrtc::VideoTrackInterface>
+ CreateLocalVideoTrackAndFakeCapturer(const std::string& id,
+ OrtcFactoryInterface* ortc_factory) {
+ cricket::FakeVideoCapturer* fake_capturer =
+ new webrtc::FakePeriodicVideoCapturer();
+ fake_video_capturers_.push_back(fake_capturer);
+ rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> source =
+ ortc_factory->CreateVideoSource(
+ std::unique_ptr<cricket::VideoCapturer>(fake_capturer));
+ return rtc::scoped_refptr<webrtc::VideoTrackInterface>(
+ ortc_factory->CreateVideoTrack(id, source));
+ }
+
+ rtc::PhysicalSocketServer physical_socket_server_;
+ rtc::VirtualSocketServer virtual_socket_server_;
+ rtc::Thread network_thread_;
+ rtc::FakeNetworkManager fake_network_manager_;
+ rtc::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module1_;
+ rtc::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module2_;
+ std::unique_ptr<OrtcFactoryInterface> ortc_factory1_;
+ std::unique_ptr<OrtcFactoryInterface> ortc_factory2_;
+ // Actually owned by video tracks.
+ std::vector<cricket::FakeVideoCapturer*> fake_video_capturers_;
+};
+
+// Very basic end-to-end test with a single pair of audio RTP sender and
+// receiver.
+//
+// Uses muxed RTCP, and minimal parameters with a hard-coded config that's
+// known to work.
+TEST_F(OrtcFactoryIntegrationTest, BasicOneWayAudioRtpSenderAndReceiver) {
+ auto udp_transports = CreateAndConnectUdpTransportPair();
+ auto rtp_transports =
+ CreateRtpTransportPair(MakeRtcpMuxParameters(), udp_transports);
+
+ auto sender_result = ortc_factory1_->CreateRtpSender(
+ cricket::MEDIA_TYPE_AUDIO, rtp_transports.first.get());
+ auto receiver_result = ortc_factory2_->CreateRtpReceiver(
+ cricket::MEDIA_TYPE_AUDIO, rtp_transports.second.get());
+ ASSERT_TRUE(sender_result.ok());
+ ASSERT_TRUE(receiver_result.ok());
+ auto sender = sender_result.MoveValue();
+ auto receiver = receiver_result.MoveValue();
+
+ RTCError error =
+ sender->SetTrack(CreateLocalAudioTrack("audio", ortc_factory1_.get()));
+ EXPECT_TRUE(error.ok());
+
+ RtpParameters opus_parameters = MakeMinimalOpusParameters();
+ EXPECT_TRUE(receiver->Receive(opus_parameters).ok());
+ EXPECT_TRUE(sender->Send(opus_parameters).ok());
+ // Sender and receiver are connected and configured; audio frames should be
+ // able to flow at this point.
+ EXPECT_TRUE_WAIT(
+ fake_audio_capture_module2_->frames_received() > kDefaultNumFrames,
+ kDefaultTimeout);
+}
+
+// Very basic end-to-end test with a single pair of video RTP sender and
+// receiver.
+//
+// Uses muxed RTCP, and minimal parameters with a hard-coded config that's
+// known to work.
+TEST_F(OrtcFactoryIntegrationTest, BasicOneWayVideoRtpSenderAndReceiver) {
+ auto udp_transports = CreateAndConnectUdpTransportPair();
+ auto rtp_transports =
+ CreateRtpTransportPair(MakeRtcpMuxParameters(), udp_transports);
+
+ auto sender_result = ortc_factory1_->CreateRtpSender(
+ cricket::MEDIA_TYPE_VIDEO, rtp_transports.first.get());
+ auto receiver_result = ortc_factory2_->CreateRtpReceiver(
+ cricket::MEDIA_TYPE_VIDEO, rtp_transports.second.get());
+ ASSERT_TRUE(sender_result.ok());
+ ASSERT_TRUE(receiver_result.ok());
+ auto sender = sender_result.MoveValue();
+ auto receiver = receiver_result.MoveValue();
+
+ RTCError error = sender->SetTrack(
+ CreateLocalVideoTrackAndFakeCapturer("video", ortc_factory1_.get()));
+ EXPECT_TRUE(error.ok());
+
+ RtpParameters vp8_parameters = MakeMinimalVp8Parameters();
+ EXPECT_TRUE(receiver->Receive(vp8_parameters).ok());
+ EXPECT_TRUE(sender->Send(vp8_parameters).ok());
+ FakeVideoTrackRenderer fake_renderer(
+ static_cast<VideoTrackInterface*>(receiver->GetTrack().get()));
+ // Sender and receiver are connected and configured; video frames should be
+ // able to flow at this point.
+ EXPECT_TRUE_WAIT(fake_renderer.num_rendered_frames() > kDefaultNumFrames,
+ kDefaultTimeout);
+}
+
+// Test that if the track is changed while sending, the sender seamlessly
+// transitions to sending it and frames are received end-to-end.
+//
+// Only doing this for video, since given that audio is sourced from a single
+// fake audio capture module, the audio track is just a dummy object.
+// TODO(deadbeef): Change this when possible.
+TEST_F(OrtcFactoryIntegrationTest, SetTrackWhileSending) {
+ auto udp_transports = CreateAndConnectUdpTransportPair();
+ auto rtp_transports =
+ CreateRtpTransportPair(MakeRtcpMuxParameters(), udp_transports);
+
+ auto sender_result = ortc_factory1_->CreateRtpSender(
+ cricket::MEDIA_TYPE_VIDEO, rtp_transports.first.get());
+ auto receiver_result = ortc_factory2_->CreateRtpReceiver(
+ cricket::MEDIA_TYPE_VIDEO, rtp_transports.second.get());
+ ASSERT_TRUE(sender_result.ok());
+ ASSERT_TRUE(receiver_result.ok());
+ auto sender = sender_result.MoveValue();
+ auto receiver = receiver_result.MoveValue();
+
+ RTCError error = sender->SetTrack(
+ CreateLocalVideoTrackAndFakeCapturer("video_1", ortc_factory1_.get()));
+ EXPECT_TRUE(error.ok());
+ RtpParameters vp8_parameters = MakeMinimalVp8Parameters();
+ EXPECT_TRUE(receiver->Receive(vp8_parameters).ok());
+ EXPECT_TRUE(sender->Send(vp8_parameters).ok());
+ FakeVideoTrackRenderer fake_renderer(
+ static_cast<VideoTrackInterface*>(receiver->GetTrack().get()));
+ // Expect for some initial number of frames to be received.
+ EXPECT_TRUE_WAIT(fake_renderer.num_rendered_frames() > kDefaultNumFrames,
+ kDefaultTimeout);
+ // Stop the old capturer, set a new track, and verify new frames are received
+ // from the new track. Stopping the old capturer ensures that we aren't
+ // actually still getting frames from it.
+ fake_video_capturers_[0]->Stop();
+ int prev_num_frames = fake_renderer.num_rendered_frames();
+ error = sender->SetTrack(
+ CreateLocalVideoTrackAndFakeCapturer("video_2", ortc_factory1_.get()));
+ EXPECT_TRUE(error.ok());
+ EXPECT_TRUE_WAIT(
+ fake_renderer.num_rendered_frames() > kDefaultNumFrames + prev_num_frames,
+ kDefaultTimeout);
+}
+
+// End-to-end test with two pairs of RTP senders and receivers, for audio and
+// video.
+//
+// Uses muxed RTCP, and minimal parameters with hard-coded configs that are
+// known to work.
+TEST_F(OrtcFactoryIntegrationTest,
+ BasicTwoWayAudioVideoRtpSendersAndReceivers) {
+ auto udp_transports = CreateAndConnectUdpTransportPair();
+ auto rtp_transports =
+ CreateRtpTransportPair(MakeRtcpMuxParameters(), udp_transports);
+
+ // Create all the senders and receivers (four per endpoint).
+ auto audio_sender_result1 = ortc_factory1_->CreateRtpSender(
+ cricket::MEDIA_TYPE_AUDIO, rtp_transports.first.get());
+ auto video_sender_result1 = ortc_factory1_->CreateRtpSender(
+ cricket::MEDIA_TYPE_VIDEO, rtp_transports.first.get());
+ auto audio_receiver_result1 = ortc_factory1_->CreateRtpReceiver(
+ cricket::MEDIA_TYPE_AUDIO, rtp_transports.first.get());
+ auto video_receiver_result1 = ortc_factory1_->CreateRtpReceiver(
+ cricket::MEDIA_TYPE_VIDEO, rtp_transports.first.get());
+ ASSERT_TRUE(audio_sender_result1.ok());
+ ASSERT_TRUE(video_sender_result1.ok());
+ ASSERT_TRUE(audio_receiver_result1.ok());
+ ASSERT_TRUE(video_receiver_result1.ok());
+ auto audio_sender1 = audio_sender_result1.MoveValue();
+ auto video_sender1 = video_sender_result1.MoveValue();
+ auto audio_receiver1 = audio_receiver_result1.MoveValue();
+ auto video_receiver1 = video_receiver_result1.MoveValue();
+
+ auto audio_sender_result2 = ortc_factory2_->CreateRtpSender(
+ cricket::MEDIA_TYPE_AUDIO, rtp_transports.second.get());
+ auto video_sender_result2 = ortc_factory2_->CreateRtpSender(
+ cricket::MEDIA_TYPE_VIDEO, rtp_transports.second.get());
+ auto audio_receiver_result2 = ortc_factory2_->CreateRtpReceiver(
+ cricket::MEDIA_TYPE_AUDIO, rtp_transports.second.get());
+ auto video_receiver_result2 = ortc_factory2_->CreateRtpReceiver(
+ cricket::MEDIA_TYPE_VIDEO, rtp_transports.second.get());
+ ASSERT_TRUE(audio_sender_result2.ok());
+ ASSERT_TRUE(video_sender_result2.ok());
+ ASSERT_TRUE(audio_receiver_result2.ok());
+ ASSERT_TRUE(video_receiver_result2.ok());
+ auto audio_sender2 = audio_sender_result2.MoveValue();
+ auto video_sender2 = video_sender_result2.MoveValue();
+ auto audio_receiver2 = audio_receiver_result2.MoveValue();
+ auto video_receiver2 = video_receiver_result2.MoveValue();
+
+ // Add fake tracks.
+ RTCError error = audio_sender1->SetTrack(
+ CreateLocalAudioTrack("audio", ortc_factory1_.get()));
+ EXPECT_TRUE(error.ok());
+ error = video_sender1->SetTrack(
+ CreateLocalVideoTrackAndFakeCapturer("video", ortc_factory1_.get()));
+ EXPECT_TRUE(error.ok());
+ error = audio_sender2->SetTrack(
+ CreateLocalAudioTrack("audio", ortc_factory2_.get()));
+ EXPECT_TRUE(error.ok());
+ error = video_sender2->SetTrack(
+ CreateLocalVideoTrackAndFakeCapturer("video", ortc_factory2_.get()));
+ EXPECT_TRUE(error.ok());
+
+ // "sent_X_parameters1" are the parameters that endpoint 1 sends with and
+ // endpoint 2 receives with.
+ RtpParameters sent_opus_parameters1 =
+ MakeMinimalOpusParametersWithSsrc(0xdeadbeef);
+ RtpParameters sent_vp8_parameters1 =
+ MakeMinimalVp8ParametersWithSsrc(0xbaadfeed);
+ RtpParameters sent_opus_parameters2 =
+ MakeMinimalOpusParametersWithSsrc(0x13333337);
+ RtpParameters sent_vp8_parameters2 =
+ MakeMinimalVp8ParametersWithSsrc(0x12345678);
+
+ // Configure the senders' and receivers' parameters.
+ EXPECT_TRUE(audio_receiver1->Receive(sent_opus_parameters2).ok());
+ EXPECT_TRUE(video_receiver1->Receive(sent_vp8_parameters2).ok());
+ EXPECT_TRUE(audio_receiver2->Receive(sent_opus_parameters1).ok());
+ EXPECT_TRUE(video_receiver2->Receive(sent_vp8_parameters1).ok());
+ EXPECT_TRUE(audio_sender1->Send(sent_opus_parameters1).ok());
+ EXPECT_TRUE(video_sender1->Send(sent_vp8_parameters1).ok());
+ EXPECT_TRUE(audio_sender2->Send(sent_opus_parameters2).ok());
+ EXPECT_TRUE(video_sender2->Send(sent_vp8_parameters2).ok());
+
+ FakeVideoTrackRenderer fake_video_renderer1(
+ static_cast<VideoTrackInterface*>(video_receiver1->GetTrack().get()));
+ FakeVideoTrackRenderer fake_video_renderer2(
+ static_cast<VideoTrackInterface*>(video_receiver2->GetTrack().get()));
+
+ // Senders and receivers are connected and configured; audio and video frames
+ // should be able to flow at this point.
+ EXPECT_TRUE_WAIT(
+ fake_audio_capture_module1_->frames_received() > kDefaultNumFrames &&
+ fake_video_renderer1.num_rendered_frames() > kDefaultNumFrames &&
+ fake_audio_capture_module2_->frames_received() > kDefaultNumFrames &&
+ fake_video_renderer2.num_rendered_frames() > kDefaultNumFrames,
+ kDefaultTimeout);
+}
+
+// End-to-end test with two pairs of RTP senders and receivers, for audio and
+// video. Unlike the test above, this attempts to make the parameters as
+// complex as possible.
+//
+// Uses non-muxed RTCP, with separate audio/video transports, and a full set of
+// parameters, as would normally be used in a PeerConnection.
+//
+// TODO(deadbeef): Update this test as more audio/video features become
+// supported.
+TEST_F(OrtcFactoryIntegrationTest, FullTwoWayAudioVideoRtpSendersAndReceivers) {
+ // We want four pairs of UDP transports for this test, for audio/video and
+ // RTP/RTCP.
+ auto audio_rtp_udp_transports = CreateAndConnectUdpTransportPair();
+ auto audio_rtcp_udp_transports = CreateAndConnectUdpTransportPair();
+ auto video_rtp_udp_transports = CreateAndConnectUdpTransportPair();
+ auto video_rtcp_udp_transports = CreateAndConnectUdpTransportPair();
+
+ // Since we have multiple RTP transports on each side, we need an RTP
+ // transport controller.
+ auto transport_controllers = CreateRtpTransportControllerPair();
+
+ RtcpParameters audio_rtcp_parameters;
+ audio_rtcp_parameters.mux = false;
+ auto audio_rtp_transports =
+ CreateRtpTransportPair(audio_rtcp_parameters, audio_rtp_udp_transports,
+ audio_rtcp_udp_transports, transport_controllers);
+
+ RtcpParameters video_rtcp_parameters;
+ video_rtcp_parameters.mux = false;
+ video_rtcp_parameters.reduced_size = true;
+ auto video_rtp_transports =
+ CreateRtpTransportPair(video_rtcp_parameters, video_rtp_udp_transports,
+ video_rtcp_udp_transports, transport_controllers);
+
+ // Create all the senders and receivers (four per endpoint).
+ auto audio_sender_result1 = ortc_factory1_->CreateRtpSender(
+ cricket::MEDIA_TYPE_AUDIO, audio_rtp_transports.first.get());
+ auto video_sender_result1 = ortc_factory1_->CreateRtpSender(
+ cricket::MEDIA_TYPE_VIDEO, video_rtp_transports.first.get());
+ auto audio_receiver_result1 = ortc_factory1_->CreateRtpReceiver(
+ cricket::MEDIA_TYPE_AUDIO, audio_rtp_transports.first.get());
+ auto video_receiver_result1 = ortc_factory1_->CreateRtpReceiver(
+ cricket::MEDIA_TYPE_VIDEO, video_rtp_transports.first.get());
+ ASSERT_TRUE(audio_sender_result1.ok());
+ ASSERT_TRUE(video_sender_result1.ok());
+ ASSERT_TRUE(audio_receiver_result1.ok());
+ ASSERT_TRUE(video_receiver_result1.ok());
+ auto audio_sender1 = audio_sender_result1.MoveValue();
+ auto video_sender1 = video_sender_result1.MoveValue();
+ auto audio_receiver1 = audio_receiver_result1.MoveValue();
+ auto video_receiver1 = video_receiver_result1.MoveValue();
+
+ auto audio_sender_result2 = ortc_factory2_->CreateRtpSender(
+ cricket::MEDIA_TYPE_AUDIO, audio_rtp_transports.second.get());
+ auto video_sender_result2 = ortc_factory2_->CreateRtpSender(
+ cricket::MEDIA_TYPE_VIDEO, video_rtp_transports.second.get());
+ auto audio_receiver_result2 = ortc_factory2_->CreateRtpReceiver(
+ cricket::MEDIA_TYPE_AUDIO, audio_rtp_transports.second.get());
+ auto video_receiver_result2 = ortc_factory2_->CreateRtpReceiver(
+ cricket::MEDIA_TYPE_VIDEO, video_rtp_transports.second.get());
+ ASSERT_TRUE(audio_sender_result2.ok());
+ ASSERT_TRUE(video_sender_result2.ok());
+ ASSERT_TRUE(audio_receiver_result2.ok());
+ ASSERT_TRUE(video_receiver_result2.ok());
+ auto audio_sender2 = audio_sender_result2.MoveValue();
+ auto video_sender2 = video_sender_result2.MoveValue();
+ auto audio_receiver2 = audio_receiver_result2.MoveValue();
+ auto video_receiver2 = video_receiver_result2.MoveValue();
+
+ RTCError error = audio_sender1->SetTrack(
+ CreateLocalAudioTrack("audio", ortc_factory1_.get()));
+ EXPECT_TRUE(error.ok());
+ error = video_sender1->SetTrack(
+ CreateLocalVideoTrackAndFakeCapturer("video", ortc_factory1_.get()));
+ EXPECT_TRUE(error.ok());
+ error = audio_sender2->SetTrack(
+ CreateLocalAudioTrack("audio", ortc_factory2_.get()));
+ EXPECT_TRUE(error.ok());
+ error = video_sender2->SetTrack(
+ CreateLocalVideoTrackAndFakeCapturer("video", ortc_factory2_.get()));
+ EXPECT_TRUE(error.ok());
+
+ // Use different codecs in different directions for extra challenge.
+ RtpParameters opus_send_parameters = MakeFullOpusParameters();
+ RtpParameters isac_send_parameters = MakeFullIsacParameters();
+ RtpParameters vp8_send_parameters = MakeFullVp8Parameters();
+ RtpParameters vp9_send_parameters = MakeFullVp9Parameters();
+
+ // Remove "payload_type" from receive parameters. Receiver will need to
+ // discern the payload type from packets received.
+ RtpParameters opus_receive_parameters = opus_send_parameters;
+ RtpParameters isac_receive_parameters = isac_send_parameters;
+ RtpParameters vp8_receive_parameters = vp8_send_parameters;
+ RtpParameters vp9_receive_parameters = vp9_send_parameters;
+ opus_receive_parameters.encodings[0].codec_payload_type.reset();
+ isac_receive_parameters.encodings[0].codec_payload_type.reset();
+ vp8_receive_parameters.encodings[0].codec_payload_type.reset();
+ vp9_receive_parameters.encodings[0].codec_payload_type.reset();
+
+ // Configure the senders' and receivers' parameters.
+ //
+ // Note: Intentionally, the top codec in the receive parameters does not
+ // match the codec sent by the other side. If "Receive" is called with a list
+ // of codecs, the receiver should be prepared to receive any of them, not
+ // just the one on top.
+ EXPECT_TRUE(audio_receiver1->Receive(opus_receive_parameters).ok());
+ EXPECT_TRUE(video_receiver1->Receive(vp8_receive_parameters).ok());
+ EXPECT_TRUE(audio_receiver2->Receive(isac_receive_parameters).ok());
+ EXPECT_TRUE(video_receiver2->Receive(vp9_receive_parameters).ok());
+ EXPECT_TRUE(audio_sender1->Send(opus_send_parameters).ok());
+ EXPECT_TRUE(video_sender1->Send(vp8_send_parameters).ok());
+ EXPECT_TRUE(audio_sender2->Send(isac_send_parameters).ok());
+ EXPECT_TRUE(video_sender2->Send(vp9_send_parameters).ok());
+
+ FakeVideoTrackRenderer fake_video_renderer1(
+ static_cast<VideoTrackInterface*>(video_receiver1->GetTrack().get()));
+ FakeVideoTrackRenderer fake_video_renderer2(
+ static_cast<VideoTrackInterface*>(video_receiver2->GetTrack().get()));
+
+ // Senders and receivers are connected and configured; audio and video frames
+ // should be able to flow at this point.
+ EXPECT_TRUE_WAIT(
+ fake_audio_capture_module1_->frames_received() > kDefaultNumFrames &&
+ fake_video_renderer1.num_rendered_frames() > kDefaultNumFrames &&
+ fake_audio_capture_module2_->frames_received() > kDefaultNumFrames &&
+ fake_video_renderer2.num_rendered_frames() > kDefaultNumFrames,
+ kDefaultTimeout);
+}
+
+// TODO(deadbeef): End-to-end test for multiple senders/receivers of the same
+// media type, once that's supported. Currently, it is not because the
+// BaseChannel model relies on there being a single VoiceChannel and
+// VideoChannel, and these only support a single set of codecs/etc. per
+// send/receive direction.
+
+// TODO(deadbeef): End-to-end test for simulcast, once that's supported by this
+// API.
+
+} // namespace webrtc
« no previous file with comments | « webrtc/ortc/ortcfactory.cc ('k') | webrtc/ortc/ortcfactory_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698