Title: [251188] trunk
Revision
251188
Author
you...@apple.com
Date
2019-10-16 09:48:48 -0700 (Wed, 16 Oct 2019)

Log Message

WebAudioSourceProviderAVFObjC::provideInput should set its WebAudioBufferList parameters correctly
https://bugs.webkit.org/show_bug.cgi?id=202930
<rdar://problem/56006776>

Reviewed by Eric Carlson.

Source/WebCore:

There is a time where the bus channel number and audio source channel numbers may be different.
In case the bus channel number is less than the audio source channel number, initialization of
the WebAudioBufferList might not be fully done.
In that case, output silence and return early.
Reduce the number of frames to process based on the number of frames the output audio bus plans to process.

Partially covered by new API test (this a race so we cannot reproduce the crash easily).

* Modules/webaudio/MediaStreamAudioSourceNode.cpp:
(WebCore::MediaStreamAudioSourceNode::process):
Make sure to process the number of frames the output bus expect.
* platform/mediastream/mac/WebAudioSourceProviderAVFObjC.mm:
(WebCore::WebAudioSourceProviderAVFObjC::provideInput):

Tools:

Add a test that has an audio track that goes from 1 to 2 channels while being piped to a WebAudio pipeline.

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKit/GetUserMedia.mm:
(-[GUMMessageHandler userContentController:didReceiveScriptMessage:]):
(TestWebKitAPI::TEST):
* TestWebKitAPI/Tests/WebKit/getUserMedia-webaudio.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (251187 => 251188)


--- trunk/Source/WebCore/ChangeLog	2019-10-16 14:43:41 UTC (rev 251187)
+++ trunk/Source/WebCore/ChangeLog	2019-10-16 16:48:48 UTC (rev 251188)
@@ -1,3 +1,25 @@
+2019-10-16  Youenn Fablet  <you...@apple.com>
+
+        WebAudioSourceProviderAVFObjC::provideInput should set its WebAudioBufferList parameters correctly
+        https://bugs.webkit.org/show_bug.cgi?id=202930
+        <rdar://problem/56006776>
+
+        Reviewed by Eric Carlson.
+
+        There is a time where the bus channel number and audio source channel numbers may be different.
+        In case the bus channel number is less than the audio source channel number, initialization of
+        the WebAudioBufferList might not be fully done.
+        In that case, output silence and return early.
+        Reduce the number of frames to process based on the number of frames the output audio bus plans to process.
+
+        Partially covered by new API test (this a race so we cannot reproduce the crash easily).
+
+        * Modules/webaudio/MediaStreamAudioSourceNode.cpp:
+        (WebCore::MediaStreamAudioSourceNode::process):
+        Make sure to process the number of frames the output bus expect.
+        * platform/mediastream/mac/WebAudioSourceProviderAVFObjC.mm:
+        (WebCore::WebAudioSourceProviderAVFObjC::provideInput):
+
 2019-10-16  Zalan Bujtas  <za...@apple.com>
 
         [LFC][TFC] TableFormattingContext::distributeExtraHorizontalSpace should not ignore fixed width columns

Modified: trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSourceNode.cpp (251187 => 251188)


--- trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSourceNode.cpp	2019-10-16 14:43:41 UTC (rev 251187)
+++ trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSourceNode.cpp	2019-10-16 16:48:48 UTC (rev 251188)
@@ -131,6 +131,9 @@
         return;
     }
 
+    if (numberOfFrames > outputBus->length())
+        numberOfFrames = outputBus->length();
+
     if (m_multiChannelResampler.get()) {
         ASSERT(m_sourceSampleRate != sampleRate());
         m_multiChannelResampler->process(provider, outputBus, numberOfFrames);

Modified: trunk/Source/WebCore/platform/mediastream/mac/WebAudioSourceProviderAVFObjC.mm (251187 => 251188)


--- trunk/Source/WebCore/platform/mediastream/mac/WebAudioSourceProviderAVFObjC.mm	2019-10-16 14:43:41 UTC (rev 251187)
+++ trunk/Source/WebCore/platform/mediastream/mac/WebAudioSourceProviderAVFObjC.mm	2019-10-16 16:48:48 UTC (rev 251188)
@@ -79,8 +79,13 @@
     }
 
     WebAudioBufferList list { m_outputDescription.value() };
+    if (bus->numberOfChannels() < list.bufferCount()) {
+        bus->zero();
+        return;
+    }
+
     for (unsigned i = 0; i < bus->numberOfChannels(); ++i) {
-        AudioChannel& channel = *bus->channel(i);
+        auto& channel = *bus->channel(i);
         if (i >= list.bufferCount()) {
             channel.zero();
             continue;
@@ -91,6 +96,7 @@
         buffer->mDataByteSize = channel.length() * sizeof(float);
     }
 
+    ASSERT(framesToProcess <= bus->length());
     m_dataSource->pullSamples(*list.list(), framesToProcess, m_readCount, 0, AudioSampleDataSource::Copy);
     m_readCount += framesToProcess;
 }

Modified: trunk/Tools/ChangeLog (251187 => 251188)


--- trunk/Tools/ChangeLog	2019-10-16 14:43:41 UTC (rev 251187)
+++ trunk/Tools/ChangeLog	2019-10-16 16:48:48 UTC (rev 251188)
@@ -1,3 +1,19 @@
+2019-10-16  Youenn Fablet  <you...@apple.com>
+
+        WebAudioSourceProviderAVFObjC::provideInput should set its WebAudioBufferList parameters correctly
+        https://bugs.webkit.org/show_bug.cgi?id=202930
+        <rdar://problem/56006776>
+
+        Reviewed by Eric Carlson.
+
+        Add a test that has an audio track that goes from 1 to 2 channels while being piped to a WebAudio pipeline.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebKit/GetUserMedia.mm:
+        (-[GUMMessageHandler userContentController:didReceiveScriptMessage:]):
+        (TestWebKitAPI::TEST):
+        * TestWebKitAPI/Tests/WebKit/getUserMedia-webaudio.html: Added.
+
 2019-10-15  Carlos Garcia Campos  <cgar...@igalia.com>
 
         [GTK][WPE] Add user messages API

Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (251187 => 251188)


--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2019-10-16 14:43:41 UTC (rev 251187)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2019-10-16 16:48:48 UTC (rev 251188)
@@ -218,6 +218,7 @@
 		4135FB842011FAA700332139 /* InjectInternals_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4135FB832011FAA300332139 /* InjectInternals_Bundle.cpp */; };
 		4135FB852011FABF00332139 /* libWebCoreTestSupport.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4135FB862011FABF00332139 /* libWebCoreTestSupport.dylib */; };
 		414AD6862285D1C000777F2D /* StorageQuota.mm in Sources */ = {isa = PBXBuildFile; fileRef = 414AD6852285D1B000777F2D /* StorageQuota.mm */; };
+		41661C662355E85E00D33C27 /* getUserMedia-webaudio.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 41661C652355D98B00D33C27 /* getUserMedia-webaudio.html */; };
 		41882F0321010C0D002FF288 /* ProcessPreWarming.mm in Sources */ = {isa = PBXBuildFile; fileRef = 41882F0221010A70002FF288 /* ProcessPreWarming.mm */; };
 		44077BB123144B5000179E2D /* DataDetectorsTestIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 44077BB0231449D200179E2D /* DataDetectorsTestIOS.mm */; };
 		4433A396208044140091ED57 /* SynchronousTimeoutTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4433A395208044130091ED57 /* SynchronousTimeoutTests.mm */; };
@@ -1120,6 +1121,7 @@
 			dstPath = TestWebKitAPI.resources;
 			dstSubfolderSpec = 7;
 			files = (
+				41661C662355E85E00D33C27 /* getUserMedia-webaudio.html in Copy Resources */,
 				55A817FF2181021A0004A39A /* 100x100-red.tga in Copy Resources */,
 				1A9E52C913E65EF4006917F5 /* 18-characters.html in Copy Resources */,
 				55A81800218102210004A39A /* 400x400-green.png in Copy Resources */,
@@ -1714,6 +1716,7 @@
 		4135FB832011FAA300332139 /* InjectInternals_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = InjectInternals_Bundle.cpp; path = Tests/InjectInternals_Bundle.cpp; sourceTree = SOURCE_ROOT; };
 		4135FB862011FABF00332139 /* libWebCoreTestSupport.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; path = libWebCoreTestSupport.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
 		414AD6852285D1B000777F2D /* StorageQuota.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = StorageQuota.mm; sourceTree = "<group>"; };
+		41661C652355D98B00D33C27 /* getUserMedia-webaudio.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "getUserMedia-webaudio.html"; sourceTree = "<group>"; };
 		41882F0221010A70002FF288 /* ProcessPreWarming.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ProcessPreWarming.mm; sourceTree = "<group>"; };
 		41973B5C1AF22875006C7B36 /* SharedBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SharedBuffer.cpp; sourceTree = "<group>"; };
 		44077BB0231449D200179E2D /* DataDetectorsTestIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DataDetectorsTestIOS.mm; sourceTree = "<group>"; };
@@ -3750,6 +3753,7 @@
 				26F52EB018288F0F0023D412 /* geolocationWatchPosition.html */,
 				26F52EB118288F0F0023D412 /* geolocationWatchPositionWithHighAccuracy.html */,
 				4A410F4D19AF7BEF002EBAB5 /* getUserMedia.html */,
+				41661C652355D98B00D33C27 /* getUserMedia-webaudio.html */,
 				4A410F4D19AF7BEF002EBAC5 /* getUserMediaAudioVideoCapture.html */,
 				BCBD372E125ABBE600D2C29F /* icon.png */,
 				CE3524F51B142BBB0028A7C5 /* input-focus-blur.html */,

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKit/GetUserMedia.mm (251187 => 251188)


--- trunk/Tools/TestWebKitAPI/Tests/WebKit/GetUserMedia.mm	2019-10-16 14:43:41 UTC (rev 251187)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit/GetUserMedia.mm	2019-10-16 16:48:48 UTC (rev 251188)
@@ -30,12 +30,16 @@
 #import "PlatformUtilities.h"
 #import "Test.h"
 #import "TestWKWebView.h"
+#import "WKWebViewConfigurationExtras.h"
 #import <WebKit/WKPreferencesPrivate.h>
+#import <WebKit/WKProcessPoolPrivate.h>
 #import <WebKit/WKUIDelegatePrivate.h>
 #import <WebKit/WKWebView.h>
 #import <WebKit/WKWebViewConfiguration.h>
 #import <WebKit/_WKProcessPoolConfiguration.h>
 
+static bool done;
+
 @interface GetUserMediaCaptureUIDelegate : NSObject<WKUIDelegate>
 - (void)_webView:(WKWebView *)webView requestMediaCaptureAuthorization: (_WKCaptureDevices)devices decisionHandler:(void (^)(BOOL))decisionHandler;
 - (void)_webView:(WKWebView *)webView checkUserMediaPermissionForURL:(NSURL *)url mainFrameURL:(NSURL *)mainFrameURL frameIdentifier:(NSUInteger)frameIdentifier decisionHandler:(void (^)(NSString *salt, BOOL authorized))decisionHandler;
@@ -53,6 +57,17 @@
 }
 @end
 
+@interface GUMMessageHandler : NSObject <WKScriptMessageHandler>
+@end
+
+@implementation GUMMessageHandler
+- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
+{
+    EXPECT_WK_STREQ(@"PASS", [message body]);
+    done = true;
+}
+@end
+
 namespace TestWebKitAPI {
 
 void waitUntilCaptureState(WKWebView *webView, _WKMediaCaptureState expectedState)
@@ -112,6 +127,37 @@
     waitUntilCaptureState(webView, _WKMediaCaptureStateNone);
 }
 
+#if WK_HAVE_C_SPI
+TEST(WebKit, WebAudioAndGetUserMedia)
+{
+    done = false;
+
+    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    auto context = adoptWK(TestWebKitAPI::Util::createContextForInjectedBundleTest("InternalsInjectedBundleTest"));
+    configuration.get().processPool = (WKProcessPool *)context.get();
+    configuration.get().processPool._configuration.shouldCaptureAudioInUIProcess = NO;
+
+    auto preferences = [configuration preferences];
+    preferences._mediaCaptureRequiresSecureConnection = NO;
+    preferences._mediaDevicesEnabled = YES;
+    preferences._mockCaptureDevicesEnabled = YES;
+
+    auto messageHandler = adoptNS([[GUMMessageHandler alloc] init]);
+    [[configuration.get() userContentController] addScriptMessageHandler:messageHandler.get() name:@"gum"];
+
+    auto webView = [[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500) configuration:configuration.get()];
+
+    auto delegate = adoptNS([[GetUserMediaCaptureUIDelegate alloc] init]);
+    webView.UIDelegate = delegate.get();
+
+    auto url = "" "html"));
+    [webView loadTestPageNamed:@"getUserMedia-webaudio"];
+
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+}
+#endif
+
 } // namespace TestWebKitAPI
 
 #endif // ENABLE(MEDIA_STREAM)

Added: trunk/Tools/TestWebKitAPI/Tests/WebKit/getUserMedia-webaudio.html (0 => 251188)


--- trunk/Tools/TestWebKitAPI/Tests/WebKit/getUserMedia-webaudio.html	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit/getUserMedia-webaudio.html	2019-10-16 16:48:48 UTC (rev 251188)
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <script>
+async function capture()
+{
+    try {
+        const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: false });
+        internals.setMockAudioTrackChannelNumber(stream.getAudioTracks()[0], 2);
+
+        var audioContext = new webkitAudioContext();
+        var analyzer = audioContext.createAnalyser();
+        analyzer.fftSize = 256;
+        let source = audioContext.createMediaStreamSource(stream);
+        source.connect(analyzer);
+        analyzer.connect(audioContext.destination);
+
+        for (let cptr = 0; cptr < 1000; cptr++) {
+          internals.setMockAudioTrackChannelNumber(stream.getAudioTracks()[0], (cptr % 2) ? 1 : 2);
+          await new Promise(resolve => setTimeout(resolve, 20));
+        }
+
+        source.disconnect(analyzer);
+        analyzer.disconnect(audioContext.destination);
+
+        window.webkit.messageHandlers.gum.postMessage("PASS");
+    } catch (e) {
+        window.webkit.messageHandlers.gum.postMessage("FAIL: " + e);
+    }
+}
+        </script>
+    <head>
+
+    <body _onload_="capture()">
+    </body>
+</html>
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to