DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (3391eef42443)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
/* -*- 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 "nsIMemoryReporter.h"

using mozilla::AudioCompactor;
using mozilla::AudioData;
using mozilla::AudioDataValue;
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);
  }

  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";
    }
  }
}