diff options
Diffstat (limited to 'dom/media/gtest/TestAudioCompactor.cpp')
-rw-r--r-- | dom/media/gtest/TestAudioCompactor.cpp | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/dom/media/gtest/TestAudioCompactor.cpp b/dom/media/gtest/TestAudioCompactor.cpp new file mode 100644 index 000000000..9a28254b3 --- /dev/null +++ b/dom/media/gtest/TestAudioCompactor.cpp @@ -0,0 +1,145 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "gtest/gtest.h" +#include "AudioCompactor.h" +#include "MediaDecoderReader.h" + +using mozilla::AudioCompactor; +using mozilla::AudioData; +using mozilla::AudioDataValue; +using mozilla::MediaDecoderReader; +using mozilla::MediaQueue; + +class MemoryFunctor : public nsDequeFunctor { +public: + MemoryFunctor() : mSize(0) {} + MOZ_DEFINE_MALLOC_SIZE_OF(MallocSizeOf); + + void* operator()(void* aObject) override { + const AudioData* audioData = static_cast<const AudioData*>(aObject); + mSize += audioData->SizeOfIncludingThis(MallocSizeOf); + return nullptr; + } + + size_t mSize; +}; + +class TestCopy +{ +public: + TestCopy(uint32_t aFrames, uint32_t aChannels, + uint32_t &aCallCount, uint32_t &aFrameCount) + : mFrames(aFrames) + , mChannels(aChannels) + , mCallCount(aCallCount) + , mFrameCount(aFrameCount) + { } + + uint32_t operator()(AudioDataValue *aBuffer, uint32_t aSamples) + { + mCallCount += 1; + uint32_t frames = std::min(mFrames - mFrameCount, aSamples / mChannels); + mFrameCount += frames; + return frames; + } + +private: + const uint32_t mFrames; + const uint32_t mChannels; + uint32_t &mCallCount; + uint32_t &mFrameCount; +}; + +static void TestAudioCompactor(size_t aBytes) +{ + MediaQueue<AudioData> queue; + AudioCompactor compactor(queue); + + uint64_t offset = 0; + uint64_t time = 0; + uint32_t sampleRate = 44000; + uint32_t channels = 2; + uint32_t frames = aBytes / (channels * sizeof(AudioDataValue)); + size_t maxSlop = aBytes / AudioCompactor::MAX_SLOP_DIVISOR; + + uint32_t callCount = 0; + uint32_t frameCount = 0; + + compactor.Push(offset, time, sampleRate, frames, channels, + TestCopy(frames, channels, callCount, frameCount)); + + EXPECT_GT(callCount, 0U) << "copy functor never called"; + EXPECT_EQ(frames, frameCount) << "incorrect number of frames copied"; + + MemoryFunctor memoryFunc; + queue.LockedForEach(memoryFunc); + size_t allocSize = memoryFunc.mSize - (callCount * sizeof(AudioData)); + size_t slop = allocSize - aBytes; + EXPECT_LE(slop, maxSlop) << "allowed too much allocation slop"; +} + +TEST(Media, AudioCompactor_4000) +{ + TestAudioCompactor(4000); +} + +TEST(Media, AudioCompactor_4096) +{ + TestAudioCompactor(4096); +} + +TEST(Media, AudioCompactor_5000) +{ + TestAudioCompactor(5000); +} + +TEST(Media, AudioCompactor_5256) +{ + TestAudioCompactor(5256); +} + +TEST(Media, AudioCompactor_NativeCopy) +{ + const uint32_t channels = 2; + const size_t srcBytes = 32; + const uint32_t srcSamples = srcBytes / sizeof(AudioDataValue); + const uint32_t srcFrames = srcSamples / channels; + uint8_t src[srcBytes]; + + for (uint32_t i = 0; i < srcBytes; ++i) { + src[i] = i; + } + + AudioCompactor::NativeCopy copy(src, srcBytes, channels); + + const uint32_t dstSamples = srcSamples * 2; + AudioDataValue dst[dstSamples]; + + const AudioDataValue notCopied = 0xffff; + for (uint32_t i = 0; i < dstSamples; ++i) { + dst[i] = notCopied; + } + + const uint32_t copyCount = 8; + uint32_t copiedFrames = 0; + uint32_t nextSample = 0; + for (uint32_t i = 0; i < copyCount; ++i) { + uint32_t copySamples = dstSamples / copyCount; + copiedFrames += copy(dst + nextSample, copySamples); + nextSample += copySamples; + } + + EXPECT_EQ(srcFrames, copiedFrames) << "copy exact number of source frames"; + + // Verify that the only the correct bytes were copied. + for (uint32_t i = 0; i < dstSamples; ++i) { + if (i < srcSamples) { + EXPECT_NE(notCopied, dst[i]) << "should have copied over these bytes"; + } else { + EXPECT_EQ(notCopied, dst[i]) << "should not have copied over these bytes"; + } + } +} |