summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorsatish@chromium.org <satish@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-02 16:16:49 +0000
committersatish@chromium.org <satish@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-02 16:16:49 +0000
commit3af7229b4f97f17b4f2aee34bd3ef3af7fd16e50 (patch)
tree3b19af016ec61763cbe6e4f5c925a5fbd3ac0c64 /media
parent4f8452d18c71301f141795eb95a9c2e0a8358aaf (diff)
downloadchromium_src-3af7229b4f97f17b4f2aee34bd3ef3af7fd16e50.zip
chromium_src-3af7229b4f97f17b4f2aee34bd3ef3af7fd16e50.tar.gz
chromium_src-3af7229b4f97f17b4f2aee34bd3ef3af7fd16e50.tar.bz2
This test now works for the mac audio capture code as well, and in a future CL I'll enable audio recording in linux and this test will suit that code too.
In the process I changed a uint32 in a function prototype to int because style guide recommends int for such cases. I also added parameter validation code to the mac audio manager to get it pass this new test. BUG=none TEST=media_unittests should succeed as before. Review URL: http://codereview.chromium.org/3357004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@58365 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r--media/audio/audio_input_unittest.cc (renamed from media/audio/win/audio_input_win_unittest.cc)85
-rw-r--r--media/audio/audio_manager.cc2
-rw-r--r--media/audio/audio_manager.h2
-rw-r--r--media/audio/linux/audio_manager_linux.cc2
-rw-r--r--media/audio/linux/audio_manager_linux.h2
-rw-r--r--media/audio/mac/audio_input_mac.cc2
-rw-r--r--media/audio/mac/audio_input_mac.h2
-rw-r--r--media/audio/mac/audio_input_mac_unittest.cc105
-rw-r--r--media/audio/mac/audio_manager_mac.cc10
-rw-r--r--media/audio/mac/audio_manager_mac.h2
-rw-r--r--media/audio/win/audio_manager_win.cc2
-rw-r--r--media/audio/win/audio_manager_win.h2
-rw-r--r--media/media.gyp3
13 files changed, 69 insertions, 152 deletions
diff --git a/media/audio/win/audio_input_win_unittest.cc b/media/audio/audio_input_unittest.cc
index 39cc3fba..6a67f0c 100644
--- a/media/audio/win/audio_input_win_unittest.cc
+++ b/media/audio/audio_input_unittest.cc
@@ -2,15 +2,20 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <windows.h>
-
#include "base/basictypes.h"
+#include "base/environment.h"
+#include "base/message_loop.h"
+#include "base/platform_thread.h"
+#include "base/scoped_ptr.h"
#include "media/audio/audio_io.h"
#include "media/audio/audio_manager.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
+const int kSamplingRate = 8000;
+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 {
@@ -27,7 +32,8 @@ class TestInputCallback : public AudioInputStream::AudioInputCallback {
// Read the first byte to make sure memory is good.
if (size) {
ASSERT_LE(static_cast<int>(size), max_data_bytes_);
- EXPECT_TRUE(data[0] >= 0);
+ int value = data[0];
+ EXPECT_TRUE(value >= 0);
}
}
virtual void OnClose(AudioInputStream* stream) {
@@ -75,7 +81,7 @@ class TestInputCallbackBlocking : public TestInputCallback {
// Call the base, which increments the callback_count_.
TestInputCallback::OnData(stream, data, size);
if (callback_count() > block_after_callback_)
- ::Sleep(block_for_ms_);
+ PlatformThread::Sleep(block_for_ms_);
}
private:
@@ -84,17 +90,30 @@ class TestInputCallbackBlocking : public TestInputCallback {
};
bool CanRunAudioTests() {
+ scoped_ptr<base::Environment> env(base::Environment::Create());
+ if (env->HasVar("CHROME_HEADLESS"))
+ return false;
+
AudioManager* audio_man = AudioManager::GetAudioManager();
if (NULL == audio_man)
return false;
- return (audio_man->HasAudioInputDevices() &&
- ::GetEnvironmentVariableW(L"CHROME_HEADLESS", NULL, 0) == 0);
+
+ return audio_man->HasAudioInputDevices();
+}
+
+AudioInputStream* CreateTestAudioInputStream() {
+ AudioManager* audio_man = AudioManager::GetAudioManager();
+ AudioInputStream* ais = audio_man->MakeAudioInputStream(
+ AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, kSamplingRate, 16),
+ kSamplesPerPacket);
+ EXPECT_TRUE(NULL != ais);
+ return ais;
}
} // namespace.
// Test that AudioInputStream rejects out of range parameters.
-TEST(WinAudioInputTest, SanityOnMakeParams) {
+TEST(AudioInputTest, SanityOnMakeParams) {
if (!CanRunAudioTests())
return;
AudioManager* audio_man = AudioManager::GetAudioManager();
@@ -118,46 +137,46 @@ TEST(WinAudioInputTest, SanityOnMakeParams) {
}
// Test create and close of an AudioInputStream without recording audio.
-TEST(WinAudioInputTest, CreateAndClose) {
+TEST(AudioInputTest, CreateAndClose) {
if (!CanRunAudioTests())
return;
- AudioManager* audio_man = AudioManager::GetAudioManager();
- AudioInputStream* ais = audio_man->MakeAudioInputStream(
- AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, 8000, 16), 0);
- ASSERT_TRUE(NULL != ais);
+ AudioInputStream* ais = CreateTestAudioInputStream();
ais->Close();
}
// Test create, open and close of an AudioInputStream without recording audio.
-TEST(WinAudioInputTest, OpenAndClose) {
+TEST(AudioInputTest, OpenAndClose) {
if (!CanRunAudioTests())
return;
- AudioManager* audio_man = AudioManager::GetAudioManager();
- AudioInputStream* ais = audio_man->MakeAudioInputStream(
- AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, 8000, 16), 0);
- ASSERT_TRUE(NULL != ais);
+ AudioInputStream* ais = CreateTestAudioInputStream();
EXPECT_TRUE(ais->Open());
ais->Close();
}
+// Test create, open, stop and close of an AudioInputStream without recording.
+TEST(AudioInputTest, OpenStopAndClose) {
+ if (!CanRunAudioTests())
+ return;
+ AudioInputStream* ais = CreateTestAudioInputStream();
+ EXPECT_TRUE(ais->Open());
+ ais->Stop();
+ ais->Close();
+}
+
// Test a normal recording sequence using an AudioInputStream.
-TEST(WinAudioInputTest, Record) {
+TEST(AudioInputTest, Record) {
if (!CanRunAudioTests())
return;
- AudioManager* audio_man = AudioManager::GetAudioManager();
- const int kSamplingRate = 8000;
- const int kSamplesPerPacket = kSamplingRate / 20;
- AudioInputStream* ais = audio_man->MakeAudioInputStream(
- AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, kSamplingRate, 16),
- kSamplesPerPacket);
- ASSERT_TRUE(NULL != ais);
+ MessageLoop message_loop(MessageLoop::TYPE_DEFAULT);
+ AudioInputStream* ais = CreateTestAudioInputStream();
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.
- Sleep(590);
+ message_loop.PostDelayedTask(FROM_HERE, new MessageLoop::QuitTask(), 590);
+ message_loop.Run();
EXPECT_GE(test_callback.callback_count(), 10);
EXPECT_FALSE(test_callback.had_error());
@@ -166,16 +185,11 @@ TEST(WinAudioInputTest, Record) {
}
// Test a recording sequence with delays in the audio callback.
-TEST(WinAudioInputTest, RecordWithSlowSink) {
+TEST(AudioInputTest, RecordWithSlowSink) {
if (!CanRunAudioTests())
return;
- AudioManager* audio_man = AudioManager::GetAudioManager();
- const int kSamplingRate = 8000;
- const int kSamplesPerPacket = kSamplingRate / 20;
- AudioInputStream* ais = audio_man->MakeAudioInputStream(
- AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, kSamplingRate, 16),
- kSamplesPerPacket);
- ASSERT_TRUE(NULL != ais);
+ MessageLoop message_loop(MessageLoop::TYPE_DEFAULT);
+ AudioInputStream* ais = CreateTestAudioInputStream();
EXPECT_TRUE(ais->Open());
// We should normally get a callback every 50ms, and a 20ms delay inside each
@@ -184,7 +198,8 @@ TEST(WinAudioInputTest, RecordWithSlowSink) {
ais->Start(&test_callback);
// Verify at least 500ms worth of audio was recorded, after giving sufficient
// extra time.
- Sleep(590);
+ message_loop.PostDelayedTask(FROM_HERE, new MessageLoop::QuitTask(), 590);
+ message_loop.Run();
EXPECT_GE(test_callback.callback_count(), 10);
EXPECT_FALSE(test_callback.had_error());
diff --git a/media/audio/audio_manager.cc b/media/audio/audio_manager.cc
index 7bb2402..3abd010 100644
--- a/media/audio/audio_manager.cc
+++ b/media/audio/audio_manager.cc
@@ -25,7 +25,7 @@ class NullAudioManager : public AudioManager {
return NULL;
}
virtual AudioInputStream* MakeAudioInputStream(AudioParameters params,
- uint32 samples_per_packet) {
+ int samples_per_packet) {
NOTIMPLEMENTED();
return NULL;
}
diff --git a/media/audio/audio_manager.h b/media/audio/audio_manager.h
index 2c988ba..805db89 100644
--- a/media/audio/audio_manager.h
+++ b/media/audio/audio_manager.h
@@ -54,7 +54,7 @@ class AudioManager {
// Do not free the returned AudioInputStream. It is owned by AudioManager.
// When you are done with it, call |Stop()| and |Close()| to release it.
virtual AudioInputStream* MakeAudioInputStream(AudioParameters params,
- uint32 samples_per_packet) = 0;
+ int samples_per_packet) = 0;
// Muting continues playback but effectively the volume is set to zero.
// Un-muting returns the volume to the previous level.
diff --git a/media/audio/linux/audio_manager_linux.cc b/media/audio/linux/audio_manager_linux.cc
index 00f23b1a..40a8783 100644
--- a/media/audio/linux/audio_manager_linux.cc
+++ b/media/audio/linux/audio_manager_linux.cc
@@ -50,7 +50,7 @@ AudioOutputStream* AudioManagerLinux::MakeAudioOutputStream(
}
AudioInputStream* AudioManagerLinux::MakeAudioInputStream(
- AudioParameters params, uint32 samples_per_packet) {
+ AudioParameters params, int samples_per_packet) {
if (params.format == AudioParameters::AUDIO_MOCK) {
return FakeAudioInputStream::MakeFakeStream(params, samples_per_packet);
}
diff --git a/media/audio/linux/audio_manager_linux.h b/media/audio/linux/audio_manager_linux.h
index f13e1a8..afa60af 100644
--- a/media/audio/linux/audio_manager_linux.h
+++ b/media/audio/linux/audio_manager_linux.h
@@ -28,7 +28,7 @@ class AudioManagerLinux : public AudioManagerBase {
virtual bool HasAudioInputDevices();
virtual AudioOutputStream* MakeAudioOutputStream(AudioParameters params);
virtual AudioInputStream* MakeAudioInputStream(
- AudioParameters params, uint32 samples_per_packet);
+ AudioParameters params, int samples_per_packet);
virtual void MuteAll();
virtual void UnMuteAll();
diff --git a/media/audio/mac/audio_input_mac.cc b/media/audio/mac/audio_input_mac.cc
index 9705cb30..88db2db 100644
--- a/media/audio/mac/audio_input_mac.cc
+++ b/media/audio/mac/audio_input_mac.cc
@@ -19,7 +19,7 @@ enum {
PCMQueueInAudioInputStream::PCMQueueInAudioInputStream(
AudioManagerMac* manager,
AudioParameters params,
- uint32 samples_per_buffer)
+ int samples_per_buffer)
: manager_(manager),
callback_(NULL),
audio_queue_(NULL),
diff --git a/media/audio/mac/audio_input_mac.h b/media/audio/mac/audio_input_mac.h
index c232d85..8b049f7 100644
--- a/media/audio/mac/audio_input_mac.h
+++ b/media/audio/mac/audio_input_mac.h
@@ -20,7 +20,7 @@ class PCMQueueInAudioInputStream : public AudioInputStream {
// Parameters as per AudioManager::MakeAudioInputStream.
PCMQueueInAudioInputStream(AudioManagerMac* manager,
AudioParameters params,
- uint32 samples_per_packet);
+ int samples_per_packet);
virtual ~PCMQueueInAudioInputStream();
// Implementation of AudioInputStream.
diff --git a/media/audio/mac/audio_input_mac_unittest.cc b/media/audio/mac/audio_input_mac_unittest.cc
deleted file mode 100644
index da0c918..0000000
--- a/media/audio/mac/audio_input_mac_unittest.cc
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright (c) 2010 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.
-
-// Tests the mac audio input stream implementation.
-// TODO(joth): See if we can generalize this for all platforms?
-
-#include "base/time.h"
-#include "media/audio/audio_io.h"
-#include "media/audio/audio_manager.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using ::testing::AllOf;
-using ::testing::AtLeast;
-using ::testing::Gt;
-using ::testing::Le;
-using ::testing::NotNull;
-using ::testing::StrictMock;
-
-class MockAudioInputCallback : public AudioInputStream::AudioInputCallback {
- public:
- MOCK_METHOD3(OnData, void(AudioInputStream* stream, const uint8* src,
- uint32 size));
- MOCK_METHOD1(OnClose, void(AudioInputStream* stream));
- MOCK_METHOD2(OnError, void(AudioInputStream* stream, int code));
-};
-
-// Test fixture.
-class AudioInputStreamMacTest : public testing::Test {
- protected:
- // From testing::Test.
- virtual void SetUp() {
- ias_ = NULL;
- AudioManager* audio_man = AudioManager::GetAudioManager();
- ASSERT_TRUE(NULL != audio_man);
- if (audio_man->HasAudioInputDevices()) {
- AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, 2,
- kSampleRate, 16);
- ias_ = audio_man->MakeAudioInputStream(params, kSamplesPerCall);
- }
- }
- virtual void TearDown() {
- ias_->Close();
- }
-
- bool TestEnabled() const {
- return NULL != ias_;
- }
-
- static const int kSampleRate = 8000;
- static const int kSamplesPerCall = 3000;
- // This is the default callback implementation; it will assert the expected
- // calls were received when it is destroyed.
- StrictMock<MockAudioInputCallback> client_;
- // The audio input stream under test.
- AudioInputStream* ias_;
-};
-
-// Test that can it be created and closed.
-TEST_F(AudioInputStreamMacTest, PCMInputStreamCreateAndClose) {
- if (!TestEnabled())
- return;
-}
-
-// Test that it can be opened and closed.
-TEST_F(AudioInputStreamMacTest, PCMInputStreamOpenAndClose) {
- if (!TestEnabled())
- return;
- EXPECT_TRUE(ias_->Open());
-}
-
-// Test we handle a open then stop OK.
-TEST_F(AudioInputStreamMacTest, PCMInputStreamOpenTheStop) {
- if (!TestEnabled())
- return;
- EXPECT_TRUE(ias_->Open());
- ias_->Stop();
-}
-
-// Record for a short time then stop. Make sure we get the callbacks.
-TEST_F(AudioInputStreamMacTest, PCMInputStreamRecordCoupleSeconds) {
- if (!TestEnabled())
- return;
- ASSERT_TRUE(ias_->Open());
- // For a given sample rate, number of samples per callback, and recording time
- // we can estimate the number of callbacks we should get. We underestimate
- // this slightly, as the callback thread could be slow.
- static const double kRecordPeriodSecs = 1.5;
- static const int kMinExpectedCalls =
- (kRecordPeriodSecs * kSampleRate / kSamplesPerCall) - 1;
- // Check this is in reasonable bounds.
- EXPECT_GT(kMinExpectedCalls, 1);
- EXPECT_LT(kMinExpectedCalls, 10);
-
- static const uint kMaxBytesPerCall = 2 * 2 * kSamplesPerCall;
- EXPECT_CALL(client_, OnData(ias_, NotNull(),
- AllOf(Gt(0u), Le(kMaxBytesPerCall))))
- .Times(AtLeast(kMinExpectedCalls));
- EXPECT_CALL(client_, OnClose(ias_));
-
- ias_->Start(&client_);
- usleep(kRecordPeriodSecs * base::Time::kMicrosecondsPerSecond);
- ias_->Stop();
-}
diff --git a/media/audio/mac/audio_manager_mac.cc b/media/audio/mac/audio_manager_mac.cc
index dde2917..1eb9398 100644
--- a/media/audio/mac/audio_manager_mac.cc
+++ b/media/audio/mac/audio_manager_mac.cc
@@ -9,8 +9,12 @@
#include "media/audio/mac/audio_input_mac.h"
#include "media/audio/mac/audio_manager_mac.h"
#include "media/audio/mac/audio_output_mac.h"
+#include "media/base/limits.h"
namespace {
+const int kMaxInputChannels = 2;
+const int kMaxSamplesPerPacket = media::Limits::kMaxSampleRate;
+
bool HasAudioHardware(AudioObjectPropertySelector selector) {
AudioDeviceID output_device_id = kAudioObjectUnknown;
const AudioObjectPropertyAddress property_address = {
@@ -48,7 +52,11 @@ AudioOutputStream* AudioManagerMac::MakeAudioOutputStream(
}
AudioInputStream* AudioManagerMac::MakeAudioInputStream(
- AudioParameters params, uint32 samples_per_packet) {
+ AudioParameters params, int samples_per_packet) {
+ if (!params.IsValid() || (params.channels > kMaxInputChannels) ||
+ (samples_per_packet > kMaxSamplesPerPacket) || (samples_per_packet < 0))
+ return NULL;
+
if (params.format == AudioParameters::AUDIO_MOCK) {
return FakeAudioInputStream::MakeFakeStream(params, samples_per_packet);
} else if (params.format == AudioParameters::AUDIO_PCM_LINEAR) {
diff --git a/media/audio/mac/audio_manager_mac.h b/media/audio/mac/audio_manager_mac.h
index 53df700..3abfab1 100644
--- a/media/audio/mac/audio_manager_mac.h
+++ b/media/audio/mac/audio_manager_mac.h
@@ -23,7 +23,7 @@ class AudioManagerMac : public AudioManagerBase {
virtual bool HasAudioInputDevices();
virtual AudioOutputStream* MakeAudioOutputStream(AudioParameters params);
virtual AudioInputStream* MakeAudioInputStream(AudioParameters params,
- uint32 samples_per_packet);
+ int samples_per_packet);
virtual void MuteAll();
virtual void UnMuteAll();
diff --git a/media/audio/win/audio_manager_win.cc b/media/audio/win/audio_manager_win.cc
index f1c88e3..2e65879 100644
--- a/media/audio/win/audio_manager_win.cc
+++ b/media/audio/win/audio_manager_win.cc
@@ -65,7 +65,7 @@ AudioOutputStream* AudioManagerWin::MakeAudioOutputStream(
// Factory for the implementations of AudioInputStream.
AudioInputStream* AudioManagerWin::MakeAudioInputStream(
- AudioParameters params, uint32 samples_per_packet) {
+ AudioParameters params, int samples_per_packet) {
if (!params.IsValid() || (params.channels > kWinMaxInputChannels) ||
(samples_per_packet > kMaxSamplesPerPacket) || (samples_per_packet < 0))
return NULL;
diff --git a/media/audio/win/audio_manager_win.h b/media/audio/win/audio_manager_win.h
index 61c7b33..09f0019 100644
--- a/media/audio/win/audio_manager_win.h
+++ b/media/audio/win/audio_manager_win.h
@@ -24,7 +24,7 @@ class AudioManagerWin : public AudioManagerBase {
virtual bool HasAudioInputDevices();
virtual AudioOutputStream* MakeAudioOutputStream(AudioParameters params);
virtual AudioInputStream* MakeAudioInputStream(AudioParameters params,
- uint32 samples_per_packet);
+ int samples_per_packet);
virtual void MuteAll();
virtual void UnMuteAll();
diff --git a/media/media.gyp b/media/media.gyp
index 6b56922..70e7c26 100644
--- a/media/media.gyp
+++ b/media/media.gyp
@@ -238,14 +238,13 @@
],
'sources': [
'audio/audio_input_controller_unittest.cc',
+ 'audio/audio_input_unittest.cc',
'audio/audio_output_controller_unittest.cc',
'audio/audio_util_unittest.cc',
'audio/fake_audio_input_stream_unittest.cc',
'audio/linux/alsa_output_unittest.cc',
- 'audio/mac/audio_input_mac_unittest.cc',
'audio/mac/audio_output_mac_unittest.cc',
'audio/simple_sources_unittest.cc',
- 'audio/win/audio_input_win_unittest.cc',
'audio/win/audio_output_win_unittest.cc',
'base/clock_impl_unittest.cc',
'base/data_buffer_unittest.cc',