зеркало из https://github.com/mozilla/gecko-dev.git
146 строки
3.8 KiB
C++
146 строки
3.8 KiB
C++
/* -*- 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);
|
|
|
|
virtual void* operator()(void* aObject) {
|
|
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";
|
|
}
|
|
}
|
|
}
|