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

Unified Diff: webrtc/ortc/ortcfactory_integrationtest.cc

Issue 2675173003: Adding "adapter" ORTC objects on top of ChannelManager/BaseChannel/etc. (Closed)
Patch Set: Some comments. 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
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..b2461cb40b14b6f887fdcd2cddeeec6f7fd1804d
--- /dev/null
+++ b/webrtc/ortc/ortcfactory_integrationtest.cc
@@ -0,0 +1,298 @@
+/*
+ * 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 "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/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.
pthatcher1 2017/02/10 22:41:13 Any particular reason?
Taylor Brandstetter 2017/02/14 06:55:05 It's just what we've been generally using.
+static const rtc::IPAddress kIPv4LocalHostAddress =
+ rtc::IPAddress(0x7F000001); // 127.0.0.1
+
+class PacketReceiver : public sigslot::has_slots<> {
+ public:
+ explicit PacketReceiver(rtc::PacketTransportInternal* transport) {
+ transport->SignalReadPacket.connect(this, &PacketReceiver::OnReadPacket);
+ }
+ int packets_read() const {
pthatcher1 2017/02/10 22:41:13 I think I would call this something like count_rec
Taylor Brandstetter 2017/02/14 06:55:05 The signal is named "OnReadPacket", and it's used
+ rtc::CritScope cs(&critsec_);
+ return packets_read_;
+ }
+
+ private:
+ void OnReadPacket(rtc::PacketTransportInternal*,
+ const char*,
+ size_t,
+ const rtc::PacketTime&,
+ int) {
+ rtc::CritScope cs(&critsec_);
+ ++packets_read_;
+ }
+
+ int packets_read_ = 0;
+ rtc::CriticalSection critsec_;
+};
+
+} // 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 OrtcFactoryTest : public testing::Test {
+ public:
+ OrtcFactoryTest()
+ : 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_)
+ .ConsumeValue();
+ ortc_factory2_ = OrtcFactoryInterface::Create(
+ &network_thread_, nullptr, &fake_network_manager_,
+ nullptr, fake_audio_capture_module2_)
+ .ConsumeValue();
+ }
+
+ protected:
+ // 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_;
+};
+
+TEST_F(OrtcFactoryTest, EndToEndUdpTransport) {
+ std::unique_ptr<UdpTransportInterface> transport1 =
+ ortc_factory1_->CreateUdpTransport(AF_INET).ConsumeValue();
+ std::unique_ptr<UdpTransportInterface> transport2 =
+ ortc_factory2_->CreateUdpTransport(AF_INET).ConsumeValue();
+ // Sockets are bound to the ANY address, so we need to provide the IP address
+ // explicitly.
+ 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()));
+
+ // TODO(deadbeef): Once there's something (RTP senders/receivers) that can
+ // use UdpTransport end-to-end, use that for this end-to-end test instead of
+ // making assumptions about the implementation.
+ //
+ // For now, this assumes the returned object is a UdpTransportProxy that wraps
+ // a UdpTransport.
+ cricket::UdpTransport* internal_transport1 =
+ static_cast<cricket::UdpTransport*>(transport1->GetInternal());
+ cricket::UdpTransport* internal_transport2 =
+ static_cast<cricket::UdpTransport*>(transport2->GetInternal());
+ PacketReceiver receiver1(internal_transport1);
+ PacketReceiver receiver2(internal_transport2);
+ // Need to call internal "SendPacket" method on network thread.
+ network_thread_.Invoke<void>(
+ RTC_FROM_HERE, [internal_transport1, internal_transport2]() {
+ internal_transport1->SendPacket("foo", sizeof("foo"),
+ rtc::PacketOptions(), 0);
+ internal_transport2->SendPacket("foo", sizeof("foo"),
+ rtc::PacketOptions(), 0);
pthatcher1 2017/02/10 22:41:13 Just to be safe, you might want to make them send
Taylor Brandstetter 2017/02/14 06:55:05 Done.
+ });
+ EXPECT_EQ_WAIT(1, receiver1.packets_read(), kDefaultTimeout);
+ EXPECT_EQ_WAIT(1, receiver2.packets_read(), kDefaultTimeout);
+}
+
+// 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(OrtcFactoryTest, UnidirectionalAudioRtpSenderAndReceiver) {
+ // Start by creating underlying UDP transports.
+ std::unique_ptr<UdpTransportInterface> sender_udp_transport =
+ ortc_factory1_->CreateUdpTransport(AF_INET).ConsumeValue();
+ std::unique_ptr<UdpTransportInterface> receiver_udp_transport =
+ ortc_factory2_->CreateUdpTransport(AF_INET).ConsumeValue();
+ // Sockets are bound to the ANY address, so we need to provide the IP address
+ // explicitly.
+ sender_udp_transport->SetRemoteAddress(
+ rtc::SocketAddress(virtual_socket_server_.GetDefaultRoute(AF_INET),
+ receiver_udp_transport->GetLocalAddress().port()));
+ receiver_udp_transport->SetRemoteAddress(
+ rtc::SocketAddress(virtual_socket_server_.GetDefaultRoute(AF_INET),
+ sender_udp_transport->GetLocalAddress().port()));
+
+ // Create RTP transports.
+ RtcpParameters rtcp_parameters;
+ rtcp_parameters.mux = true;
+ std::unique_ptr<RtpTransportInterface> sender_rtp_transport =
+ ortc_factory1_
+ ->CreateRtpTransport(rtcp_parameters, sender_udp_transport.get(),
+ nullptr, nullptr)
+ .ConsumeValue();
+ std::unique_ptr<RtpTransportInterface> receiver_rtp_transport =
+ ortc_factory2_
+ ->CreateRtpTransport(rtcp_parameters, receiver_udp_transport.get(),
+ nullptr, nullptr)
+ .ConsumeValue();
+
+ RtpParameters parameters;
+ RtpCodecParameters opus_codec;
+ opus_codec.name = "opus";
+ opus_codec.kind = cricket::MEDIA_TYPE_AUDIO;
+ opus_codec.payload_type = 111;
+ opus_codec.clock_rate.emplace(48000);
+ opus_codec.num_channels.emplace(2);
+ parameters.codecs.push_back(std::move(opus_codec));
+ RtpEncodingParameters encoding;
+ encoding.ssrc.emplace(0xdeadbeef);
pthatcher1 2017/02/10 22:41:13 :)
+ encoding.codec_payload_type.emplace(111);
+ parameters.encodings.push_back(std::move(encoding));
+
+ auto sender_result = ortc_factory1_->CreateRtpSender(
+ cricket::MEDIA_TYPE_AUDIO, sender_rtp_transport.get());
+ auto receiver_result = ortc_factory2_->CreateRtpReceiver(
+ cricket::MEDIA_TYPE_AUDIO, receiver_rtp_transport.get());
+ ASSERT_TRUE(sender_result.ok());
+ ASSERT_TRUE(receiver_result.ok());
+
+ auto sender = sender_result.ConsumeValue();
+ auto receiver = receiver_result.ConsumeValue();
+ EXPECT_TRUE(receiver->Receive(parameters).ok());
+ EXPECT_TRUE(
+ sender->SetTrack(CreateLocalAudioTrack("audio", ortc_factory1_.get()))
+ .ok());
+ EXPECT_TRUE(sender->Send(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() > 10,
+ 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(OrtcFactoryTest, UnidirectionalVideoRtpSenderAndReceiver) {
+ // Start by creating underlying UDP transports.
+ std::unique_ptr<UdpTransportInterface> sender_udp_transport =
+ ortc_factory1_->CreateUdpTransport(AF_INET).ConsumeValue();
+ std::unique_ptr<UdpTransportInterface> receiver_udp_transport =
+ ortc_factory2_->CreateUdpTransport(AF_INET).ConsumeValue();
+ // Sockets are bound to the ANY address, so we need to provide the IP address
+ // explicitly.
+ sender_udp_transport->SetRemoteAddress(
+ rtc::SocketAddress(virtual_socket_server_.GetDefaultRoute(AF_INET),
+ receiver_udp_transport->GetLocalAddress().port()));
+ receiver_udp_transport->SetRemoteAddress(
+ rtc::SocketAddress(virtual_socket_server_.GetDefaultRoute(AF_INET),
+ sender_udp_transport->GetLocalAddress().port()));
+
+ // Create RTP transports.
+ RtcpParameters rtcp_parameters;
+ rtcp_parameters.mux = true;
+ std::unique_ptr<RtpTransportInterface> sender_rtp_transport =
+ ortc_factory1_
+ ->CreateRtpTransport(rtcp_parameters, sender_udp_transport.get(),
+ nullptr, nullptr)
+ .ConsumeValue();
+ std::unique_ptr<RtpTransportInterface> receiver_rtp_transport =
+ ortc_factory2_
+ ->CreateRtpTransport(rtcp_parameters, receiver_udp_transport.get(),
+ nullptr, nullptr)
+ .ConsumeValue();
+
+ RtpParameters parameters;
+ RtpCodecParameters vp8_codec;
+ vp8_codec.name = "VP8";
+ vp8_codec.kind = cricket::MEDIA_TYPE_VIDEO;
+ vp8_codec.payload_type = 111;
+ parameters.codecs.push_back(std::move(vp8_codec));
+ RtpEncodingParameters encoding;
+ encoding.ssrc.emplace(0xdeadbeef);
+ encoding.codec_payload_type.emplace(111);
+ parameters.encodings.push_back(std::move(encoding));
+
+ auto sender_result = ortc_factory1_->CreateRtpSender(
+ cricket::MEDIA_TYPE_VIDEO, sender_rtp_transport.get());
+ auto receiver_result = ortc_factory2_->CreateRtpReceiver(
+ cricket::MEDIA_TYPE_VIDEO, receiver_rtp_transport.get());
+ ASSERT_TRUE(sender_result.ok());
+ ASSERT_TRUE(receiver_result.ok());
+
+ auto sender = sender_result.ConsumeValue();
+ auto receiver = receiver_result.ConsumeValue();
+ EXPECT_TRUE(receiver->Receive(parameters).ok());
+ FakeVideoTrackRenderer fake_renderer(
+ static_cast<VideoTrackInterface*>(receiver->GetTrack().get()));
+ EXPECT_TRUE(sender
+ ->SetTrack(CreateLocalVideoTrackAndFakeCapturer(
+ "video", ortc_factory1_.get()))
+ .ok());
+ EXPECT_TRUE(sender->Send(parameters).ok());
+ // 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() > 10, kDefaultTimeout);
+}
+
+} // namespace webrtc

Powered by Google App Engine
This is Rietveld 408576698