Bug 1524890 - P4. Use Span<> with AudioBufferCursor. r=bryce

And we add some strong assertions that we never read passed the end of the buffer.

Differential Revision: https://phabricator.services.mozilla.com/D20162

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jean-Yves Avenard 2019-02-22 09:18:05 +00:00
Родитель afe04d2952
Коммит 1f5dfb6d37
3 изменённых файлов: 31 добавлений и 15 удалений

Просмотреть файл

@ -627,8 +627,10 @@ long AudioStream::DataCallback(void* aBuffer, long aFrames) {
MonitorAutoLock mon(mMonitor);
MOZ_ASSERT(mState != SHUTDOWN, "No data callback after shutdown");
auto writer = AudioBufferWriter(reinterpret_cast<AudioDataValue*>(aBuffer),
mOutChannels, aFrames);
auto writer = AudioBufferWriter(
MakeSpan<AudioDataValue>(reinterpret_cast<AudioDataValue*>(aBuffer),
mOutChannels * aFrames),
mOutChannels, aFrames);
if (mPrefillQuirk) {
// Don't consume audio data until Start() is called.

Просмотреть файл

@ -92,14 +92,16 @@ class AudioClock {
*/
class AudioBufferCursor {
public:
AudioBufferCursor(AudioDataValue* aPtr, uint32_t aChannels, uint32_t aFrames)
: mPtr(aPtr), mChannels(aChannels), mFrames(aFrames) {}
AudioBufferCursor(Span<AudioDataValue> aSpan, uint32_t aChannels,
uint32_t aFrames)
: mChannels(aChannels), mSpan(aSpan), mFrames(aFrames) {}
// Advance the cursor to account for frames that are consumed.
uint32_t Advance(uint32_t aFrames) {
MOZ_DIAGNOSTIC_ASSERT(Contains(aFrames));
MOZ_ASSERT(mFrames >= aFrames);
mFrames -= aFrames;
mPtr += mChannels * aFrames;
mOffset += mChannels * aFrames;
return aFrames;
}
@ -107,11 +109,20 @@ class AudioBufferCursor {
uint32_t Available() const { return mFrames; }
// Return a pointer where read/write should begin.
AudioDataValue* Ptr() const { return mPtr; }
AudioDataValue* Ptr() const {
MOZ_DIAGNOSTIC_ASSERT(mOffset <= mSpan.Length());
return mSpan.Elements() + mOffset;
}
protected:
AudioDataValue* mPtr;
bool Contains(uint32_t aFrames) const {
return mSpan.Length() >= mOffset + mChannels * aFrames;
}
const uint32_t mChannels;
private:
const Span<AudioDataValue> mSpan;
size_t mOffset = 0;
uint32_t mFrames;
};
@ -121,16 +132,19 @@ class AudioBufferCursor {
*/
class AudioBufferWriter : private AudioBufferCursor {
public:
AudioBufferWriter(AudioDataValue* aPtr, uint32_t aChannels, uint32_t aFrames)
: AudioBufferCursor(aPtr, aChannels, aFrames) {}
AudioBufferWriter(Span<AudioDataValue> aSpan, uint32_t aChannels,
uint32_t aFrames)
: AudioBufferCursor(aSpan, aChannels, aFrames) {}
uint32_t WriteZeros(uint32_t aFrames) {
memset(mPtr, 0, sizeof(AudioDataValue) * mChannels * aFrames);
MOZ_DIAGNOSTIC_ASSERT(Contains(aFrames));
memset(Ptr(), 0, sizeof(AudioDataValue) * mChannels * aFrames);
return Advance(aFrames);
}
uint32_t Write(const AudioDataValue* aPtr, uint32_t aFrames) {
memcpy(mPtr, aPtr, sizeof(AudioDataValue) * mChannels * aFrames);
MOZ_DIAGNOSTIC_ASSERT(Contains(aFrames));
memcpy(Ptr(), aPtr, sizeof(AudioDataValue) * mChannels * aFrames);
return Advance(aFrames);
}
@ -141,7 +155,8 @@ class AudioBufferWriter : private AudioBufferCursor {
// return: The number of frames actually written by the function.
template <typename Function>
uint32_t Write(const Function& aFunction, uint32_t aFrames) {
return Advance(aFunction(mPtr, aFrames));
MOZ_DIAGNOSTIC_ASSERT(Contains(aFrames));
return Advance(aFunction(Ptr(), aFrames));
}
using AudioBufferCursor::Available;

Просмотреть файл

@ -245,9 +245,8 @@ UniquePtr<AudioStream::Chunk> AudioSink::PopFrames(uint32_t aFrames) {
mCurrentData = mProcessedQueue.PeekFront();
{
MonitorAutoLock mon(mMonitor);
mCursor = MakeUnique<AudioBufferCursor>(mCurrentData->Data().Elements(),
mCurrentData->mChannels,
mCurrentData->mFrames);
mCursor = MakeUnique<AudioBufferCursor>(
mCurrentData->Data(), mCurrentData->mChannels, mCurrentData->mFrames);
}
MOZ_ASSERT(mCurrentData->mFrames > 0);
mProcessedQueueLength -=