Title: [284674] trunk/Source
Revision
284674
Author
[email protected]
Date
2021-10-22 01:44:57 -0700 (Fri, 22 Oct 2021)

Log Message

Audio over peer connection becomes latent when changing the output
https://bugs.webkit.org/show_bug.cgi?id=231110
<rdar://problem/84049005>

Reviewed by Eric Carlson.

Source/WebCore:

Add support for detecting change of timeline by looking at sample times. This happens when changing audio output.
Make AudioMediaStreamTrackRendererInternalUnit call a callback to let the unit deal with it.
When switching output, audio data is kept growing but is not read for some time by the remote unit, even though the remote unit is running.
The unit can ask its sources to update their offset to not keep extra buffered data.

Manually tested.

* platform/audio/cocoa/AudioSampleDataSource.h:
* platform/mediastream/cocoa/AudioMediaStreamTrackRendererCocoa.cpp:
* platform/mediastream/cocoa/AudioMediaStreamTrackRendererCocoa.h:
* platform/mediastream/cocoa/AudioMediaStreamTrackRendererInternalUnit.cpp:
* platform/mediastream/cocoa/AudioMediaStreamTrackRendererInternalUnit.h:
* platform/mediastream/cocoa/AudioMediaStreamTrackRendererUnit.cpp:
* platform/mediastream/cocoa/AudioMediaStreamTrackRendererUnit.h:

Source/WebKit:

When detecting an audio timeline change, send it from GPUProcess to WebProcess.
Let the WebProcess reset the sources to properly restart.

* GPUProcess/webrtc/RemoteAudioMediaStreamTrackRendererInternalUnitManager.cpp:
* WebProcess/GPU/GPUProcessConnection.cpp:
* WebProcess/GPU/GPUProcessConnection.h:
* WebProcess/GPU/GPUProcessConnection.messages.in:
* WebProcess/GPU/webrtc/AudioMediaStreamTrackRendererInternalUnitManager.cpp:
* WebProcess/GPU/webrtc/AudioMediaStreamTrackRendererInternalUnitManager.h:
* WebProcess/WebProcess.cpp:
* WebProcess/cocoa/UserMediaCaptureManager.cpp:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (284673 => 284674)


--- trunk/Source/WebCore/ChangeLog	2021-10-22 08:44:02 UTC (rev 284673)
+++ trunk/Source/WebCore/ChangeLog	2021-10-22 08:44:57 UTC (rev 284674)
@@ -1,3 +1,26 @@
+2021-10-22  Youenn Fablet  <[email protected]>
+
+        Audio over peer connection becomes latent when changing the output
+        https://bugs.webkit.org/show_bug.cgi?id=231110
+        <rdar://problem/84049005>
+
+        Reviewed by Eric Carlson.
+
+        Add support for detecting change of timeline by looking at sample times. This happens when changing audio output.
+        Make AudioMediaStreamTrackRendererInternalUnit call a callback to let the unit deal with it.
+        When switching output, audio data is kept growing but is not read for some time by the remote unit, even though the remote unit is running.
+        The unit can ask its sources to update their offset to not keep extra buffered data.
+
+        Manually tested.
+
+        * platform/audio/cocoa/AudioSampleDataSource.h:
+        * platform/mediastream/cocoa/AudioMediaStreamTrackRendererCocoa.cpp:
+        * platform/mediastream/cocoa/AudioMediaStreamTrackRendererCocoa.h:
+        * platform/mediastream/cocoa/AudioMediaStreamTrackRendererInternalUnit.cpp:
+        * platform/mediastream/cocoa/AudioMediaStreamTrackRendererInternalUnit.h:
+        * platform/mediastream/cocoa/AudioMediaStreamTrackRendererUnit.cpp:
+        * platform/mediastream/cocoa/AudioMediaStreamTrackRendererUnit.h:
+
 2021-10-22  Antti Koivisto  <[email protected]>
 
         Remove Style::Resolver::m_isDeleted

Modified: trunk/Source/WebCore/platform/audio/cocoa/AudioSampleDataSource.h (284673 => 284674)


--- trunk/Source/WebCore/platform/audio/cocoa/AudioSampleDataSource.h	2021-10-22 08:44:02 UTC (rev 284673)
+++ trunk/Source/WebCore/platform/audio/cocoa/AudioSampleDataSource.h	2021-10-22 08:44:57 UTC (rev 284674)
@@ -70,6 +70,8 @@
 
     const CAAudioStreamDescription* inputDescription() const { return m_inputDescription ? &m_inputDescription.value() : nullptr; }
 
+    void recomputeSampleOffset() { m_shouldComputeOutputSampleOffset = true; }
+
 #if !RELEASE_LOG_DISABLED
     const Logger& logger() const final { return m_logger; }
     const void* logIdentifier() const final { return m_logIdentifier; }

Modified: trunk/Source/WebCore/platform/audio/cocoa/AudioSampleDataSource.mm (284673 => 284674)


--- trunk/Source/WebCore/platform/audio/cocoa/AudioSampleDataSource.mm	2021-10-22 08:44:02 UTC (rev 284673)
+++ trunk/Source/WebCore/platform/audio/cocoa/AudioSampleDataSource.mm	2021-10-22 08:44:57 UTC (rev 284674)
@@ -234,7 +234,8 @@
     if (m_shouldComputeOutputSampleOffset) {
         uint64_t buffered = endFrame - startFrame;
         if (m_isFirstPull) {
-            if (buffered >= m_waitToStartForPushCount * m_lastPushedSampleCount) {
+            auto minimumBuffer = m_waitToStartForPushCount * m_lastPushedSampleCount;
+            if (buffered >= minimumBuffer) {
                 m_outputSampleOffset = startFrame - timeStamp;
                 m_shouldComputeOutputSampleOffset = false;
                 m_endFrameWhenNotEnoughData = 0;

Modified: trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererCocoa.cpp (284673 => 284674)


--- trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererCocoa.cpp	2021-10-22 08:44:02 UTC (rev 284673)
+++ trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererCocoa.cpp	2021-10-22 08:44:57 UTC (rev 284674)
@@ -36,7 +36,10 @@
 
 namespace WebCore {
 
-AudioMediaStreamTrackRendererCocoa::AudioMediaStreamTrackRendererCocoa() = default;
+AudioMediaStreamTrackRendererCocoa::AudioMediaStreamTrackRendererCocoa()
+    : m_resetObserver([this] { reset(); })
+{
+}
 
 AudioMediaStreamTrackRendererCocoa::~AudioMediaStreamTrackRendererCocoa() = default;
 
@@ -72,11 +75,17 @@
         m_dataSource->setVolume(volume);
 }
 
+void AudioMediaStreamTrackRendererCocoa::reset()
+{
+    if (m_dataSource)
+        m_dataSource->recomputeSampleOffset();
+}
+
 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;
+    m_shouldRecreateDataSource = true;
 }
 
 static unsigned pollSamplesCount()
@@ -92,7 +101,7 @@
 {
     ASSERT(!isMainThread());
     ASSERT(description.platformDescription().type == PlatformDescription::CAAudioStreamBasicType);
-    if (!m_dataSource || m_shouldReset || !m_dataSource->inputDescription() || *m_dataSource->inputDescription() != description) {
+    if (!m_dataSource || m_shouldRecreateDataSource || !m_dataSource->inputDescription() || *m_dataSource->inputDescription() != description) {
         DisableMallocRestrictionsForCurrentThreadScope scope;
 
         // FIXME: For non libwebrtc sources, we can probably reduce poll samples count to 2.
@@ -120,10 +129,11 @@
                 AudioMediaStreamTrackRendererUnit::singleton().removeSource(*oldSource);
 
             newSource->setVolume(volume());
+            AudioMediaStreamTrackRendererUnit::singleton().addResetObserver(m_resetObserver);
             AudioMediaStreamTrackRendererUnit::singleton().addSource(WTFMove(newSource));
         });
         m_dataSource = WTFMove(dataSource);
-        m_shouldReset = false;
+        m_shouldRecreateDataSource = false;
     }
 
     m_dataSource->pushSamples(sampleTime, audioData, sampleCount);

Modified: trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererCocoa.h (284673 => 284674)


--- trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererCocoa.h	2021-10-22 08:44:02 UTC (rev 284673)
+++ trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererCocoa.h	2021-10-22 08:44:57 UTC (rev 284674)
@@ -28,6 +28,7 @@
 #if ENABLE(MEDIA_STREAM)
 
 #include "AudioMediaStreamTrackRenderer.h"
+#include "AudioMediaStreamTrackRendererUnit.h"
 #include "Logging.h"
 #include <wtf/WeakPtr.h>
 
@@ -55,9 +56,12 @@
     void setVolume(float) final;
     void setAudioOutputDevice(const String&) final;
 
+    void reset();
+
     std::unique_ptr<CAAudioStreamDescription> m_outputDescription;
     RefPtr<AudioSampleDataSource> m_dataSource;
-    bool m_shouldReset { false };
+    bool m_shouldRecreateDataSource { false };
+    WebCore::AudioMediaStreamTrackRendererUnit::ResetObserver m_resetObserver;
 };
 
 }

Modified: trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererInternalUnit.cpp (284673 => 284674)


--- trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererInternalUnit.cpp	2021-10-22 08:44:02 UTC (rev 284673)
+++ trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererInternalUnit.cpp	2021-10-22 08:44:57 UTC (rev 284674)
@@ -50,7 +50,7 @@
 class LocalAudioMediaStreamTrackRendererInternalUnit final : public AudioMediaStreamTrackRendererInternalUnit {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    explicit LocalAudioMediaStreamTrackRendererInternalUnit(RenderCallback&&);
+    LocalAudioMediaStreamTrackRendererInternalUnit(RenderCallback&&, ResetCallback&&);
 
 private:
     void createAudioUnitIfNeeded();
@@ -61,24 +61,28 @@
     void retrieveFormatDescription(CompletionHandler<void(const CAAudioStreamDescription*)>&&) final;
     void setAudioOutputDevice(const String&) final;
 
+    OSStatus render(AudioUnitRenderActionFlags*, const AudioTimeStamp*, UInt32 sampleCount, AudioBufferList*);
     static OSStatus renderingCallback(void*, AudioUnitRenderActionFlags*, const AudioTimeStamp*, UInt32 inBusNumber, UInt32 sampleCount, AudioBufferList*);
 
     RenderCallback m_renderCallback;
+    ResetCallback m_resetCallback;
     std::unique_ptr<CAAudioStreamDescription> m_outputDescription;
     AudioComponentInstance m_remoteIOUnit { nullptr };
     bool m_isStarted { false };
+    uint64_t m_sampleTime { 0 };
 #if PLATFORM(MAC)
     uint32_t m_deviceID { 0 };
 #endif
 };
 
-UniqueRef<AudioMediaStreamTrackRendererInternalUnit> AudioMediaStreamTrackRendererInternalUnit::createLocalInternalUnit(RenderCallback&& renderCallback)
+UniqueRef<AudioMediaStreamTrackRendererInternalUnit> AudioMediaStreamTrackRendererInternalUnit::createLocalInternalUnit(RenderCallback&& renderCallback, ResetCallback&& resetCallback)
 {
-    return makeUniqueRef<LocalAudioMediaStreamTrackRendererInternalUnit>(WTFMove(renderCallback));
+    return makeUniqueRef<LocalAudioMediaStreamTrackRendererInternalUnit>(WTFMove(renderCallback), WTFMove(resetCallback));
 }
 
-LocalAudioMediaStreamTrackRendererInternalUnit::LocalAudioMediaStreamTrackRendererInternalUnit(RenderCallback&& renderCallback)
+LocalAudioMediaStreamTrackRendererInternalUnit::LocalAudioMediaStreamTrackRendererInternalUnit(RenderCallback&& renderCallback, ResetCallback&& resetCallback)
     : m_renderCallback(WTFMove(renderCallback))
+    , m_resetCallback(WTFMove(resetCallback))
 {
 }
 
@@ -125,6 +129,7 @@
     if (!m_remoteIOUnit)
         return;
 
+    m_sampleTime = 0;
     if (auto error = PAL::AudioOutputUnitStart(m_remoteIOUnit)) {
         RELEASE_LOG_ERROR(WebRTC, "AudioMediaStreamTrackRendererInternalUnit::start AudioOutputUnitStart failed, error = %d", error);
         PAL::AudioComponentInstanceDispose(m_remoteIOUnit);
@@ -230,9 +235,20 @@
     m_remoteIOUnit = remoteIOUnit;
 }
 
+OSStatus LocalAudioMediaStreamTrackRendererInternalUnit::render(AudioUnitRenderActionFlags* actionFlags, const AudioTimeStamp* timeStamp, UInt32 sampleCount, AudioBufferList* ioData)
+{
+    auto sampleTime = timeStamp->mSampleTime;
+    // If we observe an irregularity in the timeline, we trigger a reset.
+    if (m_sampleTime && (m_sampleTime + 2 * sampleCount < sampleTime || sampleTime <= m_sampleTime))
+        m_resetCallback();
+    m_sampleTime = sampleTime < std::numeric_limits<Float64>::max() - sampleCount ? sampleTime : 0;
+
+    return m_renderCallback(sampleCount, *ioData, sampleTime, timeStamp->mHostTime, *actionFlags);
+}
+
 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);
+    return static_cast<LocalAudioMediaStreamTrackRendererInternalUnit*>(processor)->render(actionFlags, timeStamp, sampleCount, ioData);
 }
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererInternalUnit.h (284673 => 284674)


--- trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererInternalUnit.h	2021-10-22 08:44:02 UTC (rev 284673)
+++ trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererInternalUnit.h	2021-10-22 08:44:57 UTC (rev 284674)
@@ -40,7 +40,8 @@
     virtual ~AudioMediaStreamTrackRendererInternalUnit() = default;
 
     using RenderCallback = Function<OSStatus(size_t sampleCount, AudioBufferList&, uint64_t sampleTime, double hostTime, AudioUnitRenderActionFlags&)>;
-    WEBCORE_EXPORT static UniqueRef<AudioMediaStreamTrackRendererInternalUnit> createLocalInternalUnit(RenderCallback&&);
+    using ResetCallback = Function<void()>;
+    WEBCORE_EXPORT static UniqueRef<AudioMediaStreamTrackRendererInternalUnit> createLocalInternalUnit(RenderCallback&&, ResetCallback&&);
 
     virtual void start() = 0;
     virtual void stop() = 0;

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


--- trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererUnit.cpp	2021-10-22 08:44:02 UTC (rev 284673)
+++ trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererUnit.cpp	2021-10-22 08:44:57 UTC (rev 284674)
@@ -46,16 +46,17 @@
 
 static UniqueRef<AudioMediaStreamTrackRendererInternalUnit> createInternalUnit(AudioMediaStreamTrackRendererUnit& unit)
 {
-    AudioMediaStreamTrackRendererInternalUnit::RenderCallback callback = [&unit](auto sampleCount, auto& list, auto sampleTime, auto hostTime, auto& flags) {
+    AudioMediaStreamTrackRendererInternalUnit::RenderCallback renderCallback = [&unit](auto sampleCount, auto& list, auto sampleTime, auto hostTime, auto& flags) {
         unit.render(sampleCount, list, sampleTime, hostTime, flags);
         return 0;
     };
+    AudioMediaStreamTrackRendererInternalUnit::ResetCallback startCallback = [&unit]() { unit.reset(); };
 
     auto& function = getCreateInternalUnitFunction();
     if (function)
-        return function(WTFMove(callback));
+        return function(WTFMove(renderCallback), WTFMove(startCallback));
 
-    return AudioMediaStreamTrackRendererInternalUnit::createLocalInternalUnit(WTFMove(callback));
+    return AudioMediaStreamTrackRendererInternalUnit::createLocalInternalUnit(WTFMove(renderCallback), WTFMove(startCallback));
 }
 
 AudioMediaStreamTrackRendererUnit& AudioMediaStreamTrackRendererUnit::singleton()
@@ -137,6 +138,16 @@
     m_internalUnit->stop();
 }
 
+void AudioMediaStreamTrackRendererUnit::reset()
+{
+    RELEASE_LOG(WebRTC, "AudioMediaStreamTrackRendererUnit::reset");
+    ASSERT(isMainThread());
+
+    m_resetObservers.forEach([](auto& observer) {
+        observer();
+    });
+}
+
 void AudioMediaStreamTrackRendererUnit::retrieveFormatDescription(CompletionHandler<void(const CAAudioStreamDescription*)>&& callback)
 {
     ASSERT(isMainThread());

Modified: trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererUnit.h (284673 => 284674)


--- trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererUnit.h	2021-10-22 08:44:02 UTC (rev 284673)
+++ trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererUnit.h	2021-10-22 08:44:57 UTC (rev 284674)
@@ -31,8 +31,10 @@
 #include <wtf/Forward.h>
 #include <wtf/HashSet.h>
 #include <wtf/Lock.h>
+#include <wtf/Observer.h>
 #include <wtf/UniqueRef.h>
 #include <wtf/Vector.h>
+#include <wtf/WeakHashSet.h>
 
 namespace WebCore {
 
@@ -48,10 +50,11 @@
     AudioMediaStreamTrackRendererUnit();
     ~AudioMediaStreamTrackRendererUnit();
 
-    using CreateInternalUnitFunction = Function<UniqueRef<AudioMediaStreamTrackRendererInternalUnit>(AudioMediaStreamTrackRendererInternalUnit::RenderCallback&&)>;
+    using CreateInternalUnitFunction = Function<UniqueRef<AudioMediaStreamTrackRendererInternalUnit>(AudioMediaStreamTrackRendererInternalUnit::RenderCallback&&, AudioMediaStreamTrackRendererInternalUnit::ResetCallback&&)>;
     WEBCORE_EXPORT static void setCreateInternalUnitFunction(CreateInternalUnitFunction&&);
 
     WEBCORE_EXPORT void render(size_t sampleCount, AudioBufferList&, uint64_t sampleTime, double hostTime, AudioUnitRenderActionFlags&);
+    void reset();
 
     void setAudioOutputDevice(const String&);
 
@@ -58,6 +61,8 @@
     void addSource(Ref<AudioSampleDataSource>&&);
     void removeSource(AudioSampleDataSource&);
 
+    using ResetObserver = Observer<void()>;
+    void addResetObserver(ResetObserver& observer) { m_resetObservers.add(observer); }
     void retrieveFormatDescription(CompletionHandler<void(const CAAudioStreamDescription*)>&&);
 
 private:
@@ -73,6 +78,7 @@
     bool m_hasPendingRenderSources WTF_GUARDED_BY_LOCK(m_pendingRenderSourcesLock) { false };
     Lock m_pendingRenderSourcesLock;
     UniqueRef<AudioMediaStreamTrackRendererInternalUnit> m_internalUnit;
+    WeakHashSet<ResetObserver> m_resetObservers;
 };
 
 }

Modified: trunk/Source/WebKit/ChangeLog (284673 => 284674)


--- trunk/Source/WebKit/ChangeLog	2021-10-22 08:44:02 UTC (rev 284673)
+++ trunk/Source/WebKit/ChangeLog	2021-10-22 08:44:57 UTC (rev 284674)
@@ -1,3 +1,23 @@
+2021-10-22  Youenn Fablet  <[email protected]>
+
+        Audio over peer connection becomes latent when changing the output
+        https://bugs.webkit.org/show_bug.cgi?id=231110
+        <rdar://problem/84049005>
+
+        Reviewed by Eric Carlson.
+
+        When detecting an audio timeline change, send it from GPUProcess to WebProcess.
+        Let the WebProcess reset the sources to properly restart.
+
+        * GPUProcess/webrtc/RemoteAudioMediaStreamTrackRendererInternalUnitManager.cpp:
+        * WebProcess/GPU/GPUProcessConnection.cpp:
+        * WebProcess/GPU/GPUProcessConnection.h:
+        * WebProcess/GPU/GPUProcessConnection.messages.in:
+        * WebProcess/GPU/webrtc/AudioMediaStreamTrackRendererInternalUnitManager.cpp:
+        * WebProcess/GPU/webrtc/AudioMediaStreamTrackRendererInternalUnitManager.h:
+        * WebProcess/WebProcess.cpp:
+        * WebProcess/cocoa/UserMediaCaptureManager.cpp:
+
 2021-10-22  Kimmo Kinnunen  <[email protected]>
 
         StreamConnectionWorkQueue is not thread-safe

Modified: trunk/Source/WebKit/GPUProcess/webrtc/RemoteAudioMediaStreamTrackRendererInternalUnitManager.cpp (284673 => 284674)


--- trunk/Source/WebKit/GPUProcess/webrtc/RemoteAudioMediaStreamTrackRendererInternalUnitManager.cpp	2021-10-22 08:44:02 UTC (rev 284673)
+++ trunk/Source/WebKit/GPUProcess/webrtc/RemoteAudioMediaStreamTrackRendererInternalUnitManager.cpp	2021-10-22 08:44:57 UTC (rev 284674)
@@ -57,6 +57,7 @@
     void stop();
     void setAudioOutputDevice(const String&);
     OSStatus render(size_t sampleCount, AudioBufferList&, uint64_t sampleTime, double hostTime, AudioUnitRenderActionFlags&);
+    void notifyReset();
 
 private:
     void storageChanged(SharedMemory*, const WebCore::CAAudioStreamDescription&, size_t);
@@ -123,10 +124,17 @@
     };
 }
 
+static WebCore::AudioMediaStreamTrackRendererInternalUnit::ResetCallback resetCallback(RemoteAudioMediaStreamTrackRendererInternalUnitManager::Unit& unit)
+{
+    return [&unit]() {
+        return unit.notifyReset();
+    };
+}
+
 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(WebCore::AudioMediaStreamTrackRendererInternalUnit::createLocalInternalUnit(renderCallback(*this), resetCallback(*this)))
 {
     m_localUnit->retrieveFormatDescription([weakThis = WeakPtr { *this }, this, callback = WTFMove(callback)](auto&& description) mutable {
         if (!weakThis || !description) {
@@ -144,6 +152,11 @@
     stop();
 }
 
+void RemoteAudioMediaStreamTrackRendererInternalUnitManager::Unit::notifyReset()
+{
+    m_connection->send(Messages::GPUProcessConnection::ResetAudioMediaStreamTrackRendererInternalUnit { m_identifier }, 0);
+}
+
 void RemoteAudioMediaStreamTrackRendererInternalUnitManager::Unit::start(const SharedMemory::Handle& handle, const WebCore::CAAudioStreamDescription& description, uint64_t numberOfFrames, IPC::Semaphore&& semaphore)
 {
     if (m_isPlaying)

Modified: trunk/Source/WebKit/WebProcess/GPU/GPUProcessConnection.cpp (284673 => 284674)


--- trunk/Source/WebKit/WebProcess/GPU/GPUProcessConnection.cpp	2021-10-22 08:44:02 UTC (rev 284673)
+++ trunk/Source/WebKit/WebProcess/GPU/GPUProcessConnection.cpp	2021-10-22 08:44:57 UTC (rev 284674)
@@ -28,6 +28,7 @@
 
 #if ENABLE(GPU_PROCESS)
 
+#include "AudioMediaStreamTrackRendererInternalUnitManager.h"
 #include "DataReference.h"
 #include "GPUConnectionToWebProcessMessages.h"
 #include "GPUProcessConnectionInitializationParameters.h"
@@ -152,6 +153,11 @@
         m_sampleBufferDisplayLayerManager = makeUnique<SampleBufferDisplayLayerManager>();
     return *m_sampleBufferDisplayLayerManager;
 }
+
+void GPUProcessConnection::resetAudioMediaStreamTrackRendererInternalUnit(AudioMediaStreamTrackRendererInternalUnitIdentifier identifier)
+{
+    WebProcess::singleton().audioMediaStreamTrackRendererInternalUnitManager().reset(identifier);
+}
 #endif
 
 RemoteMediaPlayerManager& GPUProcessConnection::mediaPlayerManager()

Modified: trunk/Source/WebKit/WebProcess/GPU/GPUProcessConnection.h (284673 => 284674)


--- trunk/Source/WebKit/WebProcess/GPU/GPUProcessConnection.h	2021-10-22 08:44:02 UTC (rev 284673)
+++ trunk/Source/WebKit/WebProcess/GPU/GPUProcessConnection.h	2021-10-22 08:44:57 UTC (rev 284674)
@@ -74,6 +74,7 @@
 #endif
 #if PLATFORM(COCOA) && ENABLE(MEDIA_STREAM)
     SampleBufferDisplayLayerManager& sampleBufferDisplayLayerManager();
+    void resetAudioMediaStreamTrackRendererInternalUnit(AudioMediaStreamTrackRendererInternalUnitIdentifier);
 #endif
 
     RemoteMediaPlayerManager& mediaPlayerManager();

Modified: trunk/Source/WebKit/WebProcess/GPU/GPUProcessConnection.messages.in (284673 => 284674)


--- trunk/Source/WebKit/WebProcess/GPU/GPUProcessConnection.messages.in	2021-10-22 08:44:02 UTC (rev 284673)
+++ trunk/Source/WebKit/WebProcess/GPU/GPUProcessConnection.messages.in	2021-10-22 08:44:57 UTC (rev 284674)
@@ -29,6 +29,9 @@
     BeginRoutingArbitrationWithCategory(enum:uint8_t WebCore::AudioSession::CategoryType category) -> (enum:uint8_t WebKit::AudioSessionRoutingArbitratorProxy::RoutingArbitrationError error, enum:bool WebKit::AudioSessionRoutingArbitratorProxy::DefaultRouteChanged defaultRouteChanged) Async
     EndRoutingArbitration();
 #endif
+#if ENABLE(MEDIA_STREAM) && PLATFORM(COCOA)
+    ResetAudioMediaStreamTrackRendererInternalUnit(WebKit::AudioMediaStreamTrackRendererInternalUnitIdentifier identifier)
+#endif
 }
 
 #endif // ENABLE(GPU_PROCESS)

Modified: trunk/Source/WebKit/WebProcess/GPU/webrtc/AudioMediaStreamTrackRendererInternalUnitManager.cpp (284673 => 284674)


--- trunk/Source/WebKit/WebProcess/GPU/webrtc/AudioMediaStreamTrackRendererInternalUnitManager.cpp	2021-10-22 08:44:02 UTC (rev 284673)
+++ trunk/Source/WebKit/WebProcess/GPU/webrtc/AudioMediaStreamTrackRendererInternalUnitManager.cpp	2021-10-22 08:44:57 UTC (rev 284674)
@@ -45,12 +45,13 @@
 class AudioMediaStreamTrackRendererInternalUnitManager::Proxy final : public WebCore::AudioMediaStreamTrackRendererInternalUnit, public CanMakeWeakPtr<Proxy> {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    explicit Proxy(WebCore::AudioMediaStreamTrackRendererInternalUnit::RenderCallback&&);
+    Proxy(WebCore::AudioMediaStreamTrackRendererInternalUnit::RenderCallback&&, WebCore::AudioMediaStreamTrackRendererInternalUnit::ResetCallback&&);
     ~Proxy();
 
     AudioMediaStreamTrackRendererInternalUnitIdentifier identifier() const { return m_identifier; }
 
-    void restartIfNeeded();
+    enum class IsClosed { No, Yes };
+    void reset(IsClosed);
 
 private:
     // AudioMediaStreamTrackRendererUnit::InternalUnit API.
@@ -67,6 +68,7 @@
     void createRemoteUnit();
 
     WebCore::AudioMediaStreamTrackRendererInternalUnit::RenderCallback m_renderCallback;
+    WebCore::AudioMediaStreamTrackRendererInternalUnit::ResetCallback m_resetCallback;
     AudioMediaStreamTrackRendererInternalUnitIdentifier m_identifier;
 
     Deque<CompletionHandler<void(const WebCore::CAAudioStreamDescription*)>> m_descriptionCallbacks;
@@ -97,19 +99,27 @@
     m_proxies.remove(proxy.identifier());
 }
 
-UniqueRef<WebCore::AudioMediaStreamTrackRendererInternalUnit> AudioMediaStreamTrackRendererInternalUnitManager::createRemoteInternalUnit(WebCore::AudioMediaStreamTrackRendererInternalUnit::RenderCallback&& callback)
+UniqueRef<WebCore::AudioMediaStreamTrackRendererInternalUnit> AudioMediaStreamTrackRendererInternalUnitManager::createRemoteInternalUnit(WebCore::AudioMediaStreamTrackRendererInternalUnit::RenderCallback&& renderCallback, WebCore::AudioMediaStreamTrackRendererInternalUnit::ResetCallback&& resetCallback)
 {
-    return makeUniqueRef<AudioMediaStreamTrackRendererInternalUnitManager::Proxy>(WTFMove(callback));
+    return makeUniqueRef<AudioMediaStreamTrackRendererInternalUnitManager::Proxy>(WTFMove(renderCallback), WTFMove(resetCallback));
 }
 
-void AudioMediaStreamTrackRendererInternalUnitManager::gpuProcessConnectionClosed()
+void AudioMediaStreamTrackRendererInternalUnitManager::reset(AudioMediaStreamTrackRendererInternalUnitIdentifier identifier)
 {
-    for (auto proxy : m_proxies.values())
-        proxy->restartIfNeeded();
+    if (auto proxy = m_proxies.get(identifier))
+        proxy->reset(Proxy::IsClosed::No);
 }
 
-AudioMediaStreamTrackRendererInternalUnitManager::Proxy::Proxy(WebCore::AudioMediaStreamTrackRendererInternalUnit::RenderCallback&& renderCallback)
+void AudioMediaStreamTrackRendererInternalUnitManager::restartAllUnits()
+{
+    auto proxies = std::exchange(m_proxies, { });
+    for (auto proxy : proxies.values())
+        proxy->reset(Proxy::IsClosed::Yes);
+}
+
+AudioMediaStreamTrackRendererInternalUnitManager::Proxy::Proxy(WebCore::AudioMediaStreamTrackRendererInternalUnit::RenderCallback&& renderCallback, WebCore::AudioMediaStreamTrackRendererInternalUnit::ResetCallback&& resetCallback)
     : m_renderCallback(WTFMove(renderCallback))
+    , m_resetCallback(WTFMove(resetCallback))
     , m_identifier(AudioMediaStreamTrackRendererInternalUnitIdentifier::generate())
 {
     WebProcess::singleton().audioMediaStreamTrackRendererInternalUnitManager().add(*this);
@@ -258,10 +268,11 @@
     m_thread = Thread::create("AudioMediaStreamTrackRendererInternalUnit thread", WTFMove(threadLoop), ThreadType::Audio, Thread::QOS::UserInteractive);
 }
 
-void AudioMediaStreamTrackRendererInternalUnitManager::Proxy::restartIfNeeded()
+void AudioMediaStreamTrackRendererInternalUnitManager::Proxy::reset(IsClosed isClosed)
 {
     stopThread();
-    m_didClose = true;
+    m_didClose = isClosed == IsClosed::Yes;
+    m_resetCallback();
     if (m_isPlaying)
         start();
 }

Modified: trunk/Source/WebKit/WebProcess/GPU/webrtc/AudioMediaStreamTrackRendererInternalUnitManager.h (284673 => 284674)


--- trunk/Source/WebKit/WebProcess/GPU/webrtc/AudioMediaStreamTrackRendererInternalUnitManager.h	2021-10-22 08:44:02 UTC (rev 284673)
+++ trunk/Source/WebKit/WebProcess/GPU/webrtc/AudioMediaStreamTrackRendererInternalUnitManager.h	2021-10-22 08:44:57 UTC (rev 284674)
@@ -47,13 +47,14 @@
 public:
     AudioMediaStreamTrackRendererInternalUnitManager() = default;
 
-    UniqueRef<WebCore::AudioMediaStreamTrackRendererInternalUnit> createRemoteInternalUnit(WebCore::AudioMediaStreamTrackRendererInternalUnit::RenderCallback&&);
+    UniqueRef<WebCore::AudioMediaStreamTrackRendererInternalUnit> createRemoteInternalUnit(WebCore::AudioMediaStreamTrackRendererInternalUnit::RenderCallback&&, WebCore::AudioMediaStreamTrackRendererInternalUnit::ResetCallback&&);
 
     class Proxy;
     void add(Proxy&);
     void remove(Proxy&);
 
-    void gpuProcessConnectionClosed();
+    void reset(AudioMediaStreamTrackRendererInternalUnitIdentifier);
+    void restartAllUnits();
 
 private:
     HashMap<AudioMediaStreamTrackRendererInternalUnitIdentifier, WeakPtr<Proxy>> m_proxies;

Modified: trunk/Source/WebKit/WebProcess/WebProcess.cpp (284673 => 284674)


--- trunk/Source/WebKit/WebProcess/WebProcess.cpp	2021-10-22 08:44:02 UTC (rev 284673)
+++ trunk/Source/WebKit/WebProcess/WebProcess.cpp	2021-10-22 08:44:57 UTC (rev 284674)
@@ -1310,7 +1310,7 @@
 
 #if ENABLE(MEDIA_STREAM) && PLATFORM(COCOA)
     if (m_audioMediaStreamTrackRendererInternalUnitManager)
-        m_audioMediaStreamTrackRendererInternalUnitManager->gpuProcessConnectionClosed();
+        m_audioMediaStreamTrackRendererInternalUnitManager->restartAllUnits();
 #endif
 }
 

Modified: trunk/Source/WebKit/WebProcess/cocoa/UserMediaCaptureManager.cpp (284673 => 284674)


--- trunk/Source/WebKit/WebProcess/cocoa/UserMediaCaptureManager.cpp	2021-10-22 08:44:02 UTC (rev 284673)
+++ trunk/Source/WebKit/WebProcess/cocoa/UserMediaCaptureManager.cpp	2021-10-22 08:44:57 UTC (rev 284674)
@@ -81,8 +81,8 @@
     m_videoFactory.setShouldCaptureInGPUProcess(shouldCaptureVideoInGPUProcess);
 
     if (shouldCaptureAudioInGPUProcess) {
-        WebCore::AudioMediaStreamTrackRendererUnit::setCreateInternalUnitFunction([](auto&& renderCallback) {
-            return WebProcess::singleton().audioMediaStreamTrackRendererInternalUnitManager().createRemoteInternalUnit(WTFMove(renderCallback));
+        WebCore::AudioMediaStreamTrackRendererUnit::setCreateInternalUnitFunction([](auto&& renderCallback, auto&& resetCallback) {
+            return WebProcess::singleton().audioMediaStreamTrackRendererInternalUnitManager().createRemoteInternalUnit(WTFMove(renderCallback), WTFMove(resetCallback));
         });
     }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to