summaryrefslogtreecommitdiffstats
path: root/dom/media/gtest/TestAudioCompactor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/media/gtest/TestAudioCompactor.cpp')
-rw-r--r--dom/media/gtest/TestAudioCompactor.cpp145
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";
+ }
+ }
+}