- Revision
- 215624
- Author
- [email protected]
- Date
- 2017-04-21 12:22:47 -0700 (Fri, 21 Apr 2017)
Log Message
Make AudioSampleBufferList::reset() less expensive.
https://bugs.webkit.org/show_bug.cgi?id=171124
Reviewed by Eric Carlson.
Previously, AudioSampleBufferList would reallocate its constituent WebAudioBufferList every time reset() was
called. Instead, add a reset() method to WebAudioBufferList which re-initializes its AudioBufferList (which is a
simple memcpy of a 24-byte struct), reusing the existing memory buffers.
While making these changes, we'll also take the opportunity to clean up the AudioSampleBufferList class by
making some of its members into UniqueRefs instead of unique_ptrs, thus removing the possibility of null-
dereferences.
* platform/audio/WebAudioBufferList.cpp:
(WebCore::WebAudioBufferList::WebAudioBufferList):
(WebCore::WebAudioBufferList::reset):
* platform/audio/WebAudioBufferList.h:
* platform/audio/mac/AudioSampleBufferList.cpp:
(WebCore::AudioSampleBufferList::AudioSampleBufferList):
(WebCore::AudioSampleBufferList::applyGain):
(WebCore::AudioSampleBufferList::mixFrom):
(WebCore::AudioSampleBufferList::reset):
(WebCore::AudioSampleBufferList::zero):
(WebCore::AudioSampleBufferList::~AudioSampleBufferList): Deleted.
* platform/audio/mac/AudioSampleBufferList.h:
(WebCore::AudioSampleBufferList::bufferList):
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (215623 => 215624)
--- trunk/Source/WebCore/ChangeLog 2017-04-21 19:04:56 UTC (rev 215623)
+++ trunk/Source/WebCore/ChangeLog 2017-04-21 19:22:47 UTC (rev 215624)
@@ -1,5 +1,34 @@
2017-04-21 Jer Noble <[email protected]>
+ Make AudioSampleBufferList::reset() less expensive.
+ https://bugs.webkit.org/show_bug.cgi?id=171124
+
+ Reviewed by Eric Carlson.
+
+ Previously, AudioSampleBufferList would reallocate its constituent WebAudioBufferList every time reset() was
+ called. Instead, add a reset() method to WebAudioBufferList which re-initializes its AudioBufferList (which is a
+ simple memcpy of a 24-byte struct), reusing the existing memory buffers.
+
+ While making these changes, we'll also take the opportunity to clean up the AudioSampleBufferList class by
+ making some of its members into UniqueRefs instead of unique_ptrs, thus removing the possibility of null-
+ dereferences.
+
+ * platform/audio/WebAudioBufferList.cpp:
+ (WebCore::WebAudioBufferList::WebAudioBufferList):
+ (WebCore::WebAudioBufferList::reset):
+ * platform/audio/WebAudioBufferList.h:
+ * platform/audio/mac/AudioSampleBufferList.cpp:
+ (WebCore::AudioSampleBufferList::AudioSampleBufferList):
+ (WebCore::AudioSampleBufferList::applyGain):
+ (WebCore::AudioSampleBufferList::mixFrom):
+ (WebCore::AudioSampleBufferList::reset):
+ (WebCore::AudioSampleBufferList::zero):
+ (WebCore::AudioSampleBufferList::~AudioSampleBufferList): Deleted.
+ * platform/audio/mac/AudioSampleBufferList.h:
+ (WebCore::AudioSampleBufferList::bufferList):
+
+2017-04-21 Jer Noble <[email protected]>
+
Fix some spurious ASSERTs when working with capturing media elements
https://bugs.webkit.org/show_bug.cgi?id=171096
Modified: trunk/Source/WebCore/platform/audio/WebAudioBufferList.cpp (215623 => 215624)
--- trunk/Source/WebCore/platform/audio/WebAudioBufferList.cpp 2017-04-21 19:04:56 UTC (rev 215623)
+++ trunk/Source/WebCore/platform/audio/WebAudioBufferList.cpp 2017-04-21 19:22:47 UTC (rev 215624)
@@ -42,11 +42,11 @@
ASSERT(bufferListSize <= SIZE_MAX);
m_listBufferSize = static_cast<size_t>(bufferListSize);
- m_list = std::unique_ptr<AudioBufferList>(static_cast<AudioBufferList*>(::operator new (m_listBufferSize)));
- memset(m_list.get(), 0, m_listBufferSize);
- m_list->mNumberBuffers = bufferCount;
+ m_canonicalList = std::unique_ptr<AudioBufferList>(static_cast<AudioBufferList*>(::operator new (m_listBufferSize)));
+ memset(m_canonicalList.get(), 0, m_listBufferSize);
+ m_canonicalList->mNumberBuffers = bufferCount;
for (uint32_t buffer = 0; buffer < bufferCount; ++buffer)
- m_list->mBuffers[buffer].mNumberChannels = channelCount;
+ m_canonicalList->mBuffers[buffer].mNumberChannels = channelCount;
}
WebAudioBufferList::WebAudioBufferList(const CAAudioStreamDescription& format, uint32_t sampleCount)
@@ -62,11 +62,13 @@
m_flatBuffer.reserveInitialCapacity(bufferCount * bytesPerBuffer);
auto data = ""
- for (uint32_t buffer = 0; buffer < m_list->mNumberBuffers; ++buffer) {
- m_list->mBuffers[buffer].mData = data;
- m_list->mBuffers[buffer].mDataByteSize = bytesPerBuffer;
+ for (uint32_t buffer = 0; buffer < m_canonicalList->mNumberBuffers; ++buffer) {
+ m_canonicalList->mBuffers[buffer].mData = data;
+ m_canonicalList->mBuffers[buffer].mDataByteSize = bytesPerBuffer;
data += bytesPerBuffer;
}
+
+ reset();
}
WebAudioBufferList::WebAudioBufferList(const CAAudioStreamDescription& format, CMSampleBufferRef sampleBuffer)
@@ -76,10 +78,19 @@
return;
CMBlockBufferRef buffer = nullptr;
- if (noErr == CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(sampleBuffer, nullptr, m_list.get(), m_listBufferSize, kCFAllocatorSystemDefault, kCFAllocatorSystemDefault, kCMSampleBufferFlag_AudioBufferList_Assure16ByteAlignment, &buffer))
+ if (noErr == CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(sampleBuffer, nullptr, m_canonicalList.get(), m_listBufferSize, kCFAllocatorSystemDefault, kCFAllocatorSystemDefault, kCMSampleBufferFlag_AudioBufferList_Assure16ByteAlignment, &buffer))
m_blockBuffer = adoptCF(buffer);
+
+ reset();
}
+void WebAudioBufferList::reset()
+{
+ if (!m_list)
+ m_list = std::unique_ptr<AudioBufferList>(static_cast<AudioBufferList*>(::operator new (m_listBufferSize)));
+ memcpy(m_list.get(), m_canonicalList.get(), m_listBufferSize);
+}
+
WTF::IteratorRange<AudioBuffer*> WebAudioBufferList::buffers() const
{
return WTF::makeIteratorRange(&m_list->mBuffers[0], &m_list->mBuffers[m_list->mNumberBuffers]);
Modified: trunk/Source/WebCore/platform/audio/WebAudioBufferList.h (215623 => 215624)
--- trunk/Source/WebCore/platform/audio/WebAudioBufferList.h 2017-04-21 19:04:56 UTC (rev 215623)
+++ trunk/Source/WebCore/platform/audio/WebAudioBufferList.h 2017-04-21 19:22:47 UTC (rev 215624)
@@ -45,6 +45,8 @@
WEBCORE_EXPORT WebAudioBufferList(const CAAudioStreamDescription&, uint32_t sampleCount);
WebAudioBufferList(const CAAudioStreamDescription&, CMSampleBufferRef);
+ void reset();
+
AudioBufferList* list() const { return m_list.get(); }
operator AudioBufferList&() const { return *m_list; }
@@ -56,6 +58,7 @@
Kind kind() const { return Kind::WebAudioBufferList; }
size_t m_listBufferSize { 0 };
+ std::unique_ptr<AudioBufferList> m_canonicalList;
std::unique_ptr<AudioBufferList> m_list;
RetainPtr<CMBlockBufferRef> m_blockBuffer;
Vector<uint8_t> m_flatBuffer;
Modified: trunk/Source/WebCore/platform/audio/mac/AudioSampleBufferList.cpp (215623 => 215624)
--- trunk/Source/WebCore/platform/audio/mac/AudioSampleBufferList.cpp 2017-04-21 19:04:56 UTC (rev 215623)
+++ trunk/Source/WebCore/platform/audio/mac/AudioSampleBufferList.cpp 2017-04-21 19:22:47 UTC (rev 215624)
@@ -44,21 +44,15 @@
}
AudioSampleBufferList::AudioSampleBufferList(const CAAudioStreamDescription& format, size_t maximumSampleCount)
+ : m_internalFormat(makeUniqueRef<CAAudioStreamDescription>(format))
+ , m_sampleCapacity(maximumSampleCount)
+ , m_maxBufferSizePerChannel(maximumSampleCount * format.bytesPerFrame() / format.numberOfChannelStreams())
+ , m_bufferList(makeUniqueRef<WebAudioBufferList>(m_internalFormat, m_maxBufferSizePerChannel))
{
- m_internalFormat = std::make_unique<CAAudioStreamDescription>(format);
-
- m_sampleCapacity = maximumSampleCount;
- m_maxBufferSizePerChannel = maximumSampleCount * format.bytesPerFrame() / format.numberOfChannelStreams();
-
ASSERT(format.sampleRate() >= 0);
- reset();
}
-AudioSampleBufferList::~AudioSampleBufferList()
-{
- m_internalFormat = nullptr;
- m_bufferList = nullptr;
-}
+AudioSampleBufferList::~AudioSampleBufferList() = default;
void AudioSampleBufferList::setSampleCount(size_t count)
{
@@ -106,7 +100,7 @@
void AudioSampleBufferList::applyGain(float gain)
{
- applyGain(*m_bufferList, gain, m_internalFormat->format());
+ applyGain(m_bufferList.get(), gain, m_internalFormat->format());
}
OSStatus AudioSampleBufferList::mixFrom(const AudioSampleBufferList& source, size_t frameCount)
@@ -124,7 +118,7 @@
m_sampleCount = frameCount;
- WebAudioBufferList& sourceBuffer = source.bufferList();
+ auto& sourceBuffer = source.bufferList();
for (uint32_t i = 0; i < m_bufferList->bufferCount(); i++) {
switch (m_internalFormat->format()) {
case AudioStreamDescription::Int16: {
@@ -204,12 +198,12 @@
m_timestamp = 0;
m_hostTime = -1;
- m_bufferList = std::make_unique<WebAudioBufferList>(*m_internalFormat, m_maxBufferSizePerChannel);
+ m_bufferList->reset();
}
void AudioSampleBufferList::zero()
{
- zeroABL(*m_bufferList, m_internalFormat->bytesPerPacket() * m_sampleCapacity);
+ zeroABL(m_bufferList.get(), m_internalFormat->bytesPerPacket() * m_sampleCapacity);
}
void AudioSampleBufferList::zeroABL(AudioBufferList& buffer, size_t byteCount)
Modified: trunk/Source/WebCore/platform/audio/mac/AudioSampleBufferList.h (215623 => 215624)
--- trunk/Source/WebCore/platform/audio/mac/AudioSampleBufferList.h 2017-04-21 19:04:56 UTC (rev 215623)
+++ trunk/Source/WebCore/platform/audio/mac/AudioSampleBufferList.h 2017-04-21 19:22:47 UTC (rev 215624)
@@ -60,7 +60,8 @@
OSStatus copyTo(AudioBufferList&, size_t count = SIZE_MAX);
const AudioStreamBasicDescription& streamDescription() const { return m_internalFormat->streamDescription(); }
- WebAudioBufferList& bufferList() const { return *m_bufferList; }
+ const WebAudioBufferList& bufferList() const { return m_bufferList; }
+ WebAudioBufferList& bufferList() { return m_bufferList; }
uint32_t sampleCapacity() const { return m_sampleCapacity; }
uint32_t sampleCount() const { return m_sampleCount; }
@@ -78,7 +79,7 @@
protected:
AudioSampleBufferList(const CAAudioStreamDescription&, size_t);
- std::unique_ptr<CAAudioStreamDescription> m_internalFormat;
+ UniqueRef<CAAudioStreamDescription> m_internalFormat;
uint64_t m_timestamp { 0 };
double m_hostTime { -1 };
@@ -86,7 +87,7 @@
size_t m_sampleCapacity { 0 };
size_t m_maxBufferSizePerChannel { 0 };
size_t m_bufferListBaseSize { 0 };
- std::unique_ptr<WebAudioBufferList> m_bufferList;
+ UniqueRef<WebAudioBufferList> m_bufferList;
};
inline size_t AudioSampleBufferList::audioBufferListSizeForStream(const CAAudioStreamDescription& description)