Title: [277876] trunk
Revision
277876
Author
eric.carl...@apple.com
Date
2021-05-21 12:47:15 -0700 (Fri, 21 May 2021)

Log Message

[Cocoa] Update AudioSession buffer size handling
https://bugs.webkit.org/show_bug.cgi?id=225927
rdar://76920375

Reviewed by Jer Noble.

Source/WebCore:

Previously we only set the audio session buffer size when there was an active
MediaSession. This meant that when no audio was being played or captured, the buffer
size would be left at whatever size was appropriate for the last MediaSession
stopped. This was especially bad when the last MediaSession played WebAudio
or captured audio because those require a smaller buffer size than the default,
and was made even worse when using the GPU process because it may live for much
longer than the last web process that played audio. Fix this by using the low power
buffer size when playing audio or when there is no MediaSession at all.

Add AudioBufferSize API test.

* Modules/webaudio/AudioContext.h:
Make mediaType() return `None` if the context is suspended or stopped so the media
session manager won't set the buffer size for WebAudio.

* platform/audio/cocoa/MediaSessionManagerCocoa.h:
* platform/audio/cocoa/MediaSessionManagerCocoa.mm:
(WebCore::MediaSessionManagerCocoa::updateSessionState): Always use "low power"
buffer size when there is no WebAudio or audio capture.
(WebCore::MediaSessionManagerCocoa::addSession): Cache supported hardware buffer sizes.
(WebCore::MediaSessionManagerCocoa::audioOutputDeviceChanged): Update cached buffer
sizes.

* testing/Internals.cpp:
(WebCore::Internals::currentAudioBufferSize const): Expose current audio session buffer
size for testing.
* testing/Internals.h:
* testing/Internals.idl:

Tools:

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:

* TestWebKitAPI/Tests/WebKit/audio-buffer-size.html: Added.
* TestWebKitAPI/Tests/WebKitCocoa/AudioBufferSize.mm: Added.
(TestWebKitAPI::waitForBufferSizeChange):
(TestWebKitAPI::TEST):

* TestWebKitAPI/Tests/WebKitCocoa/PreferredAudioBufferSize.mm:
(TEST_F):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (277875 => 277876)


--- trunk/Source/WebCore/ChangeLog	2021-05-21 19:24:05 UTC (rev 277875)
+++ trunk/Source/WebCore/ChangeLog	2021-05-21 19:47:15 UTC (rev 277876)
@@ -1,3 +1,40 @@
+2021-05-21  Eric Carlson  <eric.carl...@apple.com>
+
+        [Cocoa] Update AudioSession buffer size handling
+        https://bugs.webkit.org/show_bug.cgi?id=225927
+        rdar://76920375
+
+        Reviewed by Jer Noble.
+
+        Previously we only set the audio session buffer size when there was an active
+        MediaSession. This meant that when no audio was being played or captured, the buffer
+        size would be left at whatever size was appropriate for the last MediaSession
+        stopped. This was especially bad when the last MediaSession played WebAudio
+        or captured audio because those require a smaller buffer size than the default,
+        and was made even worse when using the GPU process because it may live for much
+        longer than the last web process that played audio. Fix this by using the low power
+        buffer size when playing audio or when there is no MediaSession at all.
+        
+        Add AudioBufferSize API test.
+
+        * Modules/webaudio/AudioContext.h:
+        Make mediaType() return `None` if the context is suspended or stopped so the media
+        session manager won't set the buffer size for WebAudio.
+
+        * platform/audio/cocoa/MediaSessionManagerCocoa.h:
+        * platform/audio/cocoa/MediaSessionManagerCocoa.mm:
+        (WebCore::MediaSessionManagerCocoa::updateSessionState): Always use "low power"
+        buffer size when there is no WebAudio or audio capture.
+        (WebCore::MediaSessionManagerCocoa::addSession): Cache supported hardware buffer sizes.
+        (WebCore::MediaSessionManagerCocoa::audioOutputDeviceChanged): Update cached buffer
+        sizes.
+
+        * testing/Internals.cpp:
+        (WebCore::Internals::currentAudioBufferSize const): Expose current audio session buffer
+        size for testing.
+        * testing/Internals.h:
+        * testing/Internals.idl:
+
 2021-05-21  Chris Dumez  <cdu...@apple.com>
 
         Use CheckedLock more in cases where we try-lock

Modified: trunk/Source/WebCore/Modules/webaudio/AudioContext.h (277875 => 277876)


--- trunk/Source/WebCore/Modules/webaudio/AudioContext.h	2021-05-21 19:24:05 UTC (rev 277875)
+++ trunk/Source/WebCore/Modules/webaudio/AudioContext.h	2021-05-21 19:47:15 UTC (rev 277876)
@@ -120,7 +120,7 @@
     void pageMutedStateDidChange() final;
 
     // PlatformMediaSessionClient
-    PlatformMediaSession::MediaType mediaType() const final { return isSuspended() ? PlatformMediaSession::MediaType::None : PlatformMediaSession::MediaType::WebAudio; }
+    PlatformMediaSession::MediaType mediaType() const final { return isSuspended() || isStopped() ? PlatformMediaSession::MediaType::None : PlatformMediaSession::MediaType::WebAudio; }
     PlatformMediaSession::MediaType presentationType() const final { return PlatformMediaSession::MediaType::WebAudio; }
     void mayResumePlayback(bool shouldResume) final;
     void suspendPlayback() final;

Modified: trunk/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.h (277875 => 277876)


--- trunk/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.h	2021-05-21 19:24:05 UTC (rev 277875)
+++ trunk/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.h	2021-05-21 19:47:15 UTC (rev 277876)
@@ -117,6 +117,9 @@
 
     const std::unique_ptr<NowPlayingManager> m_nowPlayingManager;
     RefPtr<AudioHardwareListener> m_audioHardwareListener;
+
+    AudioHardwareListener::BufferSizeRange m_supportedAudioHardwareBufferSizes;
+    size_t m_defaultBufferSize;
 };
 
 }

Modified: trunk/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.mm (277875 => 277876)


--- trunk/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.mm	2021-05-21 19:24:05 UTC (rev 277875)
+++ trunk/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.mm	2021-05-21 19:47:15 UTC (rev 277876)
@@ -58,6 +58,7 @@
 
 MediaSessionManagerCocoa::MediaSessionManagerCocoa()
     : m_nowPlayingManager(platformStrategies()->mediaStrategy().createNowPlayingManager())
+    , m_defaultBufferSize(AudioSession::sharedSession().preferredBufferSize())
 {
     ensureCodecsRegistered();
 }
@@ -101,7 +102,8 @@
             ++audioCount;
             break;
         case PlatformMediaSession::MediaType::WebAudio:
-            ++webAudioCount;
+            if (session.canProduceAudio())
+                ++webAudioCount;
             break;
         }
 
@@ -120,21 +122,17 @@
         "VideoAudio(", videoAudioCount, "), "
         "WebAudio(", webAudioCount, ")");
 
+    size_t bufferSize = m_defaultBufferSize;
     if (webAudioCount)
-        AudioSession::sharedSession().setPreferredBufferSize(AudioUtilities::renderQuantumSize);
-    // In case of audio capture, we want to grab 20 ms chunks to limit the latency so that it is not noticeable by users
-    // while having a large enough buffer so that the audio rendering remains stable, hence a computation based on sample rate.
-    else if (captureCount)
-        AudioSession::sharedSession().setPreferredBufferSize(AudioSession::sharedSession().sampleRate() / 50);
-    else if ((videoAudioCount || audioCount) && DeprecatedGlobalSettings::lowPowerVideoAudioBufferSizeEnabled()) {
-        size_t bufferSize;
-        if (m_audioHardwareListener && m_audioHardwareListener->supportedBufferSizes())
-            bufferSize = m_audioHardwareListener->supportedBufferSizes().nearest(kLowPowerVideoBufferSize);
-        else
-            bufferSize = AudioUtilities::renderQuantumSize;
+        bufferSize = AudioUtilities::renderQuantumSize;
+    else if (captureCount) {
+        // In case of audio capture, we want to grab 20 ms chunks to limit the latency so that it is not noticeable by users
+        // while having a large enough buffer so that the audio rendering remains stable, hence a computation based on sample rate.
+        bufferSize = AudioSession::sharedSession().sampleRate() / 50;
+    } else if (m_supportedAudioHardwareBufferSizes && DeprecatedGlobalSettings::lowPowerVideoAudioBufferSizeEnabled())
+        bufferSize = m_supportedAudioHardwareBufferSizes.nearest(kLowPowerVideoBufferSize);
 
-        AudioSession::sharedSession().setPreferredBufferSize(bufferSize);
-    }
+    AudioSession::sharedSession().setPreferredBufferSize(bufferSize);
 
     if (!DeprecatedGlobalSettings::shouldManageAudioSessionCategory())
         return;
@@ -199,8 +197,10 @@
 {
     m_nowPlayingManager->addClient(*this);
 
-    if (!m_audioHardwareListener)
+    if (!m_audioHardwareListener) {
         m_audioHardwareListener = AudioHardwareListener::create(*this);
+        m_supportedAudioHardwareBufferSizes = m_audioHardwareListener->supportedBufferSizes();
+    }
 
     PlatformMediaSessionManager::addSession(session);
 }
@@ -412,6 +412,9 @@
 
 void MediaSessionManagerCocoa::audioOutputDeviceChanged()
 {
+    ASSERT(m_audioHardwareListener);
+    m_supportedAudioHardwareBufferSizes = m_audioHardwareListener->supportedBufferSizes();
+    m_defaultBufferSize = AudioSession::sharedSession().preferredBufferSize();
     AudioSession::sharedSession().audioOutputDeviceChanged();
     updateSessionState();
 }

Modified: trunk/Source/WebCore/testing/Internals.cpp (277875 => 277876)


--- trunk/Source/WebCore/testing/Internals.cpp	2021-05-21 19:24:05 UTC (rev 277875)
+++ trunk/Source/WebCore/testing/Internals.cpp	2021-05-21 19:47:15 UTC (rev 277876)
@@ -5439,6 +5439,15 @@
     return 0;
 }
 
+double Internals::currentAudioBufferSize() const
+{
+#if USE(AUDIO_SESSION)
+    return AudioSession::sharedSession().bufferSize();
+#endif
+    return 0;
+}
+
+
 bool Internals::audioSessionActive() const
 {
 #if USE(AUDIO_SESSION)

Modified: trunk/Source/WebCore/testing/Internals.h (277875 => 277876)


--- trunk/Source/WebCore/testing/Internals.h	2021-05-21 19:24:05 UTC (rev 277875)
+++ trunk/Source/WebCore/testing/Internals.h	2021-05-21 19:47:15 UTC (rev 277876)
@@ -845,6 +845,7 @@
     bool supportsAudioSession() const;
     String audioSessionCategory() const;
     double preferredAudioBufferSize() const;
+    double currentAudioBufferSize() const;
     bool audioSessionActive() const;
 
     void storeRegistrationsOnDisk(DOMPromiseDeferred<void>&&);

Modified: trunk/Source/WebCore/testing/Internals.idl (277875 => 277876)


--- trunk/Source/WebCore/testing/Internals.idl	2021-05-21 19:24:05 UTC (rev 277875)
+++ trunk/Source/WebCore/testing/Internals.idl	2021-05-21 19:47:15 UTC (rev 277876)
@@ -894,6 +894,7 @@
     readonly attribute boolean supportsAudioSession;
     DOMString audioSessionCategory();
     double preferredAudioBufferSize();
+    double currentAudioBufferSize();
     boolean audioSessionActive();
 
     [Conditional=SERVICE_WORKER] Promise<boolean> hasServiceWorkerRegistration(DOMString scopeURL);

Modified: trunk/Tools/ChangeLog (277875 => 277876)


--- trunk/Tools/ChangeLog	2021-05-21 19:24:05 UTC (rev 277875)
+++ trunk/Tools/ChangeLog	2021-05-21 19:47:15 UTC (rev 277876)
@@ -1,3 +1,21 @@
+2021-05-21  Eric Carlson  <eric.carl...@apple.com>
+
+        [Cocoa] Update AudioSession buffer size handling
+        https://bugs.webkit.org/show_bug.cgi?id=225927
+        rdar://76920375
+
+        Reviewed by Jer Noble.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+
+        * TestWebKitAPI/Tests/WebKit/audio-buffer-size.html: Added.
+        * TestWebKitAPI/Tests/WebKitCocoa/AudioBufferSize.mm: Added.
+        (TestWebKitAPI::waitForBufferSizeChange):
+        (TestWebKitAPI::TEST):
+
+        * TestWebKitAPI/Tests/WebKitCocoa/PreferredAudioBufferSize.mm:
+        (TEST_F):
+
 2021-05-21  Sam Sneddon  <gsnedd...@apple.com>
 
         Fix Python 3.6+ DeprecationWarnings about unknown escapes

Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (277875 => 277876)


--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2021-05-21 19:24:05 UTC (rev 277875)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2021-05-21 19:47:15 UTC (rev 277876)
@@ -48,6 +48,8 @@
 		041A1E34216FFDBC00789E0A /* PublicSuffix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 041A1E33216FFDBC00789E0A /* PublicSuffix.cpp */; };
 		04DB2396235E43EC00328F17 /* BumpPointerAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0451A5A6235E438E009DF945 /* BumpPointerAllocator.cpp */; };
 		0711DF52226A95FC003DD2F7 /* AVFoundationSoftLinkTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0711DF51226A95FB003DD2F7 /* AVFoundationSoftLinkTest.mm */; };
+		0713704A265320E500CA2C9A /* AudioBufferSize.mm in Sources */ = {isa = PBXBuildFile; fileRef = 07137049265320E500CA2C9A /* AudioBufferSize.mm */; };
+		0713705526532E3900CA2C9A /* audio-buffer-size.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 0713705426532E3900CA2C9A /* audio-buffer-size.html */; };
 		07492B3B1DF8B14C00633DE1 /* EnumerateMediaDevices.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07492B3A1DF8AE2D00633DE1 /* EnumerateMediaDevices.cpp */; };
 		07492B3C1DF8B86600633DE1 /* enumerateMediaDevices.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 07492B391DF8ADA400633DE1 /* enumerateMediaDevices.html */; };
 		074994421EA5034B000DA44E /* getUserMedia.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 4A410F4D19AF7BEF002EBAB5 /* getUserMedia.html */; };
@@ -1378,6 +1380,7 @@
 				F42BD7D9245CC508001E207A /* attributedStringNewlineAtEndOfDocument.html in Copy Resources */,
 				7C9ED98B17A19F4B00E4DC33 /* attributedStringStrikethrough.html in Copy Resources */,
 				37137E4B21124D01002BEEA4 /* AttrStyle.html in Copy Resources */,
+				0713705526532E3900CA2C9A /* audio-buffer-size.html in Copy Resources */,
 				46F03C1C255B2D5A00AA51C5 /* audio-context-playing.html in Copy Resources */,
 				CD9E292E1C90C33F000BB800 /* audio-only.html in Copy Resources */,
 				C944160021430E8900B1EDDA /* audio-with-controls.html in Copy Resources */,
@@ -1776,6 +1779,8 @@
 		041A1E33216FFDBC00789E0A /* PublicSuffix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PublicSuffix.cpp; sourceTree = "<group>"; };
 		0451A5A6235E438E009DF945 /* BumpPointerAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BumpPointerAllocator.cpp; sourceTree = "<group>"; };
 		0711DF51226A95FB003DD2F7 /* AVFoundationSoftLinkTest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AVFoundationSoftLinkTest.mm; sourceTree = "<group>"; };
+		07137049265320E500CA2C9A /* AudioBufferSize.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AudioBufferSize.mm; sourceTree = "<group>"; };
+		0713705426532E3900CA2C9A /* audio-buffer-size.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = "audio-buffer-size.html"; path = "Tests/WebKit/audio-buffer-size.html"; sourceTree = "<group>"; };
 		0746645722FF62D000E3451A /* AccessibilityTestSupportProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AccessibilityTestSupportProtocol.h; sourceTree = "<group>"; };
 		0746645822FF630500E3451A /* AccessibilityTestPlugin.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = AccessibilityTestPlugin.mm; sourceTree = "<group>"; };
 		07492B391DF8ADA400633DE1 /* enumerateMediaDevices.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = enumerateMediaDevices.html; sourceTree = "<group>"; };
@@ -3195,6 +3200,7 @@
 		08FB7794FE84155DC02AAC07 /* TestWebKitAPI */ = {
 			isa = PBXGroup;
 			children = (
+				0713705426532E3900CA2C9A /* audio-buffer-size.html */,
 				49AEEF682407276F00C87E4C /* Info.plist */,
 				5C9D922622D7DD7B008E9266 /* Derived Sources */,
 				5C9D921D22D7DBF7008E9266 /* Sources.txt */,
@@ -3363,6 +3369,7 @@
 				51B40D9D23AC960E00E05241 /* AsyncFunction.mm */,
 				834138C6203261B900F26960 /* AsyncPolicyForNavigationResponse.mm */,
 				3760C4F0211249AF00233ACC /* AttrStyle.mm */,
+				07137049265320E500CA2C9A /* AudioBufferSize.mm */,
 				CDED342E249DDD9D0002AE7A /* AudioRoutingArbitration.mm */,
 				754CEC801F6722DC00D0039A /* AutoFillAvailable.mm */,
 				2DD355351BD08378005DF4A7 /* AutoLayoutIntegration.mm */,
@@ -4427,7 +4434,6 @@
 				933D631B1FCB76180032ECD6 /* Hasher.cpp */,
 				0BCD833414857CE400EA2003 /* HashMap.cpp */,
 				26B2DFF815BDE599004F691D /* HashSet.cpp */,
-				33C2C9C02651F5B900E407F6 /* SmallSet.cpp */,
 				7C8BFF7023C0106700C009B3 /* HexNumber.cpp */,
 				33976D8224DC479B00812304 /* IndexSparseSet.cpp */,
 				266FAFD215E5775200F61D5B /* IntegerToStringConversion.cpp */,
@@ -4473,6 +4479,7 @@
 				0BCD85691485C98B00EA2003 /* SetForScope.cpp */,
 				CD5393C91757BAC400C07123 /* SHA1.cpp */,
 				E3953F951F2CF32100A76A2E /* Signals.cpp */,
+				33C2C9C02651F5B900E407F6 /* SmallSet.cpp */,
 				93FCDB33263631560046DD7D /* SortedArrayMap.cpp */,
 				FE2BCDC62470FC7000DEC33B /* StdLibExtras.cpp */,
 				81B50192140F232300D9EB58 /* StringBuilder.cpp */,
@@ -5164,7 +5171,6 @@
 			files = (
 				7C83DE991D0A590C00FEBCF3 /* AtomString.cpp in Sources */,
 				FE2D9474245EB2F400E48135 /* Bitmap.cpp in Sources */,
-				33C2C9C12651F5B900E407F6 /* SmallSet.cpp in Sources */,
 				1ADAD1501D77A9F600212586 /* BlockPtr.mm in Sources */,
 				7C83DE9C1D0A590C00FEBCF3 /* BloomFilter.cpp in Sources */,
 				7C83DF181D0A590C00FEBCF3 /* BoxPtr.cpp in Sources */,
@@ -5232,6 +5238,7 @@
 				7C83DF3D1D0A590C00FEBCF3 /* SetForScope.cpp in Sources */,
 				7C83DF2A1D0A590C00FEBCF3 /* SHA1.cpp in Sources */,
 				E373D7911F2CF35200C6FAAF /* Signals.cpp in Sources */,
+				33C2C9C12651F5B900E407F6 /* SmallSet.cpp in Sources */,
 				93FCDB34263631560046DD7D /* SortedArrayMap.cpp in Sources */,
 				FE2BCDC72470FDA300DEC33B /* StdLibExtras.cpp in Sources */,
 				7C83DF321D0A590C00FEBCF3 /* StringBuilder.cpp in Sources */,
@@ -5305,6 +5312,7 @@
 				7CCE7EB41A411A7E00447C4C /* AttributedString.mm in Sources */,
 				F4FA2A4F24D1F05700618A46 /* AttributedSubstringForProposedRange.mm in Sources */,
 				3760C4F1211249AF00233ACC /* AttrStyle.mm in Sources */,
+				0713704A265320E500CA2C9A /* AudioBufferSize.mm in Sources */,
 				CDED342F249DDE0E0002AE7A /* AudioRoutingArbitration.mm in Sources */,
 				CDC8E48D1BC5CB4500594FEC /* AudioSessionCategoryIOS.mm in Sources */,
 				F42D634422A1729F00D2FB3A /* AutocorrectionTestsIOS.mm in Sources */,

Added: trunk/Tools/TestWebKitAPI/Tests/WebKit/audio-buffer-size.html (0 => 277876)


--- trunk/Tools/TestWebKitAPI/Tests/WebKit/audio-buffer-size.html	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit/audio-buffer-size.html	2021-05-21 19:47:15 UTC (rev 277876)
@@ -0,0 +1,81 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <script>
+
+let context;
+let oscillator;
+let stream;
+let gain;
+
+function sendMessage(message)
+{
+    try {
+        if (window.webkit)
+            window.webkit.messageHandlers.testHandler.postMessage(message);
+        else
+            console.log(`MESSAGE - ${message}`);
+    } catch(err) {
+        console.log(`failed to send message ${message}: ${err}`);
+    }
+}
+
+function createWebAudioNode()
+{
+    context = new AudioContext();
+
+    gain = new GainNode(context, {gain: 0.05});
+    gain.connect(context.destination);
+
+    oscillator = new OscillatorNode(context);
+    oscillator.connect(gain);
+    oscillator.start();
+}
+
+function disconnectWebAudioNode()
+{
+    oscillator.stop();
+    oscillator.disconnect();
+    gain.disconnect();
+    context.close();
+}
+
+async function startCapture()
+{
+    stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: { volume: 0.05 } });
+}
+
+function stopCapture()
+{
+    stream.getTracks().forEach(track => track.stop());
+}
+
+async function playVideo() 
+{
+    let video = document.getElementsByTagName('video')[0];
+    video.src = '';
+    video.volume = 0.05;
+    await video.play();
+    sendMessage('playing');
+}
+
+function pauseVideo() 
+{
+    video = document.getElementsByTagName('video')[0].pause();
+}
+        </script>
+    <head>
+
+    <body>
+        <video controls></video>
+        <br>
+        <button _onclick_="createWebAudioNode()">Create Audio Node</button>
+        <button _onclick_="disconnectWebAudioNode()">Disconnect Audio Node</button>
+        <br>
+        <button _onclick_="startCapture()">Start Capture</button>
+        <button _onclick_="stopCapture()">Stop Capture</button>
+        <br>
+        <button _onclick_="playVideo()">Play &lt;video&gt;</button>
+        <button _onclick_="pauseVideo()">Pause &lt;video&gt;</button>
+    </body>
+</html>

Added: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/AudioBufferSize.mm (0 => 277876)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/AudioBufferSize.mm	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/AudioBufferSize.mm	2021-05-21 19:47:15 UTC (rev 277876)
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#import "config.h"
+
+#if WK_HAVE_C_SPI
+
+#import "PlatformUtilities.h"
+#import "Test.h"
+#import "TestWKWebView.h"
+#import "UserMediaCaptureUIDelegate.h"
+#import <WebKit/WKPreferencesPrivate.h>
+#import <WebKit/WKWebViewConfiguration.h>
+#import <WebKit/WKWebViewConfigurationPrivate.h>
+#import <WebKit/WKWebViewPrivate.h>
+
+#import <wtf/RetainPtr.h>
+#import <wtf/Seconds.h>
+
+namespace TestWebKitAPI {
+
+double waitForBufferSizeChange(WKWebView* webView, double oldSize)
+{
+    int tries = 0;
+    do {
+        auto size = [webView stringByEvaluatingJavaScript:@"window.internals.currentAudioBufferSize()"].doubleValue;
+        if (size != oldSize)
+            return size;
+
+        TestWebKitAPI::Util::sleep(0.1);
+    } while (++tries <= 100);
+
+    ASSERT_NOT_REACHED();
+    return 0;
+}
+
+TEST(WebKit, AudioBufferSize)
+{
+    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    auto context = adoptWK(TestWebKitAPI::Util::createContextForInjectedBundleTest("InternalsInjectedBundleTest"));
+
+#if PLATFORM(IOS)
+    configuration.get().allowsInlineMediaPlayback = YES;
+    configuration.get()._inlineMediaPlaybackRequiresPlaysInlineAttribute = NO;
+#endif
+    configuration.get()._mediaDataLoadsAutomatically = YES;
+    configuration.get().mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
+    configuration.get().processPool = (WKProcessPool *)context.get();
+    configuration.get()._mediaCaptureEnabled = YES;
+    auto preferences = [configuration preferences];
+    preferences._mediaCaptureRequiresSecureConnection = NO;
+    preferences._mockCaptureDevicesEnabled = YES;
+
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 300, 300) configuration:configuration.get() addToWindow:YES]);
+    auto delegate = adoptNS([[UserMediaCaptureUIDelegate alloc] init]);
+    webView.get().UIDelegate = delegate.get();
+
+    [webView synchronouslyLoadTestPageNamed:@"audio-buffer-size"];
+
+    __block bool gotMessage = false;
+    [webView performAfterReceivingMessage:@"playing" action:^{ gotMessage = true; }];
+    [webView evaluateJavaScript:@"playVideo()" completionHandler:nil];
+    TestWebKitAPI::Util::run(&gotMessage);
+    auto bufferSizePlayingAudio = [webView stringByEvaluatingJavaScript:@"window.internals.currentAudioBufferSize()"].doubleValue;
+
+    [webView evaluateJavaScript:@"startCapture()" completionHandler:nil];
+    [delegate waitUntilPrompted];
+    auto bufferSizeCapturingAudio = waitForBufferSizeChange(webView.get(), bufferSizePlayingAudio);
+    ASSERT_LT(bufferSizeCapturingAudio, bufferSizePlayingAudio);
+
+    [webView evaluateJavaScript:@"createWebAudioNode()" completionHandler:nil];
+    auto bufferSizeWithWebAudio = waitForBufferSizeChange(webView.get(), bufferSizeCapturingAudio);
+    ASSERT_LT(bufferSizeWithWebAudio, bufferSizeCapturingAudio);
+
+    [webView evaluateJavaScript:@"disconnectWebAudioNode()" completionHandler:nil];
+    auto bufferSizeWithoutWebAudio = waitForBufferSizeChange(webView.get(), bufferSizeWithWebAudio);
+    ASSERT_GT(bufferSizeWithoutWebAudio, bufferSizeWithWebAudio);
+    ASSERT_EQ(bufferSizeWithoutWebAudio, bufferSizeCapturingAudio);
+
+    [webView evaluateJavaScript:@"stopCapture()" completionHandler:nil];
+    auto bufferSizeWithoutCapture = waitForBufferSizeChange(webView.get(), bufferSizeWithoutWebAudio);
+    ASSERT_GT(bufferSizeWithoutCapture, bufferSizeWithoutWebAudio);
+    ASSERT_EQ(bufferSizeWithoutCapture, bufferSizePlayingAudio);
+
+    [webView removeFromSuperview];
+}
+
+} // namespace TestWebKitAPI
+
+#endif // WK_HAVE_C_SPI

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/PreferredAudioBufferSize.mm (277875 => 277876)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/PreferredAudioBufferSize.mm	2021-05-21 19:24:05 UTC (rev 277875)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/PreferredAudioBufferSize.mm	2021-05-21 19:47:15 UTC (rev 277876)
@@ -91,7 +91,7 @@
 
 TEST_F(PreferredAudioBufferSize, VideoOnly)
 {
-    runPlayingTestWithPageNamed(@"video-without-audio", 512);
+    runPlayingTestWithPageNamed(@"video-without-audio", 4096);
 }
 
 TEST_F(PreferredAudioBufferSize, VideoWithAudio)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to