TestAudioCompactor.cpp (3809B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 #include "AudioCompactor.h" 7 #include "gtest/gtest.h" 8 #include "nsDeque.h" 9 #include "nsIMemoryReporter.h" 10 11 using mozilla::AudioCompactor; 12 using mozilla::AudioData; 13 using mozilla::AudioDataValue; 14 using mozilla::MediaQueue; 15 16 class MemoryFunctor : public nsDequeFunctor<AudioData> { 17 public: 18 MemoryFunctor() : mSize(0) {} 19 MOZ_DEFINE_MALLOC_SIZE_OF(MallocSizeOf); 20 21 void operator()(AudioData* aObject) override { 22 mSize += aObject->SizeOfIncludingThis(MallocSizeOf); 23 } 24 25 size_t mSize; 26 }; 27 28 class TestCopy { 29 public: 30 TestCopy(uint32_t aFrames, uint32_t aChannels, uint32_t& aCallCount, 31 uint32_t& aFrameCount) 32 : mFrames(aFrames), 33 mChannels(aChannels), 34 mCallCount(aCallCount), 35 mFrameCount(aFrameCount) {} 36 37 uint32_t operator()(AudioDataValue* aBuffer, uint32_t aSamples) { 38 mCallCount += 1; 39 uint32_t frames = std::min(mFrames - mFrameCount, aSamples / mChannels); 40 mFrameCount += frames; 41 return frames; 42 } 43 44 private: 45 const uint32_t mFrames; 46 const uint32_t mChannels; 47 uint32_t& mCallCount; 48 uint32_t& mFrameCount; 49 }; 50 51 static void TestAudioCompactor(size_t aBytes) { 52 MediaQueue<AudioData> queue; 53 AudioCompactor compactor(queue); 54 55 uint64_t offset = 0; 56 uint64_t time = 0; 57 uint32_t sampleRate = 44000; 58 uint32_t channels = 2; 59 uint32_t frames = aBytes / (channels * sizeof(AudioDataValue)); 60 size_t maxSlop = aBytes / AudioCompactor::MAX_SLOP_DIVISOR; 61 62 uint32_t callCount = 0; 63 uint32_t frameCount = 0; 64 65 compactor.Push(offset, time, sampleRate, frames, channels, 66 TestCopy(frames, channels, callCount, frameCount)); 67 68 EXPECT_GT(callCount, 0U) << "copy functor never called"; 69 EXPECT_EQ(frames, frameCount) << "incorrect number of frames copied"; 70 71 MemoryFunctor memoryFunc; 72 queue.LockedForEach(memoryFunc); 73 size_t allocSize = memoryFunc.mSize - (callCount * sizeof(AudioData)); 74 size_t slop = allocSize - aBytes; 75 EXPECT_LE(slop, maxSlop) << "allowed too much allocation slop"; 76 } 77 78 TEST(Media, AudioCompactor_4000) 79 { 80 TestAudioCompactor(4000); 81 } 82 83 TEST(Media, AudioCompactor_4096) 84 { 85 TestAudioCompactor(4096); 86 } 87 88 TEST(Media, AudioCompactor_5000) 89 { 90 TestAudioCompactor(5000); 91 } 92 93 TEST(Media, AudioCompactor_5256) 94 { 95 TestAudioCompactor(5256); 96 } 97 98 TEST(Media, AudioCompactor_NativeCopy) 99 { 100 const uint32_t channels = 2; 101 const size_t srcBytes = 32; 102 const uint32_t srcSamples = srcBytes / sizeof(AudioDataValue); 103 const uint32_t srcFrames = srcSamples / channels; 104 uint8_t src[srcBytes]; 105 106 for (uint32_t i = 0; i < srcBytes; ++i) { 107 src[i] = i; 108 } 109 110 AudioCompactor::NativeCopy copy(src, srcBytes, channels); 111 112 const uint32_t dstSamples = srcSamples * 2; 113 AudioDataValue dst[dstSamples]; 114 115 const AudioDataValue notCopied = 0xffff; 116 for (uint32_t i = 0; i < dstSamples; ++i) { 117 dst[i] = notCopied; 118 } 119 120 const uint32_t copyCount = 8; 121 uint32_t copiedFrames = 0; 122 uint32_t nextSample = 0; 123 for (uint32_t i = 0; i < copyCount; ++i) { 124 uint32_t copySamples = dstSamples / copyCount; 125 copiedFrames += copy(dst + nextSample, copySamples); 126 nextSample += copySamples; 127 } 128 129 EXPECT_EQ(srcFrames, copiedFrames) << "copy exact number of source frames"; 130 131 // Verify that the only the correct bytes were copied. 132 for (uint32_t i = 0; i < dstSamples; ++i) { 133 if (i < srcSamples) { 134 EXPECT_NE(notCopied, dst[i]) << "should have copied over these bytes"; 135 } else { 136 EXPECT_EQ(notCopied, dst[i]) << "should not have copied over these bytes"; 137 } 138 } 139 }