summaryrefslogtreecommitdiff
path: root/Source/WebCore/platform/mediastream/libwebrtc
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/platform/mediastream/libwebrtc
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WebCore/platform/mediastream/libwebrtc')
-rw-r--r--Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCAudioFormat.h46
-rw-r--r--Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCAudioModule.cpp101
-rw-r--r--Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCAudioModule.h162
-rw-r--r--Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCMacros.h44
-rw-r--r--Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCProvider.cpp160
-rw-r--r--Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCProvider.h68
6 files changed, 581 insertions, 0 deletions
diff --git a/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCAudioFormat.h b/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCAudioFormat.h
new file mode 100644
index 000000000..e49107f10
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCAudioFormat.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if USE(LIBWEBRTC)
+
+namespace WebCore {
+
+namespace LibWebRTCAudioFormat {
+
+static const size_t sampleRate = 48000;
+static const size_t chunkSampleCount = 480;
+static const size_t sampleSize = 16;
+static const size_t sampleByteSize = 2;
+static const bool isFloat = false;
+static const bool isBigEndian = false;
+static const bool isNonInterleaved = false;
+
+}
+
+} // namespace WebCore
+
+#endif // USE(LIBWEBRTC)
diff --git a/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCAudioModule.cpp b/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCAudioModule.cpp
new file mode 100644
index 000000000..8ba6f4333
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCAudioModule.cpp
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "LibWebRTCAudioModule.h"
+
+#if USE(LIBWEBRTC)
+
+namespace WebCore {
+
+LibWebRTCAudioModule::LibWebRTCAudioModule()
+ : m_audioTaskRunner(rtc::Thread::Create())
+{
+ m_audioTaskRunner->Start();
+}
+
+int32_t LibWebRTCAudioModule::RegisterAudioCallback(webrtc::AudioTransport* audioTransport)
+{
+ m_audioTransport = audioTransport;
+ return 0;
+}
+
+void LibWebRTCAudioModule::OnMessage(rtc::Message* message)
+{
+ ASSERT_UNUSED(message, message->message_id == 1);
+ StartPlayoutOnAudioThread();
+}
+
+int32_t LibWebRTCAudioModule::StartPlayout()
+{
+ if (!m_isPlaying && m_audioTaskRunner) {
+ m_audioTaskRunner->Post(RTC_FROM_HERE, this, 1);
+ m_isPlaying = true;
+ }
+ return 0;
+}
+
+int32_t LibWebRTCAudioModule::StopPlayout()
+{
+ if (m_isPlaying)
+ m_isPlaying = false;
+ return 0;
+}
+
+// libwebrtc uses 10ms frames.
+const unsigned samplingRate = 48000;
+const unsigned frameLengthMs = 10;
+const unsigned samplesPerFrame = samplingRate * frameLengthMs / 1000;
+const unsigned pollSamples = 5;
+const unsigned pollInterval = 5 * frameLengthMs;
+const unsigned channels = 2;
+const unsigned bytesPerSample = 2;
+
+void LibWebRTCAudioModule::StartPlayoutOnAudioThread()
+{
+ while (true) {
+ PollFromSource();
+ m_audioTaskRunner->SleepMs(pollInterval);
+ if (!m_isPlaying)
+ return;
+ }
+}
+
+void LibWebRTCAudioModule::PollFromSource()
+{
+ if (!m_audioTransport)
+ return;
+
+ for (unsigned i = 0; i < pollSamples; i++) {
+ int64_t elapsedTime = -1;
+ int64_t ntpTime = -1;
+ char data[(bytesPerSample * channels * samplesPerFrame)];
+ m_audioTransport->PullRenderData(bytesPerSample * 8, samplingRate, channels, samplesPerFrame, data, &elapsedTime, &ntpTime);
+ }
+}
+
+} // namespace WebCore
+
+#endif // USE(LIBWEBRTC)
diff --git a/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCAudioModule.h b/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCAudioModule.h
new file mode 100644
index 000000000..95988609d
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCAudioModule.h
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if USE(LIBWEBRTC)
+
+#include "LibWebRTCMacros.h"
+#include <webrtc/base/messagehandler.h>
+#include <webrtc/base/thread.h>
+#include <webrtc/modules/audio_device/include/audio_device.h>
+
+namespace WebCore {
+
+// LibWebRTCAudioModule is pulling streamed data to ensure audio data is passed to the audio track.
+class LibWebRTCAudioModule final : public webrtc::AudioDeviceModule, private rtc::MessageHandler {
+public:
+ LibWebRTCAudioModule();
+
+private:
+ template<typename U> U shouldNotBeCalled(U value) const
+ {
+ ASSERT_NOT_REACHED();
+ return value;
+ }
+
+ int32_t AddRef() const final { return 1; }
+ int32_t Release() const final { return 1; }
+ void OnMessage(rtc::Message*);
+
+ // webrtc::AudioDeviceModule API
+ int32_t StartPlayout() final;
+ int32_t StopPlayout() final;
+ int32_t RegisterAudioCallback(webrtc::AudioTransport*) final;
+ bool Playing() const final { return m_isPlaying; }
+
+ int64_t TimeUntilNextProcess() final { return std::numeric_limits<int64_t>::max(); }
+ void Process() final { }
+ int32_t ActiveAudioLayer(AudioLayer*) const final { return shouldNotBeCalled(-1); }
+ ErrorCode LastError() const final { return kAdmErrNone; }
+ int32_t RegisterEventObserver(webrtc::AudioDeviceObserver*) final { return 0; }
+ int32_t Init() final { return 0; }
+ int32_t Terminate() final { return 0; }
+ bool Initialized() const final { return true; }
+ int16_t PlayoutDevices() final { return 0; }
+ int16_t RecordingDevices() final { return 0; }
+ int32_t PlayoutDeviceName(uint16_t, char[webrtc::kAdmMaxDeviceNameSize], char[webrtc::kAdmMaxGuidSize]) final { return 0; }
+ int32_t RecordingDeviceName(uint16_t, char[webrtc::kAdmMaxDeviceNameSize], char[webrtc::kAdmMaxGuidSize]) final { return 0; }
+ int32_t SetPlayoutDevice(uint16_t) final { return 0; }
+ int32_t SetPlayoutDevice(WindowsDeviceType) final { return 0; }
+ int32_t SetRecordingDevice(uint16_t) final { return 0; }
+ int32_t SetRecordingDevice(WindowsDeviceType) final { return 0; }
+ int32_t PlayoutIsAvailable(bool*) final { return shouldNotBeCalled(-1); }
+ int32_t InitPlayout() final { return 0; }
+ bool PlayoutIsInitialized() const final { return true; }
+ int32_t RecordingIsAvailable(bool*) final { return shouldNotBeCalled(-1); }
+ int32_t InitRecording() final { return 0; }
+ bool RecordingIsInitialized() const final { return false; }
+ int32_t StartRecording() final { return 0; }
+ int32_t StopRecording() final { return 0; }
+ bool Recording() const final { return 0; }
+ int32_t SetAGC(bool) final { return 0; }
+ bool AGC() const final { return shouldNotBeCalled(0); }
+ int32_t SetWaveOutVolume(uint16_t, uint16_t) final { return shouldNotBeCalled(-1); }
+ int32_t WaveOutVolume(uint16_t*, uint16_t*) const final { return shouldNotBeCalled(-1); }
+ int32_t InitSpeaker() final { return 0; }
+ bool SpeakerIsInitialized() const final { return false; }
+ int32_t InitMicrophone() final { return 0; }
+ bool MicrophoneIsInitialized() const final { return false; }
+ int32_t SpeakerVolumeIsAvailable(bool*) final { return shouldNotBeCalled(-1); }
+ int32_t SetSpeakerVolume(uint32_t) final { return shouldNotBeCalled(-1); }
+ int32_t SpeakerVolume(uint32_t*) const final { return shouldNotBeCalled(-1); }
+ int32_t MaxSpeakerVolume(uint32_t*) const final { return shouldNotBeCalled(-1); }
+ int32_t MinSpeakerVolume(uint32_t*) const final { return shouldNotBeCalled(-1); }
+ int32_t SpeakerVolumeStepSize(uint16_t*) const final { return shouldNotBeCalled(-1); }
+ int32_t MicrophoneVolumeIsAvailable(bool*) final { return shouldNotBeCalled(-1); }
+ int32_t SetMicrophoneVolume(uint32_t) final { return shouldNotBeCalled(-1); }
+ int32_t MicrophoneVolume(uint32_t*) const final { return shouldNotBeCalled(-1); }
+ int32_t MaxMicrophoneVolume(uint32_t*) const final { return shouldNotBeCalled(-1); }
+ int32_t MinMicrophoneVolume(uint32_t*) const final { return shouldNotBeCalled(-1); }
+ int32_t MicrophoneVolumeStepSize(uint16_t*) const final { return shouldNotBeCalled(-1); }
+ int32_t SpeakerMuteIsAvailable(bool*) final { return shouldNotBeCalled(-1); }
+ int32_t SetSpeakerMute(bool) final { return shouldNotBeCalled(-1); }
+ int32_t SpeakerMute(bool*) const final { return shouldNotBeCalled(-1); }
+ int32_t MicrophoneMuteIsAvailable(bool*) final { return shouldNotBeCalled(-1); }
+ int32_t SetMicrophoneMute(bool) final { return shouldNotBeCalled(-1); }
+ int32_t MicrophoneMute(bool*) const final { return shouldNotBeCalled(-1); }
+ int32_t MicrophoneBoostIsAvailable(bool*) final { return shouldNotBeCalled(-1); }
+ int32_t SetMicrophoneBoost(bool) final { return shouldNotBeCalled(-1); }
+ int32_t MicrophoneBoost(bool*) const final { return shouldNotBeCalled(-1); }
+ int32_t StereoPlayoutIsAvailable(bool* available) const final { *available = false; return 0; }
+ int32_t SetStereoPlayout(bool) final { return 0; }
+ int32_t StereoPlayout(bool*) const final { return shouldNotBeCalled(-1); }
+ int32_t StereoRecordingIsAvailable(bool* available) const final { *available = false; return 0; }
+ int32_t SetStereoRecording(bool) final { return 0; }
+ int32_t StereoRecording(bool*) const final { return shouldNotBeCalled(-1); }
+ int32_t SetRecordingChannel(const ChannelType) final { return 0; }
+ int32_t RecordingChannel(ChannelType*) const final { return shouldNotBeCalled(-1); }
+ int32_t SetPlayoutBuffer(const BufferType, uint16_t) final { return shouldNotBeCalled(-1); }
+ int32_t PlayoutBuffer(BufferType*, uint16_t*) const final { return shouldNotBeCalled(-1); }
+ int32_t PlayoutDelay(uint16_t* delay) const final { *delay = 0; return 0; }
+ int32_t RecordingDelay(uint16_t*) const final { return shouldNotBeCalled(-1); }
+ int32_t CPULoad(uint16_t*) const final { return shouldNotBeCalled(-1); }
+ int32_t StartRawOutputFileRecording(const char[webrtc::kAdmMaxFileNameSize]) final { return shouldNotBeCalled(-1); }
+ int32_t StopRawOutputFileRecording() final { return shouldNotBeCalled(-1); }
+ int32_t StartRawInputFileRecording(const char[webrtc::kAdmMaxFileNameSize]) final { return shouldNotBeCalled(-1); }
+ int32_t StopRawInputFileRecording() final { return shouldNotBeCalled(-1); }
+ int32_t SetRecordingSampleRate(const uint32_t) final { return shouldNotBeCalled(-1); }
+ int32_t RecordingSampleRate(uint32_t*) const final { return shouldNotBeCalled(-1); }
+ int32_t SetPlayoutSampleRate(const uint32_t) final { return shouldNotBeCalled(-1); }
+ int32_t PlayoutSampleRate(uint32_t*) const final { return shouldNotBeCalled(-1); }
+ int32_t ResetAudioDevice() final { return shouldNotBeCalled(-1); }
+ int32_t SetLoudspeakerStatus(bool) final { return shouldNotBeCalled(-1); }
+ int32_t GetLoudspeakerStatus(bool*) const final { return shouldNotBeCalled(-1); }
+ bool BuiltInAECIsAvailable() const final { return false; }
+ bool BuiltInAGCIsAvailable() const final { return false; }
+ bool BuiltInNSIsAvailable() const final { return false; }
+ int32_t EnableBuiltInAEC(bool) final { return shouldNotBeCalled(-1); }
+ int32_t EnableBuiltInAGC(bool) final { return shouldNotBeCalled(-1); }
+ int32_t EnableBuiltInNS(bool) final { return shouldNotBeCalled(-1); }
+
+#if defined(WEBRTC_IOS)
+ int GetPlayoutAudioParameters(webrtc::AudioParameters*) const final { return shouldNotBeCalled(-1); }
+ int GetRecordAudioParameters(webrtc::AudioParameters*) const final { return shouldNotBeCalled(-1); }
+#endif
+
+private:
+ void StartPlayoutOnAudioThread();
+
+ void PollFromSource();
+
+ std::unique_ptr<rtc::Thread> m_audioTaskRunner;
+
+ bool m_isPlaying = false;
+ webrtc::AudioTransport* m_audioTransport = nullptr;
+};
+
+} // namespace WebCore
+
+#endif // USE(LIBWEBRTC)
diff --git a/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCMacros.h b/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCMacros.h
new file mode 100644
index 000000000..982d94be5
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCMacros.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2017 Apple Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted, provided that the following conditions
+ * are required to be met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. AND ITS CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if USE(LIBWEBRTC)
+
+#if PLATFORM(IOS)
+#define WEBRTC_IOS
+#endif
+
+#if PLATFORM(MAC)
+#define WEBRTC_MAC
+#endif
+
+#define WEBRTC_POSIX 1
+#define _COMMON_INCLUDED_
+
+#endif // USE(LIBWEBRTC)
diff --git a/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCProvider.cpp b/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCProvider.cpp
new file mode 100644
index 000000000..0095c517f
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCProvider.cpp
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "LibWebRTCProvider.h"
+
+#if USE(LIBWEBRTC)
+
+#include "LibWebRTCAudioModule.h"
+#include <webrtc/api/peerconnectionfactory.h>
+#include <webrtc/api/peerconnectionfactoryproxy.h>
+#include <webrtc/base/physicalsocketserver.h>
+#include <webrtc/p2p/client/basicportallocator.h>
+#include <webrtc/sdk/objc/Framework/Classes/videotoolboxvideocodecfactory.h>
+#include <wtf/Function.h>
+#include <wtf/NeverDestroyed.h>
+
+namespace WebCore {
+
+struct PeerConnectionFactoryAndThreads : public rtc::MessageHandler {
+ std::unique_ptr<LibWebRTCAudioModule> audioDeviceModule;
+ std::unique_ptr<rtc::Thread> networkThread;
+ std::unique_ptr<rtc::Thread> signalingThread;
+ rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> factory;
+ bool networkThreadWithSocketServer { false };
+private:
+ void OnMessage(rtc::Message*);
+};
+
+static inline PeerConnectionFactoryAndThreads& staticFactoryAndThreads()
+{
+ static NeverDestroyed<PeerConnectionFactoryAndThreads> factoryAndThreads;
+ return factoryAndThreads.get();
+}
+
+struct ThreadMessageData : public rtc::MessageData {
+ ThreadMessageData(Function<void()>&& callback)
+ : callback(WTFMove(callback))
+ { }
+ Function<void()> callback;
+};
+
+void PeerConnectionFactoryAndThreads::OnMessage(rtc::Message* message)
+{
+ ASSERT(message->message_id == 1);
+ static_cast<ThreadMessageData*>(message->pdata)->callback();
+}
+
+void LibWebRTCProvider::callOnWebRTCNetworkThread(Function<void()>&& callback)
+{
+ PeerConnectionFactoryAndThreads& threads = staticFactoryAndThreads();
+ threads.networkThread->Post(RTC_FROM_HERE, &threads, 1, new ThreadMessageData(WTFMove(callback)));
+}
+
+void LibWebRTCProvider::callOnWebRTCSignalingThread(Function<void()>&& callback)
+{
+ PeerConnectionFactoryAndThreads& threads = staticFactoryAndThreads();
+ threads.signalingThread->Post(RTC_FROM_HERE, &threads, 1, new ThreadMessageData(WTFMove(callback)));
+}
+
+static void initializePeerConnectionFactoryAndThreads()
+{
+ auto& factoryAndThreads = staticFactoryAndThreads();
+
+ ASSERT(!factoryAndThreads.factory);
+
+ auto thread = rtc::Thread::Create();
+ factoryAndThreads.networkThread = factoryAndThreads.networkThreadWithSocketServer ? rtc::Thread::CreateWithSocketServer() : rtc::Thread::Create();
+ bool result = factoryAndThreads.networkThread->Start();
+ ASSERT_UNUSED(result, result);
+
+ factoryAndThreads.signalingThread = rtc::Thread::Create();
+ result = factoryAndThreads.signalingThread->Start();
+ ASSERT(result);
+
+ factoryAndThreads.audioDeviceModule = std::make_unique<LibWebRTCAudioModule>();
+
+ factoryAndThreads.factory = webrtc::CreatePeerConnectionFactory(factoryAndThreads.networkThread.get(), factoryAndThreads.networkThread.get(), factoryAndThreads.signalingThread.get(), factoryAndThreads.audioDeviceModule.get(), new webrtc::VideoToolboxVideoEncoderFactory(), new webrtc::VideoToolboxVideoDecoderFactory());
+
+ ASSERT(factoryAndThreads.factory);
+}
+
+webrtc::PeerConnectionFactoryInterface& LibWebRTCProvider::factory()
+{
+ if (!staticFactoryAndThreads().factory)
+ initializePeerConnectionFactoryAndThreads();
+ return *staticFactoryAndThreads().factory;
+}
+
+void LibWebRTCProvider::setPeerConnectionFactory(rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface>&& factory)
+{
+ if (!staticFactoryAndThreads().factory)
+ initializePeerConnectionFactoryAndThreads();
+
+ staticFactoryAndThreads().factory = webrtc::PeerConnectionFactoryProxy::Create(staticFactoryAndThreads().signalingThread.get(), WTFMove(factory));
+}
+
+static rtc::scoped_refptr<webrtc::PeerConnectionInterface> createActualPeerConnection(webrtc::PeerConnectionObserver& observer, std::unique_ptr<cricket::BasicPortAllocator>&& portAllocator)
+{
+ ASSERT(staticFactoryAndThreads().factory);
+
+ webrtc::PeerConnectionInterface::RTCConfiguration config;
+ // FIXME: Add a default configuration.
+ return staticFactoryAndThreads().factory->CreatePeerConnection(config, WTFMove(portAllocator), nullptr, &observer);
+}
+
+rtc::scoped_refptr<webrtc::PeerConnectionInterface> LibWebRTCProvider::createPeerConnection(webrtc::PeerConnectionObserver& observer)
+{
+ // Default WK1 implementation.
+ auto& factoryAndThreads = staticFactoryAndThreads();
+ if (!factoryAndThreads.factory) {
+ staticFactoryAndThreads().networkThreadWithSocketServer = true;
+ initializePeerConnectionFactoryAndThreads();
+ }
+ ASSERT(staticFactoryAndThreads().networkThreadWithSocketServer);
+
+ return createActualPeerConnection(observer, nullptr);
+}
+
+rtc::scoped_refptr<webrtc::PeerConnectionInterface> LibWebRTCProvider::createPeerConnection(webrtc::PeerConnectionObserver& observer, rtc::NetworkManager& networkManager, rtc::PacketSocketFactory& packetSocketFactory)
+{
+ ASSERT(!staticFactoryAndThreads().networkThreadWithSocketServer);
+
+ auto& factoryAndThreads = staticFactoryAndThreads();
+ if (!factoryAndThreads.factory)
+ initializePeerConnectionFactoryAndThreads();
+
+ std::unique_ptr<cricket::BasicPortAllocator> portAllocator;
+ staticFactoryAndThreads().signalingThread->Invoke<void>(RTC_FROM_HERE, [&]() {
+ portAllocator.reset(new cricket::BasicPortAllocator(&networkManager, &packetSocketFactory));
+ });
+
+ return createActualPeerConnection(observer, WTFMove(portAllocator));
+}
+
+} // namespace WebCore
+
+#endif // USE(LIBWEBRTC)
diff --git a/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCProvider.h b/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCProvider.h
new file mode 100644
index 000000000..dca1c2275
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCProvider.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "LibWebRTCMacros.h"
+#include <wtf/Forward.h>
+
+#if USE(LIBWEBRTC)
+
+#include <webrtc/api/peerconnectioninterface.h>
+#include <webrtc/base/scoped_ref_ptr.h>
+
+namespace rtc {
+class NetworkManager;
+class PacketSocketFactory;
+}
+
+namespace webrtc {
+class PeerConnectionFactoryInterface;
+}
+#endif
+
+namespace WebCore {
+
+class WEBCORE_EXPORT LibWebRTCProvider {
+public:
+ LibWebRTCProvider() = default;
+ virtual ~LibWebRTCProvider() = default;
+
+#if USE(LIBWEBRTC)
+ WEBCORE_EXPORT virtual rtc::scoped_refptr<webrtc::PeerConnectionInterface> createPeerConnection(webrtc::PeerConnectionObserver&);
+
+ // FIXME: Make these methods not static.
+ static WEBCORE_EXPORT void callOnWebRTCNetworkThread(Function<void()>&&);
+ static WEBCORE_EXPORT void callOnWebRTCSignalingThread(Function<void()>&&);
+ static WEBCORE_EXPORT webrtc::PeerConnectionFactoryInterface& factory();
+ // Used for mock testing
+ static void setPeerConnectionFactory(rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface>&&);
+
+protected:
+ WEBCORE_EXPORT rtc::scoped_refptr<webrtc::PeerConnectionInterface> createPeerConnection(webrtc::PeerConnectionObserver&, rtc::NetworkManager&, rtc::PacketSocketFactory&);
+#endif
+};
+
+} // namespace WebCore