Changeset 261557 in webkit


Ignore:
Timestamp:
May 12, 2020 9:45:31 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:

Source/WebKit:

  • WebProcess/cocoa/RemoteCaptureSampleManager.cpp:

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

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

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r261554 r261557  
     12020-05-12  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
    1272020-05-12  Carlos Garcia Campos  <cgarcia@igalia.com>
    228
  • trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSource.cpp

    r236877 r261557  
    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

    r258698 r261557  
    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

    r233829 r261557  
    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

    r235190 r261557  
    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    if (sampleCount)
     60        setSampleCount(sampleCount);
     61}
     62
     63void WebAudioBufferList::setSampleCount(uint32_t sampleCount)
     64{
     65    uint32_t bufferCount = m_canonicalList->mNumberBuffers;
     66    if (!bufferCount || m_sampleCount == sampleCount)
    5967        return;
    6068
    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);
     69    m_sampleCount = sampleCount;
     70    size_t bytesPerBuffer = m_sampleCount * m_channelCount * m_bytesPerFrame;
     71    m_flatBuffer.reserveCapacity(bufferCount * bytesPerBuffer);
    6672    auto data = m_flatBuffer.data();
    6773
     
    7884    : WebAudioBufferList(format)
    7985{
    80 
    8186    if (!sampleBuffer)
    8287        return;
  • trunk/Source/WebCore/platform/audio/cocoa/WebAudioBufferList.h

    r248762 r261557  
    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/WebKit/ChangeLog

    r261555 r261557  
     12020-05-12  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-12  Carlos Garcia Campos  <cgarcia@igalia.com>
    214
  • trunk/Source/WebKit/WebProcess/cocoa/RemoteCaptureSampleManager.cpp

    r261375 r261557  
    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

    r261375 r261557  
    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.