⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 273732 in webkit


Ignore:
Timestamp:
Mar 2, 2021, 9:16:24 AM (6 years ago)
Author:
youenn@apple.com
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:
Location:
trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r273727 r273732  
     12021-03-02  Youenn Fablet  <youenn@apple.com>
     2
     3        Use capture settings after recovering capture from GPUProcess
     4        https://bugs.webkit.org/show_bug.cgi?id=221126
     5        <rdar://problem/73744819>
     6
     7        Reviewed by Eric Carlson.
     8
     9        When updating constraints, store the constraints so that, on crash recovery,
     10        we recreate the remote source and reapply the last constraints.
     11
     12        Manually tested and partially covered by API test.
     13
     14        * WebProcess/cocoa/RemoteRealtimeAudioSource.cpp:
     15        (WebKit::RemoteRealtimeAudioSource::applyConstraints):
     16        (WebKit::RemoteRealtimeAudioSource::gpuProcessConnectionDidClose):
     17        * WebProcess/cocoa/RemoteRealtimeAudioSource.h:
     18        * WebProcess/cocoa/RemoteRealtimeVideoSource.cpp:
     19        (WebKit::RemoteRealtimeVideoSource::setFrameRateWithPreset):
     20        (WebKit::RemoteRealtimeVideoSource::gpuProcessConnectionDidClose):
     21        * WebProcess/cocoa/RemoteRealtimeVideoSource.h:
     22
    1232021-03-02  Rob Buis  <rbuis@igalia.com>
    224
  • trunk/Source/WebKit/WebProcess/cocoa/RemoteRealtimeAudioSource.cpp

    r272855 r273732  
    136136}
    137137
     138void RemoteRealtimeAudioSource::applyConstraints(const MediaConstraints& constraints, ApplyConstraintsHandler&& callback)
     139{
     140    m_constraints = constraints;
     141    m_proxy.applyConstraints(constraints, WTFMove(callback));
     142}
     143
    138144#if ENABLE(GPU_PROCESS)
    139145void RemoteRealtimeAudioSource::gpuProcessConnectionDidClose(GPUProcessConnection&)
    … …  
    154160    m_proxy.resetReady();
    155161    createRemoteMediaSource();
    156     // FIXME: We should update the track according current settings.
     162
     163    m_proxy.failApplyConstraintCallbacks("GPU Process terminated"_s);
     164    if (m_constraints)
     165        m_proxy.applyConstraints(*m_constraints, [](auto) { });
     166
    157167    if (isProducingData())
    158168        startProducingData();
    159169
    160     m_proxy.failApplyConstraintCallbacks("GPU Process terminated"_s);
    161170}
    162171#endif
  • trunk/Source/WebKit/WebProcess/cocoa/RemoteRealtimeAudioSource.h

    r272855 r273732  
    8080    void beginConfiguration() final { }
    8181    void commitConfiguration() final { }
    82     void applyConstraints(const WebCore::MediaConstraints& constraints, ApplyConstraintsHandler&& callback) final { m_proxy.applyConstraints(constraints, WTFMove(callback)); }
     82    void applyConstraints(const WebCore::MediaConstraints&, ApplyConstraintsHandler&&);
    8383    void hasEnded() final;
    8484    const WebCore::RealtimeMediaSourceSettings& settings() final { return m_settings; }
    … …  
    9797    RemoteRealtimeMediaSourceProxy m_proxy;
    9898    UserMediaCaptureManager& m_manager;
     99    Optional<WebCore::MediaConstraints> m_constraints;
    99100    WebCore::RealtimeMediaSourceCapabilities m_capabilities;
    100101    WebCore::RealtimeMediaSourceSettings m_settings;
  • trunk/Source/WebKit/WebProcess/cocoa/RemoteRealtimeVideoSource.cpp

    r272855 r273732  
    187187    }
    188188
    189     connection()->send(Messages::UserMediaCaptureManagerProxy::ApplyConstraints { identifier(), constraints }, 0);
     189    m_sizeConstraints = constraints;
     190    m_proxy.applyConstraints(constraints, [](auto) { });
    190191}
    191192
    … …  
    213214    m_proxy.resetReady();
    214215    createRemoteMediaSource();
    215     // FIXME: We should update the track according current settings.
     216
     217    if (m_sizeConstraints)
     218        m_proxy.applyConstraints(*m_sizeConstraints, [](auto) { });
     219
    216220    if (isProducingData())
    217221        startProducingData();
  • trunk/Source/WebKit/WebProcess/cocoa/RemoteRealtimeVideoSource.h

    r272855 r273732  
    104104    UserMediaCaptureManager& m_manager;
    105105
     106    Optional<WebCore::MediaConstraints> m_sizeConstraints;
    106107    WebCore::RealtimeMediaSourceCapabilities m_capabilities;
    107108    WebCore::RealtimeMediaSourceSettings m_settings;
  • trunk/Tools/ChangeLog

    r273730 r273732  
     12021-03-02  Youenn Fablet  <youenn@apple.com>
     2
     3        Use capture settings after recovering capture from GPUProcess
     4        https://bugs.webkit.org/show_bug.cgi?id=221126
     5        <rdar://problem/73744819>
     6
     7        Reviewed by Eric Carlson.
     8
     9        * TestWebKitAPI/Tests/WebKit/GetUserMedia.mm:
     10        (TestWebKitAPI::TEST):
     11        * TestWebKitAPI/Tests/WebKit/getUserMedia.html:
     12
    1132021-03-02  Youenn Fablet  <youenn@apple.com>
    214
  • trunk/Tools/TestWebKitAPI/Tests/WebKit/GetUserMedia.mm

    r273308 r273732  
    422422}
    423423
     424TEST(WebKit2, CrashGPUProcessAfterApplyingConstraints)
     425{
     426    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
     427    auto preferences = [configuration preferences];
     428
     429    for (_WKInternalDebugFeature *feature in [WKPreferences _internalDebugFeatures]) {
     430        if ([feature.key isEqualToString:@"CaptureAudioInGPUProcessEnabled"])
     431            [preferences _setEnabled:YES forInternalDebugFeature:feature];
     432        if ([feature.key isEqualToString:@"CaptureAudioInUIProcessEnabled"])
     433            [preferences _setEnabled:NO forInternalDebugFeature:feature];
     434        if ([feature.key isEqualToString:@"CaptureVideoInGPUProcessEnabled"])
     435            [preferences _setEnabled:YES forInternalDebugFeature:feature];
     436    }
     437    preferences._mediaCaptureRequiresSecureConnection = NO;
     438    configuration.get()._mediaCaptureEnabled = YES;
     439    preferences._mockCaptureDevicesEnabled = YES;
     440
     441#if PLATFORM(IOS_FAMILY)
     442    [configuration setAllowsInlineMediaPlayback:YES];
     443#endif
     444
     445    auto messageHandler = adoptNS([[GUMMessageHandler alloc] init]);
     446    [[configuration userContentController] addScriptMessageHandler:messageHandler.get() name:@"gum"];
     447
     448    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 400, 400) configuration:configuration.get()]);
     449
     450    auto delegate = adoptNS([[UserMediaCaptureUIDelegate alloc] init]);
     451    webView.get().UIDelegate = delegate.get();
     452
     453    [webView loadTestPageNamed:@"getUserMedia"];
     454    EXPECT_TRUE(waitUntilCaptureState(webView.get(), _WKMediaCaptureStateActiveCamera));
     455
     456    done = false;
     457    [webView stringByEvaluatingJavaScript:@"captureAudioAndVideo(true)"];
     458    TestWebKitAPI::Util::run(&done);
     459
     460    done = false;
     461    [webView stringByEvaluatingJavaScript:@"changeConstraints()"];
     462    TestWebKitAPI::Util::run(&done);
     463
     464    auto webViewPID = [webView _webProcessIdentifier];
     465
     466    // The GPU process should get launched.
     467    auto* processPool = configuration.get().processPool;
     468    unsigned timeout = 0;
     469    while (![processPool _gpuProcessIdentifier] && timeout++ < 100)
     470        TestWebKitAPI::Util::sleep(0.1);
     471
     472    EXPECT_NE([processPool _gpuProcessIdentifier], 0);
     473    if (![processPool _gpuProcessIdentifier])
     474        return;
     475    auto gpuProcessPID = [processPool _gpuProcessIdentifier];
     476
     477    // Kill the GPU Process.
     478    kill(gpuProcessPID, 9);
     479
     480    // GPU Process should get relaunched.
     481    timeout = 0;
     482    while ((![processPool _gpuProcessIdentifier] || [processPool _gpuProcessIdentifier] == gpuProcessPID) && timeout++ < 100)
     483        TestWebKitAPI::Util::sleep(0.1);
     484    EXPECT_NE([processPool _gpuProcessIdentifier], 0);
     485    EXPECT_NE([processPool _gpuProcessIdentifier], gpuProcessPID);
     486    gpuProcessPID = [processPool _gpuProcessIdentifier];
     487
     488    // Make sure the WebProcess did not crash.
     489    EXPECT_EQ(webViewPID, [webView _webProcessIdentifier]);
     490
     491    done = false;
     492    [webView stringByEvaluatingJavaScript:@"checkConstraintsStatus()"];
     493    TestWebKitAPI::Util::run(&done);
     494
     495    EXPECT_EQ(gpuProcessPID, [processPool _gpuProcessIdentifier]);
     496    EXPECT_EQ(webViewPID, [webView _webProcessIdentifier]);
     497}
     498
    424499TEST(WebKit2, CrashGPUProcessWhileCapturingAndCalling)
    425500{
  • trunk/Tools/TestWebKitAPI/Tests/WebKit/getUserMedia.html

    r272202 r273732  
    194194                });
    195195            }
     196
     197            function changeConstraints() {
     198                async function doChangeConstraints() {
     199                    const videoTrack = stream.getVideoTracks()[0];
     200                    await videoTrack.applyConstraints({ width: 320, height: 240, frameRate: 5});
     201
     202                    const audioTrack = stream.getAudioTracks()[0];
     203                    await audioTrack.applyConstraints({ echoCancellation: false });
     204                }
     205                doChangeConstraints().then(() => {
     206                    window.webkit.messageHandlers.gum.postMessage("PASS");
     207                }, (e) => {
     208                    window.webkit.messageHandlers.gum.postMessage("FAIL doChangeConstraints: " + e);
     209                });
     210            }
     211
     212            function checkConstraintsStatus() {
     213                async function doCheckConstraints() {
     214                    video2.srcObject = stream;
     215                    await video2.play();
     216
     217                    if (video2.videoWidth !== 320) {
     218                        window.webkit.messageHandlers.gum.postMessage("FAIL checkConstraints, width is not 320 but " + video.videoWidth);
     219                        return;
     220                    }
     221                    if (video2.videoHeight !== 240) {
     222                        window.webkit.messageHandlers.gum.postMessage("FAIL checkConstraints, height is not 240 but " + video.videoHeight);
     223                        return;
     224                    }
     225                    let settings = stream.getVideoTracks()[0].getSettings();
     226                    if (settings.width !== 320 && settings.height !== 240) {
     227                        window.webkit.messageHandlers.gum.postMessage("FAIL checkConstraints, video settings are not correct");
     228                        return;
     229                    }
     230                    settings = stream.getAudioTracks()[0].getSettings();
     231                    if (settings.echoCancellation) {
     232                        window.webkit.messageHandlers.gum.postMessage("FAIL checkConstraints, audio settings are not correct");
     233                        return;
     234                    }
     235                    window.webkit.messageHandlers.gum.postMessage("PASS");
     236                }
     237                doCheckConstraints().catch(e => {
     238                    window.webkit.messageHandlers.gum.postMessage("FAIL checkConstraintsStatus, " + e);
     239                });
     240            }
    196241        </script>
    197242    <head>
    198243
    199244    <body onload="promptForCapture()">
    200         <video id="video" controls></video>
     245        <video id="video" controls playsinline autoplay></video>
     246        <video id="video2" controls playsinline autoplay></video>
    201247        <p>
    202248        <button onclick="stop()">Stop</button>
Note: See TracChangeset for help on using the changeset viewer.