Title: [277364] trunk/Source
Revision
277364
Author
[email protected]
Date
2021-05-12 01:57:38 -0700 (Wed, 12 May 2021)

Log Message

Introduce an internal unit to render audio MediaStreamTrack(s)
https://bugs.webkit.org/show_bug.cgi?id=225601

Reviewed by Eric Carlson.

Source/WebCore:

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.

Source/WebKit:

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:

Modified Paths

Added Paths

Removed Paths

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, &param, 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, &param, 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;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to