- 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>