Changeset 261626 in webkit


Ignore:
Timestamp:
May 13, 2020 11:02:09 AM (4 years ago)
Author:
youenn@apple.com
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:
  • platform/mediastream/mac/MockAudioSharedUnit.mm:

(WebCore::MockAudioSharedUnit::reconfigure):
Drive-by fix, we do not need to give the size in bytes but the size in samples.

Source/WebKit:

  • WebProcess/cocoa/RemoteCaptureSampleManager.cpp:

(WebKit::RemoteCaptureSampleManager::RemoteAudio::setStorage):
(WebKit::RemoteCaptureSampleManager::RemoteAudio::audioSamplesAvailable):

  • WebProcess/cocoa/RemoteCaptureSampleManager.h:
Location:
trunk/Source
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r261625 r261626  
     12020-05-13  Youenn Fablet  <youenn@apple.com>
     2
     3        Allow WebAudioBufferList to dynamically change its number of frames
     4        https://bugs.webkit.org/show_bug.cgi?id=211720
     5
     6        Reviewed by Eric Carlson.
     7
     8        We sometimes create WebAudioBufferList on the stack which triggers allocation of several vectors.
     9        Instead of doing that for every audio sample chunk, we should allocate the WebAudioBufferList and resize it as necessary.
     10        For that purpose, we introduce WebAudioBufferList::updateWithNumberOfFrames and use it in two places:
     11        - When creating an audio track into WebAudio.
     12        - When receiving audio chunks from another process.
     13        Covered by existing tests.
     14
     15        * Modules/webaudio/MediaStreamAudioSource.cpp:
     16        (WebCore::MediaStreamAudioSource::~MediaStreamAudioSource):
     17        * Modules/webaudio/MediaStreamAudioSource.h:
     18        * Modules/webaudio/MediaStreamAudioSourceCocoa.cpp:
     19        (WebCore::streamDescription):
     20        (WebCore::MediaStreamAudioSource::consumeAudio):
     21        * platform/audio/cocoa/WebAudioBufferList.cpp:
     22        (WebCore::WebAudioBufferList::WebAudioBufferList):
     23        (WebCore::WebAudioBufferList::updateWithNumberOfFrames):
     24        (WebCore::WebAudioBufferList::channelCount const):
     25        * platform/audio/cocoa/WebAudioBufferList.h:
     26        * platform/mediastream/mac/MockAudioSharedUnit.mm:
     27        (WebCore::MockAudioSharedUnit::reconfigure):
     28        Drive-by fix, we do not need to give the size in bytes but the size in samples.
     29
    1302020-05-13  Andres Gonzalez  <andresg_22@apple.com>
    231
  • trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSource.cpp

    r261566 r261626  
    3030
    3131#include "NotImplemented.h"
    32 #include <wtf/UUID.h>
     32#include "PlatformAudioData.h"
    3333
    3434namespace WebCore {
     
    3939    m_currentSettings.setSampleRate(sampleRate);
    4040}
     41
     42MediaStreamAudioSource::~MediaStreamAudioSource() = default;
    4143
    4244const RealtimeMediaSourceCapabilities& MediaStreamAudioSource::capabilities()
  • trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSource.h

    r261566 r261626  
    3636
    3737class AudioBus;
     38class PlatformAudioData;
    3839class RealtimeMediaSourceCapabilities;
    3940
     
    4243    static Ref<MediaStreamAudioSource> create(float sampleRate) { return adoptRef(*new MediaStreamAudioSource { sampleRate }); }
    4344
    44     ~MediaStreamAudioSource() = default;
     45    ~MediaStreamAudioSource();
    4546
    4647    const RealtimeMediaSourceCapabilities& capabilities() final;
     
    5960    String m_deviceId;
    6061    RealtimeMediaSourceSettings m_currentSettings;
     62    std::unique_ptr<PlatformAudioData> m_audioBuffer;
    6163#if USE(AVFOUNDATION)
    6264    size_t m_numberOfFrames { 0 };
  • trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSourceCocoa.cpp

    r261566 r261626  
    4242namespace WebCore {
    4343
    44 static inline AudioStreamBasicDescription streamDescription(size_t sampleRate, size_t channelCount)
     44static inline CAAudioStreamDescription streamDescription(size_t sampleRate, size_t channelCount)
    4545{
    4646    bool isFloat = true;
     
    7676    m_numberOfFrames += numberOfFrames;
    7777
    78     AudioStreamBasicDescription newDescription = streamDescription(m_currentSettings.sampleRate(), bus.numberOfChannels());
     78    auto* audioBuffer = m_audioBuffer ? &downcast<WebAudioBufferList>(*m_audioBuffer) : nullptr;
    7979
    80     // FIXME: We should do the memory allocation once in MediaStreamAudioSource and resize it according numberOfFrames.
    81     WebAudioBufferList audioBufferList { CAAudioStreamDescription(newDescription), WTF::safeCast<uint32_t>(numberOfFrames) };
     80    auto description = streamDescription(m_currentSettings.sampleRate(), bus.numberOfChannels());
     81    if (!audioBuffer || audioBuffer->channelCount() != bus.numberOfChannels()) {
     82        m_audioBuffer = makeUnique<WebAudioBufferList>(description, WTF::safeCast<uint32_t>(numberOfFrames));
     83        audioBuffer = &downcast<WebAudioBufferList>(*m_audioBuffer);
     84    } else
     85        audioBuffer->setSampleCount(numberOfFrames);
    8286
    8387    for (size_t cptr = 0; cptr < bus.numberOfChannels(); ++cptr)
    84         copyChannelData(*bus.channel(cptr), *audioBufferList.buffer(cptr), numberOfFrames, muted());
     88        copyChannelData(*bus.channel(cptr), *audioBuffer->buffer(cptr), numberOfFrames, muted());
    8589
    86     audioSamplesAvailable(mediaTime, audioBufferList, CAAudioStreamDescription(newDescription), numberOfFrames);
     90    audioSamplesAvailable(mediaTime, *m_audioBuffer, description, numberOfFrames);
    8791}
    8892
  • trunk/Source/WebCore/platform/audio/cocoa/WebAudioBufferList.cpp

    r261566 r261626  
    3434
    3535WebAudioBufferList::WebAudioBufferList(const CAAudioStreamDescription& format)
     36    : m_bytesPerFrame(format.bytesPerFrame())
     37    , m_channelCount(format.numberOfInterleavedChannels())
    3638{
    3739    // AudioBufferList is a variable-length struct, so create on the heap with a generic new() operator
    3840    // with a custom size, and initialize the struct manually.
    3941    uint32_t bufferCount = format.numberOfChannelStreams();
    40     uint32_t channelCount = format.numberOfInterleavedChannels();
    4142
    4243    uint64_t bufferListSize = offsetof(AudioBufferList, mBuffers) + (sizeof(AudioBuffer) * std::max(1U, bufferCount));
     
    4849    m_canonicalList->mNumberBuffers = bufferCount;
    4950    for (uint32_t buffer = 0; buffer < bufferCount; ++buffer)
    50         m_canonicalList->mBuffers[buffer].mNumberChannels = channelCount;
     51        m_canonicalList->mBuffers[buffer].mNumberChannels = m_channelCount;
    5152
    5253    reset();
     
    5657    : WebAudioBufferList(format)
    5758{
    58     if (!sampleCount)
     59    setSampleCount(sampleCount);
     60}
     61
     62void WebAudioBufferList::setSampleCount(uint32_t sampleCount)
     63{
     64    if (!sampleCount || m_sampleCount == sampleCount)
    5965        return;
    6066
    61     uint32_t bufferCount = format.numberOfChannelStreams();
    62     uint32_t channelCount = format.numberOfInterleavedChannels();
    63 
    64     size_t bytesPerBuffer = sampleCount * channelCount * format.bytesPerFrame();
    65     m_flatBuffer.reserveInitialCapacity(bufferCount * bytesPerBuffer);
    66     auto data = m_flatBuffer.data();
     67    m_sampleCount = sampleCount;
     68    size_t bytesPerBuffer = m_sampleCount * m_channelCount * m_bytesPerFrame;
     69    m_flatBuffer.resize(m_canonicalList->mNumberBuffers * bytesPerBuffer);
     70    auto* data = m_flatBuffer.data();
    6771
    6872    for (uint32_t buffer = 0; buffer < m_canonicalList->mNumberBuffers; ++buffer) {
     
    7882    : WebAudioBufferList(format)
    7983{
    80 
    8184    if (!sampleBuffer)
    8285        return;
  • trunk/Source/WebCore/platform/audio/cocoa/WebAudioBufferList.h

    r261566 r261626  
    4747
    4848    void reset();
     49    WEBCORE_EXPORT void setSampleCount(uint32_t);
    4950
    5051    AudioBufferList* list() const { return m_list.get(); }
     
    5253
    5354    uint32_t bufferCount() const;
     55    uint32_t channelCount() const { return m_channelCount; }
    5456    AudioBuffer* buffer(uint32_t index) const;
    5557    WTF::IteratorRange<AudioBuffer*> buffers() const;
     
    5961
    6062    size_t m_listBufferSize { 0 };
     63    uint32_t m_bytesPerFrame { 0 };
     64    uint32_t m_channelCount { 0 };
     65    uint32_t m_sampleCount { 0 };
    6166    std::unique_ptr<AudioBufferList> m_canonicalList;
    6267    std::unique_ptr<AudioBufferList> m_list;
  • trunk/Source/WebCore/platform/mediastream/mac/MockAudioSharedUnit.mm

    r254259 r261626  
    214214    FillOutASBDForLPCM(m_streamFormat, rate, channelCount, bitsPerByte * bytesPerFloat, bitsPerByte * bytesPerFloat, isFloat, isBigEndian, isNonInterleaved);
    215215
    216     m_audioBufferList = makeUnique<WebAudioBufferList>(m_streamFormat, m_streamFormat.mBytesPerFrame * m_maximiumFrameCount);
     216    m_audioBufferList = makeUnique<WebAudioBufferList>(m_streamFormat, m_maximiumFrameCount);
    217217
    218218    CMFormatDescriptionRef formatDescription;
  • trunk/Source/WebKit/ChangeLog

    r261624 r261626  
     12020-05-13  Youenn Fablet  <youenn@apple.com>
     2
     3        Allow WebAudioBufferList to dynamically change its number of frames
     4        https://bugs.webkit.org/show_bug.cgi?id=211720
     5
     6        Reviewed by Eric Carlson.
     7
     8        * WebProcess/cocoa/RemoteCaptureSampleManager.cpp:
     9        (WebKit::RemoteCaptureSampleManager::RemoteAudio::setStorage):
     10        (WebKit::RemoteCaptureSampleManager::RemoteAudio::audioSamplesAvailable):
     11        * WebProcess/cocoa/RemoteCaptureSampleManager.h:
     12
    1132020-05-13  Per Arne Vollan  <pvollan@apple.com>
    214
  • trunk/Source/WebKit/WebProcess/cocoa/RemoteCaptureSampleManager.cpp

    r261566 r261626  
    139139    storage.setReadOnly(true);
    140140    m_ringBuffer->allocate(description, numberOfFrames);
     141    m_buffer = makeUnique<WebAudioBufferList>(description, numberOfFrames);
    141142}
    142143
    143144void RemoteCaptureSampleManager::RemoteAudio::audioSamplesAvailable(MediaTime time, uint64_t numberOfFrames, uint64_t startFrame, uint64_t endFrame)
    144145{
    145     // FIXME: We should allocate this buffer once and resize it as needed.
    146     WebAudioBufferList audioData(m_description, numberOfFrames);
     146    m_buffer->setSampleCount(numberOfFrames);
    147147
    148148    m_ringBuffer->setCurrentFrameBounds(startFrame, endFrame);
    149     m_ringBuffer->fetch(audioData.list(), numberOfFrames, time.timeValue());
     149    m_ringBuffer->fetch(m_buffer->list(), numberOfFrames, time.timeValue());
    150150
    151     m_source->remoteAudioSamplesAvailable(time, audioData, m_description, numberOfFrames);
     151    m_source->remoteAudioSamplesAvailable(time, *m_buffer, m_description, numberOfFrames);
    152152}
    153153
  • trunk/Source/WebKit/WebProcess/cocoa/RemoteCaptureSampleManager.h

    r261566 r261626  
    3434#include <WebCore/CAAudioStreamDescription.h>
    3535#include <WebCore/CARingBuffer.h>
     36#include <WebCore/WebAudioBufferList.h>
    3637#include <wtf/HashMap.h>
    3738#include <wtf/WorkQueue.h>
     
    7273        WebCore::CAAudioStreamDescription m_description;
    7374        std::unique_ptr<WebCore::CARingBuffer> m_ringBuffer;
     75        std::unique_ptr<WebCore::WebAudioBufferList> m_buffer;
    7476    };
    7577
Note: See TracChangeset for help on using the changeset viewer.