Title: [273732] trunk
Revision
273732
Author
[email protected]
Date
2021-03-02 09:16:24 -0800 (Tue, 02 Mar 2021)

Log Message

Use capture settings after recovering capture from GPUProcess
https://bugs.webkit.org/show_bug.cgi?id=221126
<rdar://problem/73744819>

Reviewed by Eric Carlson.

Source/WebKit:

When updating constraints, store the constraints so that, on crash recovery,
we recreate the remote source and reapply the last constraints.

Manually tested and partially covered by API test.

* WebProcess/cocoa/RemoteRealtimeAudioSource.cpp:
(WebKit::RemoteRealtimeAudioSource::applyConstraints):
(WebKit::RemoteRealtimeAudioSource::gpuProcessConnectionDidClose):
* WebProcess/cocoa/RemoteRealtimeAudioSource.h:
* WebProcess/cocoa/RemoteRealtimeVideoSource.cpp:
(WebKit::RemoteRealtimeVideoSource::setFrameRateWithPreset):
(WebKit::RemoteRealtimeVideoSource::gpuProcessConnectionDidClose):
* WebProcess/cocoa/RemoteRealtimeVideoSource.h:

Tools:

* TestWebKitAPI/Tests/WebKit/GetUserMedia.mm:
(TestWebKitAPI::TEST):
* TestWebKitAPI/Tests/WebKit/getUserMedia.html:

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (273731 => 273732)


--- trunk/Source/WebKit/ChangeLog	2021-03-02 16:31:54 UTC (rev 273731)
+++ trunk/Source/WebKit/ChangeLog	2021-03-02 17:16:24 UTC (rev 273732)
@@ -1,3 +1,25 @@
+2021-03-02  Youenn Fablet  <[email protected]>
+
+        Use capture settings after recovering capture from GPUProcess
+        https://bugs.webkit.org/show_bug.cgi?id=221126
+        <rdar://problem/73744819>
+
+        Reviewed by Eric Carlson.
+
+        When updating constraints, store the constraints so that, on crash recovery,
+        we recreate the remote source and reapply the last constraints.
+
+        Manually tested and partially covered by API test.
+
+        * WebProcess/cocoa/RemoteRealtimeAudioSource.cpp:
+        (WebKit::RemoteRealtimeAudioSource::applyConstraints):
+        (WebKit::RemoteRealtimeAudioSource::gpuProcessConnectionDidClose):
+        * WebProcess/cocoa/RemoteRealtimeAudioSource.h:
+        * WebProcess/cocoa/RemoteRealtimeVideoSource.cpp:
+        (WebKit::RemoteRealtimeVideoSource::setFrameRateWithPreset):
+        (WebKit::RemoteRealtimeVideoSource::gpuProcessConnectionDidClose):
+        * WebProcess/cocoa/RemoteRealtimeVideoSource.h:
+
 2021-03-02  Rob Buis  <[email protected]>
 
         Null check platformData when decoding

Modified: trunk/Source/WebKit/WebProcess/cocoa/RemoteRealtimeAudioSource.cpp (273731 => 273732)


--- trunk/Source/WebKit/WebProcess/cocoa/RemoteRealtimeAudioSource.cpp	2021-03-02 16:31:54 UTC (rev 273731)
+++ trunk/Source/WebKit/WebProcess/cocoa/RemoteRealtimeAudioSource.cpp	2021-03-02 17:16:24 UTC (rev 273732)
@@ -135,6 +135,12 @@
     hasEnded();
 }
 
+void RemoteRealtimeAudioSource::applyConstraints(const MediaConstraints& constraints, ApplyConstraintsHandler&& callback)
+{
+    m_constraints = constraints;
+    m_proxy.applyConstraints(constraints, WTFMove(callback));
+}
+
 #if ENABLE(GPU_PROCESS)
 void RemoteRealtimeAudioSource::gpuProcessConnectionDidClose(GPUProcessConnection&)
 {
@@ -153,11 +159,14 @@
     m_manager.remoteCaptureSampleManager().didUpdateSourceConnection(connection());
     m_proxy.resetReady();
     createRemoteMediaSource();
-    // FIXME: We should update the track according current settings.
+
+    m_proxy.failApplyConstraintCallbacks("GPU Process terminated"_s);
+    if (m_constraints)
+        m_proxy.applyConstraints(*m_constraints, [](auto) { });
+
     if (isProducingData())
         startProducingData();
 
-    m_proxy.failApplyConstraintCallbacks("GPU Process terminated"_s);
 }
 #endif
 

Modified: trunk/Source/WebKit/WebProcess/cocoa/RemoteRealtimeAudioSource.h (273731 => 273732)


--- trunk/Source/WebKit/WebProcess/cocoa/RemoteRealtimeAudioSource.h	2021-03-02 16:31:54 UTC (rev 273731)
+++ trunk/Source/WebKit/WebProcess/cocoa/RemoteRealtimeAudioSource.h	2021-03-02 17:16:24 UTC (rev 273732)
@@ -79,7 +79,7 @@
     bool isCaptureSource() const final { return true; }
     void beginConfiguration() final { }
     void commitConfiguration() final { }
-    void applyConstraints(const WebCore::MediaConstraints& constraints, ApplyConstraintsHandler&& callback) final { m_proxy.applyConstraints(constraints, WTFMove(callback)); }
+    void applyConstraints(const WebCore::MediaConstraints&, ApplyConstraintsHandler&&);
     void hasEnded() final;
     const WebCore::RealtimeMediaSourceSettings& settings() final { return m_settings; }
     const WebCore::RealtimeMediaSourceCapabilities& capabilities() final { return m_capabilities; }
@@ -96,6 +96,7 @@
 
     RemoteRealtimeMediaSourceProxy m_proxy;
     UserMediaCaptureManager& m_manager;
+    Optional<WebCore::MediaConstraints> m_constraints;
     WebCore::RealtimeMediaSourceCapabilities m_capabilities;
     WebCore::RealtimeMediaSourceSettings m_settings;
 };

Modified: trunk/Source/WebKit/WebProcess/cocoa/RemoteRealtimeVideoSource.cpp (273731 => 273732)


--- trunk/Source/WebKit/WebProcess/cocoa/RemoteRealtimeVideoSource.cpp	2021-03-02 16:31:54 UTC (rev 273731)
+++ trunk/Source/WebKit/WebProcess/cocoa/RemoteRealtimeVideoSource.cpp	2021-03-02 17:16:24 UTC (rev 273732)
@@ -186,7 +186,8 @@
         constraints.mandatoryConstraints.set(MediaConstraintType::Height, heightConstraint);
     }
 
-    connection()->send(Messages::UserMediaCaptureManagerProxy::ApplyConstraints { identifier(), constraints }, 0);
+    m_sizeConstraints = constraints;
+    m_proxy.applyConstraints(constraints, [](auto) { });
 }
 
 bool RemoteRealtimeVideoSource::prefersPreset(VideoPreset&)
@@ -212,7 +213,10 @@
     m_manager.remoteCaptureSampleManager().didUpdateSourceConnection(connection());
     m_proxy.resetReady();
     createRemoteMediaSource();
-    // FIXME: We should update the track according current settings.
+
+    if (m_sizeConstraints)
+        m_proxy.applyConstraints(*m_sizeConstraints, [](auto) { });
+
     if (isProducingData())
         startProducingData();
 }

Modified: trunk/Source/WebKit/WebProcess/cocoa/RemoteRealtimeVideoSource.h (273731 => 273732)


--- trunk/Source/WebKit/WebProcess/cocoa/RemoteRealtimeVideoSource.h	2021-03-02 16:31:54 UTC (rev 273731)
+++ trunk/Source/WebKit/WebProcess/cocoa/RemoteRealtimeVideoSource.h	2021-03-02 17:16:24 UTC (rev 273732)
@@ -103,6 +103,7 @@
     RemoteRealtimeMediaSourceProxy m_proxy;
     UserMediaCaptureManager& m_manager;
 
+    Optional<WebCore::MediaConstraints> m_sizeConstraints;
     WebCore::RealtimeMediaSourceCapabilities m_capabilities;
     WebCore::RealtimeMediaSourceSettings m_settings;
     WebCore::MediaSample::VideoRotation m_sampleRotation { WebCore::MediaSample::VideoRotation::None };

Modified: trunk/Tools/ChangeLog (273731 => 273732)


--- trunk/Tools/ChangeLog	2021-03-02 16:31:54 UTC (rev 273731)
+++ trunk/Tools/ChangeLog	2021-03-02 17:16:24 UTC (rev 273732)
@@ -1,5 +1,17 @@
 2021-03-02  Youenn Fablet  <[email protected]>
 
+        Use capture settings after recovering capture from GPUProcess
+        https://bugs.webkit.org/show_bug.cgi?id=221126
+        <rdar://problem/73744819>
+
+        Reviewed by Eric Carlson.
+
+        * TestWebKitAPI/Tests/WebKit/GetUserMedia.mm:
+        (TestWebKitAPI::TEST):
+        * TestWebKitAPI/Tests/WebKit/getUserMedia.html:
+
+2021-03-02  Youenn Fablet  <[email protected]>
+
         Enable MEDIA_SOURCE in IOS Simulator
         https://bugs.webkit.org/show_bug.cgi?id=222041
         <rdar://problem/74433510>

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKit/GetUserMedia.mm (273731 => 273732)


--- trunk/Tools/TestWebKitAPI/Tests/WebKit/GetUserMedia.mm	2021-03-02 16:31:54 UTC (rev 273731)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit/GetUserMedia.mm	2021-03-02 17:16:24 UTC (rev 273732)
@@ -421,6 +421,81 @@
     EXPECT_EQ(webViewPID, [webView _webProcessIdentifier]);
 }
 
+TEST(WebKit2, CrashGPUProcessAfterApplyingConstraints)
+{
+    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    auto preferences = [configuration preferences];
+
+    for (_WKInternalDebugFeature *feature in [WKPreferences _internalDebugFeatures]) {
+        if ([feature.key isEqualToString:@"CaptureAudioInGPUProcessEnabled"])
+            [preferences _setEnabled:YES forInternalDebugFeature:feature];
+        if ([feature.key isEqualToString:@"CaptureAudioInUIProcessEnabled"])
+            [preferences _setEnabled:NO forInternalDebugFeature:feature];
+        if ([feature.key isEqualToString:@"CaptureVideoInGPUProcessEnabled"])
+            [preferences _setEnabled:YES forInternalDebugFeature:feature];
+    }
+    preferences._mediaCaptureRequiresSecureConnection = NO;
+    configuration.get()._mediaCaptureEnabled = YES;
+    preferences._mockCaptureDevicesEnabled = YES;
+
+#if PLATFORM(IOS_FAMILY)
+    [configuration setAllowsInlineMediaPlayback:YES];
+#endif
+
+    auto messageHandler = adoptNS([[GUMMessageHandler alloc] init]);
+    [[configuration userContentController] addScriptMessageHandler:messageHandler.get() name:@"gum"];
+
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 400, 400) configuration:configuration.get()]);
+
+    auto delegate = adoptNS([[UserMediaCaptureUIDelegate alloc] init]);
+    webView.get().UIDelegate = delegate.get();
+
+    [webView loadTestPageNamed:@"getUserMedia"];
+    EXPECT_TRUE(waitUntilCaptureState(webView.get(), _WKMediaCaptureStateActiveCamera));
+
+    done = false;
+    [webView stringByEvaluatingJavaScript:@"captureAudioAndVideo(true)"];
+    TestWebKitAPI::Util::run(&done);
+
+    done = false;
+    [webView stringByEvaluatingJavaScript:@"changeConstraints()"];
+    TestWebKitAPI::Util::run(&done);
+
+    auto webViewPID = [webView _webProcessIdentifier];
+
+    // The GPU process should get launched.
+    auto* processPool = configuration.get().processPool;
+    unsigned timeout = 0;
+    while (![processPool _gpuProcessIdentifier] && timeout++ < 100)
+        TestWebKitAPI::Util::sleep(0.1);
+
+    EXPECT_NE([processPool _gpuProcessIdentifier], 0);
+    if (![processPool _gpuProcessIdentifier])
+        return;
+    auto gpuProcessPID = [processPool _gpuProcessIdentifier];
+
+    // Kill the GPU Process.
+    kill(gpuProcessPID, 9);
+
+    // GPU Process should get relaunched.
+    timeout = 0;
+    while ((![processPool _gpuProcessIdentifier] || [processPool _gpuProcessIdentifier] == gpuProcessPID) && timeout++ < 100)
+        TestWebKitAPI::Util::sleep(0.1);
+    EXPECT_NE([processPool _gpuProcessIdentifier], 0);
+    EXPECT_NE([processPool _gpuProcessIdentifier], gpuProcessPID);
+    gpuProcessPID = [processPool _gpuProcessIdentifier];
+
+    // Make sure the WebProcess did not crash.
+    EXPECT_EQ(webViewPID, [webView _webProcessIdentifier]);
+
+    done = false;
+    [webView stringByEvaluatingJavaScript:@"checkConstraintsStatus()"];
+    TestWebKitAPI::Util::run(&done);
+
+    EXPECT_EQ(gpuProcessPID, [processPool _gpuProcessIdentifier]);
+    EXPECT_EQ(webViewPID, [webView _webProcessIdentifier]);
+}
+
 TEST(WebKit2, CrashGPUProcessWhileCapturingAndCalling)
 {
     auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKit/getUserMedia.html (273731 => 273732)


--- trunk/Tools/TestWebKitAPI/Tests/WebKit/getUserMedia.html	2021-03-02 16:31:54 UTC (rev 273731)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit/getUserMedia.html	2021-03-02 17:16:24 UTC (rev 273732)
@@ -193,11 +193,57 @@
                     setTimeout(() => checkAudioStatus(++counter), 50);
                 });
             }
+
+            function changeConstraints() {
+                async function doChangeConstraints() {
+                    const videoTrack = stream.getVideoTracks()[0];
+                    await videoTrack.applyConstraints({ width: 320, height: 240, frameRate: 5});
+
+                    const audioTrack = stream.getAudioTracks()[0];
+                    await audioTrack.applyConstraints({ echoCancellation: false });
+                }
+                doChangeConstraints().then(() => {
+                    window.webkit.messageHandlers.gum.postMessage("PASS");
+                }, (e) => {
+                    window.webkit.messageHandlers.gum.postMessage("FAIL doChangeConstraints: " + e);
+                });
+            }
+
+            function checkConstraintsStatus() {
+                async function doCheckConstraints() {
+                    video2.srcObject = stream;
+                    await video2.play();
+
+                    if (video2.videoWidth !== 320) {
+                        window.webkit.messageHandlers.gum.postMessage("FAIL checkConstraints, width is not 320 but " + video.videoWidth);
+                        return;
+                    }
+                    if (video2.videoHeight !== 240) {
+                        window.webkit.messageHandlers.gum.postMessage("FAIL checkConstraints, height is not 240 but " + video.videoHeight);
+                        return;
+                    }
+                    let settings = stream.getVideoTracks()[0].getSettings();
+                    if (settings.width !== 320 && settings.height !== 240) {
+                        window.webkit.messageHandlers.gum.postMessage("FAIL checkConstraints, video settings are not correct");
+                        return;
+                    }
+                    settings = stream.getAudioTracks()[0].getSettings();
+                    if (settings.echoCancellation) {
+                        window.webkit.messageHandlers.gum.postMessage("FAIL checkConstraints, audio settings are not correct");
+                        return;
+                    }
+                    window.webkit.messageHandlers.gum.postMessage("PASS");
+                }
+                doCheckConstraints().catch(e => {
+                    window.webkit.messageHandlers.gum.postMessage("FAIL checkConstraintsStatus, " + e);
+                });
+            }
         </script>
     <head>
 
     <body _onload_="promptForCapture()">
-        <video id="video" controls></video>
+        <video id="video" controls playsinline autoplay></video>
+        <video id="video2" controls playsinline autoplay></video>
         <p>
         <button _onclick_="stop()">Stop</button>
         </p>
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to