Skip to content

Commit e56bbb1

Browse files
committed
Add support for AudioConfiguration.spatialRendering
https://bugs.webkit.org/show_bug.cgi?id=218727 <rdar://problem/71213348> Reviewed by Eric Carlson. Source/WebCore: Test: media/mediacapabilities/mock-decodingInfo-spatialRendering.html Add support for spatialRendring. On Cocoa ports, this will query AVAudioContext for spatial rendering support. Drive-by fix: The AudioConfiguration.idl marks sampleRate, bitrate, and channels as optional; those need to be reflected in the C++ struct. * Modules/mediacapabilities/AudioConfiguration.idl: * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm: (WebCore::exernalDeviceDisplayNameForPlayer): * platform/graphics/cocoa/MediaEngineConfigurationFactoryCocoa.cpp: (WebCore::createMediaPlayerDecodingConfigurationCocoa): * platform/mediacapabilities/AudioConfiguration.h: * platform/mediacapabilities/MediaCapabilitiesLogging.cpp: (WebCore::toJSONObject): * platform/mock/MediaEngineConfigurationFactoryMock.cpp: (WebCore::canDecodeMedia): (WebCore::canSmoothlyDecodeMedia): (WebCore::canPowerEfficientlyDecodeMedia): (WebCore::canSmoothlyEncodeMedia): (WebCore::canPowerEfficientlyEncodeMedia): Source/WebCore/PAL: * PAL.xcodeproj/project.pbxproj: * pal/avfoundation/OutputContext.h: Copied from Source/WebCore/platform/mediacapabilities/AudioConfiguration.h. (PAL::OutputContext::platformContext const): * pal/avfoundation/OutputContext.mm: Added. (PAL::OutputContext::OutputContext): (PAL::OutputContext::sharedAudioPresentationOutputContext): (PAL::OutputContext::supportsMultipleOutputDevices): (PAL::OutputContext::deviceName): (PAL::OutputContext::outputDevices const): * pal/avfoundation/OutputDevice.h: Copied from Source/WebCore/platform/mediacapabilities/AudioConfiguration.h. (PAL::OutputDevice::platformDevice const): * pal/avfoundation/OutputDevice.mm: Copied from Source/WebCore/platform/mediacapabilities/AudioConfiguration.h. (PAL::OutputDevice::OutputDevice): (PAL::OutputDevice::name const): (PAL::OutputDevice::deviceFeatures const): (PAL::OutputDevice::supportsSpatialAudio const): * pal/spi/cocoa/AVFoundationSPI.h: LayoutTests: * media/mediacapabilities/mock-decodingInfo-spatialRendering-expected.txt: Added. * media/mediacapabilities/mock-decodingInfo-spatialRendering.html: Added. Canonical link: https://commits.webkit.org/231421@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@269631 268f45cc-cd09-0410-ab3c-d52691b4dbfc
1 parent a675a51 commit e56bbb1

17 files changed

Lines changed: 492 additions & 30 deletions

LayoutTests/ChangeLog

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
2020-11-10 Jer Noble <jer.noble@apple.com>
2+
3+
Add support for AudioConfiguration.spatialRendering
4+
https://bugs.webkit.org/show_bug.cgi?id=218727
5+
<rdar://problem/71213348>
6+
7+
Reviewed by Eric Carlson.
8+
9+
* media/mediacapabilities/mock-decodingInfo-spatialRendering-expected.txt: Added.
10+
* media/mediacapabilities/mock-decodingInfo-spatialRendering.html: Added.
11+
112
2020-11-10 Ryan Haddad <ryanhaddad@apple.com>
213

314
[Debug] imported/w3c/web-platform-tests/html/canvas/element/path-objects/2d.path.ellipse.basics.html is asserting
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
RUN(internals.enableMockMediaCapabilities())
2+
RUN(internals.settings.setMediaCapabilitiesExtensionsEnabled(true))
3+
RUN(promise = navigator.mediaCapabilities.decodingInfo({ type: 'file', audio: { contentType: 'audio/mp4; codecs="mp4a.40.2"', channels: '5.1', bitrate: 1000, samplerate: 44100 } });)
4+
Promise resolved OK
5+
EXPECTED (info.supported == 'true') OK
6+
EXPECTED (typeof info.supportedConfiguration.audio.spatialRendering == 'undefined') OK
7+
RUN(promise = navigator.mediaCapabilities.decodingInfo({ type: 'file', audio: { contentType: 'audio/mp4; codecs="mp4a.40.2"', channels: '5.1', bitrate: 1000, samplerate: 44100, spatialRendering: true } });)
8+
Promise resolved OK
9+
EXPECTED (info.supported == 'true') OK
10+
EXPECTED (info.supportedConfiguration.audio.spatialRendering == 'true') OK
11+
RUN(promise = navigator.mediaCapabilities.decodingInfo({ type: 'file', audio: { contentType: 'audio/mp4; codecs="mp4a.40.2"', channels: '2', bitrate: 1000, samplerate: 44100, spatialRendering: true } });)
12+
Promise resolved OK
13+
EXPECTED (info.supported == 'false') OK
14+
EXPECTED (info.supportedConfiguration.audio.spatialRendering == 'true') OK
15+
RUN(promise = navigator.mediaCapabilities.decodingInfo({ type: 'file', audio: { contentType: 'audio/mp4; codecs="mp4a.40.2"', channels: '2', bitrate: 1000, samplerate: 44100, spatialRendering: false } });)
16+
Promise resolved OK
17+
EXPECTED (info.supported == 'true') OK
18+
EXPECTED (info.supportedConfiguration.audio.spatialRendering == 'false') OK
19+
END OF TEST
20+
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<script src=../video-test.js></script>
5+
<script type="text/javascript">
6+
var promise;
7+
var info;
8+
9+
async function doTest()
10+
{
11+
if (!window.internals) {
12+
failTest("Internals is required for this test.")
13+
return;
14+
}
15+
16+
run('internals.enableMockMediaCapabilities()');
17+
run('internals.settings.setMediaCapabilitiesExtensionsEnabled(true)');
18+
19+
run("promise = navigator.mediaCapabilities.decodingInfo({ type: 'file', audio: { contentType: 'audio/mp4; codecs=\"mp4a.40.2\"', channels: '5.1', bitrate: 1000, samplerate: 44100 } });");
20+
21+
info = await shouldResolve(promise);
22+
testExpected('info.supported', true);
23+
testExpected('typeof info.supportedConfiguration.audio.spatialRendering', 'undefined');
24+
25+
run("promise = navigator.mediaCapabilities.decodingInfo({ type: 'file', audio: { contentType: 'audio/mp4; codecs=\"mp4a.40.2\"', channels: '5.1', bitrate: 1000, samplerate: 44100, spatialRendering: true } });");
26+
27+
info = await shouldResolve(promise);
28+
testExpected('info.supported', true);
29+
testExpected('info.supportedConfiguration.audio.spatialRendering', true);
30+
31+
run("promise = navigator.mediaCapabilities.decodingInfo({ type: 'file', audio: { contentType: 'audio/mp4; codecs=\"mp4a.40.2\"', channels: '2', bitrate: 1000, samplerate: 44100, spatialRendering: true } });");
32+
33+
info = await shouldResolve(promise);
34+
testExpected('info.supported', false);
35+
testExpected('info.supportedConfiguration.audio.spatialRendering', true);
36+
37+
run("promise = navigator.mediaCapabilities.decodingInfo({ type: 'file', audio: { contentType: 'audio/mp4; codecs=\"mp4a.40.2\"', channels: '2', bitrate: 1000, samplerate: 44100, spatialRendering: false } });");
38+
39+
info = await shouldResolve(promise);
40+
testExpected('info.supported', true);
41+
testExpected('info.supportedConfiguration.audio.spatialRendering', false);
42+
43+
endTest();
44+
}
45+
</script>
46+
</head>
47+
<body onload="doTest()" />
48+
</html>

Source/WebCore/ChangeLog

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,33 @@
1+
2020-11-10 Jer Noble <jer.noble@apple.com>
2+
3+
Add support for AudioConfiguration.spatialRendering
4+
https://bugs.webkit.org/show_bug.cgi?id=218727
5+
<rdar://problem/71213348>
6+
7+
Reviewed by Eric Carlson.
8+
9+
Test: media/mediacapabilities/mock-decodingInfo-spatialRendering.html
10+
11+
Add support for spatialRendring. On Cocoa ports, this will query AVAudioContext for spatial rendering support.
12+
13+
Drive-by fix: The AudioConfiguration.idl marks sampleRate, bitrate, and channels as optional; those need to
14+
be reflected in the C++ struct.
15+
16+
* Modules/mediacapabilities/AudioConfiguration.idl:
17+
* platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
18+
(WebCore::exernalDeviceDisplayNameForPlayer):
19+
* platform/graphics/cocoa/MediaEngineConfigurationFactoryCocoa.cpp:
20+
(WebCore::createMediaPlayerDecodingConfigurationCocoa):
21+
* platform/mediacapabilities/AudioConfiguration.h:
22+
* platform/mediacapabilities/MediaCapabilitiesLogging.cpp:
23+
(WebCore::toJSONObject):
24+
* platform/mock/MediaEngineConfigurationFactoryMock.cpp:
25+
(WebCore::canDecodeMedia):
26+
(WebCore::canSmoothlyDecodeMedia):
27+
(WebCore::canPowerEfficientlyDecodeMedia):
28+
(WebCore::canSmoothlyEncodeMedia):
29+
(WebCore::canPowerEfficientlyEncodeMedia):
30+
131
2020-11-10 Chris Dumez <cdumez@apple.com>
232

333
[GPUProcess] Regression(r268632) Garbage is rendered on speakers when using WebAudio

Source/WebCore/Modules/mediacapabilities/AudioConfiguration.idl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,5 @@
3131
DOMString channels;
3232
unsigned long long bitrate;
3333
unsigned long samplerate;
34+
boolean spatialRendering;
3435
};

Source/WebCore/PAL/ChangeLog

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,29 @@
1+
2020-11-10 Jer Noble <jer.noble@apple.com>
2+
3+
Add support for AudioConfiguration.spatialRendering
4+
https://bugs.webkit.org/show_bug.cgi?id=218727
5+
<rdar://problem/71213348>
6+
7+
Reviewed by Eric Carlson.
8+
9+
* PAL.xcodeproj/project.pbxproj:
10+
* pal/avfoundation/OutputContext.h: Copied from Source/WebCore/platform/mediacapabilities/AudioConfiguration.h.
11+
(PAL::OutputContext::platformContext const):
12+
* pal/avfoundation/OutputContext.mm: Added.
13+
(PAL::OutputContext::OutputContext):
14+
(PAL::OutputContext::sharedAudioPresentationOutputContext):
15+
(PAL::OutputContext::supportsMultipleOutputDevices):
16+
(PAL::OutputContext::deviceName):
17+
(PAL::OutputContext::outputDevices const):
18+
* pal/avfoundation/OutputDevice.h: Copied from Source/WebCore/platform/mediacapabilities/AudioConfiguration.h.
19+
(PAL::OutputDevice::platformDevice const):
20+
* pal/avfoundation/OutputDevice.mm: Copied from Source/WebCore/platform/mediacapabilities/AudioConfiguration.h.
21+
(PAL::OutputDevice::OutputDevice):
22+
(PAL::OutputDevice::name const):
23+
(PAL::OutputDevice::deviceFeatures const):
24+
(PAL::OutputDevice::supportsSpatialAudio const):
25+
* pal/spi/cocoa/AVFoundationSPI.h:
26+
127
2020-11-04 David Kilzer <ddkilzer@apple.com>
228

329
WebKit should remove unused debug variant support

Source/WebCore/PAL/PAL.xcodeproj/project.pbxproj

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,10 @@
181181
A3C66CDD1F462D6A009E6EE9 /* SessionID.h in Headers */ = {isa = PBXBuildFile; fileRef = A3C66CDB1F462D6A009E6EE9 /* SessionID.h */; };
182182
ABCA536824895DB900361BFF /* CoreMotionSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = ABCA536724895DB900361BFF /* CoreMotionSPI.h */; };
183183
C15CBB3523F3548A00300CC7 /* NSUserDefaultsSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = C15CBB3223F34A1200300CC7 /* NSUserDefaultsSPI.h */; };
184+
CD6122CC2559B6AC00FC657A /* OutputContext.h in Headers */ = {isa = PBXBuildFile; fileRef = CD6122CA2559B6AC00FC657A /* OutputContext.h */; };
185+
CD6122CD2559B6AC00FC657A /* OutputContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = CD6122CB2559B6AC00FC657A /* OutputContext.mm */; };
186+
CD6122D02559B8F200FC657A /* OutputDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = CD6122CE2559B8F200FC657A /* OutputDevice.h */; };
187+
CD6122D12559B8F200FC657A /* OutputDevice.mm in Sources */ = {isa = PBXBuildFile; fileRef = CD6122CF2559B8F200FC657A /* OutputDevice.mm */; };
184188
CDACB3602387425B0018D7CE /* MediaToolboxSoftLink.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDACB35E23873E480018D7CE /* MediaToolboxSoftLink.cpp */; };
185189
CDACB361238742740018D7CE /* MediaToolboxSoftLink.h in Headers */ = {isa = PBXBuildFile; fileRef = CDACB35F23873E480018D7CE /* MediaToolboxSoftLink.h */; };
186190
CDF91113220E4EEC001EA39E /* CelestialSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = CDF91112220E4EEC001EA39E /* CelestialSPI.h */; };
@@ -377,6 +381,10 @@
377381
C138EA1A2436447200656DF1 /* CoreServicesSPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CoreServicesSPI.h; sourceTree = "<group>"; };
378382
C15CBB3223F34A1200300CC7 /* NSUserDefaultsSPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NSUserDefaultsSPI.h; sourceTree = "<group>"; };
379383
C2147A4A1EFD0AA600056FA5 /* CopyPALHeaders.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = CopyPALHeaders.xcconfig; sourceTree = "<group>"; };
384+
CD6122CA2559B6AC00FC657A /* OutputContext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OutputContext.h; sourceTree = "<group>"; };
385+
CD6122CB2559B6AC00FC657A /* OutputContext.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = OutputContext.mm; sourceTree = "<group>"; };
386+
CD6122CE2559B8F200FC657A /* OutputDevice.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OutputDevice.h; sourceTree = "<group>"; };
387+
CD6122CF2559B8F200FC657A /* OutputDevice.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = OutputDevice.mm; sourceTree = "<group>"; };
380388
CDACB35E23873E480018D7CE /* MediaToolboxSoftLink.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MediaToolboxSoftLink.cpp; sourceTree = "<group>"; };
381389
CDACB35F23873E480018D7CE /* MediaToolboxSoftLink.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MediaToolboxSoftLink.h; sourceTree = "<group>"; };
382390
CDF91112220E4EEC001EA39E /* CelestialSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CelestialSPI.h; sourceTree = "<group>"; };
@@ -406,6 +414,10 @@
406414
children = (
407415
0C00CFD11F68CE4600AAC26D /* MediaTimeAVFoundation.cpp */,
408416
0C00CFD21F68CE4600AAC26D /* MediaTimeAVFoundation.h */,
417+
CD6122CA2559B6AC00FC657A /* OutputContext.h */,
418+
CD6122CB2559B6AC00FC657A /* OutputContext.mm */,
419+
CD6122CE2559B8F200FC657A /* OutputDevice.h */,
420+
CD6122CF2559B8F200FC657A /* OutputDevice.mm */,
409421
);
410422
path = avfoundation;
411423
sourceTree = "<group>";
@@ -874,6 +886,8 @@
874886
570AB8F920AF6E3D00B8BE87 /* NSXPCConnectionSPI.h in Headers */,
875887
0C5AF91F1F43A4C7002EAC02 /* OpenGLESSPI.h in Headers */,
876888
31647FB1251759EF0010F8FB /* OpenGLSoftLinkCocoa.h in Headers */,
889+
CD6122CC2559B6AC00FC657A /* OutputContext.h in Headers */,
890+
CD6122D02559B8F200FC657A /* OutputDevice.h in Headers */,
877891
A169B041248EF05200EE8B7B /* PassKitInstallmentsSPI.h in Headers */,
878892
A1F63C9F21A4DBF7006FB43B /* PassKitSoftLink.h in Headers */,
879893
0C2DA1551F3BEB4900DBC317 /* PassKitSPI.h in Headers */,
@@ -1011,6 +1025,8 @@
10111025
0CF99CA41F736375007EE793 /* MediaTimeAVFoundation.cpp in Sources */,
10121026
CDACB3602387425B0018D7CE /* MediaToolboxSoftLink.cpp in Sources */,
10131027
31647FB0251759DD0010F8FB /* OpenGLSoftLinkCocoa.mm in Sources */,
1028+
CD6122CD2559B6AC00FC657A /* OutputContext.mm in Sources */,
1029+
CD6122D12559B8F200FC657A /* OutputDevice.mm in Sources */,
10141030
A1F63CA021A4DBF7006FB43B /* PassKitSoftLink.mm in Sources */,
10151031
A1175B4F1F6B337300C4B9F0 /* PopupMenu.mm in Sources */,
10161032
4450FC9F21F5F602004DFA56 /* QuickLookSoftLink.mm in Sources */,
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright (C) 2020 Apple Inc. All rights reserved.
3+
*
4+
* Redistribution and use in source and binary forms, with or without
5+
* modification, are permitted provided that the following conditions
6+
* are met:
7+
* 1. Redistributions of source code must retain the above copyright
8+
* notice, this list of conditions and the following disclaimer.
9+
* 2. Redistributions in binary form must reproduce the above copyright
10+
* notice, this list of conditions and the following disclaimer in the
11+
* documentation and/or other materials provided with the distribution.
12+
*
13+
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15+
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17+
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23+
* THE POSSIBILITY OF SUCH DAMAGE.
24+
*/
25+
26+
#pragma once
27+
28+
#if USE(AVFOUNDATION)
29+
30+
#include <wtf/text/WTFString.h>
31+
32+
OBJC_CLASS AVOutputContext;
33+
34+
namespace PAL {
35+
36+
class OutputDevice;
37+
38+
class OutputContext {
39+
public:
40+
static Optional<OutputContext>& sharedAudioPresentationOutputContext();
41+
42+
bool supportsMultipleOutputDevices();
43+
String deviceName();
44+
45+
Vector<OutputDevice> outputDevices() const;
46+
47+
AVOutputContext* platformContext() const { return m_context.get(); }
48+
private:
49+
friend class NeverDestroyed<OutputContext>;
50+
OutputContext(RetainPtr<AVOutputContext>&&);
51+
52+
RetainPtr<AVOutputContext> m_context;
53+
};
54+
55+
}
56+
57+
#endif
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/*
2+
* Copyright (C) 2020 Apple Inc. All rights reserved.
3+
*
4+
* Redistribution and use in source and binary forms, with or without
5+
* modification, are permitted provided that the following conditions
6+
* are met:
7+
* 1. Redistributions of source code must retain the above copyright
8+
* notice, this list of conditions and the following disclaimer.
9+
* 2. Redistributions in binary form must reproduce the above copyright
10+
* notice, this list of conditions and the following disclaimer in the
11+
* documentation and/or other materials provided with the distribution.
12+
*
13+
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15+
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17+
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23+
* THE POSSIBILITY OF SUCH DAMAGE.
24+
*/
25+
26+
#include "config.h"
27+
#include "OutputContext.h"
28+
29+
#if USE(AVFOUNDATION)
30+
31+
#include "OutputDevice.h"
32+
#include <mutex>
33+
#include <pal/spi/cocoa/AVFoundationSPI.h>
34+
#include <wtf/NeverDestroyed.h>
35+
#include <wtf/text/StringBuilder.h>
36+
37+
#include <pal/cocoa/AVFoundationSoftLink.h>
38+
39+
namespace PAL {
40+
41+
OutputContext::OutputContext(RetainPtr<AVOutputContext>&& context)
42+
: m_context(WTFMove(context))
43+
{
44+
}
45+
46+
Optional<OutputContext>& OutputContext::sharedAudioPresentationOutputContext()
47+
{
48+
static NeverDestroyed<Optional<OutputContext>> sharedAudioPresentationOutputContext = [] () -> Optional<OutputContext> {
49+
if (![PAL::getAVOutputContextClass() respondsToSelector:@selector(sharedAudioPresentationOutputContext)])
50+
return WTF::nullopt;
51+
52+
auto context = [getAVOutputContextClass() sharedAudioPresentationOutputContext];
53+
if (!context)
54+
return WTF::nullopt;
55+
56+
return OutputContext(retainPtr(context));
57+
}();
58+
return sharedAudioPresentationOutputContext;
59+
}
60+
61+
bool OutputContext::supportsMultipleOutputDevices()
62+
{
63+
return [m_context respondsToSelector:@selector(supportsMultipleOutputDevices)]
64+
&& [m_context respondsToSelector:@selector(outputDevices)]
65+
&& [m_context supportsMultipleOutputDevices];
66+
}
67+
68+
String OutputContext::deviceName()
69+
{
70+
if (!supportsMultipleOutputDevices())
71+
return [m_context deviceName];
72+
73+
StringBuilder builder;
74+
auto devices = outputDevices();
75+
auto iterator = devices.begin();
76+
77+
while (iterator != devices.end()) {
78+
builder.append(iterator->name());
79+
80+
if (++iterator != devices.end())
81+
builder.append(" + ");
82+
}
83+
84+
return builder.toString();
85+
}
86+
87+
Vector<OutputDevice> OutputContext::outputDevices() const
88+
{
89+
if (![m_context respondsToSelector:@selector(outputDevices)]) {
90+
if (auto *outputDevice = [m_context outputDevice])
91+
return { retainPtr(outputDevice) };
92+
return { };
93+
}
94+
95+
auto *avOutputDevices = [m_context outputDevices];
96+
Vector<OutputDevice> outputDevices;
97+
outputDevices.reserveInitialCapacity(avOutputDevices.count);
98+
for (AVOutputDevice *device in avOutputDevices)
99+
outputDevices.uncheckedAppend({ retainPtr(device) });
100+
return outputDevices;
101+
}
102+
103+
104+
}
105+
106+
#endif

0 commit comments

Comments
 (0)