| Index: content/browser/renderer_host/media/audio_debug_file_writer_unittest.cc
|
| diff --git a/content/browser/renderer_host/media/audio_debug_file_writer_unittest.cc b/content/browser/renderer_host/media/audio_debug_file_writer_unittest.cc
|
| deleted file mode 100644
|
| index 4ececd04cd85c127731d9a3b81d04132a726a036..0000000000000000000000000000000000000000
|
| --- a/content/browser/renderer_host/media/audio_debug_file_writer_unittest.cc
|
| +++ /dev/null
|
| @@ -1,350 +0,0 @@
|
| -// Copyright 2015 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include <stdint.h>
|
| -
|
| -#include "base/files/file_util.h"
|
| -#include "base/memory/ptr_util.h"
|
| -#include "base/synchronization/waitable_event.h"
|
| -#include "base/sys_byteorder.h"
|
| -#include "content/browser/renderer_host/media/audio_debug_file_writer.h"
|
| -#include "content/public/browser/browser_thread.h"
|
| -#include "content/public/test/test_browser_thread_bundle.h"
|
| -#include "media/base/audio_bus.h"
|
| -#include "media/base/test_helpers.h"
|
| -#include "testing/gtest/include/gtest/gtest.h"
|
| -
|
| -namespace content {
|
| -
|
| -namespace {
|
| -
|
| -static const uint16_t kBytesPerSample = sizeof(uint16_t);
|
| -static const uint16_t kPcmEncoding = 1;
|
| -static const size_t kWavHeaderSize = 44;
|
| -
|
| -uint16_t ReadLE2(const char* buf) {
|
| - return static_cast<uint8_t>(buf[0]) | (static_cast<uint8_t>(buf[1]) << 8);
|
| -}
|
| -
|
| -uint32_t ReadLE4(const char* buf) {
|
| - return static_cast<uint8_t>(buf[0]) | (static_cast<uint8_t>(buf[1]) << 8) |
|
| - (static_cast<uint8_t>(buf[2]) << 16) |
|
| - (static_cast<uint8_t>(buf[3]) << 24);
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -// <channel layout, sample rate, frames per buffer, number of buffer writes
|
| -typedef std::tr1::tuple<media::ChannelLayout, int, int, int>
|
| - AudioDebugFileWriterTestData;
|
| -
|
| -class AudioDebugFileWriterTest
|
| - : public testing::TestWithParam<AudioDebugFileWriterTestData> {
|
| - public:
|
| - AudioDebugFileWriterTest()
|
| - : thread_bundle_(content::TestBrowserThreadBundle::REAL_FILE_THREAD),
|
| - params_(media::AudioParameters::Format::AUDIO_PCM_LINEAR,
|
| - std::tr1::get<0>(GetParam()),
|
| - std::tr1::get<1>(GetParam()),
|
| - kBytesPerSample * 8,
|
| - std::tr1::get<2>(GetParam())),
|
| - writes_(std::tr1::get<3>(GetParam())),
|
| - source_samples_(params_.frames_per_buffer() * params_.channels() *
|
| - writes_),
|
| - source_interleaved_(source_samples_ ? new int16_t[source_samples_]
|
| - : nullptr) {
|
| - InitSourceInterleaved(source_interleaved_.get(), source_samples_);
|
| - }
|
| -
|
| - protected:
|
| - virtual ~AudioDebugFileWriterTest() {}
|
| -
|
| - static void InitSourceInterleaved(int16_t* source_interleaved,
|
| - int source_samples) {
|
| - if (source_samples) {
|
| - // equal steps to cover int16_t range of values
|
| - int16_t step = 0xffff / source_samples;
|
| - int16_t val = std::numeric_limits<int16_t>::min();
|
| - for (int i = 0; i < source_samples; ++i, val += step)
|
| - source_interleaved[i] = val;
|
| - }
|
| - }
|
| -
|
| - static void VerifyHeader(const char(&wav_header)[kWavHeaderSize],
|
| - const media::AudioParameters& params,
|
| - int writes,
|
| - int64_t file_length) {
|
| - uint32_t block_align = params.channels() * kBytesPerSample;
|
| - uint32_t data_size =
|
| - static_cast<uint32_t>(params.frames_per_buffer() * params.channels() *
|
| - writes * kBytesPerSample);
|
| - // Offset Length Content
|
| - // 0 4 "RIFF"
|
| - EXPECT_EQ(0, strncmp(wav_header, "RIFF", 4));
|
| - // 4 4 <file length - 8>
|
| - ASSERT_GT(file_length, 8);
|
| - EXPECT_EQ(static_cast<uint64_t>(file_length - 8), ReadLE4(wav_header + 4));
|
| - EXPECT_EQ(static_cast<uint32_t>(data_size + kWavHeaderSize - 8),
|
| - ReadLE4(wav_header + 4));
|
| - // 8 4 "WAVE"
|
| - // 12 4 "fmt "
|
| - EXPECT_EQ(0, strncmp(wav_header + 8, "WAVEfmt ", 8));
|
| - // 16 4 <length of the fmt data> (=16)
|
| - EXPECT_EQ(16U, ReadLE4(wav_header + 16));
|
| - // 20 2 <WAVE file encoding tag>
|
| - EXPECT_EQ(kPcmEncoding, ReadLE2(wav_header + 20));
|
| - // 22 2 <channels>
|
| - EXPECT_EQ(params.channels(), ReadLE2(wav_header + 22));
|
| - // 24 4 <sample rate>
|
| - EXPECT_EQ(static_cast<uint32_t>(params.sample_rate()),
|
| - ReadLE4(wav_header + 24));
|
| - // 28 4 <bytes per second> (sample rate * block align)
|
| - EXPECT_EQ(static_cast<uint32_t>(params.sample_rate()) * block_align,
|
| - ReadLE4(wav_header + 28));
|
| - // 32 2 <block align> (channels * bits per sample / 8)
|
| - EXPECT_EQ(block_align, ReadLE2(wav_header + 32));
|
| - // 34 2 <bits per sample>
|
| - EXPECT_EQ(kBytesPerSample * 8, ReadLE2(wav_header + 34));
|
| - // 36 4 "data"
|
| - EXPECT_EQ(0, strncmp(wav_header + 36, "data", 4));
|
| - // 40 4 <sample data size(n)>
|
| - EXPECT_EQ(data_size, ReadLE4(wav_header + 40));
|
| - }
|
| -
|
| - // |result_interleaved| is expected to be little-endian.
|
| - static void VerifyDataRecording(const int16_t* source_interleaved,
|
| - const int16_t* result_interleaved,
|
| - int16_t source_samples) {
|
| - // Allow mismatch by 1 due to rounding error in int->float->int
|
| - // calculations.
|
| - for (int i = 0; i < source_samples; ++i)
|
| - EXPECT_LE(std::abs(static_cast<int16_t>(
|
| - base::ByteSwapToLE16(source_interleaved[i])) -
|
| - result_interleaved[i]),
|
| - 1)
|
| - << "i = " << i << " source " << source_interleaved[i] << " result "
|
| - << result_interleaved[i];
|
| - }
|
| -
|
| - void VerifyRecording(const base::FilePath& file_path) {
|
| - base::File file(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ);
|
| - EXPECT_TRUE(file.IsValid());
|
| -
|
| - char wav_header[kWavHeaderSize];
|
| - EXPECT_EQ(file.Read(0, wav_header, kWavHeaderSize),
|
| - static_cast<int>(kWavHeaderSize));
|
| - VerifyHeader(wav_header, params_, writes_, file.GetLength());
|
| -
|
| - if (source_samples_ > 0) {
|
| - std::unique_ptr<int16_t[]> result_interleaved(
|
| - new int16_t[source_samples_]);
|
| - memset(result_interleaved.get(), 0, source_samples_ * kBytesPerSample);
|
| -
|
| - // Recording is read from file as a byte sequence, so it stored as
|
| - // little-endian.
|
| - int read = file.Read(kWavHeaderSize,
|
| - reinterpret_cast<char*>(result_interleaved.get()),
|
| - source_samples_ * kBytesPerSample);
|
| - EXPECT_EQ(static_cast<int>(file.GetLength() - kWavHeaderSize), read);
|
| -
|
| - VerifyDataRecording(source_interleaved_.get(), result_interleaved.get(),
|
| - source_samples_);
|
| - }
|
| - }
|
| -
|
| - void TestDoneOnFileThread(const base::Closure& callback) {
|
| - DCHECK_CURRENTLY_ON(BrowserThread::FILE);
|
| -
|
| - callback.Run();
|
| - }
|
| -
|
| - void DoDebugRecording() {
|
| - // Write tasks are posted to BrowserThread::FILE.
|
| - for (int i = 0; i < writes_; ++i) {
|
| - std::unique_ptr<media::AudioBus> bus = media::AudioBus::Create(
|
| - params_.channels(), params_.frames_per_buffer());
|
| -
|
| - bus->FromInterleaved(
|
| - source_interleaved_.get() +
|
| - i * params_.channels() * params_.frames_per_buffer(),
|
| - params_.frames_per_buffer(), kBytesPerSample);
|
| -
|
| - input_debug_writer_->Write(std::move(bus));
|
| - }
|
| - }
|
| -
|
| - void WaitForRecordingCompletion() {
|
| - media::WaitableMessageLoopEvent event;
|
| -
|
| - // Post a task to BrowserThread::FILE indicating that all the writes are
|
| - // done.
|
| - BrowserThread::PostTask(
|
| - BrowserThread::FILE, FROM_HERE,
|
| - base::Bind(&AudioDebugFileWriterTest::TestDoneOnFileThread,
|
| - base::Unretained(this), event.GetClosure()));
|
| -
|
| - // Wait for TestDoneOnFileThread() to call event's closure.
|
| - event.RunAndWait();
|
| - }
|
| -
|
| - void RecordAndVerifyOnce() {
|
| - base::FilePath file_path;
|
| - EXPECT_TRUE(base::CreateTemporaryFile(&file_path));
|
| -
|
| - input_debug_writer_->Start(file_path);
|
| -
|
| - DoDebugRecording();
|
| -
|
| - input_debug_writer_->Stop();
|
| -
|
| - WaitForRecordingCompletion();
|
| -
|
| - VerifyRecording(file_path);
|
| -
|
| - if (::testing::Test::HasFailure()) {
|
| - LOG(ERROR) << "Test failed; keeping recording(s) at ["
|
| - << file_path.value().c_str() << "].";
|
| - } else {
|
| - EXPECT_TRUE(base::DeleteFile(file_path, false));
|
| - }
|
| - }
|
| -
|
| - protected:
|
| - TestBrowserThreadBundle thread_bundle_;
|
| -
|
| - // Writer under test.
|
| - std::unique_ptr<AudioDebugFileWriter> input_debug_writer_;
|
| -
|
| - // AudioBus parameters.
|
| - media::AudioParameters params_;
|
| -
|
| - // Number of times to write AudioBus to the file.
|
| - int writes_;
|
| -
|
| - // Number of samples in the source data.
|
| - int source_samples_;
|
| -
|
| - // Source data.
|
| - std::unique_ptr<int16_t[]> source_interleaved_;
|
| -
|
| - private:
|
| - DISALLOW_COPY_AND_ASSIGN(AudioDebugFileWriterTest);
|
| -};
|
| -
|
| -class AudioDebugFileWriterBehavioralTest : public AudioDebugFileWriterTest {};
|
| -
|
| -TEST_P(AudioDebugFileWriterTest, WaveRecordingTest) {
|
| - input_debug_writer_.reset(new AudioDebugFileWriter(params_));
|
| -
|
| - RecordAndVerifyOnce();
|
| -}
|
| -
|
| -TEST_P(AudioDebugFileWriterBehavioralTest,
|
| - DeletedBeforeRecordingFinishedOnFileThread) {
|
| - input_debug_writer_.reset(new AudioDebugFileWriter(params_));
|
| -
|
| - base::FilePath file_path;
|
| - EXPECT_TRUE(base::CreateTemporaryFile(&file_path));
|
| -
|
| - base::WaitableEvent* wait_for_deletion =
|
| - new base::WaitableEvent(base::WaitableEvent::ResetPolicy::MANUAL,
|
| - base::WaitableEvent::InitialState::NOT_SIGNALED);
|
| -
|
| - BrowserThread::PostTask(
|
| - BrowserThread::FILE, FROM_HERE,
|
| - base::Bind(&base::WaitableEvent::Wait, base::Owned(wait_for_deletion)));
|
| -
|
| - input_debug_writer_->Start(file_path);
|
| -
|
| - DoDebugRecording();
|
| -
|
| - input_debug_writer_.reset();
|
| - wait_for_deletion->Signal();
|
| -
|
| - WaitForRecordingCompletion();
|
| -
|
| - VerifyRecording(file_path);
|
| -
|
| - if (::testing::Test::HasFailure()) {
|
| - LOG(ERROR) << "Test failed; keeping recording(s) at ["
|
| - << file_path.value().c_str() << "].";
|
| - } else {
|
| - EXPECT_TRUE(base::DeleteFile(file_path, false));
|
| - }
|
| -}
|
| -
|
| -TEST_P(AudioDebugFileWriterBehavioralTest, FileCreationError) {
|
| - input_debug_writer_.reset(new AudioDebugFileWriter(params_));
|
| - base::FilePath file_path; // Empty file name.
|
| - input_debug_writer_->Start(file_path);
|
| - DoDebugRecording();
|
| -}
|
| -
|
| -TEST_P(AudioDebugFileWriterBehavioralTest, StartStopStartStop) {
|
| - input_debug_writer_.reset(new AudioDebugFileWriter(params_));
|
| - RecordAndVerifyOnce();
|
| - RecordAndVerifyOnce();
|
| -}
|
| -
|
| -TEST_P(AudioDebugFileWriterBehavioralTest, DestroyNotStarted) {
|
| - input_debug_writer_.reset(new AudioDebugFileWriter(params_));
|
| - input_debug_writer_.reset();
|
| -}
|
| -
|
| -TEST_P(AudioDebugFileWriterBehavioralTest, DestroyStarted) {
|
| - input_debug_writer_.reset(new AudioDebugFileWriter(params_));
|
| - base::FilePath file_path;
|
| - EXPECT_TRUE(base::CreateTemporaryFile(&file_path));
|
| - input_debug_writer_->Start(file_path);
|
| - input_debug_writer_.reset();
|
| -}
|
| -
|
| -INSTANTIATE_TEST_CASE_P(
|
| - AudioDebugFileWriterTest,
|
| - AudioDebugFileWriterTest,
|
| - // Using 10ms frames per buffer everywhere.
|
| - testing::Values(
|
| - // No writes.
|
| - std::tr1::make_tuple(media::ChannelLayout::CHANNEL_LAYOUT_MONO,
|
| - 44100,
|
| - 44100 / 100,
|
| - 0),
|
| - // 1 write of mono.
|
| - std::tr1::make_tuple(media::ChannelLayout::CHANNEL_LAYOUT_MONO,
|
| - 44100,
|
| - 44100 / 100,
|
| - 1),
|
| - // 1 second of mono.
|
| - std::tr1::make_tuple(media::ChannelLayout::CHANNEL_LAYOUT_MONO,
|
| - 44100,
|
| - 44100 / 100,
|
| - 100),
|
| - // 1 second of mono, higher rate.
|
| - std::tr1::make_tuple(media::ChannelLayout::CHANNEL_LAYOUT_MONO,
|
| - 48000,
|
| - 48000 / 100,
|
| - 100),
|
| - // 1 second of stereo.
|
| - std::tr1::make_tuple(media::ChannelLayout::CHANNEL_LAYOUT_STEREO,
|
| - 44100,
|
| - 44100 / 100,
|
| - 100),
|
| - // 15 seconds of stereo, higher rate.
|
| - std::tr1::make_tuple(media::ChannelLayout::CHANNEL_LAYOUT_STEREO,
|
| - 48000,
|
| - 48000 / 100,
|
| - 1500)));
|
| -
|
| -INSTANTIATE_TEST_CASE_P(
|
| - AudioDebugFileWriterBehavioralTest,
|
| - AudioDebugFileWriterBehavioralTest,
|
| - // Using 10ms frames per buffer everywhere.
|
| - testing::Values(
|
| - // No writes.
|
| - std::tr1::make_tuple(media::ChannelLayout::CHANNEL_LAYOUT_MONO,
|
| - 44100,
|
| - 44100 / 100,
|
| - 100)));
|
| -
|
| -} // namespace content
|
|
|