Diff
Modified: trunk/Source/WebCore/ChangeLog (277363 => 277364)
--- trunk/Source/WebCore/ChangeLog 2021-05-12 08:48:25 UTC (rev 277363)
+++ trunk/Source/WebCore/ChangeLog 2021-05-12 08:57:38 UTC (rev 277364)
@@ -1,5 +1,58 @@
2021-05-12 Youenn Fablet <[email protected]>
+ Introduce an internal unit to render audio MediaStreamTrack(s)
+ https://bugs.webkit.org/show_bug.cgi?id=225601
+
+ Reviewed by Eric Carlson.
+
+ Move files from platform/mediastream/mac to platform/mediastream/cocoa since they are used in both iOS and macOS.
+ Move Audio Unit functionality out of AudioMediaStreamTrackRendererUnit.
+ AudioMediaStreamTrackRendererUnit is responsible to manage sources and do the mixing.
+ To actually render audio, it will use an InternalUnit, which is currently done in process.
+
+ A future work will add support for a remote InternalUnit, that would run on GPUProcess.
+ To prepare for that, a callback allows customizing the Internal Unit creation.
+ We also change renderer start to be asynchronous, since it requires fetching the audio description from GPUProcess.
+
+ No change of behavior, covered by existing tests.
+
+ * SourcesCocoa.txt:
+ * WebCore.xcodeproj/project.pbxproj:
+ * platform/audio/cocoa/AudioSampleBufferList.h:
+ * platform/mediastream/AudioMediaStreamTrackRenderer.h:
+ * platform/mediastream/AudioTrackPrivateMediaStream.cpp:
+ (WebCore::AudioTrackPrivateMediaStream::startRenderer):
+ * platform/mediastream/cocoa/AudioMediaStreamTrackRendererCocoa.cpp: Renamed from Source/WebCore/platform/mediastream/mac/AudioMediaStreamTrackRendererCocoa.cpp.
+ (WebCore::AudioMediaStreamTrackRendererCocoa::start):
+ * platform/mediastream/cocoa/AudioMediaStreamTrackRendererCocoa.h: Copied from Source/WebCore/platform/mediastream/mac/AudioMediaStreamTrackRendererCocoa.h.
+ * platform/mediastream/cocoa/AudioMediaStreamTrackRendererInternalUnit.cpp: Renamed from Source/WebCore/platform/mediastream/mac/AudioMediaStreamTrackRendererUnit.cpp.
+ (WebCore::AudioMediaStreamTrackRendererInternalUnit::createLocalInternalUnit):
+ (WebCore::LocalAudioMediaStreamTrackRendererInternalUnit::LocalAudioMediaStreamTrackRendererInternalUnit):
+ (WebCore::LocalAudioMediaStreamTrackRendererInternalUnit::retrieveFormatDescription):
+ (WebCore::LocalAudioMediaStreamTrackRendererInternalUnit::setAudioOutputDevice):
+ (WebCore::LocalAudioMediaStreamTrackRendererInternalUnit::start):
+ (WebCore::LocalAudioMediaStreamTrackRendererInternalUnit::stop):
+ (WebCore::LocalAudioMediaStreamTrackRendererInternalUnit::createAudioUnitIfNeeded):
+ (WebCore::LocalAudioMediaStreamTrackRendererInternalUnit::renderingCallback):
+ * platform/mediastream/cocoa/AudioMediaStreamTrackRendererInternalUnit.h: Renamed from Source/WebCore/platform/mediastream/mac/AudioMediaStreamTrackRendererCocoa.h.
+ * platform/mediastream/cocoa/AudioMediaStreamTrackRendererUnit.cpp: Added.
+ (WebCore::getCreateInternalUnitFunction):
+ (WebCore::AudioMediaStreamTrackRendererUnit::setCreateInternalUnitFunction):
+ (WebCore::createInternalUnit):
+ (WebCore::AudioMediaStreamTrackRendererUnit::singleton):
+ (WebCore::AudioMediaStreamTrackRendererUnit::AudioMediaStreamTrackRendererUnit):
+ (WebCore::AudioMediaStreamTrackRendererUnit::~AudioMediaStreamTrackRendererUnit):
+ (WebCore::AudioMediaStreamTrackRendererUnit::setAudioOutputDevice):
+ (WebCore::AudioMediaStreamTrackRendererUnit::addSource):
+ (WebCore::AudioMediaStreamTrackRendererUnit::removeSource):
+ (WebCore::AudioMediaStreamTrackRendererUnit::start):
+ (WebCore::AudioMediaStreamTrackRendererUnit::stop):
+ (WebCore::AudioMediaStreamTrackRendererUnit::retrieveFormatDescription):
+ (WebCore::AudioMediaStreamTrackRendererUnit::render):
+ * platform/mediastream/cocoa/AudioMediaStreamTrackRendererUnit.h: Renamed from Source/WebCore/platform/mediastream/mac/AudioMediaStreamTrackRendererUnit.h.
+
+2021-05-12 Youenn Fablet <[email protected]>
+
Enumerate AVCaptureDevice list in a background thread
https://bugs.webkit.org/show_bug.cgi?id=225643
<rdar://problem/77820002>
Modified: trunk/Source/WebCore/SourcesCocoa.txt (277363 => 277364)
--- trunk/Source/WebCore/SourcesCocoa.txt 2021-05-12 08:48:25 UTC (rev 277363)
+++ trunk/Source/WebCore/SourcesCocoa.txt 2021-05-12 08:57:38 UTC (rev 277364)
@@ -527,6 +527,9 @@
platform/mediarecorder/cocoa/AudioSampleBufferCompressor.mm
platform/mediarecorder/cocoa/MediaRecorderPrivateWriterCocoa.mm
platform/mediarecorder/cocoa/VideoSampleBufferCompressor.mm
+platform/mediastream/cocoa/AudioMediaStreamTrackRendererCocoa.cpp
+platform/mediastream/cocoa/AudioMediaStreamTrackRendererInternalUnit.cpp
+platform/mediastream/cocoa/AudioMediaStreamTrackRendererUnit.cpp
platform/mediastream/ios/AVAudioSessionCaptureDevice.mm
platform/mediastream/ios/AVAudioSessionCaptureDeviceManager.mm @no-unify
platform/mediastream/ios/CoreAudioCaptureSourceIOS.mm @no-unify
@@ -533,8 +536,6 @@
platform/mediastream/libwebrtc/LibWebRTCProviderCocoa.cpp
platform/mediastream/mac/AVCaptureDeviceManager.mm @no-unify
platform/mediastream/mac/AVVideoCaptureSource.mm @no-unify
-platform/mediastream/mac/AudioMediaStreamTrackRendererCocoa.cpp
-platform/mediastream/mac/AudioMediaStreamTrackRendererUnit.cpp
platform/mediastream/mac/BaseAudioSharedUnit.cpp
platform/mediastream/mac/CoreAudioCaptureDevice.cpp
platform/mediastream/mac/CoreAudioCaptureDeviceManager.cpp
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (277363 => 277364)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2021-05-12 08:48:25 UTC (rev 277363)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2021-05-12 08:57:38 UTC (rev 277364)
@@ -1175,6 +1175,8 @@
41B8776223DE1045003638B8 /* RealtimeMediaSourceIdentifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 41B8776023DE1042003638B8 /* RealtimeMediaSourceIdentifier.h */; settings = {ATTRIBUTES = (Private, ); }; };
41BBA866257E373B00AC7F6D /* SFrameUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 41209E24257A2FBB00120ACA /* SFrameUtils.h */; settings = {ATTRIBUTES = (Private, ); }; };
41BF204922BA7BE80004F812 /* RealtimeVideoSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 41BF204022B947160004F812 /* RealtimeVideoSource.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 41C3B8A12649B1E0004ED4DE /* AudioMediaStreamTrackRendererInternalUnit.h in Headers */ = {isa = PBXBuildFile; fileRef = 41C3B89F2649B1B7004ED4DE /* AudioMediaStreamTrackRendererInternalUnit.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 41C3B8A22649B1E5004ED4DE /* AudioMediaStreamTrackRendererUnit.h in Headers */ = {isa = PBXBuildFile; fileRef = 41C3B89B2649B1B6004ED4DE /* AudioMediaStreamTrackRendererUnit.h */; settings = {ATTRIBUTES = (Private, ); }; };
41C760B10EDE03D300C1655F /* ScriptState.h in Headers */ = {isa = PBXBuildFile; fileRef = 41C760B00EDE03D300C1655F /* ScriptState.h */; settings = {ATTRIBUTES = (Private, ); }; };
41CB840125CAB7B30010E2B1 /* RealtimeIncomingVideoSourceCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 41CB840025CAB7B00010E2B1 /* RealtimeIncomingVideoSourceCocoa.h */; settings = {ATTRIBUTES = (Private, ); }; };
41CB840225CAB81E0010E2B1 /* RealtimeIncomingVideoSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CDD833A1E4324BB00621E92 /* RealtimeIncomingVideoSource.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -7697,8 +7699,6 @@
3FBC4AF2189881560046EE38 /* VideoFullscreenInterfaceAVKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoFullscreenInterfaceAVKit.h; sourceTree = "<group>"; };
41024FC823CF254F00FDF98E /* SampleBufferDisplayLayer.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = SampleBufferDisplayLayer.cpp; sourceTree = "<group>"; };
4107908A1FC3E4F20061B27A /* ClientOrigin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ClientOrigin.h; sourceTree = "<group>"; };
- 41087F01248E59C800680E91 /* AudioMediaStreamTrackRendererUnit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioMediaStreamTrackRendererUnit.cpp; sourceTree = "<group>"; };
- 41087F03248E59C900680E91 /* AudioMediaStreamTrackRendererUnit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioMediaStreamTrackRendererUnit.h; sourceTree = "<group>"; };
410938282347799A009428BA /* JSAbortControllerCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSAbortControllerCustom.cpp; sourceTree = "<group>"; };
4109382C2347850E009428BA /* JSAbortSignalCustom.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JSAbortSignalCustom.cpp; sourceTree = "<group>"; };
410A8EF424F823B9004F9070 /* TextEncoderStream.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = TextEncoderStream.idl; sourceTree = "<group>"; };
@@ -7864,8 +7864,6 @@
4162A44F101145AE00DFF3ED /* DedicatedWorkerGlobalScope.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DedicatedWorkerGlobalScope.idl; sourceTree = "<group>"; };
4162A4551011464700DFF3ED /* JSDedicatedWorkerGlobalScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDedicatedWorkerGlobalScope.cpp; sourceTree = "<group>"; };
4162A4561011464700DFF3ED /* JSDedicatedWorkerGlobalScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDedicatedWorkerGlobalScope.h; sourceTree = "<group>"; };
- 416A069223CCAA9300347109 /* AudioMediaStreamTrackRendererCocoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioMediaStreamTrackRendererCocoa.h; sourceTree = "<group>"; };
- 416A069323CCAA9400347109 /* AudioMediaStreamTrackRendererCocoa.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioMediaStreamTrackRendererCocoa.cpp; sourceTree = "<group>"; };
416A069423CCAA9E00347109 /* AudioTrackPrivateMediaStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioTrackPrivateMediaStream.cpp; sourceTree = "<group>"; };
416A069523CCAA9E00347109 /* AudioMediaStreamTrackRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioMediaStreamTrackRenderer.cpp; sourceTree = "<group>"; };
416A069623CCAA9F00347109 /* AudioMediaStreamTrackRenderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioMediaStreamTrackRenderer.h; sourceTree = "<group>"; };
@@ -8023,6 +8021,12 @@
41BCE87725F7A67A0046C2E5 /* RTCTransformEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTCTransformEvent.h; sourceTree = "<group>"; };
41BF204022B947160004F812 /* RealtimeVideoSource.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RealtimeVideoSource.h; sourceTree = "<group>"; };
41BF204222B947170004F812 /* RealtimeVideoSource.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = RealtimeVideoSource.cpp; sourceTree = "<group>"; };
+ 41C3B89B2649B1B6004ED4DE /* AudioMediaStreamTrackRendererUnit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AudioMediaStreamTrackRendererUnit.h; sourceTree = "<group>"; };
+ 41C3B89C2649B1B6004ED4DE /* AudioMediaStreamTrackRendererCocoa.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AudioMediaStreamTrackRendererCocoa.h; sourceTree = "<group>"; };
+ 41C3B89D2649B1B6004ED4DE /* AudioMediaStreamTrackRendererCocoa.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AudioMediaStreamTrackRendererCocoa.cpp; sourceTree = "<group>"; };
+ 41C3B89E2649B1B7004ED4DE /* AudioMediaStreamTrackRendererInternalUnit.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AudioMediaStreamTrackRendererInternalUnit.cpp; sourceTree = "<group>"; };
+ 41C3B89F2649B1B7004ED4DE /* AudioMediaStreamTrackRendererInternalUnit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AudioMediaStreamTrackRendererInternalUnit.h; sourceTree = "<group>"; };
+ 41C3B8A02649B1B7004ED4DE /* AudioMediaStreamTrackRendererUnit.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AudioMediaStreamTrackRendererUnit.cpp; sourceTree = "<group>"; };
41C760B00EDE03D300C1655F /* ScriptState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptState.h; sourceTree = "<group>"; };
41C7E1051E6A54360027B4DE /* CanvasCaptureMediaStreamTrack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CanvasCaptureMediaStreamTrack.cpp; sourceTree = "<group>"; };
41C7E1061E6A54360027B4DE /* CanvasCaptureMediaStreamTrack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CanvasCaptureMediaStreamTrack.h; sourceTree = "<group>"; };
@@ -17548,6 +17552,7 @@
07221B9217CF0AD400848E51 /* mediastream */ = {
isa = PBXGroup;
children = (
+ 41C3B89A2649B18E004ED4DE /* cocoa */,
CDC6751F1EAEA99600727C84 /* ios */,
415747421E38698000E914D8 /* libwebrtc */,
0729B14D17CFCCA0004F1D60 /* mac */,
@@ -17632,10 +17637,6 @@
0729B14D17CFCCA0004F1D60 /* mac */ = {
isa = PBXGroup;
children = (
- 416A069323CCAA9400347109 /* AudioMediaStreamTrackRendererCocoa.cpp */,
- 416A069223CCAA9300347109 /* AudioMediaStreamTrackRendererCocoa.h */,
- 41087F01248E59C800680E91 /* AudioMediaStreamTrackRendererUnit.cpp */,
- 41087F03248E59C900680E91 /* AudioMediaStreamTrackRendererUnit.h */,
070363DA181A1CDC00C074A5 /* AVCaptureDeviceManager.h */,
070363DB181A1CDC00C074A5 /* AVCaptureDeviceManager.mm */,
070363DE181A1CDC00C074A5 /* AVVideoCaptureSource.h */,
@@ -19874,6 +19875,19 @@
name = Streams;
sourceTree = "<group>";
};
+ 41C3B89A2649B18E004ED4DE /* cocoa */ = {
+ isa = PBXGroup;
+ children = (
+ 41C3B89D2649B1B6004ED4DE /* AudioMediaStreamTrackRendererCocoa.cpp */,
+ 41C3B89C2649B1B6004ED4DE /* AudioMediaStreamTrackRendererCocoa.h */,
+ 41C3B89E2649B1B7004ED4DE /* AudioMediaStreamTrackRendererInternalUnit.cpp */,
+ 41C3B89F2649B1B7004ED4DE /* AudioMediaStreamTrackRendererInternalUnit.h */,
+ 41C3B8A02649B1B7004ED4DE /* AudioMediaStreamTrackRendererUnit.cpp */,
+ 41C3B89B2649B1B6004ED4DE /* AudioMediaStreamTrackRendererUnit.h */,
+ );
+ path = cocoa;
+ sourceTree = "<group>";
+ };
41F54F7C1C50C4F600338488 /* fetch */ = {
isa = PBXGroup;
children = (
@@ -31552,6 +31566,8 @@
FDE2D55B159E66EB00DCCCF8 /* AudioIOCallback.h in Headers */,
FD31601012B0267600C1A359 /* AudioListener.h in Headers */,
416A06A123CCAD0300347109 /* AudioMediaStreamTrackRenderer.h in Headers */,
+ 41C3B8A12649B1E0004ED4DE /* AudioMediaStreamTrackRendererInternalUnit.h in Headers */,
+ 41C3B8A22649B1E5004ED4DE /* AudioMediaStreamTrackRendererUnit.h in Headers */,
FD31601312B0267600C1A359 /* AudioNode.h in Headers */,
FD31601612B0267600C1A359 /* AudioNodeInput.h in Headers */,
E71467B324ABAEF200FB2F50 /* AudioNodeOptions.h in Headers */,
Modified: trunk/Source/WebCore/platform/audio/cocoa/AudioSampleBufferList.h (277363 => 277364)
--- trunk/Source/WebCore/platform/audio/cocoa/AudioSampleBufferList.h 2021-05-12 08:48:25 UTC (rev 277363)
+++ trunk/Source/WebCore/platform/audio/cocoa/AudioSampleBufferList.h 2021-05-12 08:57:38 UTC (rev 277364)
@@ -72,7 +72,7 @@
void reset();
- static void zeroABL(AudioBufferList&, size_t);
+ WEBCORE_EXPORT static void zeroABL(AudioBufferList&, size_t);
void zero();
protected:
Modified: trunk/Source/WebCore/platform/mediastream/AudioMediaStreamTrackRenderer.h (277363 => 277364)
--- trunk/Source/WebCore/platform/mediastream/AudioMediaStreamTrackRenderer.h 2021-05-12 08:48:25 UTC (rev 277363)
+++ trunk/Source/WebCore/platform/mediastream/AudioMediaStreamTrackRenderer.h 2021-05-12 08:57:38 UTC (rev 277364)
@@ -45,7 +45,7 @@
static std::unique_ptr<AudioMediaStreamTrackRenderer> create();
virtual ~AudioMediaStreamTrackRenderer() = default;
- virtual void start() = 0;
+ virtual void start(CompletionHandler<void()>&&) = 0;
virtual void stop() = 0;
virtual void clear() = 0;
// May be called on a background thread. It should only be called after start/before stop is called.
Modified: trunk/Source/WebCore/platform/mediastream/AudioTrackPrivateMediaStream.cpp (277363 => 277364)
--- trunk/Source/WebCore/platform/mediastream/AudioTrackPrivateMediaStream.cpp 2021-05-12 08:48:25 UTC (rev 277363)
+++ trunk/Source/WebCore/platform/mediastream/AudioTrackPrivateMediaStream.cpp 2021-05-12 08:57:38 UTC (rev 277364)
@@ -159,13 +159,14 @@
void AudioTrackPrivateMediaStream::startRenderer()
{
ASSERT(isMainThread());
- if (m_isPlaying)
+ if (m_isPlaying || !m_renderer)
return;
m_isPlaying = true;
- if (m_renderer)
- m_renderer->start();
- m_audioSource->addAudioSampleObserver(*this);
+ m_renderer->start([protectedThis = makeRef(*this)] {
+ if (protectedThis->m_isPlaying)
+ protectedThis->m_audioSource->addAudioSampleObserver(protectedThis.get());
+ });
}
void AudioTrackPrivateMediaStream::stopRenderer()
Copied: trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererCocoa.cpp (from rev 277363, trunk/Source/WebCore/platform/mediastream/mac/AudioMediaStreamTrackRendererCocoa.cpp) (0 => 277364)
--- trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererCocoa.cpp (rev 0)
+++ trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererCocoa.cpp 2021-05-12 08:57:38 UTC (rev 277364)
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2017-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.
+ */
+
+#include "config.h"
+#include "AudioMediaStreamTrackRendererCocoa.h"
+
+#if ENABLE(MEDIA_STREAM)
+
+#include "AudioMediaStreamTrackRendererUnit.h"
+#include "AudioSampleDataSource.h"
+#include "CAAudioStreamDescription.h"
+#include "LibWebRTCAudioModule.h"
+
+namespace WebCore {
+
+AudioMediaStreamTrackRendererCocoa::AudioMediaStreamTrackRendererCocoa() = default;
+
+AudioMediaStreamTrackRendererCocoa::~AudioMediaStreamTrackRendererCocoa() = default;
+
+void AudioMediaStreamTrackRendererCocoa::start(CompletionHandler<void()>&& callback)
+{
+ clear();
+
+ AudioMediaStreamTrackRendererUnit::singleton().retrieveFormatDescription([weakThis = makeWeakPtr(this), callback = WTFMove(callback)](auto* formatDescription) mutable {
+ if (weakThis)
+ weakThis->m_outputDescription = makeUnique<CAAudioStreamDescription>(*formatDescription);
+ callback();
+ });
+}
+
+void AudioMediaStreamTrackRendererCocoa::stop()
+{
+ if (m_dataSource)
+ AudioMediaStreamTrackRendererUnit::singleton().removeSource(*m_dataSource);
+}
+
+void AudioMediaStreamTrackRendererCocoa::clear()
+{
+ stop();
+
+ m_dataSource = nullptr;
+ m_outputDescription = { };
+}
+
+void AudioMediaStreamTrackRendererCocoa::setVolume(float volume)
+{
+ AudioMediaStreamTrackRenderer::setVolume(volume);
+ if (m_dataSource)
+ m_dataSource->setVolume(volume);
+}
+
+void AudioMediaStreamTrackRendererCocoa::setAudioOutputDevice(const String& deviceId)
+{
+ // FIXME: We should create a unit for ourselves here or use the default unit if deviceId is matching.
+ AudioMediaStreamTrackRendererUnit::singleton().setAudioOutputDevice(deviceId);
+ m_shouldReset = true;
+}
+
+static unsigned pollSamplesCount()
+{
+#if USE(LIBWEBRTC)
+ return LibWebRTCAudioModule::PollSamplesCount + 1;
+#else
+ return 2;
+#endif
+}
+
+void AudioMediaStreamTrackRendererCocoa::pushSamples(const MediaTime& sampleTime, const PlatformAudioData& audioData, const AudioStreamDescription& description, size_t sampleCount)
+{
+ ASSERT(!isMainThread());
+ ASSERT(description.platformDescription().type == PlatformDescription::CAAudioStreamBasicType);
+ if (!m_dataSource || m_shouldReset || !m_dataSource->inputDescription() || *m_dataSource->inputDescription() != description) {
+ DisableMallocRestrictionsForCurrentThreadScope scope;
+
+ // FIXME: For non libwebrtc sources, we can probably reduce poll samples count to 2.
+
+ auto dataSource = AudioSampleDataSource::create(description.sampleRate() * 0.5, *this, pollSamplesCount());
+
+ if (dataSource->setInputFormat(toCAAudioStreamDescription(description))) {
+ ERROR_LOG(LOGIDENTIFIER, "Unable to set the input format of data source");
+ return;
+ }
+
+ if (!m_outputDescription || dataSource->setOutputFormat(*m_outputDescription)) {
+ ERROR_LOG(LOGIDENTIFIER, "Unable to set the output format of data source");
+ return;
+ }
+
+ callOnMainThread([this, weakThis = makeWeakPtr(this), oldSource = m_dataSource, newSource = dataSource]() mutable {
+ if (!weakThis)
+ return;
+
+ if (oldSource)
+ AudioMediaStreamTrackRendererUnit::singleton().removeSource(*oldSource);
+
+ newSource->setVolume(volume());
+ AudioMediaStreamTrackRendererUnit::singleton().addSource(WTFMove(newSource));
+ });
+ m_dataSource = WTFMove(dataSource);
+ m_shouldReset = false;
+ }
+
+ m_dataSource->pushSamples(sampleTime, audioData, sampleCount);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM)
Copied: trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererCocoa.h (from rev 277363, trunk/Source/WebCore/platform/mediastream/mac/AudioMediaStreamTrackRendererCocoa.h) (0 => 277364)
--- trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererCocoa.h (rev 0)
+++ trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererCocoa.h 2021-05-12 08:57:38 UTC (rev 277364)
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2017-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.
+ */
+
+#pragma once
+
+#if ENABLE(MEDIA_STREAM)
+
+#include "AudioMediaStreamTrackRenderer.h"
+#include "Logging.h"
+#include <wtf/WeakPtr.h>
+
+#include <AudioToolbox/AudioToolbox.h>
+#include <CoreAudio/CoreAudioTypes.h>
+
+namespace WebCore {
+
+class AudioSampleDataSource;
+class AudioSampleBufferList;
+class CAAudioStreamDescription;
+
+class AudioMediaStreamTrackRendererCocoa : public AudioMediaStreamTrackRenderer, public CanMakeWeakPtr<AudioMediaStreamTrackRendererCocoa, WeakPtrFactoryInitialization::Eager> {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ AudioMediaStreamTrackRendererCocoa();
+ ~AudioMediaStreamTrackRendererCocoa();
+
+private:
+ // AudioMediaStreamTrackRenderer
+ void pushSamples(const WTF::MediaTime&, const PlatformAudioData&, const AudioStreamDescription&, size_t) final;
+ void start(CompletionHandler<void()>&&) final;
+ void stop() final;
+ void clear() final;
+ void setVolume(float) final;
+ void setAudioOutputDevice(const String&) final;
+
+ std::unique_ptr<CAAudioStreamDescription> m_outputDescription;
+ RefPtr<AudioSampleDataSource> m_dataSource;
+ bool m_shouldReset { false };
+};
+
+}
+
+#endif // ENABLE(MEDIA_STREAM)
Copied: trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererInternalUnit.cpp (from rev 277363, trunk/Source/WebCore/platform/mediastream/mac/AudioMediaStreamTrackRendererUnit.cpp) (0 => 277364)
--- trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererInternalUnit.cpp (rev 0)
+++ trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererInternalUnit.cpp 2021-05-12 08:57:38 UTC (rev 277364)
@@ -0,0 +1,237 @@
+/*
+ * 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.
+ */
+
+#include "config.h"
+#include "AudioMediaStreamTrackRendererInternalUnit.h"
+
+#if ENABLE(MEDIA_STREAM)
+
+#include "AudioSampleDataSource.h"
+#include "AudioSession.h"
+#include "CAAudioStreamDescription.h"
+#include "Logging.h"
+
+#include <pal/spi/cocoa/AudioToolboxSPI.h>
+#include <wtf/FastMalloc.h>
+#include <wtf/Lock.h>
+
+#if PLATFORM(COCOA)
+#include "CoreAudioCaptureDevice.h"
+#include "CoreAudioCaptureDeviceManager.h"
+#endif
+
+#include <pal/cf/CoreMediaSoftLink.h>
+
+namespace WebCore {
+
+class LocalAudioMediaStreamTrackRendererInternalUnit final : public AudioMediaStreamTrackRendererInternalUnit {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ explicit LocalAudioMediaStreamTrackRendererInternalUnit(RenderCallback&&);
+
+private:
+ void createAudioUnitIfNeeded();
+
+ // AudioMediaStreamTrackRendererInternalUnit API.
+ void start() final;
+ void stop() final;
+ void retrieveFormatDescription(CompletionHandler<void(const CAAudioStreamDescription*)>&&) final;
+ void setAudioOutputDevice(const String&) final;
+
+ static OSStatus renderingCallback(void*, AudioUnitRenderActionFlags*, const AudioTimeStamp*, UInt32 inBusNumber, UInt32 sampleCount, AudioBufferList*);
+
+ RenderCallback m_renderCallback;
+ std::unique_ptr<CAAudioStreamDescription> m_outputDescription;
+ AudioComponentInstance m_remoteIOUnit { nullptr };
+ bool m_isStarted { false };
+#if PLATFORM(MAC)
+ uint32_t m_deviceID { 0 };
+#endif
+};
+
+UniqueRef<AudioMediaStreamTrackRendererInternalUnit> AudioMediaStreamTrackRendererInternalUnit::createLocalInternalUnit(RenderCallback&& renderCallback)
+{
+ return makeUniqueRef<LocalAudioMediaStreamTrackRendererInternalUnit>(WTFMove(renderCallback));
+}
+
+LocalAudioMediaStreamTrackRendererInternalUnit::LocalAudioMediaStreamTrackRendererInternalUnit(RenderCallback&& renderCallback)
+ : m_renderCallback(WTFMove(renderCallback))
+{
+}
+
+void LocalAudioMediaStreamTrackRendererInternalUnit::retrieveFormatDescription(CompletionHandler<void(const CAAudioStreamDescription*)>&& callback)
+{
+ createAudioUnitIfNeeded();
+ callback(m_outputDescription.get());
+}
+
+void LocalAudioMediaStreamTrackRendererInternalUnit::setAudioOutputDevice(const String& deviceID)
+{
+#if PLATFORM(MAC)
+ auto device = CoreAudioCaptureDeviceManager::singleton().coreAudioDeviceWithUID(deviceID);
+
+ if (!device && !deviceID.isEmpty()) {
+ RELEASE_LOG(WebRTC, "AudioMediaStreamTrackRendererInternalUnit::setAudioOutputDeviceId - did not find device");
+ return;
+ }
+
+ auto audioUnitDeviceID = device ? device->deviceID() : 0;
+ if (m_deviceID == audioUnitDeviceID)
+ return;
+
+ bool shouldRestart = m_isStarted;
+ if (m_isStarted)
+ stop();
+
+ m_deviceID = audioUnitDeviceID;
+
+ if (shouldRestart)
+ start();
+#else
+ UNUSED_PARAM(deviceID);
+#endif
+}
+
+void LocalAudioMediaStreamTrackRendererInternalUnit::start()
+{
+ if (m_isStarted)
+ return;
+
+ createAudioUnitIfNeeded();
+ if (!m_remoteIOUnit)
+ return;
+
+ if (auto error = AudioOutputUnitStart(m_remoteIOUnit)) {
+ RELEASE_LOG_ERROR(WebRTC, "AudioMediaStreamTrackRendererInternalUnit::start AudioOutputUnitStart failed, error = %d", error);
+ AudioComponentInstanceDispose(m_remoteIOUnit);
+ m_remoteIOUnit = nullptr;
+ return;
+ }
+ m_isStarted = true;
+ RELEASE_LOG(WebRTC, "AudioMediaStreamTrackRendererInternalUnit is started");
+}
+
+void LocalAudioMediaStreamTrackRendererInternalUnit::stop()
+{
+ if (!m_remoteIOUnit)
+ return;
+
+ if (m_isStarted) {
+ AudioOutputUnitStop(m_remoteIOUnit);
+ m_isStarted = false;
+ }
+
+ AudioComponentInstanceDispose(m_remoteIOUnit);
+ m_remoteIOUnit = nullptr;
+}
+
+void LocalAudioMediaStreamTrackRendererInternalUnit::createAudioUnitIfNeeded()
+{
+ ASSERT(!m_remoteIOUnit || m_outputDescription);
+ if (m_remoteIOUnit)
+ return;
+
+ CAAudioStreamDescription outputDescription;
+ AudioComponentInstance remoteIOUnit { nullptr };
+
+ AudioComponentDescription ioUnitDescription { kAudioUnitType_Output, 0, kAudioUnitManufacturer_Apple, 0, 0 };
+#if PLATFORM(IOS_FAMILY)
+ ioUnitDescription.componentSubType = kAudioUnitSubType_RemoteIO;
+#else
+ ioUnitDescription.componentSubType = kAudioUnitSubType_DefaultOutput;
+#endif
+
+ AudioComponent ioComponent = AudioComponentFindNext(nullptr, &ioUnitDescription);
+ ASSERT(ioComponent);
+ if (!ioComponent) {
+ RELEASE_LOG_ERROR(WebRTC, "AudioMediaStreamTrackRendererInternalUnit::createAudioUnit unable to find remote IO unit component");
+ return;
+ }
+
+ auto error = AudioComponentInstanceNew(ioComponent, &remoteIOUnit);
+ if (error) {
+ RELEASE_LOG_ERROR(WebRTC, "AudioMediaStreamTrackRendererInternalUnit::createAudioUnit unable to open vpio unit, error = %d", error);
+ return;
+ }
+
+#if PLATFORM(IOS_FAMILY)
+ UInt32 param = 1;
+ error = AudioUnitSetProperty(remoteIOUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, ¶m, sizeof(param));
+ if (error) {
+ RELEASE_LOG_ERROR(WebRTC, "AudioMediaStreamTrackRendererInternalUnit::createAudioUnit unable to enable vpio unit output, error = %d", error);
+ return;
+ }
+#endif
+
+#if PLATFORM(MAC)
+ if (m_deviceID) {
+ error = AudioUnitSetProperty(remoteIOUnit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &m_deviceID, sizeof(m_deviceID));
+ if (error) {
+ RELEASE_LOG_ERROR(WebRTC, "AudioMediaStreamTrackRendererInternalUnit::createAudioUnit unable to set unit device ID %d, error %d (%.4s)", (int)m_deviceID, (int)error, (char*)&error);
+ return;
+ }
+ }
+#endif
+
+ AURenderCallbackStruct callback = { LocalAudioMediaStreamTrackRendererInternalUnit::renderingCallback, this };
+ error = AudioUnitSetProperty(remoteIOUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Global, 0, &callback, sizeof(callback));
+ if (error) {
+ RELEASE_LOG_ERROR(WebRTC, "AudioMediaStreamTrackRendererInternalUnit::createAudioUnit unable to set vpio unit speaker proc, error = %d", error);
+ return;
+ }
+
+ UInt32 size = sizeof(outputDescription.streamDescription());
+ error = AudioUnitGetProperty(remoteIOUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &outputDescription.streamDescription(), &size);
+ if (error) {
+ RELEASE_LOG_ERROR(WebRTC, "AudioMediaStreamTrackRendererInternalUnit::createAudioUnit unable to get input stream format, error = %d", error);
+ return;
+ }
+
+ outputDescription.streamDescription().mSampleRate = AudioSession::sharedSession().sampleRate();
+
+ error = AudioUnitSetProperty(remoteIOUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &outputDescription.streamDescription(), sizeof(outputDescription.streamDescription()));
+ if (error) {
+ RELEASE_LOG_ERROR(WebRTC, "AudioMediaStreamTrackRendererInternalUnit::createAudioUnit unable to set input stream format, error = %d", error);
+ return;
+ }
+
+ error = AudioUnitInitialize(remoteIOUnit);
+ if (error) {
+ RELEASE_LOG_ERROR(WebRTC, "AudioMediaStreamTrackRendererInternalUnit::createAudioUnit AudioUnitInitialize() failed, error = %d", error);
+ return;
+ }
+
+ m_outputDescription = makeUnique<CAAudioStreamDescription>(outputDescription);
+ m_remoteIOUnit = remoteIOUnit;
+}
+
+OSStatus LocalAudioMediaStreamTrackRendererInternalUnit::renderingCallback(void* processor, AudioUnitRenderActionFlags* actionFlags, const AudioTimeStamp* timeStamp, UInt32, UInt32 sampleCount, AudioBufferList* ioData)
+{
+ return static_cast<LocalAudioMediaStreamTrackRendererInternalUnit*>(processor)->m_renderCallback(sampleCount, *ioData, timeStamp->mSampleTime, timeStamp->mHostTime, *actionFlags);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM)
Copied: trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererInternalUnit.h (from rev 277363, trunk/Source/WebCore/platform/mediastream/mac/AudioMediaStreamTrackRendererCocoa.h) (0 => 277364)
--- trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererInternalUnit.h (rev 0)
+++ trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererInternalUnit.h 2021-05-12 08:57:38 UTC (rev 277364)
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#if ENABLE(MEDIA_STREAM)
+
+#include <AudioToolbox/AudioToolbox.h>
+#include <CoreAudio/CoreAudioTypes.h>
+
+namespace WebCore {
+
+class AudioMediaStreamTrackRendererUnit;
+class CAAudioStreamDescription;
+
+class AudioMediaStreamTrackRendererInternalUnit {
+public:
+ virtual ~AudioMediaStreamTrackRendererInternalUnit() = default;
+
+ using RenderCallback = Function<OSStatus(size_t sampleCount, AudioBufferList&, uint64_t sampleTime, double hostTime, AudioUnitRenderActionFlags&)>;
+ WEBCORE_EXPORT static UniqueRef<AudioMediaStreamTrackRendererInternalUnit> createLocalInternalUnit(RenderCallback&&);
+
+ virtual void start() = 0;
+ virtual void stop() = 0;
+ virtual void retrieveFormatDescription(CompletionHandler<void(const CAAudioStreamDescription*)>&&) = 0;
+ virtual void setAudioOutputDevice(const String&) = 0;
+};
+
+}
+
+#endif // ENABLE(MEDIA_STREAM)
Added: trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererUnit.cpp (0 => 277364)
--- trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererUnit.cpp (rev 0)
+++ trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererUnit.cpp 2021-05-12 08:57:38 UTC (rev 277364)
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2020-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.
+ */
+
+#include "config.h"
+#include "AudioMediaStreamTrackRendererUnit.h"
+
+#if ENABLE(MEDIA_STREAM)
+
+#include "AudioSampleDataSource.h"
+#include "Logging.h"
+
+namespace WebCore {
+
+static AudioMediaStreamTrackRendererUnit::CreateInternalUnitFunction& getCreateInternalUnitFunction()
+{
+ static NeverDestroyed<AudioMediaStreamTrackRendererUnit::CreateInternalUnitFunction> function;
+ return function;
+}
+
+void AudioMediaStreamTrackRendererUnit::setCreateInternalUnitFunction(CreateInternalUnitFunction&& function)
+{
+ getCreateInternalUnitFunction() = WTFMove(function);
+}
+
+static UniqueRef<AudioMediaStreamTrackRendererInternalUnit> createInternalUnit(AudioMediaStreamTrackRendererUnit& unit)
+{
+ AudioMediaStreamTrackRendererInternalUnit::RenderCallback callback = [&unit](auto sampleCount, auto& list, auto sampleTime, auto hostTime, auto& flags) {
+ unit.render(sampleCount, list, sampleTime, hostTime, flags);
+ return 0;
+ };
+
+ auto& function = getCreateInternalUnitFunction();
+ if (function)
+ return function(WTFMove(callback));
+
+ return AudioMediaStreamTrackRendererInternalUnit::createLocalInternalUnit(WTFMove(callback));
+}
+
+AudioMediaStreamTrackRendererUnit& AudioMediaStreamTrackRendererUnit::singleton()
+{
+ static NeverDestroyed<AudioMediaStreamTrackRendererUnit> registry;
+ return registry;
+}
+
+AudioMediaStreamTrackRendererUnit::AudioMediaStreamTrackRendererUnit()
+ : m_internalUnit(createInternalUnit(*this))
+{
+}
+
+AudioMediaStreamTrackRendererUnit::~AudioMediaStreamTrackRendererUnit()
+{
+ stop();
+}
+
+void AudioMediaStreamTrackRendererUnit::setAudioOutputDevice(const String& deviceID)
+{
+ m_internalUnit->setAudioOutputDevice(deviceID);
+}
+
+void AudioMediaStreamTrackRendererUnit::addSource(Ref<AudioSampleDataSource>&& source)
+{
+ RELEASE_LOG(WebRTC, "AudioMediaStreamTrackRendererUnit::addSource");
+
+ {
+ auto locker = holdLock(m_sourcesLock);
+ ASSERT(!m_sources.contains(source.get()));
+ m_sources.add(WTFMove(source));
+ m_sourcesCopy = copyToVector(m_sources);
+ m_shouldUpdateRenderSources = true;
+ }
+ start();
+}
+
+void AudioMediaStreamTrackRendererUnit::removeSource(AudioSampleDataSource& source)
+{
+ RELEASE_LOG(WebRTC, "AudioMediaStreamTrackRendererUnit::removeSource");
+
+ bool shouldStop = false;
+ {
+ auto locker = holdLock(m_sourcesLock);
+ m_sources.remove(source);
+ shouldStop = m_sources.isEmpty();
+ m_sourcesCopy = copyToVector(m_sources);
+ m_shouldUpdateRenderSources = true;
+ }
+ if (shouldStop)
+ stop();
+}
+
+void AudioMediaStreamTrackRendererUnit::start()
+{
+ RELEASE_LOG(WebRTC, "AudioMediaStreamTrackRendererUnit::start");
+ m_internalUnit->start();
+}
+
+void AudioMediaStreamTrackRendererUnit::stop()
+{
+ RELEASE_LOG(WebRTC, "AudioMediaStreamTrackRendererUnit::stop");
+ m_internalUnit->stop();
+}
+
+void AudioMediaStreamTrackRendererUnit::retrieveFormatDescription(CompletionHandler<void(const CAAudioStreamDescription*)>&& callback)
+{
+ m_internalUnit->retrieveFormatDescription(WTFMove(callback));
+}
+
+void AudioMediaStreamTrackRendererUnit::render(size_t sampleCount, AudioBufferList& ioData, uint64_t sampleTime, double hostTime, AudioUnitRenderActionFlags& actionFlags)
+{
+ // For performance reasons, we forbid heap allocations while doing rendering on the audio thread.
+ ForbidMallocUseForCurrentThreadScope forbidMallocUse;
+
+ ASSERT(!isMainThread());
+ if (m_shouldUpdateRenderSources) {
+ auto locker = tryHoldLock(m_sourcesLock);
+ if (!locker)
+ return;
+
+ m_renderSources = WTFMove(m_sourcesCopy);
+ m_shouldUpdateRenderSources = false;
+ }
+
+ if (m_renderSources.isEmpty()) {
+ actionFlags = kAudioUnitRenderAction_OutputIsSilence;
+ return;
+ }
+
+ // Mix all sources.
+ bool isFirstSource = true;
+ for (auto& source : m_renderSources) {
+ source->pullSamples(ioData, sampleCount, sampleTime, hostTime, isFirstSource ? AudioSampleDataSource::Copy : AudioSampleDataSource::Mix);
+ isFirstSource = false;
+ }
+ return;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM)
Copied: trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererUnit.h (from rev 277363, trunk/Source/WebCore/platform/mediastream/mac/AudioMediaStreamTrackRendererUnit.h) (0 => 277364)
--- trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererUnit.h (rev 0)
+++ trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererUnit.h 2021-05-12 08:57:38 UTC (rev 277364)
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2020-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.
+ */
+
+#pragma once
+
+#if ENABLE(MEDIA_STREAM)
+
+#include "AudioMediaStreamTrackRendererInternalUnit.h"
+#include <wtf/Forward.h>
+#include <wtf/HashSet.h>
+#include <wtf/UniqueRef.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class AudioSampleDataSource;
+class AudioSampleBufferList;
+class CAAudioStreamDescription;
+class AudioMediaStreamTrackRendererInternalUnit;
+
+class AudioMediaStreamTrackRendererUnit {
+public:
+ WEBCORE_EXPORT static AudioMediaStreamTrackRendererUnit& singleton();
+
+ AudioMediaStreamTrackRendererUnit();
+ ~AudioMediaStreamTrackRendererUnit();
+
+ using CreateInternalUnitFunction = Function<UniqueRef<AudioMediaStreamTrackRendererInternalUnit>(AudioMediaStreamTrackRendererInternalUnit::RenderCallback&&)>;
+ WEBCORE_EXPORT static void setCreateInternalUnitFunction(CreateInternalUnitFunction&&);
+
+ WEBCORE_EXPORT void render(size_t sampleCount, AudioBufferList&, uint64_t sampleTime, double hostTime, AudioUnitRenderActionFlags&);
+
+ void setAudioOutputDevice(const String&);
+
+ void addSource(Ref<AudioSampleDataSource>&&);
+ void removeSource(AudioSampleDataSource&);
+
+ void retrieveFormatDescription(CompletionHandler<void(const CAAudioStreamDescription*)>&&);
+
+private:
+ void start();
+ void stop();
+
+ void createAudioUnitIfNeeded();
+
+ HashSet<Ref<AudioSampleDataSource>> m_sources;
+ Vector<Ref<AudioSampleDataSource>> m_sourcesCopy;
+ Vector<Ref<AudioSampleDataSource>> m_renderSources;
+ bool m_shouldUpdateRenderSources { false };
+ Lock m_sourcesLock;
+ UniqueRef<AudioMediaStreamTrackRendererInternalUnit> m_internalUnit;
+};
+
+}
+
+#endif // ENABLE(MEDIA_STREAM)
Deleted: trunk/Source/WebCore/platform/mediastream/mac/AudioMediaStreamTrackRendererCocoa.cpp (277363 => 277364)
--- trunk/Source/WebCore/platform/mediastream/mac/AudioMediaStreamTrackRendererCocoa.cpp 2021-05-12 08:48:25 UTC (rev 277363)
+++ trunk/Source/WebCore/platform/mediastream/mac/AudioMediaStreamTrackRendererCocoa.cpp 2021-05-12 08:57:38 UTC (rev 277364)
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2017-2020 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.
- */
-
-#include "config.h"
-#include "AudioMediaStreamTrackRendererCocoa.h"
-
-#if ENABLE(MEDIA_STREAM)
-
-#include "AudioMediaStreamTrackRendererUnit.h"
-#include "AudioSampleDataSource.h"
-#include "CAAudioStreamDescription.h"
-#include "LibWebRTCAudioModule.h"
-
-namespace WebCore {
-
-AudioMediaStreamTrackRendererCocoa::AudioMediaStreamTrackRendererCocoa() = default;
-
-AudioMediaStreamTrackRendererCocoa::~AudioMediaStreamTrackRendererCocoa() = default;
-
-void AudioMediaStreamTrackRendererCocoa::start()
-{
- clear();
-
- if (auto* formatDescription = AudioMediaStreamTrackRendererUnit::singleton().formatDescription())
- m_outputDescription = makeUnique<CAAudioStreamDescription>(*formatDescription);
-}
-
-void AudioMediaStreamTrackRendererCocoa::stop()
-{
- if (m_dataSource)
- AudioMediaStreamTrackRendererUnit::singleton().removeSource(*m_dataSource);
-}
-
-void AudioMediaStreamTrackRendererCocoa::clear()
-{
- stop();
-
- m_dataSource = nullptr;
- m_outputDescription = { };
-}
-
-void AudioMediaStreamTrackRendererCocoa::setVolume(float volume)
-{
- AudioMediaStreamTrackRenderer::setVolume(volume);
- if (m_dataSource)
- m_dataSource->setVolume(volume);
-}
-
-void AudioMediaStreamTrackRendererCocoa::setAudioOutputDevice(const String& deviceId)
-{
- // FIXME: We should create a unit for ourselves here or use the default unit if deviceId is matching.
- AudioMediaStreamTrackRendererUnit::singleton().setAudioOutputDevice(deviceId);
- m_shouldReset = true;
-}
-
-static unsigned pollSamplesCount()
-{
-#if USE(LIBWEBRTC)
- return LibWebRTCAudioModule::PollSamplesCount + 1;
-#else
- return 2;
-#endif
-}
-
-void AudioMediaStreamTrackRendererCocoa::pushSamples(const MediaTime& sampleTime, const PlatformAudioData& audioData, const AudioStreamDescription& description, size_t sampleCount)
-{
- ASSERT(!isMainThread());
- ASSERT(description.platformDescription().type == PlatformDescription::CAAudioStreamBasicType);
- if (!m_dataSource || m_shouldReset || !m_dataSource->inputDescription() || *m_dataSource->inputDescription() != description) {
- DisableMallocRestrictionsForCurrentThreadScope scope;
-
- // FIXME: For non libwebrtc sources, we can probably reduce poll samples count to 2.
-
- auto dataSource = AudioSampleDataSource::create(description.sampleRate() * 0.5, *this, pollSamplesCount());
-
- if (dataSource->setInputFormat(toCAAudioStreamDescription(description))) {
- ERROR_LOG(LOGIDENTIFIER, "Unable to set the input format of data source");
- return;
- }
-
- if (!m_outputDescription || dataSource->setOutputFormat(*m_outputDescription)) {
- ERROR_LOG(LOGIDENTIFIER, "Unable to set the output format of data source");
- return;
- }
-
- callOnMainThread([this, weakThis = makeWeakPtr(this), oldSource = m_dataSource, newSource = dataSource]() mutable {
- if (!weakThis)
- return;
-
- if (oldSource)
- AudioMediaStreamTrackRendererUnit::singleton().removeSource(*oldSource);
-
- newSource->setVolume(volume());
- AudioMediaStreamTrackRendererUnit::singleton().addSource(WTFMove(newSource));
- });
- m_dataSource = WTFMove(dataSource);
- m_shouldReset = false;
- }
-
- m_dataSource->pushSamples(sampleTime, audioData, sampleCount);
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(MEDIA_STREAM)
Deleted: trunk/Source/WebCore/platform/mediastream/mac/AudioMediaStreamTrackRendererCocoa.h (277363 => 277364)
--- trunk/Source/WebCore/platform/mediastream/mac/AudioMediaStreamTrackRendererCocoa.h 2021-05-12 08:48:25 UTC (rev 277363)
+++ trunk/Source/WebCore/platform/mediastream/mac/AudioMediaStreamTrackRendererCocoa.h 2021-05-12 08:57:38 UTC (rev 277364)
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#pragma once
-
-#if ENABLE(MEDIA_STREAM)
-
-#include "AudioMediaStreamTrackRenderer.h"
-#include "Logging.h"
-#include <wtf/WeakPtr.h>
-
-#include <AudioToolbox/AudioToolbox.h>
-#include <CoreAudio/CoreAudioTypes.h>
-
-namespace WebCore {
-
-class AudioSampleDataSource;
-class AudioSampleBufferList;
-class CAAudioStreamDescription;
-
-class AudioMediaStreamTrackRendererCocoa : public AudioMediaStreamTrackRenderer, public CanMakeWeakPtr<AudioMediaStreamTrackRendererCocoa, WeakPtrFactoryInitialization::Eager> {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- AudioMediaStreamTrackRendererCocoa();
- ~AudioMediaStreamTrackRendererCocoa();
-
-private:
- // AudioMediaStreamTrackRenderer
- void pushSamples(const WTF::MediaTime&, const PlatformAudioData&, const AudioStreamDescription&, size_t) final;
- void start() final;
- void stop() final;
- void clear() final;
- void setVolume(float) final;
- void setAudioOutputDevice(const String&) final;
-
- std::unique_ptr<CAAudioStreamDescription> m_outputDescription;
- RefPtr<AudioSampleDataSource> m_dataSource;
- bool m_shouldReset { false };
-};
-
-}
-
-#endif // ENABLE(MEDIA_STREAM)
Deleted: trunk/Source/WebCore/platform/mediastream/mac/AudioMediaStreamTrackRendererUnit.cpp (277363 => 277364)
--- trunk/Source/WebCore/platform/mediastream/mac/AudioMediaStreamTrackRendererUnit.cpp 2021-05-12 08:48:25 UTC (rev 277363)
+++ trunk/Source/WebCore/platform/mediastream/mac/AudioMediaStreamTrackRendererUnit.cpp 2021-05-12 08:57:38 UTC (rev 277364)
@@ -1,277 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#include "config.h"
-#include "AudioMediaStreamTrackRendererUnit.h"
-
-#if ENABLE(MEDIA_STREAM)
-
-#include "AudioSampleDataSource.h"
-#include "AudioSession.h"
-#include "CAAudioStreamDescription.h"
-#include "Logging.h"
-
-#include <pal/spi/cocoa/AudioToolboxSPI.h>
-#include <wtf/FastMalloc.h>
-#include <wtf/Lock.h>
-
-#if PLATFORM(COCOA)
-#include "CoreAudioCaptureDevice.h"
-#include "CoreAudioCaptureDeviceManager.h"
-#endif
-
-#include <pal/cf/CoreMediaSoftLink.h>
-
-namespace WebCore {
-
-AudioMediaStreamTrackRendererUnit& AudioMediaStreamTrackRendererUnit::singleton()
-{
- static NeverDestroyed<AudioMediaStreamTrackRendererUnit> registry;
- return registry;
-}
-
-AudioMediaStreamTrackRendererUnit::~AudioMediaStreamTrackRendererUnit()
-{
- stop();
-}
-
-void AudioMediaStreamTrackRendererUnit::setAudioOutputDevice(const String& deviceID)
-{
-#if PLATFORM(MAC)
- auto device = CoreAudioCaptureDeviceManager::singleton().coreAudioDeviceWithUID(deviceID);
-
- if (!device && !deviceID.isEmpty()) {
- RELEASE_LOG(WebRTC, "AudioMediaStreamTrackRendererUnit::setAudioOutputDeviceId - did not find device");
- return;
- }
-
- auto audioUnitDeviceID = device ? device->deviceID() : 0;
- if (m_deviceID == audioUnitDeviceID)
- return;
-
- bool shouldRestart = m_isStarted;
- if (m_isStarted)
- stop();
-
- m_deviceID = audioUnitDeviceID;
-
- if (shouldRestart)
- start();
-#else
- UNUSED_PARAM(deviceID);
-#endif
-}
-
-void AudioMediaStreamTrackRendererUnit::addSource(Ref<AudioSampleDataSource>&& source)
-{
- RELEASE_LOG(WebRTC, "AudioMediaStreamTrackRendererUnit::addSource");
-
- {
- auto locker = holdLock(m_sourcesLock);
- ASSERT(!m_sources.contains(source.get()));
- m_sources.add(WTFMove(source));
- m_sourcesCopy = copyToVector(m_sources);
- m_shouldUpdateRenderSources = true;
- }
- start();
-}
-
-void AudioMediaStreamTrackRendererUnit::removeSource(AudioSampleDataSource& source)
-{
- RELEASE_LOG(WebRTC, "AudioMediaStreamTrackRendererUnit::removeSource");
-
- bool shouldStop = false;
- {
- auto locker = holdLock(m_sourcesLock);
- m_sources.remove(source);
- shouldStop = m_sources.isEmpty();
- m_sourcesCopy = copyToVector(m_sources);
- m_shouldUpdateRenderSources = true;
- }
- if (shouldStop)
- stop();
-}
-
-void AudioMediaStreamTrackRendererUnit::start()
-{
- RELEASE_LOG(WebRTC, "AudioMediaStreamTrackRendererUnit::start");
-
- if (m_isStarted)
- return;
-
- createAudioUnitIfNeeded();
- if (!m_remoteIOUnit)
- return;
-
- if (auto error = AudioOutputUnitStart(m_remoteIOUnit)) {
- RELEASE_LOG_ERROR(WebRTC, "AudioMediaStreamTrackRendererUnit::start AudioOutputUnitStart failed, error = %d", error);
- AudioComponentInstanceDispose(m_remoteIOUnit);
- m_remoteIOUnit = nullptr;
- }
- m_isStarted = true;
- RELEASE_LOG(WebRTC, "AudioMediaStreamTrackRendererUnit is started");
-}
-
-void AudioMediaStreamTrackRendererUnit::stop()
-{
- RELEASE_LOG(WebRTC, "AudioMediaStreamTrackRendererUnit::stop");
-
- if (!m_remoteIOUnit)
- return;
-
- if (m_isStarted) {
- AudioOutputUnitStop(m_remoteIOUnit);
- m_isStarted = false;
- }
-
- AudioComponentInstanceDispose(m_remoteIOUnit);
- m_remoteIOUnit = nullptr;
-}
-
-CAAudioStreamDescription* AudioMediaStreamTrackRendererUnit::formatDescription()
-{
- createAudioUnitIfNeeded();
- return m_outputDescription.get();
-}
-
-void AudioMediaStreamTrackRendererUnit::createAudioUnitIfNeeded()
-{
- ASSERT(!m_remoteIOUnit || m_outputDescription);
- if (m_remoteIOUnit)
- return;
-
- CAAudioStreamDescription outputDescription;
- AudioComponentInstance remoteIOUnit { nullptr };
-
- AudioComponentDescription ioUnitDescription { kAudioUnitType_Output, 0, kAudioUnitManufacturer_Apple, 0, 0 };
-#if PLATFORM(IOS_FAMILY)
- ioUnitDescription.componentSubType = kAudioUnitSubType_RemoteIO;
-#else
- ioUnitDescription.componentSubType = kAudioUnitSubType_DefaultOutput;
-#endif
-
- AudioComponent ioComponent = AudioComponentFindNext(nullptr, &ioUnitDescription);
- ASSERT(ioComponent);
- if (!ioComponent) {
- RELEASE_LOG_ERROR(WebRTC, "AudioMediaStreamTrackRendererUnit::createAudioUnit unable to find remote IO unit component");
- return;
- }
-
- auto error = AudioComponentInstanceNew(ioComponent, &remoteIOUnit);
- if (error) {
- RELEASE_LOG_ERROR(WebRTC, "AudioMediaStreamTrackRendererUnit::createAudioUnit unable to open vpio unit, error = %d", error);
- return;
- }
-
-#if PLATFORM(IOS_FAMILY)
- UInt32 param = 1;
- error = AudioUnitSetProperty(remoteIOUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, ¶m, sizeof(param));
- if (error) {
- RELEASE_LOG_ERROR(WebRTC, "AudioMediaStreamTrackRendererUnit::createAudioUnit unable to enable vpio unit output, error = %d", error);
- return;
- }
-#endif
-
-#if PLATFORM(MAC)
- if (m_deviceID) {
- error = AudioUnitSetProperty(remoteIOUnit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &m_deviceID, sizeof(m_deviceID));
- if (error) {
- RELEASE_LOG_ERROR(WebRTC, "AudioMediaStreamTrackRendererUnit::createAudioUnit unable to set unit device ID %d, error %d (%.4s)", (int)m_deviceID, (int)error, (char*)&error);
- return;
- }
- }
-#endif
-
- AURenderCallbackStruct callback = { renderingCallback, this };
- error = AudioUnitSetProperty(remoteIOUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Global, 0, &callback, sizeof(callback));
- if (error) {
- RELEASE_LOG_ERROR(WebRTC, "AudioMediaStreamTrackRendererUnit::createAudioUnit unable to set vpio unit speaker proc, error = %d", error);
- return;
- }
-
- UInt32 size = sizeof(outputDescription.streamDescription());
- error = AudioUnitGetProperty(remoteIOUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &outputDescription.streamDescription(), &size);
- if (error) {
- RELEASE_LOG_ERROR(WebRTC, "AudioMediaStreamTrackRendererUnit::createAudioUnit unable to get input stream format, error = %d", error);
- return;
- }
-
- outputDescription.streamDescription().mSampleRate = AudioSession::sharedSession().sampleRate();
-
- error = AudioUnitSetProperty(remoteIOUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &outputDescription.streamDescription(), sizeof(outputDescription.streamDescription()));
- if (error) {
- RELEASE_LOG_ERROR(WebRTC, "AudioMediaStreamTrackRendererUnit::createAudioUnit unable to set input stream format, error = %d", error);
- return;
- }
-
- error = AudioUnitInitialize(remoteIOUnit);
- if (error) {
- RELEASE_LOG_ERROR(WebRTC, "AudioMediaStreamTrackRendererUnit::createAudioUnit AudioUnitInitialize() failed, error = %d", error);
- return;
- }
-
- m_outputDescription = makeUnique<CAAudioStreamDescription>(outputDescription);
- m_remoteIOUnit = remoteIOUnit;
-}
-
-OSStatus AudioMediaStreamTrackRendererUnit::render(UInt32 sampleCount, AudioBufferList& ioData, UInt32 /*inBusNumber*/, const AudioTimeStamp& timeStamp, AudioUnitRenderActionFlags& actionFlags)
-{
- // For performance reasons, we forbid heap allocations while doing rendering on the audio thread.
- ForbidMallocUseForCurrentThreadScope forbidMallocUse;
-
- ASSERT(!isMainThread());
- if (m_shouldUpdateRenderSources) {
- auto locker = tryHoldLock(m_sourcesLock);
- if (!locker)
- return 0;
-
- m_renderSources = WTFMove(m_sourcesCopy);
- m_shouldUpdateRenderSources = false;
- }
-
- if (m_renderSources.isEmpty()) {
- if (m_outputDescription)
- AudioSampleBufferList::zeroABL(ioData, static_cast<size_t>(sampleCount * m_outputDescription->bytesPerFrame()));
- actionFlags = kAudioUnitRenderAction_OutputIsSilence;
- return 0;
- }
-
- // Mix all sources.
- bool isFirstSource = true;
- for (auto& source : m_renderSources) {
- source->pullSamples(ioData, static_cast<size_t>(sampleCount), timeStamp.mSampleTime, timeStamp.mHostTime, isFirstSource ? AudioSampleDataSource::Copy : AudioSampleDataSource::Mix);
- isFirstSource = false;
- }
- return 0;
-}
-
-OSStatus AudioMediaStreamTrackRendererUnit::renderingCallback(void* processor, AudioUnitRenderActionFlags* actionFlags, const AudioTimeStamp* timeStamp, UInt32 inBusNumber, UInt32 sampleCount, AudioBufferList* ioData)
-{
- return static_cast<AudioMediaStreamTrackRendererUnit*>(processor)->render(sampleCount, *ioData, inBusNumber, *timeStamp, *actionFlags);
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(MEDIA_STREAM)
Deleted: trunk/Source/WebCore/platform/mediastream/mac/AudioMediaStreamTrackRendererUnit.h (277363 => 277364)
--- trunk/Source/WebCore/platform/mediastream/mac/AudioMediaStreamTrackRendererUnit.h 2021-05-12 08:48:25 UTC (rev 277363)
+++ trunk/Source/WebCore/platform/mediastream/mac/AudioMediaStreamTrackRendererUnit.h 2021-05-12 08:57:38 UTC (rev 277364)
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#pragma once
-
-#if ENABLE(MEDIA_STREAM)
-
-#include <AudioToolbox/AudioToolbox.h>
-#include <CoreAudio/CoreAudioTypes.h>
-#include <wtf/Forward.h>
-#include <wtf/HashSet.h>
-#include <wtf/Vector.h>
-
-namespace WebCore {
-
-class AudioSampleDataSource;
-class AudioSampleBufferList;
-class CAAudioStreamDescription;
-
-class AudioMediaStreamTrackRendererUnit {
-public:
- static AudioMediaStreamTrackRendererUnit& singleton();
-
- AudioMediaStreamTrackRendererUnit() = default;
- ~AudioMediaStreamTrackRendererUnit();
-
- static OSStatus renderingCallback(void*, AudioUnitRenderActionFlags*, const AudioTimeStamp*, UInt32 inBusNumber, UInt32 numberOfFrames, AudioBufferList*);
-
- void start();
- void stop();
-
- void setAudioOutputDevice(const String&);
-
- void addSource(Ref<AudioSampleDataSource>&&);
- void removeSource(AudioSampleDataSource&);
-
- CAAudioStreamDescription* formatDescription();
-
-private:
- void createAudioUnitIfNeeded();
- OSStatus render(UInt32 sampleCount, AudioBufferList&, UInt32 inBusNumber, const AudioTimeStamp&, AudioUnitRenderActionFlags&);
-
- AudioComponentInstance m_remoteIOUnit { nullptr };
- std::unique_ptr<CAAudioStreamDescription> m_outputDescription;
- HashSet<Ref<AudioSampleDataSource>> m_sources;
- Vector<Ref<AudioSampleDataSource>> m_sourcesCopy;
- Vector<Ref<AudioSampleDataSource>> m_renderSources;
- bool m_shouldUpdateRenderSources { false };
- Lock m_sourcesLock;
- bool m_isStarted { false };
-#if PLATFORM(MAC)
- uint32_t m_deviceID { 0 };
-#endif
-};
-
-}
-
-#endif // ENABLE(MEDIA_STREAM)
Modified: trunk/Source/WebKit/ChangeLog (277363 => 277364)
--- trunk/Source/WebKit/ChangeLog 2021-05-12 08:48:25 UTC (rev 277363)
+++ trunk/Source/WebKit/ChangeLog 2021-05-12 08:57:38 UTC (rev 277364)
@@ -1,3 +1,18 @@
+2021-05-12 Youenn Fablet <[email protected]>
+
+ Introduce an internal unit to render audio MediaStreamTrack(s)
+ https://bugs.webkit.org/show_bug.cgi?id=225601
+
+ Reviewed by Eric Carlson.
+
+ Update according new WebCore API.
+
+ * GPUProcess/webrtc/RemoteAudioMediaStreamTrackRenderer.cpp:
+ (WebKit::RemoteAudioMediaStreamTrackRenderer::start):
+ * WebProcess/GPU/webrtc/AudioMediaStreamTrackRenderer.cpp:
+ (WebKit::AudioMediaStreamTrackRenderer::start):
+ * WebProcess/GPU/webrtc/AudioMediaStreamTrackRenderer.h:
+
2021-05-12 Martin Robinson <[email protected]>
REGRESSION(r277083): Proximity scroll snap is broken on iOS
Modified: trunk/Source/WebKit/GPUProcess/webrtc/RemoteAudioMediaStreamTrackRenderer.cpp (277363 => 277364)
--- trunk/Source/WebKit/GPUProcess/webrtc/RemoteAudioMediaStreamTrackRenderer.cpp 2021-05-12 08:48:25 UTC (rev 277363)
+++ trunk/Source/WebKit/GPUProcess/webrtc/RemoteAudioMediaStreamTrackRenderer.cpp 2021-05-12 08:57:38 UTC (rev 277364)
@@ -77,7 +77,7 @@
void RemoteAudioMediaStreamTrackRenderer::start()
{
- m_renderer->start();
+ m_renderer->start([] { });
}
void RemoteAudioMediaStreamTrackRenderer::stop()
Modified: trunk/Source/WebKit/WebProcess/GPU/webrtc/AudioMediaStreamTrackRenderer.cpp (277363 => 277364)
--- trunk/Source/WebKit/WebProcess/GPU/webrtc/AudioMediaStreamTrackRenderer.cpp 2021-05-12 08:48:25 UTC (rev 277363)
+++ trunk/Source/WebKit/WebProcess/GPU/webrtc/AudioMediaStreamTrackRenderer.cpp 2021-05-12 08:57:38 UTC (rev 277364)
@@ -64,10 +64,11 @@
m_connection->send(Messages::RemoteAudioMediaStreamTrackRendererManager::CreateRenderer { m_identifier }, 0);
}
-void AudioMediaStreamTrackRenderer::start()
+void AudioMediaStreamTrackRenderer::start(CompletionHandler<void()>&& callback)
{
m_isPlaying = true;
m_connection->send(Messages::RemoteAudioMediaStreamTrackRenderer::Start { }, m_identifier);
+ callback();
}
void AudioMediaStreamTrackRenderer::stop()
Modified: trunk/Source/WebKit/WebProcess/GPU/webrtc/AudioMediaStreamTrackRenderer.h (277363 => 277364)
--- trunk/Source/WebKit/WebProcess/GPU/webrtc/AudioMediaStreamTrackRenderer.h 2021-05-12 08:48:25 UTC (rev 277363)
+++ trunk/Source/WebKit/WebProcess/GPU/webrtc/AudioMediaStreamTrackRenderer.h 2021-05-12 08:57:38 UTC (rev 277364)
@@ -54,7 +54,7 @@
void storageChanged(SharedMemory*, const WebCore::CAAudioStreamDescription& format, size_t frameCount);
// WebCore::AudioMediaStreamTrackRenderer
- void start() final;
+ void start(CompletionHandler<void()>&&) final;
void stop() final;
void clear() final;
void setVolume(float) final;