WebRTC video does not resume receiving when switching back to Safari 11 on iOS
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 25 Sep 2017 23:23:27 +0000 (23:23 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 25 Sep 2017 23:23:27 +0000 (23:23 +0000)
https://bugs.webkit.org/show_bug.cgi?id=175472
<rdar://problem/33860863>

Patch by Youenn Fablet <youenn@apple.com> on 2017-09-25
Reviewed by Darin Adler.

Source/ThirdParty/libwebrtc:

Adding a method to disable any decoding/encoding task.
When reenabling the decoder, the decoder will request an I frame after failing the first initial decoding task.

* Source/webrtc/sdk/objc/Framework/Classes/VideoToolbox/decoder.h:
(webrtc::H264VideoToolboxDecoder::SetActive):
* Source/webrtc/sdk/objc/Framework/Classes/VideoToolbox/decoder.mm:
(webrtc::H264VideoToolboxDecoder::Decode):
* Source/webrtc/sdk/objc/Framework/Classes/VideoToolbox/encoder.h:
* Source/webrtc/sdk/objc/Framework/Classes/VideoToolbox/encoder.mm:
(webrtc::H264VideoToolboxEncoder::Encode):

Source/WebCore:

Test: webrtc/video-interruption.html and manual testing.

Using new SetActive method from libwebrtc encoder/decoder to enable/disable them based on interuptions.
For that purpose, LibWebRTCProvider is now storing the peer connection factory and keeping track of the encoder/decoder factories.
LibWebRTCProvider is then notified by WebPage when backgrounded/foregrounded.

* WebCore.xcodeproj/project.pbxproj:
* platform/mediastream/libwebrtc/LibWebRTCProvider.cpp:
(WebCore::staticFactoryAndThreads):
(WebCore::initializePeerConnectionFactoryAndThreads):
(WebCore::LibWebRTCProvider::factory):
(WebCore::LibWebRTCProvider::setPeerConnectionFactory):
(WebCore::LibWebRTCProvider::createPeerConnection):
(WebCore::LibWebRTCProvider::setActive):
(WebCore::LibWebRTCProvider::webRTCAvailable):
(WebCore::LibWebRTCProvider::mayResumePlayback): Deleted.
(WebCore::LibWebRTCProvider::suspendPlayback): Deleted.
* platform/mediastream/libwebrtc/LibWebRTCProvider.h:
* platform/mediastream/libwebrtc/VideoToolBoxDecoderFactory.cpp: Copied from Source/WebCore/platform/mediastream/libwebrtc/VideoToolBoxEncoderFactory.cpp.
(WebCore::VideoToolboxVideoDecoderFactory::setActive):
(WebCore::VideoToolboxVideoDecoderFactory::CreateVideoDecoder):
(WebCore::VideoToolboxVideoDecoderFactory::DestroyVideoDecoder):
* platform/mediastream/libwebrtc/VideoToolBoxDecoderFactory.h: Copied from Source/WebCore/platform/mediastream/libwebrtc/VideoToolBoxEncoderFactory.h.
* platform/mediastream/libwebrtc/VideoToolBoxEncoderFactory.cpp:
(WebCore::VideoToolboxVideoEncoderFactory::setActive):
(WebCore::VideoToolboxVideoEncoderFactory::CreateSupportedVideoEncoder):
(WebCore::VideoToolboxVideoEncoderFactory::DestroyVideoEncoder):
* platform/mediastream/libwebrtc/VideoToolBoxEncoderFactory.h:
* testing/Internals.cpp:
(WebCore::Internals::resetToConsistentState):
* testing/MockLibWebRTCPeerConnection.cpp:
(WebCore::useRealRTCPeerConnectionFactory):
(WebCore::useMockRTCPeerConnectionFactory):
* testing/MockLibWebRTCPeerConnection.h:

Source/WebKit:

Notifying LibWebRTC of backgrounding/foregrouding.

* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::applicationDidEnterBackground):
(WebKit::WebPage::applicationWillEnterForeground):

LayoutTests:

* webrtc/video-interruption-expected.txt: Added.
* webrtc/video-interruption.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@222478 268f45cc-cd09-0410-ab3c-d52691b4dbfc

22 files changed:
LayoutTests/ChangeLog
LayoutTests/webrtc/video-interruption-expected.txt [new file with mode: 0644]
LayoutTests/webrtc/video-interruption.html [new file with mode: 0644]
Source/ThirdParty/libwebrtc/ChangeLog
Source/ThirdParty/libwebrtc/Source/webrtc/sdk/objc/Framework/Classes/VideoToolbox/decoder.h
Source/ThirdParty/libwebrtc/Source/webrtc/sdk/objc/Framework/Classes/VideoToolbox/decoder.mm
Source/ThirdParty/libwebrtc/Source/webrtc/sdk/objc/Framework/Classes/VideoToolbox/encoder.h
Source/ThirdParty/libwebrtc/Source/webrtc/sdk/objc/Framework/Classes/VideoToolbox/encoder.mm
Source/WebCore/ChangeLog
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCProvider.cpp
Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCProvider.h
Source/WebCore/platform/mediastream/libwebrtc/VideoToolBoxDecoderFactory.cpp [new file with mode: 0644]
Source/WebCore/platform/mediastream/libwebrtc/VideoToolBoxDecoderFactory.h [new file with mode: 0644]
Source/WebCore/platform/mediastream/libwebrtc/VideoToolBoxEncoderFactory.cpp
Source/WebCore/platform/mediastream/libwebrtc/VideoToolBoxEncoderFactory.h
Source/WebCore/testing/Internals.cpp
Source/WebCore/testing/MockLibWebRTCPeerConnection.cpp
Source/WebCore/testing/MockLibWebRTCPeerConnection.h
Source/WebKit/ChangeLog
Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm
WebKit.xcworkspace/xcshareddata/xcschemes/All Source.xcscheme

index 77a5c79..c10adfd 100644 (file)
@@ -1,3 +1,14 @@
+2017-09-25  Youenn Fablet  <youenn@apple.com>
+
+        WebRTC video does not resume receiving when switching back to Safari 11 on iOS
+        https://bugs.webkit.org/show_bug.cgi?id=175472
+        <rdar://problem/33860863>
+
+        Reviewed by Darin Adler.
+
+        * webrtc/video-interruption-expected.txt: Added.
+        * webrtc/video-interruption.html: Added.
+
 2017-09-25  Per Arne Vollan  <pvollan@apple.com>
 
         Crash in WebCore::TreeScope::documentScope
diff --git a/LayoutTests/webrtc/video-interruption-expected.txt b/LayoutTests/webrtc/video-interruption-expected.txt
new file mode 100644 (file)
index 0000000..8869b58
--- /dev/null
@@ -0,0 +1,4 @@
+
+PASS Basic video exchange with media session interruption 
+
diff --git a/LayoutTests/webrtc/video-interruption.html b/LayoutTests/webrtc/video-interruption.html
new file mode 100644 (file)
index 0000000..d45a224
--- /dev/null
@@ -0,0 +1,85 @@
+<!doctype html>
+<html>
+    <head>
+        <meta charset="utf-8">
+        <title>Testing basic video exchange from offerer to receiver</title>
+        <script src="../resources/testharness.js"></script>
+        <script src="../resources/testharnessreport.js"></script>
+    </head>
+    <body>
+        <video id="video1" autoplay=""></video>
+        <video id="video2" autoplay=""></video>
+        <canvas id="canvas" width="640" height="480"></canvas>
+        <script src ="routines.js"></script>
+        <script>
+video = document.getElementById("video");
+canvas = document.getElementById("canvas");
+
+function testImage(video)
+{
+    canvas.width = video.videoWidth;
+    canvas.height = video.videoHeight;
+    canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
+
+    imageData = canvas.getContext('2d').getImageData(10, 325, 250, 1);
+    data = imageData.data;
+
+    var index = 20;
+    assert_true(data[index] < 100);
+    assert_true(data[index + 1] < 100);
+    assert_true(data[index + 2] < 100);
+
+    index = 80;
+    assert_true(data[index] > 200);
+    assert_true(data[index + 1] > 200);
+    assert_true(data[index + 2] > 200);
+
+    index += 80;
+    assert_true(data[index] > 200);
+    assert_true(data[index + 1] > 200);
+    assert_true(data[index + 2] < 100);
+}
+
+promise_test((test) => {
+    if (window.testRunner)
+        testRunner.setUserMediaPermission(true);
+
+    var stream;
+    return navigator.mediaDevices.getUserMedia({video: {advanced: [{width:{min:1280}}, {height:{min:720} } ]}}).then((stream) => {
+        return new Promise((resolve, reject) => {
+            createConnections((firstConnection) => {
+                var track = stream.getVideoTracks()[0];
+                firstConnection.addTrack(stream.getVideoTracks()[0], stream);
+            }, (secondConnection) => {
+                secondConnection.ontrack = (trackEvent) => {
+                    assert_true(trackEvent.track instanceof MediaStreamTrack);
+                    assert_true(trackEvent.receiver instanceof RTCRtpReceiver);
+                    assert_true(Array.isArray(trackEvent.streams), "Array.isArray() should return true");
+                    assert_true(Object.isFrozen(trackEvent.streams), "Object.isFrozen() should return true");
+                    assert_equals(trackEvent.track.id, stream.getVideoTracks()[0].id);
+                    assert_equals(trackEvent.track, trackEvent.streams[0].getVideoTracks()[0]);
+                    resolve(trackEvent.streams[0]);
+                };
+            });
+            setTimeout(() => reject("Test timed out"), 5000);
+        });
+    }).then((s) => {
+        stream = s;
+        video1.srcObject = stream;
+        return video1.play();
+    }).then(() => {
+        testImage(video1);
+    }).then(() => {
+        internals.beginMediaSessionInterruption('EnteringBackground');
+    }).then(() => {
+        internals.endMediaSessionInterruption('');
+    }).then(() => {
+        video2.srcObject = stream;
+        return video2.play();
+    }).then(() => {
+        testImage(video2);
+    });
+}, "Basic video exchange with media session interruption");
+        </script>
+    </body>
+</html>
index 0552838..92bfbe9 100644 (file)
@@ -1,5 +1,24 @@
 2017-09-25  Youenn Fablet  <youenn@apple.com>
 
+        WebRTC video does not resume receiving when switching back to Safari 11 on iOS
+        https://bugs.webkit.org/show_bug.cgi?id=175472
+        <rdar://problem/33860863>
+
+        Reviewed by Darin Adler.
+
+        Adding a method to disable any decoding/encoding task.
+        When reenabling the decoder, the decoder will request an I frame after failing the first initial decoding task.
+
+        * Source/webrtc/sdk/objc/Framework/Classes/VideoToolbox/decoder.h:
+        (webrtc::H264VideoToolboxDecoder::SetActive):
+        * Source/webrtc/sdk/objc/Framework/Classes/VideoToolbox/decoder.mm:
+        (webrtc::H264VideoToolboxDecoder::Decode):
+        * Source/webrtc/sdk/objc/Framework/Classes/VideoToolbox/encoder.h:
+        * Source/webrtc/sdk/objc/Framework/Classes/VideoToolbox/encoder.mm:
+        (webrtc::H264VideoToolboxEncoder::Encode):
+
+2017-09-25  Youenn Fablet  <youenn@apple.com>
+
         Adding per-platform libwebrtc export files
         https://bugs.webkit.org/show_bug.cgi?id=177465
 
index f2252da..f678ca7 100644 (file)
@@ -43,6 +43,8 @@ class H264VideoToolboxDecoder : public H264Decoder {
 
   const char* ImplementationName() const override;
 
+  void SetActive(bool is_active) { is_active_ = is_active; }
+
  private:
   int ResetDecompressionSession();
   void ConfigureDecompressionSession();
@@ -52,6 +54,7 @@ class H264VideoToolboxDecoder : public H264Decoder {
   DecodedImageCallback* callback_;
   CMVideoFormatDescriptionRef video_format_;
   VTDecompressionSessionRef decompression_session_;
+  bool is_active_ { true };
 };  // H264VideoToolboxDecoder
 
 }  // namespace webrtc
index f8c28cc..4e33466 100644 (file)
@@ -95,8 +95,12 @@ int H264VideoToolboxDecoder::Decode(
     int64_t render_time_ms) {
   RTC_DCHECK(input_image._buffer);
 
-#if defined(WEBRTC_IOS) && !defined(WEBRTC_WEBKIT_BUILD)
+#if defined(WEBRTC_IOS)
+#if !defined(WEBRTC_WEBKIT_BUILD)
   if (![[RTCUIApplicationStatusObserver sharedInstance] isApplicationActive]) {
+#else
+  if (!is_active_) {
+#endif
     // Ignore all decode requests when app isn't active. In this state, the
     // hardware decoder has been invalidated by the OS.
     // Reset video format so that we won't process frames until the next
index 57309a3..414d539 100644 (file)
@@ -68,6 +68,8 @@ class H264VideoToolboxEncoder : public H264Encoder {
 
   ScalingSettings GetScalingSettings() const override;
 
+  void SetActive(bool is_active) { is_active_ = is_active; }
+
  protected:
   virtual int CreateCompressionSession(VTCompressionSessionRef&, VTCompressionOutputCallback, int32_t width, int32_t height, bool useHardwareEncoder = true);
   void DestroyCompressionSession();
@@ -93,6 +95,7 @@ class H264VideoToolboxEncoder : public H264Encoder {
 
   H264BitstreamParser h264_bitstream_parser_;
   std::vector<uint8_t> nv12_scale_buffer_;
+  bool is_active_ { true };
 };  // H264VideoToolboxEncoder
 
 }  // namespace webrtc
index 15ce9b3..109010a 100644 (file)
@@ -384,8 +384,13 @@ int H264VideoToolboxEncoder::Encode(
   if (!callback_ || !compression_session_) {
     return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
   }
-#if defined(WEBRTC_IOS) && !defined(WEBRTC_WEBKIT_BUILD)
-  if (![[RTCUIApplicationStatusObserver sharedInstance] isApplicationActive]) {
+
+#if defined(WEBRTC_IOS)
+#if !defined(WEBRTC_WEBKIT_BUILD)
+    if (![[RTCUIApplicationStatusObserver sharedInstance] isApplicationActive]) {
+#else
+    if (!is_active_) {
+#endif
     // Ignore all encode requests when app isn't active. In this state, the
     // hardware encoder has been invalidated by the OS.
     return WEBRTC_VIDEO_CODEC_OK;
index 29601bd..bfa49fb 100644 (file)
@@ -1,3 +1,46 @@
+2017-09-25  Youenn Fablet  <youenn@apple.com>
+
+        WebRTC video does not resume receiving when switching back to Safari 11 on iOS
+        https://bugs.webkit.org/show_bug.cgi?id=175472
+        <rdar://problem/33860863>
+
+        Reviewed by Darin Adler.
+
+        Test: webrtc/video-interruption.html and manual testing.
+
+        Using new SetActive method from libwebrtc encoder/decoder to enable/disable them based on interuptions.
+        For that purpose, LibWebRTCProvider is now storing the peer connection factory and keeping track of the encoder/decoder factories.
+        LibWebRTCProvider is then notified by WebPage when backgrounded/foregrounded.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * platform/mediastream/libwebrtc/LibWebRTCProvider.cpp:
+        (WebCore::staticFactoryAndThreads):
+        (WebCore::initializePeerConnectionFactoryAndThreads):
+        (WebCore::LibWebRTCProvider::factory):
+        (WebCore::LibWebRTCProvider::setPeerConnectionFactory):
+        (WebCore::LibWebRTCProvider::createPeerConnection):
+        (WebCore::LibWebRTCProvider::setActive):
+        (WebCore::LibWebRTCProvider::webRTCAvailable):
+        (WebCore::LibWebRTCProvider::mayResumePlayback): Deleted.
+        (WebCore::LibWebRTCProvider::suspendPlayback): Deleted.
+        * platform/mediastream/libwebrtc/LibWebRTCProvider.h:
+        * platform/mediastream/libwebrtc/VideoToolBoxDecoderFactory.cpp: Copied from Source/WebCore/platform/mediastream/libwebrtc/VideoToolBoxEncoderFactory.cpp.
+        (WebCore::VideoToolboxVideoDecoderFactory::setActive):
+        (WebCore::VideoToolboxVideoDecoderFactory::CreateVideoDecoder):
+        (WebCore::VideoToolboxVideoDecoderFactory::DestroyVideoDecoder):
+        * platform/mediastream/libwebrtc/VideoToolBoxDecoderFactory.h: Copied from Source/WebCore/platform/mediastream/libwebrtc/VideoToolBoxEncoderFactory.h.
+        * platform/mediastream/libwebrtc/VideoToolBoxEncoderFactory.cpp:
+        (WebCore::VideoToolboxVideoEncoderFactory::setActive):
+        (WebCore::VideoToolboxVideoEncoderFactory::CreateSupportedVideoEncoder):
+        (WebCore::VideoToolboxVideoEncoderFactory::DestroyVideoEncoder):
+        * platform/mediastream/libwebrtc/VideoToolBoxEncoderFactory.h:
+        * testing/Internals.cpp:
+        (WebCore::Internals::resetToConsistentState):
+        * testing/MockLibWebRTCPeerConnection.cpp:
+        (WebCore::useRealRTCPeerConnectionFactory):
+        (WebCore::useMockRTCPeerConnectionFactory):
+        * testing/MockLibWebRTCPeerConnection.h:
+
 2017-09-25  Sam Weinig  <sam@webkit.org>
 
         Remove unused EditorClient functions
index 6d38b8a..dd08c25 100644 (file)
                41D129D31F3D0F1600D15E47 /* CacheStorageConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 41D129CC1F3D0EE300D15E47 /* CacheStorageConnection.h */; settings = {ATTRIBUTES = (Private, ); }; };
                41D129D51F3D0F6900D15E47 /* CacheStorageProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 41D129D41F3D0F6600D15E47 /* CacheStorageProvider.h */; settings = {ATTRIBUTES = (Private, ); }; };
                41D129DB1F3D143800D15E47 /* FetchHeaders.h in Headers */ = {isa = PBXBuildFile; fileRef = 41F54F831C50C4F600338488 /* FetchHeaders.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               41D7E5571F73085500E26991 /* VideoToolBoxDecoderFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41D7E5551F73085000E26991 /* VideoToolBoxDecoderFactory.cpp */; };
                41DEFCB51E56C1BD000D9E5F /* JSDOMMapLike.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41DEFCB31E56C1B9000D9E5F /* JSDOMMapLike.cpp */; };
                41DEFCB61E56C1BD000D9E5F /* JSDOMMapLike.h in Headers */ = {isa = PBXBuildFile; fileRef = 41DEFCB41E56C1B9000D9E5F /* JSDOMMapLike.h */; };
                41E1B1D00FF5986900576B3B /* AbstractWorker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41E1B1CA0FF5986900576B3B /* AbstractWorker.cpp */; };
                41D129CC1F3D0EE300D15E47 /* CacheStorageConnection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CacheStorageConnection.h; sourceTree = "<group>"; };
                41D129D41F3D0F6600D15E47 /* CacheStorageProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CacheStorageProvider.h; sourceTree = "<group>"; };
                41D51BB21E4E2E8100131A5B /* LibWebRTCAudioFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LibWebRTCAudioFormat.h; path = libwebrtc/LibWebRTCAudioFormat.h; sourceTree = "<group>"; };
+               41D7E5541F73085000E26991 /* VideoToolBoxDecoderFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VideoToolBoxDecoderFactory.h; path = libwebrtc/VideoToolBoxDecoderFactory.h; sourceTree = "<group>"; };
+               41D7E5551F73085000E26991 /* VideoToolBoxDecoderFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = VideoToolBoxDecoderFactory.cpp; path = libwebrtc/VideoToolBoxDecoderFactory.cpp; sourceTree = "<group>"; };
                41DEFCB21E56C1B9000D9E5F /* JSDOMBindingInternals.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = JSDOMBindingInternals.js; sourceTree = "<group>"; };
                41DEFCB31E56C1B9000D9E5F /* JSDOMMapLike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMMapLike.cpp; sourceTree = "<group>"; };
                41DEFCB41E56C1B9000D9E5F /* JSDOMMapLike.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMMapLike.h; sourceTree = "<group>"; };
                                415747431E38699E00E914D8 /* LibWebRTCMacros.h */,
                                41A1B00D1E52656E007F3769 /* LibWebRTCProvider.cpp */,
                                415747441E38699E00E914D8 /* LibWebRTCProvider.h */,
+                               41D7E5551F73085000E26991 /* VideoToolBoxDecoderFactory.cpp */,
+                               41D7E5541F73085000E26991 /* VideoToolBoxDecoderFactory.h */,
                                41CAD71C1EA0905700178164 /* VideoToolBoxEncoderFactory.cpp */,
                                41CAD71D1EA0905700178164 /* VideoToolBoxEncoderFactory.h */,
                        );
                                52D5A1A91C5748A900DE34A3 /* VideoFullscreenModelVideoElement.mm in Sources */,
                                CDE83DB1183C44060031EAA3 /* VideoPlaybackQuality.cpp in Sources */,
                                CD9D82791C7B8EE1006FF066 /* VideoTextureCopierCV.cpp in Sources */,
+                               41D7E5571F73085500E26991 /* VideoToolBoxDecoderFactory.cpp in Sources */,
                                41CAD71E1EA090A100178164 /* VideoToolBoxEncoderFactory.cpp in Sources */,
                                CDC939A71E9BDFB100BB768D /* VideoToolboxSoftLink.cpp in Sources */,
                                BE88E0DE1715D2A200658D98 /* VideoTrack.cpp in Sources */,
index 7e0867b..5e5d118 100644 (file)
 #if USE(LIBWEBRTC)
 #include "LibWebRTCAudioModule.h"
 #include "Logging.h"
+#include "VideoToolBoxDecoderFactory.h"
 #include "VideoToolBoxEncoderFactory.h"
 #include <dlfcn.h>
 #include <webrtc/api/peerconnectionfactoryproxy.h>
 #include <webrtc/base/physicalsocketserver.h>
 #include <webrtc/p2p/client/basicportallocator.h>
 #include <webrtc/pc/peerconnectionfactory.h>
-#include <webrtc/sdk/objc/Framework/Classes/VideoToolbox/videocodecfactory.h>
 #include <wtf/Function.h>
 #include <wtf/NeverDestroyed.h>
 #include <wtf/darwin/WeakLinking.h>
@@ -45,31 +45,62 @@ namespace WebCore {
 
 #if USE(LIBWEBRTC)
 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 };
-    Function<std::unique_ptr<cricket::WebRtcVideoEncoderFactory>()> encoderFactoryGetter;
-    Function<std::unique_ptr<cricket::WebRtcVideoDecoderFactory>()> decoderFactoryGetter;
+    std::unique_ptr<LibWebRTCAudioModule> audioDeviceModule;
 
 private:
     void OnMessage(rtc::Message*);
 };
 
+static void initializePeerConnectionFactoryAndThreads(PeerConnectionFactoryAndThreads& factoryAndThreads)
+{
+    ASSERT(!factoryAndThreads.networkThread);
+
+#if defined(NDEBUG)
+#if !LOG_DISABLED || !RELEASE_LOG_DISABLED
+    rtc::LogMessage::LogToDebug(LogWebRTC.state != WTFLogChannelOn ? rtc::LS_NONE : rtc::LS_INFO);
+#else
+    rtc::LogMessage::LogToDebug(rtc::LS_NONE);
+#endif
+#else
+    rtc::LogMessage::LogToDebug(LogWebRTC.state != WTFLogChannelOn ? rtc::LS_WARNING : rtc::LS_INFO);
+#endif
+
+    factoryAndThreads.networkThread = factoryAndThreads.networkThreadWithSocketServer ? rtc::Thread::CreateWithSocketServer() : rtc::Thread::Create();
+    factoryAndThreads.networkThread->SetName("WebKitWebRTCNetwork", nullptr);
+    bool result = factoryAndThreads.networkThread->Start();
+    ASSERT_UNUSED(result, result);
+
+    factoryAndThreads.signalingThread = rtc::Thread::Create();
+    factoryAndThreads.signalingThread->SetName("WebKitWebRTCSignaling", nullptr);
+
+    result = factoryAndThreads.signalingThread->Start();
+    ASSERT(result);
+
+    factoryAndThreads.audioDeviceModule = std::make_unique<LibWebRTCAudioModule>();
+}
+
 static inline PeerConnectionFactoryAndThreads& staticFactoryAndThreads()
 {
     static NeverDestroyed<PeerConnectionFactoryAndThreads> factoryAndThreads;
-#if PLATFORM(COCOA)
-    static std::once_flag once;
-    std::call_once(once, [] {
-        factoryAndThreads.get().encoderFactoryGetter = []() -> std::unique_ptr<cricket::WebRtcVideoEncoderFactory> { return std::make_unique<VideoToolboxVideoEncoderFactory>(); };
-        factoryAndThreads.get().decoderFactoryGetter = []() -> std::unique_ptr<cricket::WebRtcVideoDecoderFactory> { return std::make_unique<webrtc::VideoToolboxVideoDecoderFactory>(); };
-    });
-#endif
     return factoryAndThreads.get();
 }
 
+static inline PeerConnectionFactoryAndThreads& getStaticFactoryAndThreads(bool useNetworkThreadWithSocketServer)
+{
+    auto& factoryAndThreads = staticFactoryAndThreads();
+
+    ASSERT(!factoryAndThreads.networkThread || factoryAndThreads.networkThreadWithSocketServer == useNetworkThreadWithSocketServer);
+
+    if (!factoryAndThreads.networkThread) {
+        factoryAndThreads.networkThreadWithSocketServer = useNetworkThreadWithSocketServer;
+        initializePeerConnectionFactoryAndThreads(factoryAndThreads);
+    }
+    return factoryAndThreads;
+}
+
 struct ThreadMessageData : public rtc::MessageData {
     ThreadMessageData(Function<void()>&& callback)
         : callback(WTFMove(callback))
@@ -97,118 +128,78 @@ void LibWebRTCProvider::callOnWebRTCSignalingThread(Function<void()>&& callback)
     threads.signalingThread->Post(RTC_FROM_HERE, &threads, 1, new ThreadMessageData(WTFMove(callback)));
 }
 
-static void initializePeerConnectionFactoryAndThreads()
-{
-#if defined(NDEBUG)
-#if !LOG_DISABLED || !RELEASE_LOG_DISABLED
-    rtc::LogMessage::LogToDebug(LogWebRTC.state != WTFLogChannelOn ? rtc::LS_NONE : rtc::LS_INFO);
-#else
-    rtc::LogMessage::LogToDebug(rtc::LS_NONE);
-#endif
-#else
-    rtc::LogMessage::LogToDebug(LogWebRTC.state != WTFLogChannelOn ? rtc::LS_WARNING : rtc::LS_INFO);
-#endif
-    auto& factoryAndThreads = staticFactoryAndThreads();
-
-    ASSERT(!factoryAndThreads.factory);
-
-    factoryAndThreads.networkThread = factoryAndThreads.networkThreadWithSocketServer ? rtc::Thread::CreateWithSocketServer() : rtc::Thread::Create();
-    factoryAndThreads.networkThread->SetName("WebKitWebRTCNetwork", nullptr);
-    bool result = factoryAndThreads.networkThread->Start();
-    ASSERT_UNUSED(result, result);
-
-    factoryAndThreads.signalingThread = rtc::Thread::Create();
-    factoryAndThreads.signalingThread->SetName("WebKitWebRTCSignaling", nullptr);
-    
-    result = factoryAndThreads.signalingThread->Start();
-    ASSERT(result);
-
-    factoryAndThreads.audioDeviceModule = std::make_unique<LibWebRTCAudioModule>();
-
-    std::unique_ptr<cricket::WebRtcVideoEncoderFactory> encoderFactory = factoryAndThreads.encoderFactoryGetter ? factoryAndThreads.encoderFactoryGetter() : nullptr;
-    std::unique_ptr<cricket::WebRtcVideoDecoderFactory> decoderFactory = factoryAndThreads.decoderFactoryGetter ? factoryAndThreads.decoderFactoryGetter() : nullptr;
-
-    factoryAndThreads.factory = webrtc::CreatePeerConnectionFactory(factoryAndThreads.networkThread.get(), factoryAndThreads.networkThread.get(), factoryAndThreads.signalingThread.get(), factoryAndThreads.audioDeviceModule.get(), encoderFactory.release(), decoderFactory.release());
-
-    ASSERT(factoryAndThreads.factory);
-}
-
 webrtc::PeerConnectionFactoryInterface* LibWebRTCProvider::factory()
 {
+    if (m_factory)
+        return m_factory.get();
+
     if (!webRTCAvailable())
         return nullptr;
-    if (!staticFactoryAndThreads().factory) {
-        staticFactoryAndThreads().networkThreadWithSocketServer = m_useNetworkThreadWithSocketServer;
-        initializePeerConnectionFactoryAndThreads();
-    }
-    return staticFactoryAndThreads().factory;
-}
 
-void LibWebRTCProvider::setDecoderFactoryGetter(Function<std::unique_ptr<cricket::WebRtcVideoDecoderFactory>()>&& getter)
-{
-    if (!staticFactoryAndThreads().factory)
-        initializePeerConnectionFactoryAndThreads();
+    auto& factoryAndThreads = getStaticFactoryAndThreads(m_useNetworkThreadWithSocketServer);
 
-    staticFactoryAndThreads().decoderFactoryGetter = WTFMove(getter);
-}
+    auto decoderFactory = std::make_unique<VideoToolboxVideoDecoderFactory>();
+    auto encoderFactory = std::make_unique<VideoToolboxVideoEncoderFactory>();
 
-void LibWebRTCProvider::setEncoderFactoryGetter(Function<std::unique_ptr<cricket::WebRtcVideoEncoderFactory>()>&& getter)
-{
-    if (!staticFactoryAndThreads().factory)
-        initializePeerConnectionFactoryAndThreads();
+    m_decoderFactory = decoderFactory.get();
+    m_encoderFactory = encoderFactory.get();
 
-    staticFactoryAndThreads().encoderFactoryGetter = WTFMove(getter);
-}
+    m_factory = webrtc::CreatePeerConnectionFactory(factoryAndThreads.networkThread.get(), factoryAndThreads.networkThread.get(), factoryAndThreads.signalingThread.get(), factoryAndThreads.audioDeviceModule.get(), encoderFactory.release(), decoderFactory.release());
 
-void LibWebRTCProvider::setPeerConnectionFactory(rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface>&& factory)
-{
-    if (!staticFactoryAndThreads().factory)
-        initializePeerConnectionFactoryAndThreads();
-
-    staticFactoryAndThreads().factory = webrtc::PeerConnectionFactoryProxy::Create(staticFactoryAndThreads().signalingThread.get(), WTFMove(factory));
+    return m_factory;
 }
 
-static rtc::scoped_refptr<webrtc::PeerConnectionInterface> createActualPeerConnection(webrtc::PeerConnectionObserver& observer, std::unique_ptr<cricket::BasicPortAllocator>&& portAllocator, webrtc::PeerConnectionInterface::RTCConfiguration&& configuration)
+void LibWebRTCProvider::setPeerConnectionFactory(rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface>&& factory)
 {
-    ASSERT(staticFactoryAndThreads().factory);
-
-    return staticFactoryAndThreads().factory->CreatePeerConnection(configuration, WTFMove(portAllocator), nullptr, &observer);
+    m_factory = webrtc::PeerConnectionFactoryProxy::Create(getStaticFactoryAndThreads(m_useNetworkThreadWithSocketServer).signalingThread.get(), WTFMove(factory));
 }
 
 rtc::scoped_refptr<webrtc::PeerConnectionInterface> LibWebRTCProvider::createPeerConnection(webrtc::PeerConnectionObserver& observer, webrtc::PeerConnectionInterface::RTCConfiguration&& configuration)
 {
     // Default WK1 implementation.
-    auto& factoryAndThreads = staticFactoryAndThreads();
-    if (!factoryAndThreads.factory) {
-        staticFactoryAndThreads().networkThreadWithSocketServer = true;
-        initializePeerConnectionFactoryAndThreads();
-    }
-    ASSERT(staticFactoryAndThreads().networkThreadWithSocketServer);
+    ASSERT(m_useNetworkThreadWithSocketServer);
+    auto* factory = this->factory();
+    if (!factory)
+        return nullptr;
 
-    return createActualPeerConnection(observer, nullptr, WTFMove(configuration));
+    return m_factory->CreatePeerConnection(configuration, nullptr, nullptr, &observer);
 }
 
 rtc::scoped_refptr<webrtc::PeerConnectionInterface> LibWebRTCProvider::createPeerConnection(webrtc::PeerConnectionObserver& observer, rtc::NetworkManager& networkManager, rtc::PacketSocketFactory& packetSocketFactory, webrtc::PeerConnectionInterface::RTCConfiguration&& configuration)
 {
-    ASSERT(!staticFactoryAndThreads().networkThreadWithSocketServer);
+    ASSERT(!m_useNetworkThreadWithSocketServer);
 
-    auto& factoryAndThreads = staticFactoryAndThreads();
-    if (!factoryAndThreads.factory)
-        initializePeerConnectionFactoryAndThreads();
+    auto& factoryAndThreads = getStaticFactoryAndThreads(m_useNetworkThreadWithSocketServer);
 
     std::unique_ptr<cricket::BasicPortAllocator> portAllocator;
-    staticFactoryAndThreads().signalingThread->Invoke<void>(RTC_FROM_HERE, [&]() {
+    factoryAndThreads.signalingThread->Invoke<void>(RTC_FROM_HERE, [&]() {
         auto basicPortAllocator = std::make_unique<cricket::BasicPortAllocator>(&networkManager, &packetSocketFactory);
         if (!m_enableEnumeratingAllNetworkInterfaces)
             basicPortAllocator->set_flags(basicPortAllocator->flags() | cricket::PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION);
         portAllocator = WTFMove(basicPortAllocator);
     });
 
-    return createActualPeerConnection(observer, WTFMove(portAllocator), WTFMove(configuration));
+    auto* factory = this->factory();
+    if (!factory)
+        return nullptr;
+
+    return m_factory->CreatePeerConnection(configuration, WTFMove(portAllocator), nullptr, &observer);
 }
 
 #endif // USE(LIBWEBRTC)
 
+void LibWebRTCProvider::setActive(bool value)
+{
+#if USE(LIBWEBRTC)
+    if (m_decoderFactory)
+        m_decoderFactory->setActive(value);
+    if (m_encoderFactory)
+        m_encoderFactory->setActive(value);
+#else
+    UNUSED_PARAM(value);
+#endif
+}
+
 bool LibWebRTCProvider::webRTCAvailable()
 {
 #if USE(LIBWEBRTC)
index e726c60..6bc621e 100644 (file)
@@ -45,12 +45,18 @@ class PeerConnectionFactoryInterface;
 
 namespace WebCore {
 
+class VideoToolboxVideoDecoderFactory;
+class VideoToolboxVideoEncoderFactory;
+
 class WEBCORE_EXPORT LibWebRTCProvider {
 public:
     LibWebRTCProvider() = default;
     virtual ~LibWebRTCProvider() = default;
 
     static bool webRTCAvailable();
+
+    void setActive(bool);
+
 #if USE(LIBWEBRTC)
     WEBCORE_EXPORT virtual rtc::scoped_refptr<webrtc::PeerConnectionInterface> createPeerConnection(webrtc::PeerConnectionObserver&, webrtc::PeerConnectionInterface::RTCConfiguration&&);
 
@@ -59,11 +65,9 @@ public:
     // FIXME: Make these methods not static.
     static WEBCORE_EXPORT void callOnWebRTCNetworkThread(Function<void()>&&);
     static WEBCORE_EXPORT void callOnWebRTCSignalingThread(Function<void()>&&);
-    static WEBCORE_EXPORT void setDecoderFactoryGetter(Function<std::unique_ptr<cricket::WebRtcVideoDecoderFactory>()>&&);
-    static WEBCORE_EXPORT void setEncoderFactoryGetter(Function<std::unique_ptr<cricket::WebRtcVideoEncoderFactory>()>&&);
 
     // Used for mock testing
-    static void setPeerConnectionFactory(rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface>&&);
+    void setPeerConnectionFactory(rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface>&&);
 
     void disableEnumeratingAllNetworkInterfaces() { m_enableEnumeratingAllNetworkInterfaces = false; }
     void enableEnumeratingAllNetworkInterfaces() { m_enableEnumeratingAllNetworkInterfaces = true; }
@@ -72,7 +76,12 @@ protected:
     WEBCORE_EXPORT rtc::scoped_refptr<webrtc::PeerConnectionInterface> createPeerConnection(webrtc::PeerConnectionObserver&, rtc::NetworkManager&, rtc::PacketSocketFactory&, webrtc::PeerConnectionInterface::RTCConfiguration&&);
 
     bool m_enableEnumeratingAllNetworkInterfaces { false };
+    // FIXME: Remove m_useNetworkThreadWithSocketServer member variable and make it a global.
     bool m_useNetworkThreadWithSocketServer { true };
+
+    rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> m_factory;
+    VideoToolboxVideoDecoderFactory* m_decoderFactory { nullptr };
+    VideoToolboxVideoEncoderFactory* m_encoderFactory { nullptr };
 #endif
 };
 
diff --git a/Source/WebCore/platform/mediastream/libwebrtc/VideoToolBoxDecoderFactory.cpp b/Source/WebCore/platform/mediastream/libwebrtc/VideoToolBoxDecoderFactory.cpp
new file mode 100644 (file)
index 0000000..595aa4a
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * 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 "VideoToolBoxDecoderFactory.h"
+
+#if USE(LIBWEBRTC) && PLATFORM(COCOA)
+
+namespace WebCore {
+
+void VideoToolboxVideoDecoderFactory::setActive(bool isActive)
+{
+    if (m_isActive == isActive)
+        return;
+
+    m_isActive = isActive;
+    for (webrtc::H264VideoToolboxDecoder& decoder : m_decoders)
+        decoder.SetActive(isActive);
+}
+
+webrtc::VideoDecoder* VideoToolboxVideoDecoderFactory::CreateVideoDecoder(webrtc::VideoCodecType type)
+{
+    auto* decoder = webrtc::VideoToolboxVideoDecoderFactory::CreateVideoDecoder(type);
+    if (decoder)
+        m_decoders.append(static_cast<webrtc::H264VideoToolboxDecoder&>(*decoder));
+
+    return decoder;
+}
+
+void VideoToolboxVideoDecoderFactory::DestroyVideoDecoder(webrtc::VideoDecoder* decoder)
+{
+    m_decoders.removeFirstMatching([&] (const auto& item) {
+        return &item.get() == decoder;
+    });
+    webrtc::VideoToolboxVideoDecoderFactory::DestroyVideoDecoder(decoder);
+}
+
+}
+#endif
diff --git a/Source/WebCore/platform/mediastream/libwebrtc/VideoToolBoxDecoderFactory.h b/Source/WebCore/platform/mediastream/libwebrtc/VideoToolBoxDecoderFactory.h
new file mode 100644 (file)
index 0000000..79ddb0d
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * 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) && PLATFORM(COCOA)
+
+#include "LibWebRTCMacros.h"
+#include <webrtc/sdk/objc/Framework/Classes/VideoToolbox/decoder.h>
+#include <webrtc/sdk/objc/Framework/Classes/VideoToolbox/videocodecfactory.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class VideoToolboxVideoDecoderFactory final : public webrtc::VideoToolboxVideoDecoderFactory {
+public:
+    VideoToolboxVideoDecoderFactory() = default;
+
+    void setActive(bool isActive);
+
+private:
+    webrtc::VideoDecoder* CreateVideoDecoder(webrtc::VideoCodecType) final;
+    void DestroyVideoDecoder(webrtc::VideoDecoder*) final;
+
+    Vector<std::reference_wrapper<webrtc::H264VideoToolboxDecoder>> m_decoders;
+    bool m_isActive { true };
+};
+
+}
+
+#endif
index bb93a02..6161c8f 100644 (file)
 
 namespace WebCore {
 
+void VideoToolboxVideoEncoderFactory::setActive(bool isActive)
+{
+    if (m_isActive == isActive)
+        return;
+
+    m_isActive = isActive;
+    for (H264VideoToolboxEncoder& encoder : m_encoders)
+        encoder.SetActive(isActive);
+}
+
 webrtc::VideoEncoder* VideoToolboxVideoEncoderFactory::CreateSupportedVideoEncoder(const cricket::VideoCodec& codec)
 {
-    return new H264VideoToolboxEncoder(codec);
+    auto* encoder = new H264VideoToolboxEncoder(codec);
+    m_encoders.append(*encoder);
+
+    return encoder;
 }
 
 void VideoToolboxVideoEncoderFactory::DestroyVideoEncoder(webrtc::VideoEncoder* encoder)
 {
+    m_encoders.removeFirstMatching([&] (const auto& item) {
+        return &item.get() == encoder;
+    });
+
     delete encoder;
-    encoder = nullptr;
 }
 
 }
index 4b3ed45..bcfe224 100644 (file)
 
 #include "LibWebRTCMacros.h"
 #include <webrtc/sdk/objc/Framework/Classes/VideoToolbox/videocodecfactory.h>
+#include <wtf/Vector.h>
 
 namespace WebCore {
 
+class H264VideoToolboxEncoder;
+
 class VideoToolboxVideoEncoderFactory final : public webrtc::VideoToolboxVideoEncoderFactory {
 public:
     VideoToolboxVideoEncoderFactory() = default;
 
+    void setActive(bool isActive);
+
 private:
     webrtc::VideoEncoder* CreateSupportedVideoEncoder(const cricket::VideoCodec&) final;
     void DestroyVideoEncoder(webrtc::VideoEncoder*) final;
+
+    Vector<std::reference_wrapper<H264VideoToolboxEncoder>> m_encoders;
+    bool m_isActive { true };
 };
 
 }
index 08a25b5..8350976 100644 (file)
@@ -463,7 +463,7 @@ void Internals::resetToConsistentState(Page& page)
     printContextForTesting() = nullptr;
 
 #if USE(LIBWEBRTC)
-    WebCore::useRealRTCPeerConnectionFactory();
+    WebCore::useRealRTCPeerConnectionFactory(page.libWebRTCProvider());
 #endif
 
     page.settings().setStorageAccessAPIEnabled(false);
index 468130d..0d7f9e4 100644 (file)
@@ -47,23 +47,25 @@ static inline webrtc::PeerConnectionFactoryInterface* realPeerConnectionFactory(
     return getRealPeerConnectionFactory().get();
 }
 
-void useRealRTCPeerConnectionFactory()
+void useRealRTCPeerConnectionFactory(LibWebRTCProvider& provider)
 {
     auto& factory = getRealPeerConnectionFactory();
     if (!factory)
         return;
-    LibWebRTCProvider::setPeerConnectionFactory(factory.get());
+    provider.setPeerConnectionFactory(factory.get());
     factory = nullptr;
 }
 
 void useMockRTCPeerConnectionFactory(LibWebRTCProvider* provider, const String& testCase)
 {
-    if (provider && !realPeerConnectionFactory()) {
+    if (!provider)
+        return;
+
+    if (!realPeerConnectionFactory()) {
         auto& factory = getRealPeerConnectionFactory();
         factory = provider->factory();
     }
-
-    LibWebRTCProvider::setPeerConnectionFactory(MockLibWebRTCPeerConnectionFactory::create(String(testCase)));
+    provider->setPeerConnectionFactory(MockLibWebRTCPeerConnectionFactory::create(String(testCase)));
 }
 
 class MockLibWebRTCPeerConnectionForIceCandidates : public MockLibWebRTCPeerConnection {
index 037be3f..9450359 100644 (file)
@@ -37,7 +37,7 @@ class LibWebRTCProvider;
 class MockRtpSender;
 
 void useMockRTCPeerConnectionFactory(LibWebRTCProvider*, const String&);
-void useRealRTCPeerConnectionFactory();
+void useRealRTCPeerConnectionFactory(LibWebRTCProvider&);
 
 class MockLibWebRTCPeerConnection : public webrtc::PeerConnectionInterface {
 public:
index 6916250..11a7b32 100644 (file)
@@ -1,3 +1,17 @@
+2017-09-25  Youenn Fablet  <youenn@apple.com>
+
+        WebRTC video does not resume receiving when switching back to Safari 11 on iOS
+        https://bugs.webkit.org/show_bug.cgi?id=175472
+        <rdar://problem/33860863>
+
+        Reviewed by Darin Adler.
+
+        Notifying LibWebRTC of backgrounding/foregrouding.
+
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::WebPage::applicationDidEnterBackground):
+        (WebKit::WebPage::applicationWillEnterForeground):
+
 2017-09-25  Sam Weinig  <sam@webkit.org>
 
         Remove unused EditorClient functions
index dbafa15..7936acf 100644 (file)
@@ -86,6 +86,7 @@
 #import <WebCore/HistoryItem.h>
 #import <WebCore/HitTestResult.h>
 #import <WebCore/KeyboardEvent.h>
+#import <WebCore/LibWebRTCProvider.h>
 #import <WebCore/MainFrame.h>
 #import <WebCore/MediaSessionManagerIOS.h>
 #import <WebCore/Node.h>
@@ -3109,6 +3110,8 @@ void WebPage::applicationDidEnterBackground(bool isSuspendedUnderLock)
 
     m_isSuspendedUnderLock = isSuspendedUnderLock;
     setLayerTreeStateIsFrozen(true);
+
+    m_page->libWebRTCProvider().setActive(false);
 }
 
 void WebPage::applicationDidFinishSnapshottingAfterEnteringBackground()
@@ -3123,6 +3126,8 @@ void WebPage::applicationWillEnterForeground(bool isSuspendedUnderLock)
     setLayerTreeStateIsFrozen(false);
 
     [[NSNotificationCenter defaultCenter] postNotificationName:WebUIApplicationWillEnterForegroundNotification object:nil userInfo:@{@"isSuspendedUnderLock": @(isSuspendedUnderLock)}];
+
+    m_page->libWebRTCProvider().setActive(true);
 }
 
 void WebPage::applicationDidBecomeActive()
index be19fba..7bcb53a 100644 (file)
       buildConfiguration = "Debug"
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      language = ""
       shouldUseLaunchSchemeArgsEnv = "YES">
       <Testables>
       </Testables>
       buildConfiguration = "Debug"
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      language = ""
       launchStyle = "0"
       useCustomWorkingDirectory = "NO"
       ignoresPersistentStateOnLaunch = "YES"