1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/media/gtest/TestAudioCompactor.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,145 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 +#include "gtest/gtest.h" 1.10 +#include "AudioCompactor.h" 1.11 +#include "MediaDecoderReader.h" 1.12 + 1.13 +using mozilla::AudioCompactor; 1.14 +using mozilla::AudioData; 1.15 +using mozilla::AudioDataValue; 1.16 +using mozilla::MediaDecoderReader; 1.17 +using mozilla::MediaQueue; 1.18 + 1.19 +class MemoryFunctor : public nsDequeFunctor { 1.20 +public: 1.21 + MemoryFunctor() : mSize(0) {} 1.22 + MOZ_DEFINE_MALLOC_SIZE_OF(MallocSizeOf); 1.23 + 1.24 + virtual void* operator()(void* anObject) { 1.25 + const AudioData* audioData = static_cast<const AudioData*>(anObject); 1.26 + mSize += audioData->SizeOfIncludingThis(MallocSizeOf); 1.27 + return nullptr; 1.28 + } 1.29 + 1.30 + size_t mSize; 1.31 +}; 1.32 + 1.33 +class TestCopy 1.34 +{ 1.35 +public: 1.36 + TestCopy(uint32_t aFrames, uint32_t aChannels, 1.37 + uint32_t &aCallCount, uint32_t &aFrameCount) 1.38 + : mFrames(aFrames) 1.39 + , mChannels(aChannels) 1.40 + , mCallCount(aCallCount) 1.41 + , mFrameCount(aFrameCount) 1.42 + { } 1.43 + 1.44 + uint32_t operator()(AudioDataValue *aBuffer, uint32_t aSamples) 1.45 + { 1.46 + mCallCount += 1; 1.47 + uint32_t frames = std::min(mFrames - mFrameCount, aSamples / mChannels); 1.48 + mFrameCount += frames; 1.49 + return frames; 1.50 + } 1.51 + 1.52 +private: 1.53 + const uint32_t mFrames; 1.54 + const uint32_t mChannels; 1.55 + uint32_t &mCallCount; 1.56 + uint32_t &mFrameCount; 1.57 +}; 1.58 + 1.59 +static void TestAudioCompactor(size_t aBytes) 1.60 +{ 1.61 + MediaQueue<AudioData> queue; 1.62 + AudioCompactor compactor(queue); 1.63 + 1.64 + uint64_t offset = 0; 1.65 + uint64_t time = 0; 1.66 + uint32_t sampleRate = 44000; 1.67 + uint32_t channels = 2; 1.68 + uint32_t frames = aBytes / (channels * sizeof(AudioDataValue)); 1.69 + size_t maxSlop = aBytes / AudioCompactor::MAX_SLOP_DIVISOR; 1.70 + 1.71 + uint32_t callCount = 0; 1.72 + uint32_t frameCount = 0; 1.73 + 1.74 + compactor.Push(offset, time, sampleRate, frames, channels, 1.75 + TestCopy(frames, channels, callCount, frameCount)); 1.76 + 1.77 + EXPECT_GT(callCount, 0U) << "copy functor never called"; 1.78 + EXPECT_EQ(frames, frameCount) << "incorrect number of frames copied"; 1.79 + 1.80 + MemoryFunctor memoryFunc; 1.81 + queue.LockedForEach(memoryFunc); 1.82 + size_t allocSize = memoryFunc.mSize - (callCount * sizeof(AudioData)); 1.83 + size_t slop = allocSize - aBytes; 1.84 + EXPECT_LE(slop, maxSlop) << "allowed too much allocation slop"; 1.85 +} 1.86 + 1.87 +TEST(Media, AudioCompactor_4000) 1.88 +{ 1.89 + TestAudioCompactor(4000); 1.90 +} 1.91 + 1.92 +TEST(Media, AudioCompactor_4096) 1.93 +{ 1.94 + TestAudioCompactor(4096); 1.95 +} 1.96 + 1.97 +TEST(Media, AudioCompactor_5000) 1.98 +{ 1.99 + TestAudioCompactor(5000); 1.100 +} 1.101 + 1.102 +TEST(Media, AudioCompactor_5256) 1.103 +{ 1.104 + TestAudioCompactor(5256); 1.105 +} 1.106 + 1.107 +TEST(Media, AudioCompactor_NativeCopy) 1.108 +{ 1.109 + const uint32_t channels = 2; 1.110 + const size_t srcBytes = 32; 1.111 + const uint32_t srcSamples = srcBytes / sizeof(AudioDataValue); 1.112 + const uint32_t srcFrames = srcSamples / channels; 1.113 + uint8_t src[srcBytes]; 1.114 + 1.115 + for (uint32_t i = 0; i < srcBytes; ++i) { 1.116 + src[i] = i; 1.117 + } 1.118 + 1.119 + AudioCompactor::NativeCopy copy(src, srcBytes, channels); 1.120 + 1.121 + const uint32_t dstSamples = srcSamples * 2; 1.122 + AudioDataValue dst[dstSamples]; 1.123 + 1.124 + const AudioDataValue notCopied = 0xffff; 1.125 + for (uint32_t i = 0; i < dstSamples; ++i) { 1.126 + dst[i] = notCopied; 1.127 + } 1.128 + 1.129 + const uint32_t copyCount = 8; 1.130 + uint32_t copiedFrames = 0; 1.131 + uint32_t nextSample = 0; 1.132 + for (uint32_t i = 0; i < copyCount; ++i) { 1.133 + uint32_t copySamples = dstSamples / copyCount; 1.134 + copiedFrames += copy(dst + nextSample, copySamples); 1.135 + nextSample += copySamples; 1.136 + } 1.137 + 1.138 + EXPECT_EQ(srcFrames, copiedFrames) << "copy exact number of source frames"; 1.139 + 1.140 + // Verify that the only the correct bytes were copied. 1.141 + for (uint32_t i = 0; i < dstSamples; ++i) { 1.142 + if (i < srcSamples) { 1.143 + EXPECT_NE(notCopied, dst[i]) << "should have copied over these bytes"; 1.144 + } else { 1.145 + EXPECT_EQ(notCopied, dst[i]) << "should not have copied over these bytes"; 1.146 + } 1.147 + } 1.148 +}