Title: [261557] trunk/Source
Revision
261557
Author
[email protected]
Date
2020-05-12 09:45:31 -0700 (Tue, 12 May 2020)

Log Message

Allow WebAudioBufferList to dynamically change its number of frames
https://bugs.webkit.org/show_bug.cgi?id=211720

Reviewed by Eric Carlson.

Source/WebCore:

We sometimes create WebAudioBufferList on the stack which triggers allocation of several vectors.
Instead of doing that for every audio sample chunk, we should allocate the WebAudioBufferList and resize it as necessary.
For that purpose, we introduce WebAudioBufferList::updateWithNumberOfFrames and use it in two places:
- When creating an audio track into WebAudio.
- When receiving audio chunks from another process.
Covered by existing tests.

* Modules/webaudio/MediaStreamAudioSource.cpp:
(WebCore::MediaStreamAudioSource::~MediaStreamAudioSource):
* Modules/webaudio/MediaStreamAudioSource.h:
* Modules/webaudio/MediaStreamAudioSourceCocoa.cpp:
(WebCore::streamDescription):
(WebCore::MediaStreamAudioSource::consumeAudio):
* platform/audio/cocoa/WebAudioBufferList.cpp:
(WebCore::WebAudioBufferList::WebAudioBufferList):
(WebCore::WebAudioBufferList::updateWithNumberOfFrames):
(WebCore::WebAudioBufferList::channelCount const):
* platform/audio/cocoa/WebAudioBufferList.h:

Source/WebKit:

* WebProcess/cocoa/RemoteCaptureSampleManager.cpp:
(WebKit::RemoteCaptureSampleManager::RemoteAudio::setStorage):
(WebKit::RemoteCaptureSampleManager::RemoteAudio::audioSamplesAvailable):
* WebProcess/cocoa/RemoteCaptureSampleManager.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (261556 => 261557)


--- trunk/Source/WebCore/ChangeLog	2020-05-12 16:12:21 UTC (rev 261556)
+++ trunk/Source/WebCore/ChangeLog	2020-05-12 16:45:31 UTC (rev 261557)
@@ -1,3 +1,29 @@
+2020-05-12  Youenn Fablet  <[email protected]>
+
+        Allow WebAudioBufferList to dynamically change its number of frames
+        https://bugs.webkit.org/show_bug.cgi?id=211720
+
+        Reviewed by Eric Carlson.
+
+        We sometimes create WebAudioBufferList on the stack which triggers allocation of several vectors.
+        Instead of doing that for every audio sample chunk, we should allocate the WebAudioBufferList and resize it as necessary.
+        For that purpose, we introduce WebAudioBufferList::updateWithNumberOfFrames and use it in two places:
+        - When creating an audio track into WebAudio.
+        - When receiving audio chunks from another process.
+        Covered by existing tests.
+
+        * Modules/webaudio/MediaStreamAudioSource.cpp:
+        (WebCore::MediaStreamAudioSource::~MediaStreamAudioSource):
+        * Modules/webaudio/MediaStreamAudioSource.h:
+        * Modules/webaudio/MediaStreamAudioSourceCocoa.cpp:
+        (WebCore::streamDescription):
+        (WebCore::MediaStreamAudioSource::consumeAudio):
+        * platform/audio/cocoa/WebAudioBufferList.cpp:
+        (WebCore::WebAudioBufferList::WebAudioBufferList):
+        (WebCore::WebAudioBufferList::updateWithNumberOfFrames):
+        (WebCore::WebAudioBufferList::channelCount const):
+        * platform/audio/cocoa/WebAudioBufferList.h:
+
 2020-05-12  Carlos Garcia Campos  <[email protected]>
 
         [GTK] Rework clipboard handling in preparation for GTK4

Modified: trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSource.cpp (261556 => 261557)


--- trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSource.cpp	2020-05-12 16:12:21 UTC (rev 261556)
+++ trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSource.cpp	2020-05-12 16:45:31 UTC (rev 261557)
@@ -29,7 +29,7 @@
 #if ENABLE(MEDIA_STREAM)
 
 #include "NotImplemented.h"
-#include <wtf/UUID.h>
+#include "PlatformAudioData.h"
 
 namespace WebCore {
 
@@ -39,6 +39,8 @@
     m_currentSettings.setSampleRate(sampleRate);
 }
 
+MediaStreamAudioSource::~MediaStreamAudioSource() = default;
+
 const RealtimeMediaSourceCapabilities& MediaStreamAudioSource::capabilities()
 {
     // FIXME: implement this.

Modified: trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSource.h (261556 => 261557)


--- trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSource.h	2020-05-12 16:12:21 UTC (rev 261556)
+++ trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSource.h	2020-05-12 16:45:31 UTC (rev 261557)
@@ -35,6 +35,7 @@
 namespace WebCore {
 
 class AudioBus;
+class PlatformAudioData;
 class RealtimeMediaSourceCapabilities;
 
 class MediaStreamAudioSource final : public RealtimeMediaSource {
@@ -41,7 +42,7 @@
 public:
     static Ref<MediaStreamAudioSource> create(float sampleRate) { return adoptRef(*new MediaStreamAudioSource { sampleRate }); }
 
-    ~MediaStreamAudioSource() = default;
+    ~MediaStreamAudioSource();
 
     const RealtimeMediaSourceCapabilities& capabilities() final;
     const RealtimeMediaSourceSettings& settings() final;
@@ -58,6 +59,7 @@
 
     String m_deviceId;
     RealtimeMediaSourceSettings m_currentSettings;
+    std::unique_ptr<PlatformAudioData> m_audioBuffer;
 #if USE(AVFOUNDATION)
     size_t m_numberOfFrames { 0 };
 #endif

Modified: trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSourceCocoa.cpp (261556 => 261557)


--- trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSourceCocoa.cpp	2020-05-12 16:12:21 UTC (rev 261556)
+++ trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSourceCocoa.cpp	2020-05-12 16:45:31 UTC (rev 261557)
@@ -41,7 +41,7 @@
 
 namespace WebCore {
 
-static inline AudioStreamBasicDescription streamDescription(size_t sampleRate, size_t channelCount)
+static inline CAAudioStreamDescription streamDescription(size_t sampleRate, size_t channelCount)
 {
     bool isFloat = true;
     bool isBigEndian = false;
@@ -75,15 +75,19 @@
     auto mediaTime = PAL::toMediaTime(startTime);
     m_numberOfFrames += numberOfFrames;
 
-    AudioStreamBasicDescription newDescription = streamDescription(m_currentSettings.sampleRate(), bus.numberOfChannels());
+    auto* audioBuffer = m_audioBuffer ? &downcast<WebAudioBufferList>(*m_audioBuffer) : nullptr;
 
-    // FIXME: We should do the memory allocation once in MediaStreamAudioSource and resize it according numberOfFrames.
-    WebAudioBufferList audioBufferList { CAAudioStreamDescription(newDescription), WTF::safeCast<uint32_t>(numberOfFrames) };
+    auto description = streamDescription(m_currentSettings.sampleRate(), bus.numberOfChannels());
+    if (!audioBuffer || audioBuffer->channelCount() != bus.numberOfChannels()) {
+        m_audioBuffer = makeUnique<WebAudioBufferList>(description, WTF::safeCast<uint32_t>(numberOfFrames));
+        audioBuffer = &downcast<WebAudioBufferList>(*m_audioBuffer);
+    } else
+        audioBuffer->setSampleCount(numberOfFrames);
 
     for (size_t cptr = 0; cptr < bus.numberOfChannels(); ++cptr)
-        copyChannelData(*bus.channel(cptr), *audioBufferList.buffer(cptr), numberOfFrames, muted());
+        copyChannelData(*bus.channel(cptr), *audioBuffer->buffer(cptr), numberOfFrames, muted());
 
-    audioSamplesAvailable(mediaTime, audioBufferList, CAAudioStreamDescription(newDescription), numberOfFrames);
+    audioSamplesAvailable(mediaTime, *m_audioBuffer, description, numberOfFrames);
 }
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/audio/cocoa/WebAudioBufferList.cpp (261556 => 261557)


--- trunk/Source/WebCore/platform/audio/cocoa/WebAudioBufferList.cpp	2020-05-12 16:12:21 UTC (rev 261556)
+++ trunk/Source/WebCore/platform/audio/cocoa/WebAudioBufferList.cpp	2020-05-12 16:45:31 UTC (rev 261557)
@@ -33,11 +33,12 @@
 using namespace PAL;
 
 WebAudioBufferList::WebAudioBufferList(const CAAudioStreamDescription& format)
+    : m_bytesPerFrame(format.bytesPerFrame())
+    , m_channelCount(format.numberOfInterleavedChannels())
 {
     // AudioBufferList is a variable-length struct, so create on the heap with a generic new() operator
     // with a custom size, and initialize the struct manually.
     uint32_t bufferCount = format.numberOfChannelStreams();
-    uint32_t channelCount = format.numberOfInterleavedChannels();
 
     uint64_t bufferListSize = offsetof(AudioBufferList, mBuffers) + (sizeof(AudioBuffer) * std::max(1U, bufferCount));
     ASSERT(bufferListSize <= SIZE_MAX);
@@ -47,7 +48,7 @@
     memset(m_canonicalList.get(), 0, m_listBufferSize);
     m_canonicalList->mNumberBuffers = bufferCount;
     for (uint32_t buffer = 0; buffer < bufferCount; ++buffer)
-        m_canonicalList->mBuffers[buffer].mNumberChannels = channelCount;
+        m_canonicalList->mBuffers[buffer].mNumberChannels = m_channelCount;
 
     reset();
 }
@@ -55,14 +56,19 @@
 WebAudioBufferList::WebAudioBufferList(const CAAudioStreamDescription& format, uint32_t sampleCount)
     : WebAudioBufferList(format)
 {
-    if (!sampleCount)
+    if (sampleCount)
+        setSampleCount(sampleCount);
+}
+
+void WebAudioBufferList::setSampleCount(uint32_t sampleCount)
+{
+    uint32_t bufferCount = m_canonicalList->mNumberBuffers;
+    if (!bufferCount || m_sampleCount == sampleCount)
         return;
 
-    uint32_t bufferCount = format.numberOfChannelStreams();
-    uint32_t channelCount = format.numberOfInterleavedChannels();
-
-    size_t bytesPerBuffer = sampleCount * channelCount * format.bytesPerFrame();
-    m_flatBuffer.reserveInitialCapacity(bufferCount * bytesPerBuffer);
+    m_sampleCount = sampleCount;
+    size_t bytesPerBuffer = m_sampleCount * m_channelCount * m_bytesPerFrame;
+    m_flatBuffer.reserveCapacity(bufferCount * bytesPerBuffer);
     auto data = ""
 
     for (uint32_t buffer = 0; buffer < m_canonicalList->mNumberBuffers; ++buffer) {
@@ -77,7 +83,6 @@
 WebAudioBufferList::WebAudioBufferList(const CAAudioStreamDescription& format, CMSampleBufferRef sampleBuffer)
     : WebAudioBufferList(format)
 {
-
     if (!sampleBuffer)
         return;
 

Modified: trunk/Source/WebCore/platform/audio/cocoa/WebAudioBufferList.h (261556 => 261557)


--- trunk/Source/WebCore/platform/audio/cocoa/WebAudioBufferList.h	2020-05-12 16:12:21 UTC (rev 261556)
+++ trunk/Source/WebCore/platform/audio/cocoa/WebAudioBufferList.h	2020-05-12 16:45:31 UTC (rev 261557)
@@ -46,11 +46,13 @@
     WebAudioBufferList(const CAAudioStreamDescription&, CMSampleBufferRef);
 
     void reset();
+    WEBCORE_EXPORT void setSampleCount(uint32_t);
 
     AudioBufferList* list() const { return m_list.get(); }
     operator AudioBufferList&() const { return *m_list; }
 
     uint32_t bufferCount() const;
+    uint32_t channelCount() const { return m_channelCount; }
     AudioBuffer* buffer(uint32_t index) const;
     WTF::IteratorRange<AudioBuffer*> buffers() const;
 
@@ -58,6 +60,9 @@
     Kind kind() const { return Kind::WebAudioBufferList; }
 
     size_t m_listBufferSize { 0 };
+    uint32_t m_bytesPerFrame { 0 };
+    uint32_t m_channelCount { 0 };
+    uint32_t m_sampleCount { 0 };
     std::unique_ptr<AudioBufferList> m_canonicalList;
     std::unique_ptr<AudioBufferList> m_list;
     RetainPtr<CMBlockBufferRef> m_blockBuffer;

Modified: trunk/Source/WebKit/ChangeLog (261556 => 261557)


--- trunk/Source/WebKit/ChangeLog	2020-05-12 16:12:21 UTC (rev 261556)
+++ trunk/Source/WebKit/ChangeLog	2020-05-12 16:45:31 UTC (rev 261557)
@@ -1,3 +1,15 @@
+2020-05-12  Youenn Fablet  <[email protected]>
+
+        Allow WebAudioBufferList to dynamically change its number of frames
+        https://bugs.webkit.org/show_bug.cgi?id=211720
+
+        Reviewed by Eric Carlson.
+
+        * WebProcess/cocoa/RemoteCaptureSampleManager.cpp:
+        (WebKit::RemoteCaptureSampleManager::RemoteAudio::setStorage):
+        (WebKit::RemoteCaptureSampleManager::RemoteAudio::audioSamplesAvailable):
+        * WebProcess/cocoa/RemoteCaptureSampleManager.h:
+
 2020-05-12  Carlos Garcia Campos  <[email protected]>
 
         [GTK4] Add support for clipboard operations

Modified: trunk/Source/WebKit/WebProcess/cocoa/RemoteCaptureSampleManager.cpp (261556 => 261557)


--- trunk/Source/WebKit/WebProcess/cocoa/RemoteCaptureSampleManager.cpp	2020-05-12 16:12:21 UTC (rev 261556)
+++ trunk/Source/WebKit/WebProcess/cocoa/RemoteCaptureSampleManager.cpp	2020-05-12 16:45:31 UTC (rev 261557)
@@ -138,17 +138,17 @@
     storage.setStorage(memory.releaseNonNull());
     storage.setReadOnly(true);
     m_ringBuffer->allocate(description, numberOfFrames);
+    m_buffer = makeUnique<WebAudioBufferList>(description, numberOfFrames);
 }
 
 void RemoteCaptureSampleManager::RemoteAudio::audioSamplesAvailable(MediaTime time, uint64_t numberOfFrames, uint64_t startFrame, uint64_t endFrame)
 {
-    // FIXME: We should allocate this buffer once and resize it as needed.
-    WebAudioBufferList audioData(m_description, numberOfFrames);
+    m_buffer->setSampleCount(numberOfFrames);
 
     m_ringBuffer->setCurrentFrameBounds(startFrame, endFrame);
-    m_ringBuffer->fetch(audioData.list(), numberOfFrames, time.timeValue());
+    m_ringBuffer->fetch(m_buffer->list(), numberOfFrames, time.timeValue());
 
-    m_source->remoteAudioSamplesAvailable(time, audioData, m_description, numberOfFrames);
+    m_source->remoteAudioSamplesAvailable(time, *m_buffer, m_description, numberOfFrames);
 }
 
 }

Modified: trunk/Source/WebKit/WebProcess/cocoa/RemoteCaptureSampleManager.h (261556 => 261557)


--- trunk/Source/WebKit/WebProcess/cocoa/RemoteCaptureSampleManager.h	2020-05-12 16:12:21 UTC (rev 261556)
+++ trunk/Source/WebKit/WebProcess/cocoa/RemoteCaptureSampleManager.h	2020-05-12 16:45:31 UTC (rev 261557)
@@ -33,6 +33,7 @@
 #include "SharedMemory.h"
 #include <WebCore/CAAudioStreamDescription.h>
 #include <WebCore/CARingBuffer.h>
+#include <WebCore/WebAudioBufferList.h>
 #include <wtf/HashMap.h>
 #include <wtf/WorkQueue.h>
 
@@ -71,6 +72,7 @@
         Ref<RemoteRealtimeMediaSource> m_source;
         WebCore::CAAudioStreamDescription m_description;
         std::unique_ptr<WebCore::CARingBuffer> m_ringBuffer;
+        std::unique_ptr<WebCore::WebAudioBufferList> m_buffer;
     };
 
     Ref<WorkQueue> m_queue;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to