| Index: media/audio/audio_input_unittest.cc
|
| diff --git a/media/audio/audio_input_unittest.cc b/media/audio/audio_input_unittest.cc
|
| index 260598b8043d365ad2f3312c609d0b7b1b99f463..1573abc3f0d11fb20784fd6105acf67079d0c640 100644
|
| --- a/media/audio/audio_input_unittest.cc
|
| +++ b/media/audio/audio_input_unittest.cc
|
| @@ -6,6 +6,7 @@
|
| #include "base/environment.h"
|
| #include "base/memory/scoped_ptr.h"
|
| #include "base/message_loop/message_loop.h"
|
| +#include "base/synchronization/waitable_event.h"
|
| #include "base/threading/platform_thread.h"
|
| #include "media/audio/audio_io.h"
|
| #include "media/audio/audio_manager_base.h"
|
| @@ -13,17 +14,13 @@
|
|
|
| namespace media {
|
|
|
| -static const int kSamplingRate = 8000;
|
| -static const int kSamplesPerPacket = kSamplingRate / 20;
|
| -
|
| // This class allows to find out if the callbacks are occurring as
|
| // expected and if any error has been reported.
|
| class TestInputCallback : public AudioInputStream::AudioInputCallback {
|
| public:
|
| - explicit TestInputCallback(int max_data_bytes)
|
| + explicit TestInputCallback()
|
| : callback_count_(0),
|
| - had_error_(0),
|
| - max_data_bytes_(max_data_bytes) {
|
| + had_error_(0) {
|
| }
|
| virtual void OnData(AudioInputStream* stream,
|
| const uint8* data,
|
| @@ -31,12 +28,6 @@ class TestInputCallback : public AudioInputStream::AudioInputCallback {
|
| uint32 hardware_delay_bytes,
|
| double volume) OVERRIDE {
|
| ++callback_count_;
|
| - // Read the first byte to make sure memory is good.
|
| - if (size) {
|
| - ASSERT_LE(static_cast<int>(size), max_data_bytes_);
|
| - int value = data[0];
|
| - EXPECT_GE(value, 0);
|
| - }
|
| }
|
| virtual void OnError(AudioInputStream* stream) OVERRIDE {
|
| ++had_error_;
|
| @@ -53,68 +44,140 @@ class TestInputCallback : public AudioInputStream::AudioInputCallback {
|
| private:
|
| int callback_count_;
|
| int had_error_;
|
| - int max_data_bytes_;
|
| };
|
|
|
| -static bool CanRunAudioTests(AudioManager* audio_man) {
|
| - bool has_input = audio_man->HasAudioInputDevices();
|
| +class AudioInputTest : public testing::Test {
|
| + public:
|
| + AudioInputTest() :
|
| + message_loop_(base::MessageLoop::TYPE_UI),
|
| + audio_manager_(AudioManager::CreateForTesting()),
|
| + audio_input_stream_(NULL) {
|
| + }
|
|
|
| - if (!has_input)
|
| - LOG(WARNING) << "No input devices detected";
|
| + virtual ~AudioInputTest() {}
|
|
|
| - return has_input;
|
| -}
|
| + protected:
|
| + AudioManager* audio_manager() { return audio_manager_.get(); }
|
|
|
| -static AudioInputStream* CreateTestAudioInputStream(AudioManager* audio_man) {
|
| - AudioInputStream* ais = audio_man->MakeAudioInputStream(
|
| - AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_STEREO,
|
| - kSamplingRate, 16, kSamplesPerPacket),
|
| - AudioManagerBase::kDefaultDeviceId);
|
| - EXPECT_TRUE(NULL != ais);
|
| - return ais;
|
| -}
|
| + bool CanRunAudioTests() {
|
| + bool has_input = audio_manager()->HasAudioInputDevices();
|
| + LOG_IF(WARNING, !has_input) << "No input devices detected";
|
| + return has_input;
|
| + }
|
|
|
| -// Test that AudioInputStream rejects out of range parameters.
|
| -TEST(AudioInputTest, SanityOnMakeParams) {
|
| - scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting());
|
| - if (!CanRunAudioTests(audio_man.get()))
|
| - return;
|
| + void MakeAudioInputStreamOnAudioThread() {
|
| + RunOnAudioThread(
|
| + base::Bind(&AudioInputTest::MakeAudioInputStream,
|
| + base::Unretained(this)));
|
| + }
|
|
|
| - AudioParameters::Format fmt = AudioParameters::AUDIO_PCM_LINEAR;
|
| - EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(
|
| - AudioParameters(fmt, CHANNEL_LAYOUT_7_1, 8000, 16,
|
| - kSamplesPerPacket), AudioManagerBase::kDefaultDeviceId));
|
| - EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(
|
| - AudioParameters(fmt, CHANNEL_LAYOUT_MONO, 1024 * 1024, 16,
|
| - kSamplesPerPacket), AudioManagerBase::kDefaultDeviceId));
|
| - EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(
|
| - AudioParameters(fmt, CHANNEL_LAYOUT_STEREO, 8000, 80,
|
| - kSamplesPerPacket), AudioManagerBase::kDefaultDeviceId));
|
| - EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(
|
| - AudioParameters(fmt, CHANNEL_LAYOUT_STEREO, 8000, 80,
|
| - 1000 * kSamplesPerPacket),
|
| - AudioManagerBase::kDefaultDeviceId));
|
| - EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(
|
| - AudioParameters(fmt, CHANNEL_LAYOUT_UNSUPPORTED, 8000, 16,
|
| - kSamplesPerPacket), AudioManagerBase::kDefaultDeviceId));
|
| - EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(
|
| - AudioParameters(fmt, CHANNEL_LAYOUT_STEREO, -8000, 16,
|
| - kSamplesPerPacket), AudioManagerBase::kDefaultDeviceId));
|
| - EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(
|
| - AudioParameters(fmt, CHANNEL_LAYOUT_STEREO, 8000, -16,
|
| - kSamplesPerPacket), AudioManagerBase::kDefaultDeviceId));
|
| - EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(
|
| - AudioParameters(fmt, CHANNEL_LAYOUT_STEREO, 8000, 16, -1024),
|
| - AudioManagerBase::kDefaultDeviceId));
|
| -}
|
| + void CloseAudioInputStreamOnAudioThread() {
|
| + RunOnAudioThread(
|
| + base::Bind(&AudioInputStream::Close,
|
| + base::Unretained(audio_input_stream_)));
|
| + audio_input_stream_ = NULL;
|
| + }
|
| +
|
| + void OpenAndCloseAudioInputStreamOnAudioThread() {
|
| + RunOnAudioThread(
|
| + base::Bind(&AudioInputTest::OpenAndClose,
|
| + base::Unretained(this)));
|
| + }
|
| +
|
| + void OpenStopAndCloseAudioInputStreamOnAudioThread() {
|
| + RunOnAudioThread(
|
| + base::Bind(&AudioInputTest::OpenStopAndClose,
|
| + base::Unretained(this)));
|
| + }
|
| +
|
| + void OpenAndStartAudioInputStreamOnAudioThread(
|
| + AudioInputStream::AudioInputCallback* sink) {
|
| + RunOnAudioThread(
|
| + base::Bind(&AudioInputTest::OpenAndStart,
|
| + base::Unretained(this),
|
| + sink));
|
| + }
|
| +
|
| + void StopAndCloseAudioInputStreamOnAudioThread() {
|
| + RunOnAudioThread(
|
| + base::Bind(&AudioInputTest::StopAndClose,
|
| + base::Unretained(this)));
|
| + }
|
| +
|
| + void MakeAudioInputStream() {
|
| + DCHECK(audio_manager()->GetTaskRunner()->BelongsToCurrentThread());
|
| + AudioParameters params = audio_manager()->GetInputStreamParameters(
|
| + AudioManagerBase::kDefaultDeviceId);
|
| + audio_input_stream_ = audio_manager()->MakeAudioInputStream(params,
|
| + AudioManagerBase::kDefaultDeviceId);
|
| + EXPECT_TRUE(audio_input_stream_);
|
| + }
|
| +
|
| + void OpenAndClose() {
|
| + DCHECK(audio_manager()->GetTaskRunner()->BelongsToCurrentThread());
|
| + EXPECT_TRUE(audio_input_stream_->Open());
|
| + audio_input_stream_->Close();
|
| + audio_input_stream_ = NULL;
|
| + }
|
| +
|
| + void OpenAndStart(AudioInputStream::AudioInputCallback* sink) {
|
| + DCHECK(audio_manager()->GetTaskRunner()->BelongsToCurrentThread());
|
| + EXPECT_TRUE(audio_input_stream_->Open());
|
| + audio_input_stream_->Start(sink);
|
| + }
|
| +
|
| + void OpenStopAndClose() {
|
| + DCHECK(audio_manager()->GetTaskRunner()->BelongsToCurrentThread());
|
| + EXPECT_TRUE(audio_input_stream_->Open());
|
| + audio_input_stream_->Stop();
|
| + audio_input_stream_->Close();
|
| + audio_input_stream_ = NULL;
|
| + }
|
| +
|
| + void StopAndClose() {
|
| + DCHECK(audio_manager()->GetTaskRunner()->BelongsToCurrentThread());
|
| + audio_input_stream_->Stop();
|
| + audio_input_stream_->Close();
|
| + audio_input_stream_ = NULL;
|
| + }
|
| +
|
| + // Synchronously runs the provided callback/closure on the audio thread.
|
| + void RunOnAudioThread(const base::Closure& closure) {
|
| + if (!audio_manager()->GetTaskRunner()->BelongsToCurrentThread()) {
|
| + base::WaitableEvent event(false, false);
|
| + audio_manager()->GetTaskRunner()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&AudioInputTest::RunOnAudioThreadImpl,
|
| + base::Unretained(this),
|
| + closure,
|
| + &event));
|
| + event.Wait();
|
| + } else {
|
| + closure.Run();
|
| + }
|
| + }
|
| +
|
| + void RunOnAudioThreadImpl(const base::Closure& closure,
|
| + base::WaitableEvent* event) {
|
| + DCHECK(audio_manager()->GetTaskRunner()->BelongsToCurrentThread());
|
| + closure.Run();
|
| + event->Signal();
|
| + }
|
| +
|
| + base::MessageLoop message_loop_;
|
| + scoped_ptr<AudioManager> audio_manager_;
|
| + AudioInputStream* audio_input_stream_;
|
| +
|
| + private:
|
| + DISALLOW_COPY_AND_ASSIGN(AudioInputTest);
|
| +};
|
|
|
| // Test create and close of an AudioInputStream without recording audio.
|
| -TEST(AudioInputTest, CreateAndClose) {
|
| - scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting());
|
| - if (!CanRunAudioTests(audio_man.get()))
|
| +TEST_F(AudioInputTest, CreateAndClose) {
|
| + if (!CanRunAudioTests())
|
| return;
|
| - AudioInputStream* ais = CreateTestAudioInputStream(audio_man.get());
|
| - ais->Close();
|
| + MakeAudioInputStreamOnAudioThread();
|
| + CloseAudioInputStreamOnAudioThread();
|
| }
|
|
|
| #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
|
| @@ -124,13 +187,11 @@ TEST(AudioInputTest, CreateAndClose) {
|
| #define MAYBE_OpenAndClose OpenAndClose
|
| #endif
|
| // Test create, open and close of an AudioInputStream without recording audio.
|
| -TEST(AudioInputTest, MAYBE_OpenAndClose) {
|
| - scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting());
|
| - if (!CanRunAudioTests(audio_man.get()))
|
| +TEST_F(AudioInputTest, MAYBE_OpenAndClose) {
|
| + if (!CanRunAudioTests())
|
| return;
|
| - AudioInputStream* ais = CreateTestAudioInputStream(audio_man.get());
|
| - EXPECT_TRUE(ais->Open());
|
| - ais->Close();
|
| + MakeAudioInputStreamOnAudioThread();
|
| + OpenAndCloseAudioInputStreamOnAudioThread();
|
| }
|
|
|
| #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
|
| @@ -140,14 +201,11 @@ TEST(AudioInputTest, MAYBE_OpenAndClose) {
|
| #define MAYBE_OpenStopAndClose OpenStopAndClose
|
| #endif
|
| // Test create, open, stop and close of an AudioInputStream without recording.
|
| -TEST(AudioInputTest, MAYBE_OpenStopAndClose) {
|
| - scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting());
|
| - if (!CanRunAudioTests(audio_man.get()))
|
| +TEST_F(AudioInputTest, MAYBE_OpenStopAndClose) {
|
| + if (!CanRunAudioTests())
|
| return;
|
| - AudioInputStream* ais = CreateTestAudioInputStream(audio_man.get());
|
| - EXPECT_TRUE(ais->Open());
|
| - ais->Stop();
|
| - ais->Close();
|
| + MakeAudioInputStreamOnAudioThread();
|
| + OpenStopAndCloseAudioInputStreamOnAudioThread();
|
| }
|
|
|
| #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
|
| @@ -157,28 +215,25 @@ TEST(AudioInputTest, MAYBE_OpenStopAndClose) {
|
| #define MAYBE_Record Record
|
| #endif
|
| // Test a normal recording sequence using an AudioInputStream.
|
| -TEST(AudioInputTest, MAYBE_Record) {
|
| - scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting());
|
| - if (!CanRunAudioTests(audio_man.get()))
|
| +// Very simple test which starts capturing during half a second and verifies
|
| +// that recording starts.
|
| +TEST_F(AudioInputTest, MAYBE_Record) {
|
| + if (!CanRunAudioTests())
|
| return;
|
| - base::MessageLoop message_loop;
|
| - AudioInputStream* ais = CreateTestAudioInputStream(audio_man.get());
|
| - EXPECT_TRUE(ais->Open());
|
| -
|
| - TestInputCallback test_callback(kSamplesPerPacket * 4);
|
| - ais->Start(&test_callback);
|
| - // Verify at least 500ms worth of audio was recorded, after giving sufficient
|
| - // extra time.
|
| - message_loop.PostDelayedTask(
|
| + MakeAudioInputStreamOnAudioThread();
|
| +
|
| + TestInputCallback test_callback;
|
| + OpenAndStartAudioInputStreamOnAudioThread(&test_callback);
|
| +
|
| + message_loop_.PostDelayedTask(
|
| FROM_HERE,
|
| base::MessageLoop::QuitClosure(),
|
| - base::TimeDelta::FromMilliseconds(690));
|
| - message_loop.Run();
|
| - EXPECT_GE(test_callback.callback_count(), 1);
|
| + base::TimeDelta::FromMilliseconds(500));
|
| + message_loop_.Run();
|
| + EXPECT_GE(test_callback.callback_count(), 2);
|
| EXPECT_FALSE(test_callback.had_error());
|
|
|
| - ais->Stop();
|
| - ais->Close();
|
| + StopAndCloseAudioInputStreamOnAudioThread();
|
| }
|
|
|
| } // namespace media
|
|
|