40b36d15646c46ccc9896c9553a0312360484118
[WebKit-https.git] / Source / WebCore / platform / mediastream / libwebrtc / LibWebRTCProvider.cpp
1 /*
2  * Copyright (C) 2017 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "LibWebRTCProvider.h"
28
29 #if USE(LIBWEBRTC)
30
31 #include "LibWebRTCAudioModule.h"
32 #include <webrtc/api/peerconnectionfactory.h>
33 #include <webrtc/api/peerconnectionfactoryproxy.h>
34 #include <webrtc/base/physicalsocketserver.h>
35 #include <webrtc/p2p/client/basicportallocator.h>
36 #include <webrtc/sdk/objc/Framework/Classes/videotoolboxvideocodecfactory.h>
37 #include <wtf/Function.h>
38 #include <wtf/NeverDestroyed.h>
39
40 namespace WebCore {
41
42 struct PeerConnectionFactoryAndThreads : public rtc::MessageHandler {
43     std::unique_ptr<LibWebRTCAudioModule> audioDeviceModule;
44     std::unique_ptr<rtc::Thread> networkThread;
45     std::unique_ptr<rtc::Thread> signalingThread;
46     rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> factory;
47     bool networkThreadWithSocketServer { false };
48 private:
49     void OnMessage(rtc::Message*);
50 };
51
52 static inline PeerConnectionFactoryAndThreads& staticFactoryAndThreads()
53 {
54     static NeverDestroyed<PeerConnectionFactoryAndThreads> factoryAndThreads;
55     return factoryAndThreads.get();
56 }
57
58 struct ThreadMessageData : public rtc::MessageData {
59     ThreadMessageData(Function<void()>&& callback)
60         : callback(WTFMove(callback))
61     { }
62     Function<void()> callback;
63 };
64
65 void PeerConnectionFactoryAndThreads::OnMessage(rtc::Message* message)
66 {
67     ASSERT(message->message_id == 1);
68     auto* data = static_cast<ThreadMessageData*>(message->pdata);
69     data->callback();
70     delete data;
71 }
72
73 void LibWebRTCProvider::callOnWebRTCNetworkThread(Function<void()>&& callback)
74 {
75     PeerConnectionFactoryAndThreads& threads = staticFactoryAndThreads();
76     threads.networkThread->Post(RTC_FROM_HERE, &threads, 1, new ThreadMessageData(WTFMove(callback)));
77 }
78
79 void LibWebRTCProvider::callOnWebRTCSignalingThread(Function<void()>&& callback)
80 {
81     PeerConnectionFactoryAndThreads& threads = staticFactoryAndThreads();
82     threads.signalingThread->Post(RTC_FROM_HERE, &threads, 1, new ThreadMessageData(WTFMove(callback)));
83 }
84
85 static void initializePeerConnectionFactoryAndThreads()
86 {
87 #if defined(NDEBUG)
88     rtc::LogMessage::LogToDebug(rtc::LS_NONE);
89 #endif
90     auto& factoryAndThreads = staticFactoryAndThreads();
91
92     ASSERT(!factoryAndThreads.factory);
93
94     auto thread = rtc::Thread::Create();
95     factoryAndThreads.networkThread = factoryAndThreads.networkThreadWithSocketServer ? rtc::Thread::CreateWithSocketServer() : rtc::Thread::Create();
96     bool result = factoryAndThreads.networkThread->Start();
97     ASSERT_UNUSED(result, result);
98
99     factoryAndThreads.signalingThread = rtc::Thread::Create();
100     result = factoryAndThreads.signalingThread->Start();
101     ASSERT(result);
102
103     factoryAndThreads.audioDeviceModule = std::make_unique<LibWebRTCAudioModule>();
104
105     factoryAndThreads.factory = webrtc::CreatePeerConnectionFactory(factoryAndThreads.networkThread.get(), factoryAndThreads.networkThread.get(), factoryAndThreads.signalingThread.get(), factoryAndThreads.audioDeviceModule.get(), new webrtc::VideoToolboxVideoEncoderFactory(), new webrtc::VideoToolboxVideoDecoderFactory());
106
107     ASSERT(factoryAndThreads.factory);
108 }
109
110 webrtc::PeerConnectionFactoryInterface& LibWebRTCProvider::factory()
111 {
112     if (!staticFactoryAndThreads().factory)
113         initializePeerConnectionFactoryAndThreads();
114     return *staticFactoryAndThreads().factory;
115 }
116
117 void LibWebRTCProvider::setPeerConnectionFactory(rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface>&& factory)
118 {
119     if (!staticFactoryAndThreads().factory)
120         initializePeerConnectionFactoryAndThreads();
121
122     staticFactoryAndThreads().factory = webrtc::PeerConnectionFactoryProxy::Create(staticFactoryAndThreads().signalingThread.get(), WTFMove(factory));
123 }
124
125 static rtc::scoped_refptr<webrtc::PeerConnectionInterface> createActualPeerConnection(webrtc::PeerConnectionObserver& observer, std::unique_ptr<cricket::BasicPortAllocator>&& portAllocator)
126 {
127     ASSERT(staticFactoryAndThreads().factory);
128
129     webrtc::PeerConnectionInterface::RTCConfiguration config;
130     // FIXME: Add a default configuration.
131     return staticFactoryAndThreads().factory->CreatePeerConnection(config, WTFMove(portAllocator), nullptr, &observer);
132 }
133
134 rtc::scoped_refptr<webrtc::PeerConnectionInterface> LibWebRTCProvider::createPeerConnection(webrtc::PeerConnectionObserver& observer)
135 {
136     // Default WK1 implementation.
137     auto& factoryAndThreads = staticFactoryAndThreads();
138     if (!factoryAndThreads.factory) {
139         staticFactoryAndThreads().networkThreadWithSocketServer = true;
140         initializePeerConnectionFactoryAndThreads();
141     }
142     ASSERT(staticFactoryAndThreads().networkThreadWithSocketServer);
143
144     return createActualPeerConnection(observer, nullptr);
145 }
146
147 rtc::scoped_refptr<webrtc::PeerConnectionInterface> LibWebRTCProvider::createPeerConnection(webrtc::PeerConnectionObserver& observer, rtc::NetworkManager& networkManager, rtc::PacketSocketFactory& packetSocketFactory)
148 {
149     ASSERT(!staticFactoryAndThreads().networkThreadWithSocketServer);
150
151     auto& factoryAndThreads = staticFactoryAndThreads();
152     if (!factoryAndThreads.factory)
153         initializePeerConnectionFactoryAndThreads();
154
155     std::unique_ptr<cricket::BasicPortAllocator> portAllocator;
156     staticFactoryAndThreads().signalingThread->Invoke<void>(RTC_FROM_HERE, [&]() {
157         auto basicPortAllocator = std::make_unique<cricket::BasicPortAllocator>(&networkManager, &packetSocketFactory);
158         if (!m_enableEnumeratingAllNetworkInterfaces)
159             basicPortAllocator->set_flags(basicPortAllocator->flags() | cricket::PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION);
160         portAllocator = WTFMove(basicPortAllocator);
161     });
162
163     return createActualPeerConnection(observer, WTFMove(portAllocator));
164 }
165
166 } // namespace WebCore
167
168 #endif // USE(LIBWEBRTC)