Title: [277852] trunk/Source
Revision
277852
Author
[email protected]
Date
2021-05-21 02:53:36 -0700 (Fri, 21 May 2021)

Log Message

Implement a remote Internal Unit in GPUProcess for audio MediaStreamTrack rendering
https://bugs.webkit.org/show_bug.cgi?id=225603
Source/WebCore:

<rdar://problem/78114391>

Reviewed by Eric Carlson.

Fixed the case where we were calling start even though a source was already being played.
This is more consistent since we are doing those checks for stop.
Reduce the code where we lock sources to the minimum.

In case we want to lock the sources copy in audio thread and we fail, continue rendering audio instead of dropping everything.
Add some main thread assertions in AudioMediaStreamTrackRendererUnit methods.

Manually tested.

* platform/mediastream/cocoa/AudioMediaStreamTrackRendererUnit.cpp:
(WebCore::AudioMediaStreamTrackRendererUnit::addSource):
(WebCore::AudioMediaStreamTrackRendererUnit::removeSource):
(WebCore::AudioMediaStreamTrackRendererUnit::render):

Source/WebKit:

Reviewed by Eric Carlson.

Implement an InternalUnit by creating a ring buffer that gets written on WebProcess and read on GPUProcess by an audio unit.
In the previous implementation, each audio track was sent to GPUProcess that was doing the mixing.
Sending was done by sending IPC message for each audio sample, which was also processing inefficient.

We are now creating an Audio Unit in GPUProcess and similarly to WebAudio asking WebProcess to render audio in a buffer that will be actually rendered by the audio unit.
The mixing happens in WebProcess so only one buffer is shared between GPUProcess and WebProcess, and no IPC message is sent for each chunk.

The potential downside is that the mixing is done with fixed chunk size instead of chunk size requested by the audio unit.
This might trigger some latency or some overhead if the fixed chunk size is too far from what the audio unit is asking.

In case of GPUProcess crash, we keep the same format description but we delay recreation of the unit if the unit is stopped.

* DerivedSources-input.xcfilelist:
* DerivedSources-output.xcfilelist:
* DerivedSources.make:
* GPUProcess/GPUConnectionToWebProcess.cpp:
(WebKit::GPUConnectionToWebProcess::audioMediaStreamTrackRendererInternalUnitManager):
(WebKit::GPUConnectionToWebProcess::dispatchMessage):
* GPUProcess/GPUConnectionToWebProcess.h:
* GPUProcess/webrtc/RemoteAudioMediaStreamTrackRenderer.cpp:
(WebKit::RemoteAudioMediaStreamTrackRenderer::start):
* GPUProcess/webrtc/RemoteAudioMediaStreamTrackRendererInternalUnitManager.cpp: Added.
(WebKit::RemoteAudioMediaStreamTrackRendererInternalUnitManager::RemoteAudioMediaStreamTrackRendererInternalUnitManager):
(WebKit::RemoteAudioMediaStreamTrackRendererInternalUnitManager::~RemoteAudioMediaStreamTrackRendererInternalUnitManager):
(WebKit::RemoteAudioMediaStreamTrackRendererInternalUnitManager::createUnit):
(WebKit::RemoteAudioMediaStreamTrackRendererInternalUnitManager::deleteUnit):
(WebKit::RemoteAudioMediaStreamTrackRendererInternalUnitManager::startUnit):
(WebKit::RemoteAudioMediaStreamTrackRendererInternalUnitManager::stopUnit):
(WebKit::RemoteAudioMediaStreamTrackRendererInternalUnitManager::setAudioOutputDevice):
(WebKit::renderCallback):
(WebKit::RemoteAudioMediaStreamTrackRendererInternalUnitManager::Unit::Unit):
(WebKit::RemoteAudioMediaStreamTrackRendererInternalUnitManager::Unit::~Unit):
(WebKit::RemoteAudioMediaStreamTrackRendererInternalUnitManager::Unit::start):
(WebKit::RemoteAudioMediaStreamTrackRendererInternalUnitManager::Unit::stop):
(WebKit::RemoteAudioMediaStreamTrackRendererInternalUnitManager::Unit::setAudioOutputDevice):
(WebKit::RemoteAudioMediaStreamTrackRendererInternalUnitManager::Unit::render):
* GPUProcess/webrtc/RemoteAudioMediaStreamTrackRendererInternalUnitManager.h: Added.
* GPUProcess/webrtc/RemoteAudioMediaStreamTrackRendererInternalUnitManager.messages.in: Added.
* Scripts/webkit/messages.py:
(types_that_cannot_be_forward_declared):
* Sources.txt:
* SourcesCocoa.txt:
* WebKit.xcodeproj/project.pbxproj:
* WebProcess/GPU/GPUProcessConnection.h:
* WebProcess/GPU/webrtc/AudioMediaStreamTrackRenderer.cpp:
(WebKit::AudioMediaStreamTrackRenderer::start):
* WebProcess/GPU/webrtc/AudioMediaStreamTrackRenderer.h:
* WebProcess/GPU/webrtc/AudioMediaStreamTrackRendererInternalUnitIdentifier.h: Added.
* WebProcess/GPU/webrtc/AudioMediaStreamTrackRendererInternalUnitManager.cpp: Added.
(WebKit::AudioMediaStreamTrackRendererInternalUnitManager::add):
(WebKit::AudioMediaStreamTrackRendererInternalUnitManager::remove):
(WebKit::AudioMediaStreamTrackRendererInternalUnitManager::createRemoteInternalUnit):
(WebKit::AudioMediaStreamTrackRendererInternalUnitManager::gpuProcessConnectionClosed):
(WebKit::AudioMediaStreamTrackRendererInternalUnitManager::Proxy::Proxy):
(WebKit::AudioMediaStreamTrackRendererInternalUnitManager::Proxy::~Proxy):
(WebKit::AudioMediaStreamTrackRendererInternalUnitManager::Proxy::createRemoteUnit):
(WebKit::AudioMediaStreamTrackRendererInternalUnitManager::Proxy::initialize):
(WebKit::AudioMediaStreamTrackRendererInternalUnitManager::Proxy::start):
(WebKit::AudioMediaStreamTrackRendererInternalUnitManager::Proxy::storageChanged):
(WebKit::AudioMediaStreamTrackRendererInternalUnitManager::Proxy::stop):
(WebKit::AudioMediaStreamTrackRendererInternalUnitManager::Proxy::setAudioOutputDevice):
(WebKit::AudioMediaStreamTrackRendererInternalUnitManager::Proxy::retrieveFormatDescription):
(WebKit::AudioMediaStreamTrackRendererInternalUnitManager::Proxy::stopThread):
(WebKit::AudioMediaStreamTrackRendererInternalUnitManager::Proxy::startThread):
(WebKit::AudioMediaStreamTrackRendererInternalUnitManager::Proxy::restartIfNeeded):
* WebProcess/GPU/webrtc/AudioMediaStreamTrackRendererInternalUnitManager.h: Added.
* WebProcess/GPU/webrtc/AudioMediaStreamTrackRendererInternalUnitManager.messages.in: Added.
* WebProcess/WebProcess.cpp:
(WebKit::WebProcess::audioMediaStreamTrackRendererInternalUnitManager):
* WebProcess/WebProcess.h:
* WebProcess/cocoa/UserMediaCaptureManager.cpp:
(WebKit::UserMediaCaptureManager::setupCaptureProcesses):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (277851 => 277852)


--- trunk/Source/WebCore/ChangeLog	2021-05-21 09:31:51 UTC (rev 277851)
+++ trunk/Source/WebCore/ChangeLog	2021-05-21 09:53:36 UTC (rev 277852)
@@ -1,3 +1,25 @@
+2021-05-21  Youenn Fablet  <[email protected]>
+
+        Implement a remote Internal Unit in GPUProcess for audio MediaStreamTrack rendering
+        https://bugs.webkit.org/show_bug.cgi?id=225603
+        <rdar://problem/78114391>
+
+        Reviewed by Eric Carlson.
+
+        Fixed the case where we were calling start even though a source was already being played.
+        This is more consistent since we are doing those checks for stop.
+        Reduce the code where we lock sources to the minimum.
+
+        In case we want to lock the sources copy in audio thread and we fail, continue rendering audio instead of dropping everything.
+        Add some main thread assertions in AudioMediaStreamTrackRendererUnit methods.
+
+        Manually tested.
+
+        * platform/mediastream/cocoa/AudioMediaStreamTrackRendererUnit.cpp:
+        (WebCore::AudioMediaStreamTrackRendererUnit::addSource):
+        (WebCore::AudioMediaStreamTrackRendererUnit::removeSource):
+        (WebCore::AudioMediaStreamTrackRendererUnit::render):
+
 2021-05-20  Chris Dumez  <[email protected]>
 
         Fix locking in PlatformCALayer

Modified: trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererUnit.cpp (277851 => 277852)


--- trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererUnit.cpp	2021-05-21 09:31:51 UTC (rev 277851)
+++ trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererUnit.cpp	2021-05-21 09:53:36 UTC (rev 277852)
@@ -82,29 +82,37 @@
 void AudioMediaStreamTrackRendererUnit::addSource(Ref<AudioSampleDataSource>&& source)
 {
     RELEASE_LOG(WebRTC, "AudioMediaStreamTrackRendererUnit::addSource");
+    ASSERT(isMainThread());
 
+    ASSERT(!m_sources.contains(source.get()));
+    bool shouldStart = m_sources.isEmpty();
+    m_sources.add(WTFMove(source));
+
     {
         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();
+
+    if (shouldStart)
+        start();
 }
 
 void AudioMediaStreamTrackRendererUnit::removeSource(AudioSampleDataSource& source)
 {
     RELEASE_LOG(WebRTC, "AudioMediaStreamTrackRendererUnit::removeSource");
+    ASSERT(isMainThread());
 
-    bool shouldStop = false;
+    bool shouldStop = !m_sources.isEmpty();
+    m_sources.remove(source);
+    shouldStop &= m_sources.isEmpty();
+
     {
         auto locker = holdLock(m_sourcesLock);
-        m_sources.remove(source);
-        shouldStop = m_sources.isEmpty();
         m_sourcesCopy = copyToVector(m_sources);
         m_shouldUpdateRenderSources = true;
     }
+
     if (shouldStop)
         stop();
 }
@@ -112,6 +120,8 @@
 void AudioMediaStreamTrackRendererUnit::start()
 {
     RELEASE_LOG(WebRTC, "AudioMediaStreamTrackRendererUnit::start");
+    ASSERT(isMainThread());
+
     m_internalUnit->start();
 }
 
@@ -118,11 +128,14 @@
 void AudioMediaStreamTrackRendererUnit::stop()
 {
     RELEASE_LOG(WebRTC, "AudioMediaStreamTrackRendererUnit::stop");
+    ASSERT(isMainThread());
+
     m_internalUnit->stop();
 }
 
 void AudioMediaStreamTrackRendererUnit::retrieveFormatDescription(CompletionHandler<void(const CAAudioStreamDescription*)>&& callback)
 {
+    ASSERT(isMainThread());
     m_internalUnit->retrieveFormatDescription(WTFMove(callback));
 }
 
@@ -133,12 +146,10 @@
 
     ASSERT(!isMainThread());
     if (m_shouldUpdateRenderSources) {
-        auto locker = tryHoldLock(m_sourcesLock);
-        if (!locker)
-            return;
-
-        m_renderSources = WTFMove(m_sourcesCopy);
-        m_shouldUpdateRenderSources = false;
+        if (auto locker = tryHoldLock(m_sourcesLock)) {
+            m_renderSources = WTFMove(m_sourcesCopy);
+            m_shouldUpdateRenderSources = false;
+        }
     }
 
     if (m_renderSources.isEmpty()) {

Modified: trunk/Source/WebKit/CMakeLists.txt (277851 => 277852)


--- trunk/Source/WebKit/CMakeLists.txt	2021-05-21 09:31:51 UTC (rev 277851)
+++ trunk/Source/WebKit/CMakeLists.txt	2021-05-21 09:53:36 UTC (rev 277852)
@@ -143,6 +143,7 @@
 
     GPUProcess/webrtc/LibWebRTCCodecsProxy
     GPUProcess/webrtc/RemoteAudioMediaStreamTrackRenderer
+    GPUProcess/webrtc/RemoteAudioMediaStreamTrackRendererInternalUnitManager
     GPUProcess/webrtc/RemoteAudioMediaStreamTrackRendererManager
     GPUProcess/webrtc/RemoteMediaRecorder
     GPUProcess/webrtc/RemoteMediaRecorderManager
@@ -238,6 +239,7 @@
     WebProcess/GPU/media/RemoteRemoteCommandListener
     WebProcess/GPU/media/SourceBufferPrivateRemote
 
+    WebProcess/GPU/webrtc/AudioMediaStreamTrackRendererInternalUnitManager
     WebProcess/GPU/webrtc/LibWebRTCCodecs
     WebProcess/GPU/webrtc/SampleBufferDisplayLayer
 

Modified: trunk/Source/WebKit/ChangeLog (277851 => 277852)


--- trunk/Source/WebKit/ChangeLog	2021-05-21 09:31:51 UTC (rev 277851)
+++ trunk/Source/WebKit/ChangeLog	2021-05-21 09:53:36 UTC (rev 277852)
@@ -1,3 +1,83 @@
+2021-05-21  Youenn Fablet  <[email protected]>
+
+        Implement a remote Internal Unit in GPUProcess for audio MediaStreamTrack rendering
+        https://bugs.webkit.org/show_bug.cgi?id=225603
+
+        Reviewed by Eric Carlson.
+
+        Implement an InternalUnit by creating a ring buffer that gets written on WebProcess and read on GPUProcess by an audio unit.
+        In the previous implementation, each audio track was sent to GPUProcess that was doing the mixing.
+        Sending was done by sending IPC message for each audio sample, which was also processing inefficient.
+
+        We are now creating an Audio Unit in GPUProcess and similarly to WebAudio asking WebProcess to render audio in a buffer that will be actually rendered by the audio unit.
+        The mixing happens in WebProcess so only one buffer is shared between GPUProcess and WebProcess, and no IPC message is sent for each chunk.
+
+        The potential downside is that the mixing is done with fixed chunk size instead of chunk size requested by the audio unit.
+        This might trigger some latency or some overhead if the fixed chunk size is too far from what the audio unit is asking.
+
+        In case of GPUProcess crash, we keep the same format description but we delay recreation of the unit if the unit is stopped.
+
+        * DerivedSources-input.xcfilelist:
+        * DerivedSources-output.xcfilelist:
+        * DerivedSources.make:
+        * GPUProcess/GPUConnectionToWebProcess.cpp:
+        (WebKit::GPUConnectionToWebProcess::audioMediaStreamTrackRendererInternalUnitManager):
+        (WebKit::GPUConnectionToWebProcess::dispatchMessage):
+        * GPUProcess/GPUConnectionToWebProcess.h:
+        * GPUProcess/webrtc/RemoteAudioMediaStreamTrackRenderer.cpp:
+        (WebKit::RemoteAudioMediaStreamTrackRenderer::start):
+        * GPUProcess/webrtc/RemoteAudioMediaStreamTrackRendererInternalUnitManager.cpp: Added.
+        (WebKit::RemoteAudioMediaStreamTrackRendererInternalUnitManager::RemoteAudioMediaStreamTrackRendererInternalUnitManager):
+        (WebKit::RemoteAudioMediaStreamTrackRendererInternalUnitManager::~RemoteAudioMediaStreamTrackRendererInternalUnitManager):
+        (WebKit::RemoteAudioMediaStreamTrackRendererInternalUnitManager::createUnit):
+        (WebKit::RemoteAudioMediaStreamTrackRendererInternalUnitManager::deleteUnit):
+        (WebKit::RemoteAudioMediaStreamTrackRendererInternalUnitManager::startUnit):
+        (WebKit::RemoteAudioMediaStreamTrackRendererInternalUnitManager::stopUnit):
+        (WebKit::RemoteAudioMediaStreamTrackRendererInternalUnitManager::setAudioOutputDevice):
+        (WebKit::renderCallback):
+        (WebKit::RemoteAudioMediaStreamTrackRendererInternalUnitManager::Unit::Unit):
+        (WebKit::RemoteAudioMediaStreamTrackRendererInternalUnitManager::Unit::~Unit):
+        (WebKit::RemoteAudioMediaStreamTrackRendererInternalUnitManager::Unit::start):
+        (WebKit::RemoteAudioMediaStreamTrackRendererInternalUnitManager::Unit::stop):
+        (WebKit::RemoteAudioMediaStreamTrackRendererInternalUnitManager::Unit::setAudioOutputDevice):
+        (WebKit::RemoteAudioMediaStreamTrackRendererInternalUnitManager::Unit::render):
+        * GPUProcess/webrtc/RemoteAudioMediaStreamTrackRendererInternalUnitManager.h: Added.
+        * GPUProcess/webrtc/RemoteAudioMediaStreamTrackRendererInternalUnitManager.messages.in: Added.
+        * Scripts/webkit/messages.py:
+        (types_that_cannot_be_forward_declared):
+        * Sources.txt:
+        * SourcesCocoa.txt:
+        * WebKit.xcodeproj/project.pbxproj:
+        * WebProcess/GPU/GPUProcessConnection.h:
+        * WebProcess/GPU/webrtc/AudioMediaStreamTrackRenderer.cpp:
+        (WebKit::AudioMediaStreamTrackRenderer::start):
+        * WebProcess/GPU/webrtc/AudioMediaStreamTrackRenderer.h:
+        * WebProcess/GPU/webrtc/AudioMediaStreamTrackRendererInternalUnitIdentifier.h: Added.
+        * WebProcess/GPU/webrtc/AudioMediaStreamTrackRendererInternalUnitManager.cpp: Added.
+        (WebKit::AudioMediaStreamTrackRendererInternalUnitManager::add):
+        (WebKit::AudioMediaStreamTrackRendererInternalUnitManager::remove):
+        (WebKit::AudioMediaStreamTrackRendererInternalUnitManager::createRemoteInternalUnit):
+        (WebKit::AudioMediaStreamTrackRendererInternalUnitManager::gpuProcessConnectionClosed):
+        (WebKit::AudioMediaStreamTrackRendererInternalUnitManager::Proxy::Proxy):
+        (WebKit::AudioMediaStreamTrackRendererInternalUnitManager::Proxy::~Proxy):
+        (WebKit::AudioMediaStreamTrackRendererInternalUnitManager::Proxy::createRemoteUnit):
+        (WebKit::AudioMediaStreamTrackRendererInternalUnitManager::Proxy::initialize):
+        (WebKit::AudioMediaStreamTrackRendererInternalUnitManager::Proxy::start):
+        (WebKit::AudioMediaStreamTrackRendererInternalUnitManager::Proxy::storageChanged):
+        (WebKit::AudioMediaStreamTrackRendererInternalUnitManager::Proxy::stop):
+        (WebKit::AudioMediaStreamTrackRendererInternalUnitManager::Proxy::setAudioOutputDevice):
+        (WebKit::AudioMediaStreamTrackRendererInternalUnitManager::Proxy::retrieveFormatDescription):
+        (WebKit::AudioMediaStreamTrackRendererInternalUnitManager::Proxy::stopThread):
+        (WebKit::AudioMediaStreamTrackRendererInternalUnitManager::Proxy::startThread):
+        (WebKit::AudioMediaStreamTrackRendererInternalUnitManager::Proxy::restartIfNeeded):
+        * WebProcess/GPU/webrtc/AudioMediaStreamTrackRendererInternalUnitManager.h: Added.
+        * WebProcess/GPU/webrtc/AudioMediaStreamTrackRendererInternalUnitManager.messages.in: Added.
+        * WebProcess/WebProcess.cpp:
+        (WebKit::WebProcess::audioMediaStreamTrackRendererInternalUnitManager):
+        * WebProcess/WebProcess.h:
+        * WebProcess/cocoa/UserMediaCaptureManager.cpp:
+        (WebKit::UserMediaCaptureManager::setupCaptureProcesses):
+
 2021-05-20  Julian Gonzalez  <[email protected]>
 
         WKRemoteObjectRegistry  _invokeMethod needs to check for nil completionHandlers

Modified: trunk/Source/WebKit/DerivedSources-input.xcfilelist (277851 => 277852)


--- trunk/Source/WebKit/DerivedSources-input.xcfilelist	2021-05-21 09:31:51 UTC (rev 277851)
+++ trunk/Source/WebKit/DerivedSources-input.xcfilelist	2021-05-21 09:53:36 UTC (rev 277852)
@@ -47,6 +47,7 @@
 $(PROJECT_DIR)/GPUProcess/media/ios/RemoteMediaSessionHelperProxy.messages.in
 $(PROJECT_DIR)/GPUProcess/webrtc/LibWebRTCCodecsProxy.messages.in
 $(PROJECT_DIR)/GPUProcess/webrtc/RemoteAudioMediaStreamTrackRenderer.messages.in
+$(PROJECT_DIR)/GPUProcess/webrtc/RemoteAudioMediaStreamTrackRendererInternalUnitManager.messages.in
 $(PROJECT_DIR)/GPUProcess/webrtc/RemoteAudioMediaStreamTrackRendererManager.messages.in
 $(PROJECT_DIR)/GPUProcess/webrtc/RemoteMediaRecorder.messages.in
 $(PROJECT_DIR)/GPUProcess/webrtc/RemoteMediaRecorderManager.messages.in

Modified: trunk/Source/WebKit/DerivedSources-output.xcfilelist (277851 => 277852)


--- trunk/Source/WebKit/DerivedSources-output.xcfilelist	2021-05-21 09:31:51 UTC (rev 277851)
+++ trunk/Source/WebKit/DerivedSources-output.xcfilelist	2021-05-21 09:53:36 UTC (rev 277852)
@@ -152,6 +152,9 @@
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/RemoteAudioHardwareListenerMessageReceiver.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/RemoteAudioHardwareListenerMessages.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/RemoteAudioHardwareListenerMessagesReplies.h
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/RemoteAudioMediaStreamTrackRendererInternalUnitManagerMessageReceiver.cpp
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/RemoteAudioMediaStreamTrackRendererInternalUnitManagerMessages.h
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/RemoteAudioMediaStreamTrackRendererInternalUnitManagerMessagesReplies.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/RemoteAudioMediaStreamTrackRendererManagerMessageReceiver.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/RemoteAudioMediaStreamTrackRendererManagerMessages.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/RemoteAudioMediaStreamTrackRendererManagerMessagesReplies.h

Modified: trunk/Source/WebKit/DerivedSources.make (277851 => 277852)


--- trunk/Source/WebKit/DerivedSources.make	2021-05-21 09:31:51 UTC (rev 277851)
+++ trunk/Source/WebKit/DerivedSources.make	2021-05-21 09:53:36 UTC (rev 277852)
@@ -251,6 +251,7 @@
 	GPUProcess/webrtc/RemoteSampleBufferDisplayLayer \
 	GPUProcess/webrtc/RemoteMediaRecorder \
 	GPUProcess/webrtc/RemoteAudioMediaStreamTrackRenderer \
+	GPUProcess/webrtc/RemoteAudioMediaStreamTrackRendererInternalUnitManager \
 	GPUProcess/GPUProcess \
 	GPUProcess/media/RemoteImageDecoderAVFProxy \
 	GPUProcess/media/RemoteLegacyCDMSessionProxy \

Modified: trunk/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.cpp (277851 => 277852)


--- trunk/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.cpp	2021-05-21 09:31:51 UTC (rev 277851)
+++ trunk/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.cpp	2021-05-21 09:53:36 UTC (rev 277852)
@@ -41,6 +41,8 @@
 #include "Logging.h"
 #include "MediaOverridesForTesting.h"
 #include "RemoteAudioHardwareListenerProxy.h"
+#include "RemoteAudioMediaStreamTrackRendererInternalUnitManager.h"
+#include "RemoteAudioMediaStreamTrackRendererInternalUnitManagerMessages.h"
 #include "RemoteAudioMediaStreamTrackRendererManager.h"
 #include "RemoteGraphicsContextGLMessages.h"
 #include "RemoteMediaPlayerManagerProxy.h"
@@ -403,6 +405,14 @@
 
     return *m_userMediaCaptureManagerProxy;
 }
+
+RemoteAudioMediaStreamTrackRendererInternalUnitManager& GPUConnectionToWebProcess::audioMediaStreamTrackRendererInternalUnitManager()
+{
+    if (!m_audioMediaStreamTrackRendererInternalUnitManager)
+        m_audioMediaStreamTrackRendererInternalUnitManager = makeUnique<RemoteAudioMediaStreamTrackRendererInternalUnitManager>(*this);
+
+    return *m_audioMediaStreamTrackRendererInternalUnitManager;
+}
 #endif
 
 #if PLATFORM(COCOA) && ENABLE(MEDIA_STREAM) && HAVE(AVASSETWRITERDELEGATE)
@@ -624,6 +634,10 @@
         userMediaCaptureManagerProxy().didReceiveMessageFromGPUProcess(connection, decoder);
         return true;
     }
+    if (decoder.messageReceiverName() == Messages::RemoteAudioMediaStreamTrackRendererInternalUnitManager::messageReceiverName()) {
+        audioMediaStreamTrackRendererInternalUnitManager().didReceiveMessage(connection, decoder);
+        return true;
+    }
 #endif
 #if PLATFORM(COCOA) && ENABLE(MEDIA_STREAM) && HAVE(AVASSETWRITERDELEGATE)
     if (decoder.messageReceiverName() == Messages::RemoteMediaRecorderManager::messageReceiverName()) {

Modified: trunk/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.h (277851 => 277852)


--- trunk/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.h	2021-05-21 09:31:51 UTC (rev 277851)
+++ trunk/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.h	2021-05-21 09:53:36 UTC (rev 277852)
@@ -61,6 +61,7 @@
 class RemoteAudioDestinationManager;
 class RemoteAudioHardwareListenerProxy;
 class RemoteAudioMediaStreamTrackRendererManager;
+class RemoteAudioMediaStreamTrackRendererInternalUnitManager;
 class RemoteAudioSessionProxy;
 class RemoteAudioSessionProxyManager;
 class RemoteCDMFactoryProxy;
@@ -159,6 +160,7 @@
 #endif
 #if PLATFORM(COCOA) && ENABLE(MEDIA_STREAM)
     UserMediaCaptureManagerProxy& userMediaCaptureManagerProxy();
+    RemoteAudioMediaStreamTrackRendererInternalUnitManager& audioMediaStreamTrackRendererInternalUnitManager();
 #endif
 #if PLATFORM(COCOA) && ENABLE(MEDIA_STREAM) && HAVE(AVASSETWRITERDELEGATE)
     RemoteMediaRecorderManager& mediaRecorderManager();
@@ -239,6 +241,7 @@
 #endif
 #if PLATFORM(COCOA) && ENABLE(MEDIA_STREAM)
     std::unique_ptr<UserMediaCaptureManagerProxy> m_userMediaCaptureManagerProxy;
+    std::unique_ptr<RemoteAudioMediaStreamTrackRendererInternalUnitManager> m_audioMediaStreamTrackRendererInternalUnitManager;
     Ref<RemoteAudioMediaStreamTrackRendererManager> m_audioTrackRendererManager;
     Ref<RemoteSampleBufferDisplayLayerManager> m_sampleBufferDisplayLayerManager;
 #endif

Added: trunk/Source/WebKit/GPUProcess/webrtc/RemoteAudioMediaStreamTrackRendererInternalUnitManager.cpp (0 => 277852)


--- trunk/Source/WebKit/GPUProcess/webrtc/RemoteAudioMediaStreamTrackRendererInternalUnitManager.cpp	                        (rev 0)
+++ trunk/Source/WebKit/GPUProcess/webrtc/RemoteAudioMediaStreamTrackRendererInternalUnitManager.cpp	2021-05-21 09:53:36 UTC (rev 277852)
@@ -0,0 +1,186 @@
+/*
+ * 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 "RemoteAudioMediaStreamTrackRendererInternalUnitManager.h"
+
+#if ENABLE(GPU_PROCESS) && ENABLE(MEDIA_STREAM)
+
+#include "GPUConnectionToWebProcess.h"
+#include "GPUProcess.h"
+#include "GPUProcessConnectionMessages.h"
+#include "IPCSemaphore.h"
+#include <WebCore/AudioMediaStreamTrackRendererInternalUnit.h>
+#include <WebCore/AudioSession.h>
+#include <WebCore/AudioUtilities.h>
+#include <wtf/WeakPtr.h>
+
+#if PLATFORM(COCOA)
+#include "SharedRingBufferStorage.h"
+#include <WebCore/CAAudioStreamDescription.h>
+#include <WebCore/CARingBuffer.h>
+#include <WebCore/WebAudioBufferList.h>
+#endif
+
+namespace WebKit {
+
+class RemoteAudioMediaStreamTrackRendererInternalUnitManager::Unit : public CanMakeWeakPtr<RemoteAudioMediaStreamTrackRendererInternalUnitManager::Unit> {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    Unit(AudioMediaStreamTrackRendererInternalUnitIdentifier, Ref<IPC::Connection>&&, CompletionHandler<void(const WebCore::CAAudioStreamDescription&, size_t)>&&);
+    ~Unit();
+
+    void start(const SharedMemory::Handle&, const WebCore::CAAudioStreamDescription&, uint64_t numberOfFrames, IPC::Semaphore&&);
+    void stop();
+    void setAudioOutputDevice(const String&);
+    OSStatus render(size_t sampleCount, AudioBufferList&, uint64_t sampleTime, double hostTime, AudioUnitRenderActionFlags&);
+
+private:
+    void storageChanged(SharedMemory*, const WebCore::CAAudioStreamDescription&, size_t);
+
+    AudioMediaStreamTrackRendererInternalUnitIdentifier m_identifier;
+    Ref<IPC::Connection> m_connection;
+    UniqueRef<WebCore::AudioMediaStreamTrackRendererInternalUnit> m_localUnit;
+    uint64_t m_readOffset { 0 };
+    uint64_t m_frameChunkSize { 0 };
+    IPC::Semaphore m_renderSemaphore;
+#if PLATFORM(COCOA)
+    std::unique_ptr<WebCore::CARingBuffer> m_ringBuffer;
+#endif
+    bool m_isPlaying { false };
+};
+
+RemoteAudioMediaStreamTrackRendererInternalUnitManager::RemoteAudioMediaStreamTrackRendererInternalUnitManager(GPUConnectionToWebProcess& gpuConnectionToWebProcess)
+    : m_gpuConnectionToWebProcess(gpuConnectionToWebProcess)
+{
+}
+
+RemoteAudioMediaStreamTrackRendererInternalUnitManager::~RemoteAudioMediaStreamTrackRendererInternalUnitManager()
+{
+}
+
+void RemoteAudioMediaStreamTrackRendererInternalUnitManager::createUnit(AudioMediaStreamTrackRendererInternalUnitIdentifier identifier, CompletionHandler<void(const WebCore::CAAudioStreamDescription&, size_t)>&& callback)
+{
+    ASSERT(!m_units.contains(identifier));
+    m_units.add(identifier, makeUniqueRef<RemoteAudioMediaStreamTrackRendererInternalUnitManager::Unit>(identifier, m_gpuConnectionToWebProcess.connection(), WTFMove(callback)));
+}
+
+void RemoteAudioMediaStreamTrackRendererInternalUnitManager::deleteUnit(AudioMediaStreamTrackRendererInternalUnitIdentifier identifier)
+{
+    if (!m_units.remove(identifier))
+        return;
+
+    if (m_units.isEmpty())
+        m_gpuConnectionToWebProcess.gpuProcess().tryExitIfUnusedAndUnderMemoryPressure();
+}
+
+void RemoteAudioMediaStreamTrackRendererInternalUnitManager::startUnit(AudioMediaStreamTrackRendererInternalUnitIdentifier identifier, const SharedMemory::IPCHandle& ipcHandle, const WebCore::CAAudioStreamDescription& description, uint64_t numberOfFrames, IPC::Semaphore&& semaphore)
+{
+    if (auto* unit = m_units.get(identifier))
+        unit->start(ipcHandle.handle, description, numberOfFrames, WTFMove(semaphore));
+}
+
+void RemoteAudioMediaStreamTrackRendererInternalUnitManager::stopUnit(AudioMediaStreamTrackRendererInternalUnitIdentifier identifier)
+{
+    if (auto* unit = m_units.get(identifier))
+        unit->stop();
+}
+
+void RemoteAudioMediaStreamTrackRendererInternalUnitManager::setAudioOutputDevice(AudioMediaStreamTrackRendererInternalUnitIdentifier identifier, const String& deviceId)
+{
+    if (auto* unit = m_units.get(identifier))
+        unit->setAudioOutputDevice(deviceId);
+}
+
+static AudioMediaStreamTrackRendererInternalUnit::RenderCallback renderCallback(RemoteAudioMediaStreamTrackRendererInternalUnitManager::Unit& unit)
+{
+    return [&unit](auto sampleCount, auto& list, auto sampleTime, auto hostTime, auto& flags) {
+        return unit.render(sampleCount, list, sampleTime, hostTime, flags);
+    };
+}
+
+RemoteAudioMediaStreamTrackRendererInternalUnitManager::Unit::Unit(AudioMediaStreamTrackRendererInternalUnitIdentifier identifier, Ref<IPC::Connection>&& connection, CompletionHandler<void(const WebCore::CAAudioStreamDescription&, size_t)>&& callback)
+    : m_identifier(identifier)
+    , m_connection(WTFMove(connection))
+    , m_localUnit(WebCore::AudioMediaStreamTrackRendererInternalUnit::createLocalInternalUnit(renderCallback(*this)))
+{
+    m_localUnit->retrieveFormatDescription([weakThis = makeWeakPtr(this), this, callback = WTFMove(callback)](auto&& description) mutable {
+        if (!weakThis || !description) {
+            callback({ }, 0);
+            return;
+        }
+        m_frameChunkSize = std::max(WebCore::AudioUtilities::renderQuantumSize, AudioSession::sharedSession().preferredBufferSize());
+        callback(*description, m_frameChunkSize);
+    });
+}
+
+RemoteAudioMediaStreamTrackRendererInternalUnitManager::Unit::~Unit()
+{
+    stop();
+}
+
+void RemoteAudioMediaStreamTrackRendererInternalUnitManager::Unit::start(const SharedMemory::Handle& handle, const WebCore::CAAudioStreamDescription& description, uint64_t numberOfFrames, IPC::Semaphore&& semaphore)
+{
+    if (m_isPlaying)
+        stop();
+
+    m_readOffset = 0;
+    m_isPlaying = true;
+    m_ringBuffer = CARingBuffer::adoptStorage(makeUniqueRef<ReadOnlySharedRingBufferStorage>(handle), description, numberOfFrames).moveToUniquePtr();
+    m_renderSemaphore = WTFMove(semaphore);
+    m_localUnit->start();
+}
+
+void RemoteAudioMediaStreamTrackRendererInternalUnitManager::Unit::stop()
+{
+    m_isPlaying = false;
+    m_localUnit->stop();
+}
+
+void RemoteAudioMediaStreamTrackRendererInternalUnitManager::Unit::setAudioOutputDevice(const String& deviceId)
+{
+    m_localUnit->setAudioOutputDevice(deviceId);
+}
+
+OSStatus RemoteAudioMediaStreamTrackRendererInternalUnitManager::Unit::render(size_t sampleCount, AudioBufferList& list, uint64_t, double, AudioUnitRenderActionFlags&)
+{
+    ASSERT(!isMainRunLoop());
+
+    OSStatus status = -1;
+
+    if (m_ringBuffer->fetchIfHasEnoughData(&list, sampleCount, m_readOffset)) {
+        m_readOffset += sampleCount;
+        status = noErr;
+    }
+
+    for (unsigned i = 0; i < sampleCount; i += m_frameChunkSize)
+        m_renderSemaphore.signal();
+
+    return status;
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(GPU_PROCESS) && ENABLE(MEDIA_STREAM)

Added: trunk/Source/WebKit/GPUProcess/webrtc/RemoteAudioMediaStreamTrackRendererInternalUnitManager.h (0 => 277852)


--- trunk/Source/WebKit/GPUProcess/webrtc/RemoteAudioMediaStreamTrackRendererInternalUnitManager.h	                        (rev 0)
+++ trunk/Source/WebKit/GPUProcess/webrtc/RemoteAudioMediaStreamTrackRendererInternalUnitManager.h	2021-05-21 09:53:36 UTC (rev 277852)
@@ -0,0 +1,76 @@
+/*
+ * 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(GPU_PROCESS) && ENABLE(MEDIA_STREAM)
+
+#include "AudioMediaStreamTrackRendererInternalUnitIdentifier.h"
+#include "Connection.h"
+#include "SharedMemory.h"
+#include <wtf/CompletionHandler.h>
+#include <wtf/HashMap.h>
+
+#if PLATFORM(COCOA)
+namespace WebCore {
+class CAAudioStreamDescription;
+}
+#endif
+
+namespace IPC {
+class Semaphore;
+}
+
+namespace WebKit {
+
+class GPUConnectionToWebProcess;
+class RemoteAudioDestination;
+
+class RemoteAudioMediaStreamTrackRendererInternalUnitManager : private IPC::MessageReceiver {
+    WTF_MAKE_FAST_ALLOCATED;
+    WTF_MAKE_NONCOPYABLE(RemoteAudioMediaStreamTrackRendererInternalUnitManager);
+public:
+    explicit RemoteAudioMediaStreamTrackRendererInternalUnitManager(GPUConnectionToWebProcess&);
+    ~RemoteAudioMediaStreamTrackRendererInternalUnitManager();
+
+    void didReceiveMessage(IPC::Connection&, IPC::Decoder&);
+
+    class Unit;
+
+private:
+    // Messages
+    void createUnit(AudioMediaStreamTrackRendererInternalUnitIdentifier, CompletionHandler<void(const WebCore::CAAudioStreamDescription&, size_t)>&& callback);
+    void deleteUnit(AudioMediaStreamTrackRendererInternalUnitIdentifier);
+    void startUnit(AudioMediaStreamTrackRendererInternalUnitIdentifier, const SharedMemory::IPCHandle&, const WebCore::CAAudioStreamDescription&, uint64_t numberOfFrames, IPC::Semaphore&&);
+    void stopUnit(AudioMediaStreamTrackRendererInternalUnitIdentifier);
+    void setAudioOutputDevice(AudioMediaStreamTrackRendererInternalUnitIdentifier, const String&);
+
+    HashMap<AudioMediaStreamTrackRendererInternalUnitIdentifier, UniqueRef<Unit>> m_units;
+    GPUConnectionToWebProcess& m_gpuConnectionToWebProcess;
+};
+
+} // namespace WebKit;
+
+#endif // ENABLE(GPU_PROCESS) && ENABLE(MEDIA_STREAM)

Added: trunk/Source/WebKit/GPUProcess/webrtc/RemoteAudioMediaStreamTrackRendererInternalUnitManager.messages.in (0 => 277852)


--- trunk/Source/WebKit/GPUProcess/webrtc/RemoteAudioMediaStreamTrackRendererInternalUnitManager.messages.in	                        (rev 0)
+++ trunk/Source/WebKit/GPUProcess/webrtc/RemoteAudioMediaStreamTrackRendererInternalUnitManager.messages.in	2021-05-21 09:53:36 UTC (rev 277852)
@@ -0,0 +1,36 @@
+# 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.
+
+#if ENABLE(GPU_PROCESS) && ENABLE(MEDIA_STREAM)
+
+messages -> RemoteAudioMediaStreamTrackRendererInternalUnitManager NotRefCounted {
+    CreateUnit(WebKit::AudioMediaStreamTrackRendererInternalUnitIdentifier identifier) -> (WebCore::CAAudioStreamDescription description, size_t frameChunkSize) Async
+    DeleteUnit(WebKit::AudioMediaStreamTrackRendererInternalUnitIdentifier identifier)
+
+    StartUnit(WebKit::AudioMediaStreamTrackRendererInternalUnitIdentifier identifier, WebKit::SharedMemory::IPCHandle storageHandle, WebCore::CAAudioStreamDescription description, uint64_t numberOfFrames, IPC::Semaphore renderSemaphore)
+    StopUnit(WebKit::AudioMediaStreamTrackRendererInternalUnitIdentifier identifier)
+
+    SetAudioOutputDevice(WebKit::AudioMediaStreamTrackRendererInternalUnitIdentifier identifier, String deviceId)
+}
+
+#endif

Modified: trunk/Source/WebKit/Scripts/webkit/messages.py (277851 => 277852)


--- trunk/Source/WebKit/Scripts/webkit/messages.py	2021-05-21 09:31:51 UTC (rev 277851)
+++ trunk/Source/WebKit/Scripts/webkit/messages.py	2021-05-21 09:53:36 UTC (rev 277852)
@@ -307,6 +307,7 @@
         'WebCore::WebSocketIdentifier',
         'WebKit::ActivityStateChangeID',
         'WebKit::AudioMediaStreamTrackRendererIdentifier',
+        'WebKit::AudioMediaStreamTrackRendererInternalUnitIdentifier',
         'WebKit::ContentWorldIdentifier',
         'WebKit::DisplayLinkObserverID',
         'WebKit::DownloadID',

Modified: trunk/Source/WebKit/Sources.txt (277851 => 277852)


--- trunk/Source/WebKit/Sources.txt	2021-05-21 09:31:51 UTC (rev 277851)
+++ trunk/Source/WebKit/Sources.txt	2021-05-21 09:53:36 UTC (rev 277852)
@@ -724,5 +724,6 @@
 
 RTCDataChannelRemoteManagerMessageReceiver.cpp
 RTCDataChannelRemoteManagerProxyMessageReceiver.cpp
+RemoteAudioMediaStreamTrackRendererInternalUnitManagerMessageReceiver.cpp
 RemoteGraphicsContextGLMessageReceiver.cpp
 RemoteGraphicsContextGLProxyMessageReceiver.cpp

Modified: trunk/Source/WebKit/SourcesCocoa.txt (277851 => 277852)


--- trunk/Source/WebKit/SourcesCocoa.txt	2021-05-21 09:31:51 UTC (rev 277851)
+++ trunk/Source/WebKit/SourcesCocoa.txt	2021-05-21 09:53:36 UTC (rev 277852)
@@ -68,6 +68,7 @@
 GPUProcess/media/cocoa/RemoteMediaPlayerProxyCocoa.mm
 GPUProcess/media/ios/RemoteMediaSessionHelperProxy.cpp
 GPUProcess/webrtc/LibWebRTCCodecsProxy.mm @no-unify
+GPUProcess/webrtc/RemoteAudioMediaStreamTrackRendererInternalUnitManager.cpp
 
 Platform/cf/ModuleCF.cpp
 
@@ -612,6 +613,7 @@
 WebProcess/GPU/media/cocoa/MediaPlayerPrivateRemoteCocoa.mm
 WebProcess/GPU/media/cocoa/VideoLayerRemoteCocoa.mm
 WebProcess/GPU/media/ios/RemoteMediaSessionHelper.cpp
+WebProcess/GPU/webrtc/AudioMediaStreamTrackRendererInternalUnitManager.cpp
 WebProcess/GPU/webrtc/LibWebRTCCodecs.mm
 WebProcess/GPU/webrtc/MediaRecorderPrivate.mm
 

Modified: trunk/Source/WebKit/UIProcess/GPU/GPUProcessProxy.h (277851 => 277852)


--- trunk/Source/WebKit/UIProcess/GPU/GPUProcessProxy.h	2021-05-21 09:31:51 UTC (rev 277851)
+++ trunk/Source/WebKit/UIProcess/GPU/GPUProcessProxy.h	2021-05-21 09:53:36 UTC (rev 277852)
@@ -35,6 +35,7 @@
 #include "ProcessThrottlerClient.h"
 #include "WebPageProxyIdentifier.h"
 #include "WebProcessProxyMessagesReplies.h"
+#include <WebCore/PageIdentifier.h>
 #include <memory>
 #include <pal/SessionID.h>
 

Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (277851 => 277852)


--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj	2021-05-21 09:31:51 UTC (rev 277851)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj	2021-05-21 09:53:36 UTC (rev 277852)
@@ -3821,6 +3821,12 @@
 		41B7ED6F206965900087D853 /* NetworkMDNSRegister.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkMDNSRegister.cpp; sourceTree = "<group>"; };
 		41B7ED70206965900087D853 /* NetworkMDNSRegister.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkMDNSRegister.h; sourceTree = "<group>"; };
 		41B7ED71206965900087D853 /* NetworkMDNSRegister.messages.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = NetworkMDNSRegister.messages.in; sourceTree = "<group>"; };
+		41C3B88526444AAB004ED4DE /* AudioMediaStreamTrackRendererInternalUnitManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AudioMediaStreamTrackRendererInternalUnitManager.h; sourceTree = "<group>"; };
+		41C3B88626444AAC004ED4DE /* AudioMediaStreamTrackRendererInternalUnitManager.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AudioMediaStreamTrackRendererInternalUnitManager.cpp; sourceTree = "<group>"; };
+		41C3B88726444AD3004ED4DE /* AudioMediaStreamTrackRendererInternalUnitIdentifier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AudioMediaStreamTrackRendererInternalUnitIdentifier.h; sourceTree = "<group>"; };
+		41C3B89026493B7B004ED4DE /* RemoteAudioMediaStreamTrackRendererInternalUnitManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RemoteAudioMediaStreamTrackRendererInternalUnitManager.h; sourceTree = "<group>"; };
+		41C3B89126493B7B004ED4DE /* RemoteAudioMediaStreamTrackRendererInternalUnitManager.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = RemoteAudioMediaStreamTrackRendererInternalUnitManager.cpp; sourceTree = "<group>"; };
+		41C3B89426493B7C004ED4DE /* RemoteAudioMediaStreamTrackRendererInternalUnitManager.messages.in */ = {isa = PBXFileReference; lastKnownFileType = text; path = RemoteAudioMediaStreamTrackRendererInternalUnitManager.messages.in; sourceTree = "<group>"; };
 		41C5378F21F1362D008B1FAD /* _WKWebsiteDataStoreDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKWebsiteDataStoreDelegate.h; sourceTree = "<group>"; };
 		41C858191F510DEE0065E085 /* CacheStorageEngineCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CacheStorageEngineCache.cpp; sourceTree = "<group>"; };
 		41CB840325CABF7C0010E2B1 /* MediaRecorderPrivate.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MediaRecorderPrivate.mm; sourceTree = "<group>"; };
@@ -8421,6 +8427,9 @@
 				41FCD6AE23CCC26100C62567 /* AudioMediaStreamTrackRenderer.cpp */,
 				41FCD6AD23CCC26000C62567 /* AudioMediaStreamTrackRenderer.h */,
 				41FCD6AF23CCC26100C62567 /* AudioMediaStreamTrackRendererIdentifier.h */,
+				41C3B88726444AD3004ED4DE /* AudioMediaStreamTrackRendererInternalUnitIdentifier.h */,
+				41C3B88626444AAC004ED4DE /* AudioMediaStreamTrackRendererInternalUnitManager.cpp */,
+				41C3B88526444AAB004ED4DE /* AudioMediaStreamTrackRendererInternalUnitManager.h */,
 				4172198A23B6128200AE5686 /* LibWebRTCCodecs.cpp */,
 				4172198923B6128200AE5686 /* LibWebRTCCodecs.h */,
 				4172198D23B62C7C00AE5686 /* LibWebRTCCodecs.messages.in */,
@@ -8452,6 +8461,9 @@
 				41D6455423CCB92200486E0E /* RemoteAudioMediaStreamTrackRenderer.cpp */,
 				41D6455323CCB92100486E0E /* RemoteAudioMediaStreamTrackRenderer.h */,
 				41D6455223CCB92100486E0E /* RemoteAudioMediaStreamTrackRenderer.messages.in */,
+				41C3B89126493B7B004ED4DE /* RemoteAudioMediaStreamTrackRendererInternalUnitManager.cpp */,
+				41C3B89026493B7B004ED4DE /* RemoteAudioMediaStreamTrackRendererInternalUnitManager.h */,
+				41C3B89426493B7C004ED4DE /* RemoteAudioMediaStreamTrackRendererInternalUnitManager.messages.in */,
 				41D6455623CCB96900486E0E /* RemoteAudioMediaStreamTrackRendererManager.cpp */,
 				41D6455723CCB96900486E0E /* RemoteAudioMediaStreamTrackRendererManager.h */,
 				41D6455523CCB96900486E0E /* RemoteAudioMediaStreamTrackRendererManager.messages.in */,

Modified: trunk/Source/WebKit/WebProcess/GPU/GPUProcessConnection.h (277851 => 277852)


--- trunk/Source/WebKit/WebProcess/GPU/GPUProcessConnection.h	2021-05-21 09:31:51 UTC (rev 277851)
+++ trunk/Source/WebKit/WebProcess/GPU/GPUProcessConnection.h	2021-05-21 09:53:36 UTC (rev 277852)
@@ -27,10 +27,12 @@
 
 #if ENABLE(GPU_PROCESS)
 
+#include "AudioMediaStreamTrackRendererInternalUnitIdentifier.h"
 #include "Connection.h"
 #include "MediaOverridesForTesting.h"
 #include "MessageReceiverMap.h"
 #include "SampleBufferDisplayLayerManager.h"
+#include "SharedMemory.h"
 #include <WebCore/PlatformMediaSession.h>
 #include <wtf/RefCounted.h>
 #include <wtf/WeakHashSet.h>
@@ -37,6 +39,14 @@
 #include <wtf/WeakPtr.h>
 #include <wtf/text/WTFString.h>
 
+namespace WebCore {
+class CAAudioStreamDescription;
+}
+
+namespace IPC {
+class Semaphore;
+}
+
 namespace WebKit {
 
 class RemoteAudioSourceProviderManager;

Added: trunk/Source/WebKit/WebProcess/GPU/webrtc/AudioMediaStreamTrackRendererInternalUnitIdentifier.h (0 => 277852)


--- trunk/Source/WebKit/WebProcess/GPU/webrtc/AudioMediaStreamTrackRendererInternalUnitIdentifier.h	                        (rev 0)
+++ trunk/Source/WebKit/WebProcess/GPU/webrtc/AudioMediaStreamTrackRendererInternalUnitIdentifier.h	2021-05-21 09:53:36 UTC (rev 277852)
@@ -0,0 +1,35 @@
+/*
+ * 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
+
+#include <wtf/ObjectIdentifier.h>
+
+namespace WebKit {
+
+enum AudioMediaStreamTrackRendererInternalUnitIdentifierType { };
+using AudioMediaStreamTrackRendererInternalUnitIdentifier = ObjectIdentifier<AudioMediaStreamTrackRendererInternalUnitIdentifierType>;
+
+} // namespace WebKit

Added: trunk/Source/WebKit/WebProcess/GPU/webrtc/AudioMediaStreamTrackRendererInternalUnitManager.cpp (0 => 277852)


--- trunk/Source/WebKit/WebProcess/GPU/webrtc/AudioMediaStreamTrackRendererInternalUnitManager.cpp	                        (rev 0)
+++ trunk/Source/WebKit/WebProcess/GPU/webrtc/AudioMediaStreamTrackRendererInternalUnitManager.cpp	2021-05-21 09:53:36 UTC (rev 277852)
@@ -0,0 +1,271 @@
+/*
+ * 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 "AudioMediaStreamTrackRendererInternalUnitManager.h"
+
+#if ENABLE(MEDIA_STREAM) && ENABLE(GPU_PROCESS) && PLATFORM(COCOA)
+
+#include "AudioMediaStreamTrackRendererInternalUnitIdentifier.h"
+#include "IPCSemaphore.h"
+#include "RemoteAudioMediaStreamTrackRendererInternalUnitManagerMessages.h"
+#include "SharedMemory.h"
+#include <WebCore/AudioMediaStreamTrackRendererInternalUnit.h>
+#include <WebCore/AudioMediaStreamTrackRendererUnit.h>
+#include <WebCore/CAAudioStreamDescription.h>
+#include <WebCore/CARingBuffer.h>
+#include <WebCore/WebAudioBufferList.h>
+#include <mach/mach_time.h>
+#include <wtf/Deque.h>
+
+namespace WebKit {
+
+class AudioMediaStreamTrackRendererInternalUnitManager::Proxy final : public WebCore::AudioMediaStreamTrackRendererInternalUnit, public CanMakeWeakPtr<Proxy> {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    explicit Proxy(WebCore::AudioMediaStreamTrackRendererInternalUnit::RenderCallback&&);
+    ~Proxy();
+
+    AudioMediaStreamTrackRendererInternalUnitIdentifier identifier() const { return m_identifier; }
+
+    void restartIfNeeded();
+
+private:
+    // AudioMediaStreamTrackRendererUnit::InternalUnit API.
+    void start() final;
+    void stop() final;
+    void retrieveFormatDescription(CompletionHandler<void(const WebCore::CAAudioStreamDescription*)>&&) final;
+    void setAudioOutputDevice(const String&) final;
+
+    void initialize(const WebCore::CAAudioStreamDescription&, size_t frameChunkSize);
+    void storageChanged(SharedMemory*, const CAAudioStreamDescription&, size_t);
+
+    void stopThread();
+    void startThread();
+    void createRemoteUnit();
+
+    WebCore::AudioMediaStreamTrackRendererInternalUnit::RenderCallback m_renderCallback;
+    AudioMediaStreamTrackRendererInternalUnitIdentifier m_identifier;
+
+    Deque<CompletionHandler<void(const WebCore::CAAudioStreamDescription*)>> m_descriptionCallbacks;
+
+    String m_deviceId;
+    bool m_isPlaying { false };
+
+    Optional<WebCore::CAAudioStreamDescription> m_description;
+    std::unique_ptr<WebCore::WebAudioBufferList> m_buffer;
+    std::unique_ptr<WebCore::CARingBuffer> m_ringBuffer;
+    int64_t m_writeOffset { 0 };
+    size_t m_frameChunkSize { 0 };
+    size_t m_numberOfFrames { 0 };
+
+    std::unique_ptr<IPC::Semaphore> m_semaphore;
+    RefPtr<Thread> m_thread;
+    std::atomic<bool> m_shouldStopThread { false };
+    bool m_didClose { false };
+};
+
+void AudioMediaStreamTrackRendererInternalUnitManager::add(Proxy& proxy)
+{
+    m_proxies.add(proxy.identifier(), makeWeakPtr(proxy));
+}
+
+void AudioMediaStreamTrackRendererInternalUnitManager::remove(Proxy& proxy)
+{
+    m_proxies.remove(proxy.identifier());
+}
+
+UniqueRef<WebCore::AudioMediaStreamTrackRendererInternalUnit> AudioMediaStreamTrackRendererInternalUnitManager::createRemoteInternalUnit(WebCore::AudioMediaStreamTrackRendererInternalUnit::RenderCallback&& callback)
+{
+    return makeUniqueRef<AudioMediaStreamTrackRendererInternalUnitManager::Proxy>(WTFMove(callback));
+}
+
+void AudioMediaStreamTrackRendererInternalUnitManager::gpuProcessConnectionClosed()
+{
+    for (auto proxy : m_proxies.values())
+        proxy->restartIfNeeded();
+}
+
+AudioMediaStreamTrackRendererInternalUnitManager::Proxy::Proxy(WebCore::AudioMediaStreamTrackRendererInternalUnit::RenderCallback&& renderCallback)
+    : m_renderCallback(WTFMove(renderCallback))
+    , m_identifier(AudioMediaStreamTrackRendererInternalUnitIdentifier::generate())
+{
+    WebProcess::singleton().audioMediaStreamTrackRendererInternalUnitManager().add(*this);
+    createRemoteUnit();
+}
+
+AudioMediaStreamTrackRendererInternalUnitManager::Proxy::~Proxy()
+{
+    WebProcess::singleton().audioMediaStreamTrackRendererInternalUnitManager().remove(*this);
+    WebProcess::singleton().ensureGPUProcessConnection().connection().send(Messages::RemoteAudioMediaStreamTrackRendererInternalUnitManager::DeleteUnit { m_identifier }, 0);
+
+    while (!m_descriptionCallbacks.isEmpty())
+        m_descriptionCallbacks.takeFirst()(nullptr);
+}
+
+void AudioMediaStreamTrackRendererInternalUnitManager::Proxy::createRemoteUnit()
+{
+    WebProcess::singleton().ensureGPUProcessConnection().connection().sendWithAsyncReply(Messages::RemoteAudioMediaStreamTrackRendererInternalUnitManager::CreateUnit { m_identifier }, [weakThis = makeWeakPtr(this)](auto&& description, auto frameChunkSize) {
+        if (weakThis && frameChunkSize)
+            weakThis->initialize(description, frameChunkSize);
+    }, 0);
+}
+
+void AudioMediaStreamTrackRendererInternalUnitManager::Proxy::initialize(const WebCore::CAAudioStreamDescription& description, size_t frameChunkSize)
+{
+    if (m_semaphore)
+        stopThread();
+
+    m_semaphore = makeUnique<IPC::Semaphore>();
+    m_description = description;
+    m_frameChunkSize = frameChunkSize;
+
+    while (!m_descriptionCallbacks.isEmpty())
+        m_descriptionCallbacks.takeFirst()(&description);
+
+    if (m_isPlaying)
+        start();
+}
+
+void AudioMediaStreamTrackRendererInternalUnitManager::Proxy::start()
+{
+    if (!m_description) {
+        m_isPlaying = true;
+        return;
+    }
+
+    if (m_didClose) {
+        m_didClose = false;
+        createRemoteUnit();
+        if (!m_deviceId.isEmpty())
+            setAudioOutputDevice(m_deviceId);
+        m_isPlaying = true;
+        return;
+    }
+
+    stopThread();
+
+    m_isPlaying = true;
+
+    m_numberOfFrames = m_description->sampleRate() * 2;
+    m_ringBuffer.reset();
+    m_ringBuffer = makeUnique<CARingBuffer>(makeUniqueRef<SharedRingBufferStorage>(std::bind(&AudioMediaStreamTrackRendererInternalUnitManager::Proxy::storageChanged, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)));
+    m_ringBuffer->allocate(m_description->streamDescription(), m_numberOfFrames);
+
+    m_buffer = makeUnique<WebAudioBufferList>(*m_description, m_numberOfFrames);
+    m_buffer->setSampleCount(m_frameChunkSize);
+
+    startThread();
+}
+
+void AudioMediaStreamTrackRendererInternalUnitManager::Proxy::storageChanged(SharedMemory* memory, const CAAudioStreamDescription& format, size_t frameCount)
+{
+    if (!frameCount)
+        return;
+
+    SharedMemory::Handle handle;
+    if (memory)
+        memory->createHandle(handle, SharedMemory::Protection::ReadOnly);
+
+    // FIXME: Send the actual data size with IPCHandle.
+#if OS(DARWIN) || OS(WINDOWS)
+    uint64_t dataSize = handle.size();
+#else
+    uint64_t dataSize = 0;
+#endif
+    WebProcess::singleton().ensureGPUProcessConnection().connection().send(Messages::RemoteAudioMediaStreamTrackRendererInternalUnitManager::StartUnit { m_identifier, SharedMemory::IPCHandle { WTFMove(handle),  dataSize }, format, frameCount, *m_semaphore }, 0);
+}
+
+void AudioMediaStreamTrackRendererInternalUnitManager::Proxy::stop()
+{
+    m_isPlaying = false;
+    WebProcess::singleton().ensureGPUProcessConnection().connection().send(Messages::RemoteAudioMediaStreamTrackRendererInternalUnitManager::StopUnit { m_identifier }, 0);
+}
+
+void AudioMediaStreamTrackRendererInternalUnitManager::Proxy::setAudioOutputDevice(const String& deviceId)
+{
+    m_deviceId = deviceId;
+    WebProcess::singleton().ensureGPUProcessConnection().connection().send(Messages::RemoteAudioMediaStreamTrackRendererInternalUnitManager::SetAudioOutputDevice { m_identifier, deviceId }, 0);
+}
+
+void AudioMediaStreamTrackRendererInternalUnitManager::Proxy::retrieveFormatDescription(CompletionHandler<void(const WebCore::CAAudioStreamDescription*)>&& callback)
+{
+    if (!m_description || !m_descriptionCallbacks.isEmpty()) {
+        m_descriptionCallbacks.append(WTFMove(callback));
+        return;
+    }
+    callback(&m_description.value());
+}
+
+void AudioMediaStreamTrackRendererInternalUnitManager::Proxy::stopThread()
+{
+    if (!m_thread)
+        return;
+
+    m_shouldStopThread = true;
+    m_semaphore->signal();
+    m_thread->waitForCompletion();
+    m_thread = nullptr;
+}
+
+void AudioMediaStreamTrackRendererInternalUnitManager::Proxy::startThread()
+{
+    ASSERT(!m_thread);
+    m_shouldStopThread = false;
+    auto threadLoop = [this]() mutable {
+        m_writeOffset = 0;
+        do {
+            // If wait fails, the semaphore on the other side was probably destroyed and we should just exit here and wait to launch a new thread.
+            if (!m_semaphore->wait())
+                break;
+            if (m_shouldStopThread)
+                break;
+
+            auto& bufferList = *m_buffer->list();
+
+            AudioUnitRenderActionFlags flags = 0;
+            m_renderCallback(m_frameChunkSize, bufferList, m_writeOffset, mach_absolute_time(), flags);
+
+            if (flags == kAudioUnitRenderAction_OutputIsSilence)
+                AudioSampleBufferList::zeroABL(bufferList, static_cast<size_t>(m_frameChunkSize * m_description->bytesPerFrame()));
+
+            m_ringBuffer->store(&bufferList, m_frameChunkSize, m_writeOffset);
+            m_writeOffset += m_frameChunkSize;
+        } while (!m_shouldStopThread);
+    };
+    m_thread = Thread::create("AudioMediaStreamTrackRendererInternalUnit thread", WTFMove(threadLoop), ThreadType::Audio, Thread::QOS::UserInteractive);
+}
+
+void AudioMediaStreamTrackRendererInternalUnitManager::Proxy::restartIfNeeded()
+{
+    stopThread();
+    m_didClose = true;
+    if (m_isPlaying)
+        start();
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(MEDIA_STREAM) && ENABLE(GPU_PROCESS) && PLATFORM(COCOA)

Added: trunk/Source/WebKit/WebProcess/GPU/webrtc/AudioMediaStreamTrackRendererInternalUnitManager.h (0 => 277852)


--- trunk/Source/WebKit/WebProcess/GPU/webrtc/AudioMediaStreamTrackRendererInternalUnitManager.h	                        (rev 0)
+++ trunk/Source/WebKit/WebProcess/GPU/webrtc/AudioMediaStreamTrackRendererInternalUnitManager.h	2021-05-21 09:53:36 UTC (rev 277852)
@@ -0,0 +1,64 @@
+/*
+ * 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) && ENABLE(GPU_PROCESS) && PLATFORM(COCOA)
+
+#include "AudioMediaStreamTrackRendererInternalUnitIdentifier.h"
+#include "SharedMemory.h"
+#include <WebCore/AudioMediaStreamTrackRendererInternalUnit.h>
+#include <wtf/WeakPtr.h>
+
+namespace IPC {
+class Semaphore;
+}
+
+namespace WebCore {
+class CAAudioStreamDescription;
+}
+
+namespace WebKit {
+
+class AudioMediaStreamTrackRendererInternalUnitManager {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    AudioMediaStreamTrackRendererInternalUnitManager() = default;
+
+    UniqueRef<WebCore::AudioMediaStreamTrackRendererInternalUnit> createRemoteInternalUnit(WebCore::AudioMediaStreamTrackRendererInternalUnit::RenderCallback&&);
+
+    class Proxy;
+    void add(Proxy&);
+    void remove(Proxy&);
+
+    void gpuProcessConnectionClosed();
+
+private:
+    HashMap<AudioMediaStreamTrackRendererInternalUnitIdentifier, WeakPtr<Proxy>> m_proxies;
+};
+
+}
+
+#endif // ENABLE(MEDIA_STREAM) && ENABLE(GPU_PROCESS) && PLATFORM(COCOA)

Added: trunk/Source/WebKit/WebProcess/GPU/webrtc/AudioMediaStreamTrackRendererInternalUnitManager.messages.in (0 => 277852)


--- trunk/Source/WebKit/WebProcess/GPU/webrtc/AudioMediaStreamTrackRendererInternalUnitManager.messages.in	                        (rev 0)
+++ trunk/Source/WebKit/WebProcess/GPU/webrtc/AudioMediaStreamTrackRendererInternalUnitManager.messages.in	2021-05-21 09:53:36 UTC (rev 277852)
@@ -0,0 +1,31 @@
+# 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.
+
+#if ENABLE(GPU_PROCESS) && ENABLE(MEDIA_STREAM)
+
+messages -> AudioMediaStreamTrackRendererInternalUnitManager NotRefCounted {
+    AudioStorageChanged(WebKit::SharedMemory::IPCHandle storageHandle, WebCore::CAAudioStreamDescription description, uint64_t numberOfFrames, IPC::Semaphore captureSemaphore, MediaTime mediaTime, size_t frameChunkSize);
+}
+
+#endif
+

Modified: trunk/Source/WebKit/WebProcess/WebProcess.cpp (277851 => 277852)


--- trunk/Source/WebKit/WebProcess/WebProcess.cpp	2021-05-21 09:31:51 UTC (rev 277851)
+++ trunk/Source/WebKit/WebProcess/WebProcess.cpp	2021-05-21 09:53:36 UTC (rev 277852)
@@ -29,6 +29,7 @@
 #include "APIFrameHandle.h"
 #include "APIPageGroupHandle.h"
 #include "APIPageHandle.h"
+#include "AudioMediaStreamTrackRendererInternalUnitManager.h"
 #include "AuthenticationManager.h"
 #include "AuxiliaryProcessMessages.h"
 #include "DrawingArea.h"
@@ -1262,6 +1263,11 @@
     ASSERT_UNUSED(connection, m_gpuProcessConnection == &connection);
 
     m_gpuProcessConnection = nullptr;
+
+#if ENABLE(MEDIA_STREAM) && PLATFORM(COCOA)
+    if (m_audioMediaStreamTrackRendererInternalUnitManager)
+        m_audioMediaStreamTrackRendererInternalUnitManager->gpuProcessConnectionClosed();
+#endif
 }
 
 #if PLATFORM(COCOA) && USE(LIBWEBRTC)
@@ -1273,6 +1279,15 @@
 }
 #endif
 
+#if ENABLE(MEDIA_STREAM) && PLATFORM(COCOA)
+AudioMediaStreamTrackRendererInternalUnitManager& WebProcess::audioMediaStreamTrackRendererInternalUnitManager()
+{
+    if (!m_audioMediaStreamTrackRendererInternalUnitManager)
+        m_audioMediaStreamTrackRendererInternalUnitManager = makeUnique<AudioMediaStreamTrackRendererInternalUnitManager>();
+    return *m_audioMediaStreamTrackRendererInternalUnitManager;
+}
+#endif
+
 #endif // ENABLE(GPU_PROCESS)
 
 #if ENABLE(WEB_AUTHN)

Modified: trunk/Source/WebKit/WebProcess/WebProcess.h (277851 => 277852)


--- trunk/Source/WebKit/WebProcess/WebProcess.h	2021-05-21 09:31:51 UTC (rev 277851)
+++ trunk/Source/WebKit/WebProcess/WebProcess.h	2021-05-21 09:53:36 UTC (rev 277852)
@@ -109,6 +109,7 @@
 
 namespace WebKit {
 
+class AudioMediaStreamTrackRendererInternalUnitManager;
 class EventDispatcher;
 class GamepadData;
 class GPUProcessConnection;
@@ -245,6 +246,9 @@
 #if PLATFORM(COCOA) && USE(LIBWEBRTC)
     LibWebRTCCodecs& libWebRTCCodecs();
 #endif
+#if ENABLE(MEDIA_STREAM) && PLATFORM(COCOA)
+    AudioMediaStreamTrackRendererInternalUnitManager& audioMediaStreamTrackRendererInternalUnitManager();
+#endif
 #if ENABLE(LEGACY_ENCRYPTED_MEDIA)
     RemoteLegacyCDMFactory& legacyCDMFactory();
 #endif
@@ -640,7 +644,10 @@
 #if PLATFORM(COCOA) && USE(LIBWEBRTC)
     RefPtr<LibWebRTCCodecs> m_libWebRTCCodecs;
 #endif
+#if ENABLE(MEDIA_STREAM) && PLATFORM(COCOA)
+    std::unique_ptr<AudioMediaStreamTrackRendererInternalUnitManager> m_audioMediaStreamTrackRendererInternalUnitManager;
 #endif
+#endif
 
 #if ENABLE(WEB_AUTHN)
     RefPtr<WebAuthnProcessConnection> m_webAuthnProcessConnection;

Modified: trunk/Source/WebKit/WebProcess/cocoa/UserMediaCaptureManager.cpp (277851 => 277852)


--- trunk/Source/WebKit/WebProcess/cocoa/UserMediaCaptureManager.cpp	2021-05-21 09:31:51 UTC (rev 277851)
+++ trunk/Source/WebKit/WebProcess/cocoa/UserMediaCaptureManager.cpp	2021-05-21 09:53:36 UTC (rev 277852)
@@ -28,7 +28,7 @@
 
 #if PLATFORM(COCOA) && ENABLE(MEDIA_STREAM)
 
-#include "AudioMediaStreamTrackRenderer.h"
+#include "AudioMediaStreamTrackRendererInternalUnitManager.h"
 #include "GPUProcessConnection.h"
 #include "RemoteRealtimeAudioSource.h"
 #include "RemoteRealtimeVideoSource.h"
@@ -35,6 +35,7 @@
 #include "UserMediaCaptureManagerMessages.h"
 #include "WebCoreArgumentCoders.h"
 #include "WebProcess.h"
+#include <WebCore/AudioMediaStreamTrackRendererUnit.h>
 #include <WebCore/DeprecatedGlobalSettings.h>
 #include <WebCore/MockRealtimeMediaSourceCenter.h>
 #include <WebCore/RealtimeMediaSourceCenter.h>
@@ -77,8 +78,11 @@
     m_audioFactory.setShouldCaptureInGPUProcess(shouldCaptureAudioInGPUProcess);
     m_videoFactory.setShouldCaptureInGPUProcess(shouldCaptureVideoInGPUProcess);
 
-    if (shouldCaptureAudioInGPUProcess)
-        AudioMediaStreamTrackRenderer::setCreator(WebKit::AudioMediaStreamTrackRenderer::create);
+    if (shouldCaptureAudioInGPUProcess) {
+        WebCore::AudioMediaStreamTrackRendererUnit::setCreateInternalUnitFunction([](auto&& renderCallback) {
+            return WebProcess::singleton().audioMediaStreamTrackRendererInternalUnitManager().createRemoteInternalUnit(WTFMove(renderCallback));
+        });
+    }
 
     if (shouldCaptureAudioInUIProcess || shouldCaptureAudioInGPUProcess)
         RealtimeMediaSourceCenter::singleton().setAudioCaptureFactory(m_audioFactory);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to