summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorxians@chromium.org <xians@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-07 15:25:51 +0000
committerxians@chromium.org <xians@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-07 15:25:51 +0000
commitf34a9058aa124789ebc5b1e38d9d890c29f49ce5 (patch)
tree4002bf52e0861deb1c75b7f09cd6f601487a54d7
parenteaabba206ae14905ef3a922e7b839cab285dd940 (diff)
downloadchromium_src-f34a9058aa124789ebc5b1e38d9d890c29f49ce5.zip
chromium_src-f34a9058aa124789ebc5b1e38d9d890c29f49ce5.tar.gz
chromium_src-f34a9058aa124789ebc5b1e38d9d890c29f49ce5.tar.bz2
Moved the implementations of ReleaseOutputStream() and ReleaseInputStream() to AudioManagerBase and let all the AudioManagerPlatforms inherit the same implementations.
Also moved the MakeAudioOutputStream() and MakeAudioInputStream() to AudioManagerBase, separate the AUDIO_PCM_LINEAR mode and AUDIO_PCM_LOW_LATENCY mode into two different functions inside the AudioManagerPlatforms. So that the structure is clearer and also easier to deprecate the AUDIO_PCM_LINEAR for the future. Made the destructor of the AudioManagerPlatforms protected so it can be called by only the AudioManagerBase. BUG=116064 TEST=media_unittests Review URL: http://codereview.chromium.org/9570014 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@125389 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--media/audio/android/audio_manager_android.cc49
-rw-r--r--media/audio/android/audio_manager_android.h16
-rw-r--r--media/audio/audio_input_volume_unittest.cc5
-rw-r--r--media/audio/audio_manager_base.cc80
-rw-r--r--media/audio/audio_manager_base.h42
-rw-r--r--media/audio/linux/alsa_input.cc30
-rw-r--r--media/audio/linux/alsa_input.h1
-rw-r--r--media/audio/linux/alsa_output.cc25
-rw-r--r--media/audio/linux/alsa_output_unittest.cc314
-rw-r--r--media/audio/linux/audio_manager_linux.cc132
-rw-r--r--media/audio/linux/audio_manager_linux.h26
-rw-r--r--media/audio/mac/audio_manager_mac.cc125
-rw-r--r--media/audio/mac/audio_manager_mac.h24
-rw-r--r--media/audio/openbsd/audio_manager_openbsd.cc90
-rw-r--r--media/audio/openbsd/audio_manager_openbsd.h20
-rw-r--r--media/audio/win/audio_manager_win.cc147
-rw-r--r--media/audio/win/audio_manager_win.h22
17 files changed, 627 insertions, 521 deletions
diff --git a/media/audio/android/audio_manager_android.cc b/media/audio/android/audio_manager_android.cc
index 0170675..9d17934 100644
--- a/media/audio/android/audio_manager_android.cc
+++ b/media/audio/android/audio_manager_android.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -8,13 +8,17 @@
#include "media/audio/android/audio_track_output_android.h"
#include "media/audio/audio_manager.h"
#include "media/audio/fake_audio_input_stream.h"
-#include "media/audio/fake_audio_output_stream.h"
+
+// Maximum number of output streams that can be open simultaneously.
+static const int kMaxOutputStreams = 10;
AudioManager* CreateAudioManager() {
return new AudioManagerAndroid();
}
-AudioManagerAndroid::AudioManagerAndroid() {}
+AudioManagerAndroid::AudioManagerAndroid() {
+ SetMaxOutputStreamsAllowed(kMaxOutputStreams);
+}
AudioManagerAndroid::~AudioManagerAndroid() {
audio_thread_->Stop();
@@ -28,29 +32,34 @@ bool AudioManagerAndroid::HasAudioInputDevices() {
return false;
}
-AudioOutputStream* AudioManagerAndroid::MakeAudioOutputStream(
- const AudioParameters& params) {
- if (!params.IsValid())
- return NULL;
+void AudioManagerAndroid::MuteAll() {
+ NOTIMPLEMENTED();
+}
- if (params.format == AudioParameters::AUDIO_MOCK)
- return FakeAudioOutputStream::MakeFakeStream(params);
- if (params.format == AudioParameters::AUDIO_PCM_LINEAR ||
- params.format == AudioParameters::AUDIO_PCM_LOW_LATENCY)
- return AudioTrackOutputStream::MakeStream(params);
+void AudioManagerAndroid::UnMuteAll() {
+ NOTIMPLEMENTED();
+}
- return NULL;
+AudioOutputStream* AudioManagerAndroid::MakeLinearOutputStream(
+ const AudioParameters& params) {
+ DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format);
+ return AudioTrackOutputStream::MakeStream(params);
}
-AudioInputStream* AudioManagerAndroid::MakeAudioInputStream(
- const AudioParameters& params, const std::string& device_id) {
- return FakeAudioInputStream::MakeFakeStream(params);
+AudioOutputStream* AudioManagerAndroid::MakeLowLatencyOutputStream(
+ const AudioParameters& params) {
+ DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format);
+ return AudioTrackOutputStream::MakeStream(params);
}
-void AudioManagerAndroid::MuteAll() {
- NOTIMPLEMENTED();
+AudioInputStream* AudioManagerAndroid::MakeLinearInputStream(
+ const AudioParameters& params, const std::string& device_id) {
+ DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format);
+ return FakeAudioInputStream::MakeFakeStream(params);
}
-void AudioManagerAndroid::UnMuteAll() {
- NOTIMPLEMENTED();
+AudioInputStream* AudioManagerAndroid::MakeLowLatencyInputStream(
+ const AudioParameters& params, const std::string& device_id) {
+ DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format);
+ return FakeAudioInputStream::MakeFakeStream(params);
}
diff --git a/media/audio/android/audio_manager_android.h b/media/audio/android/audio_manager_android.h
index ab43a60..5d42270 100644
--- a/media/audio/android/audio_manager_android.h
+++ b/media/audio/android/audio_manager_android.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -15,13 +15,19 @@ class AudioManagerAndroid : public AudioManagerBase {
// Implementation of AudioManager.
virtual bool HasAudioOutputDevices() OVERRIDE;
virtual bool HasAudioInputDevices() OVERRIDE;
- virtual AudioOutputStream* MakeAudioOutputStream(
- const AudioParameters& params) OVERRIDE;
- virtual AudioInputStream* MakeAudioInputStream(
- const AudioParameters& params, const std::string& device_id) OVERRIDE;
virtual void MuteAll() OVERRIDE;
virtual void UnMuteAll() OVERRIDE;
+ // Implementation of AudioManagerBase.
+ virtual AudioOutputStream* MakeLinearOutputStream(
+ const AudioParameters& params) OVERRIDE;
+ virtual AudioOutputStream* MakeLowLatencyOutputStream(
+ const AudioParameters& params) OVERRIDE;
+ virtual AudioInputStream* MakeLinearInputStream(
+ const AudioParameters& params, const std::string& device_id) OVERRIDE;
+ virtual AudioInputStream* MakeLowLatencyInputStream(
+ const AudioParameters& params, const std::string& device_id) OVERRIDE;
+
protected:
virtual ~AudioManagerAndroid();
diff --git a/media/audio/audio_input_volume_unittest.cc b/media/audio/audio_input_volume_unittest.cc
index 15cb7fb..febdb78 100644
--- a/media/audio/audio_input_volume_unittest.cc
+++ b/media/audio/audio_input_volume_unittest.cc
@@ -97,7 +97,10 @@ TEST_F(AudioInputVolumeTest, InputVolumeTest) {
// Retrieve a list of all available input devices.
AudioDeviceNames device_names;
audio_manager_->GetAudioInputDeviceNames(&device_names);
- DCHECK(!device_names.empty());
+ if (device_names.empty()) {
+ LOG(WARNING) << "Could not find any available input device";
+ return;
+ }
// Scan all available input devices and repeat the same test for all of them.
for (AudioDeviceNames::const_iterator it = device_names.begin();
diff --git a/media/audio/audio_manager_base.cc b/media/audio/audio_manager_base.cc
index 2957e96..05ed044 100644
--- a/media/audio/audio_manager_base.cc
+++ b/media/audio/audio_manager_base.cc
@@ -9,18 +9,30 @@
#include "base/threading/thread.h"
#include "media/audio/audio_output_dispatcher.h"
#include "media/audio/audio_output_proxy.h"
+#include "media/audio/fake_audio_input_stream.h"
+#include "media/audio/fake_audio_output_stream.h"
static const int kStreamCloseDelaySeconds = 5;
+// Default maximum number of output streams that can be open simultaneously
+// for all platforms.
+static const int kDefaultMaxOutputStreams = 15;
+
+static const int kMaxInputChannels = 2;
+
const char AudioManagerBase::kDefaultDeviceName[] = "Default";
const char AudioManagerBase::kDefaultDeviceId[] = "default";
AudioManagerBase::AudioManagerBase()
- : num_active_input_streams_(0) {
+ : num_active_input_streams_(0),
+ max_num_output_streams_(kDefaultMaxOutputStreams),
+ num_output_streams_(0) {
}
AudioManagerBase::~AudioManagerBase() {
Shutdown();
+ // All the output streams should have been deleted.
+ DCHECK_EQ(0, num_output_streams_);
}
void AudioManagerBase::Init() {
@@ -39,6 +51,57 @@ scoped_refptr<base::MessageLoopProxy> AudioManagerBase::GetMessageLoop() {
return audio_thread_.get() ? audio_thread_->message_loop_proxy() : NULL;
}
+AudioOutputStream* AudioManagerBase::MakeAudioOutputStream(
+ const AudioParameters& params) {
+ if (!params.IsValid()) {
+ DLOG(ERROR) << "Audio parameters are invalid";
+ return NULL;
+ }
+
+ // Limit the number of audio streams opened. This is to prevent using
+ // excessive resources for a large number of audio streams. More
+ // importantly it prevents instability on certain systems.
+ // See bug: http://crbug.com/30242.
+ if (num_output_streams_ >= max_num_output_streams_) {
+ DLOG(ERROR) << "Number of opened audio streams " << num_output_streams_
+ << " exceed the max allowed number " << max_num_output_streams_;
+ return NULL;
+ }
+
+ AudioOutputStream* stream = NULL;
+ if (params.format == AudioParameters::AUDIO_MOCK) {
+ stream = FakeAudioOutputStream::MakeFakeStream(params);
+ } else if (params.format == AudioParameters::AUDIO_PCM_LINEAR) {
+ num_output_streams_++;
+ stream = MakeLinearOutputStream(params);
+ } else if (params.format == AudioParameters::AUDIO_PCM_LOW_LATENCY) {
+ num_output_streams_++;
+ stream = MakeLowLatencyOutputStream(params);
+ }
+
+ return stream;
+}
+
+AudioInputStream* AudioManagerBase::MakeAudioInputStream(
+ const AudioParameters& params, const std::string& device_id) {
+ if (!params.IsValid() || (params.channels > kMaxInputChannels) ||
+ device_id.empty()) {
+ DLOG(ERROR) << "Audio parameters are invalid for device " << device_id;
+ return NULL;
+ }
+
+ AudioInputStream* stream = NULL;
+ if (params.format == AudioParameters::AUDIO_MOCK) {
+ stream = FakeAudioInputStream::MakeFakeStream(params);
+ } else if (params.format == AudioParameters::AUDIO_PCM_LINEAR) {
+ stream = MakeLinearInputStream(params, device_id);
+ } else if (params.format == AudioParameters::AUDIO_PCM_LOW_LATENCY) {
+ stream = MakeLowLatencyInputStream(params, device_id);
+ }
+
+ return stream;
+}
+
AudioOutputStream* AudioManagerBase::MakeAudioOutputStreamProxy(
const AudioParameters& params) {
DCHECK(GetMessageLoop()->BelongsToCurrentThread());
@@ -62,6 +125,21 @@ void AudioManagerBase::GetAudioInputDeviceNames(
media::AudioDeviceNames* device_names) {
}
+void AudioManagerBase::ReleaseOutputStream(AudioOutputStream* stream) {
+ DCHECK(stream);
+ // TODO(xians) : Have a clearer destruction path for the AudioOutputStream.
+ // For example, pass the ownership to AudioManager so it can delete the
+ // streams.
+ num_output_streams_--;
+ delete stream;
+}
+
+void AudioManagerBase::ReleaseInputStream(AudioInputStream* stream) {
+ DCHECK(stream);
+ // TODO(xians) : Have a clearer destruction path for the AudioInputStream.
+ delete stream;
+}
+
void AudioManagerBase::IncreaseActiveInputStreamCount() {
base::AtomicRefCountInc(&num_active_input_streams_);
}
diff --git a/media/audio/audio_manager_base.h b/media/audio/audio_manager_base.h
index 7f42ea7..ea9c78a 100644
--- a/media/audio/audio_manager_base.h
+++ b/media/audio/audio_manager_base.h
@@ -38,14 +38,24 @@ class MEDIA_EXPORT AudioManagerBase : public AudioManager {
virtual bool CanShowAudioInputSettings() OVERRIDE;
virtual void ShowAudioInputSettings() OVERRIDE;
- virtual void GetAudioInputDeviceNames(media::AudioDeviceNames* device_names)
- OVERRIDE;
+ virtual void GetAudioInputDeviceNames(
+ media::AudioDeviceNames* device_names) OVERRIDE;
+
+ virtual AudioOutputStream* MakeAudioOutputStream(
+ const AudioParameters& params) OVERRIDE;
+
+ virtual AudioInputStream* MakeAudioInputStream(
+ const AudioParameters& params, const std::string& device_id) OVERRIDE;
virtual AudioOutputStream* MakeAudioOutputStreamProxy(
const AudioParameters& params) OVERRIDE;
virtual bool IsRecordingInProcess() OVERRIDE;
+ // Called internally by the audio stream when it has been closed.
+ virtual void ReleaseOutputStream(AudioOutputStream* stream);
+ virtual void ReleaseInputStream(AudioInputStream* stream);
+
void IncreaseActiveInputStreamCount();
void DecreaseActiveInputStreamCount();
@@ -54,6 +64,24 @@ class MEDIA_EXPORT AudioManagerBase : public AudioManager {
// Shutdown is called.
void Shutdown();
+ // Creates the output stream for the |AUDIO_PCM_LINEAR| format. The legacy
+ // name is also from |AUDIO_PCM_LINEAR|.
+ virtual AudioOutputStream* MakeLinearOutputStream(
+ const AudioParameters& params) = 0;
+
+ // Creates the output stream for the |AUDIO_PCM_LOW_LATENCY| format.
+ virtual AudioOutputStream* MakeLowLatencyOutputStream(
+ const AudioParameters& params) = 0;
+
+ // Creates the input stream for the |AUDIO_PCM_LINEAR| format. The legacy
+ // name is also from |AUDIO_PCM_LINEAR|.
+ virtual AudioInputStream* MakeLinearInputStream(
+ const AudioParameters& params, const std::string& device_id) = 0;
+
+ // Creates the input stream for the |AUDIO_PCM_LOW_LATENCY| format.
+ virtual AudioInputStream* MakeLowLatencyInputStream(
+ const AudioParameters& params, const std::string& device_id) = 0;
+
protected:
AudioManagerBase();
@@ -63,6 +91,8 @@ class MEDIA_EXPORT AudioManagerBase : public AudioManager {
void ShutdownOnAudioThread();
+ void SetMaxOutputStreamsAllowed(int max) { max_num_output_streams_ = max; }
+
// Thread used to interact with AudioOutputStreams created by this
// audio manger.
scoped_ptr<base::Thread> audio_thread_;
@@ -72,10 +102,18 @@ class MEDIA_EXPORT AudioManagerBase : public AudioManager {
// from the audio thread (no locking).
AudioOutputDispatchersMap output_dispatchers_;
+ private:
// Counts the number of active input streams to find out if something else
// is currently recording in Chrome.
base::AtomicRefCount num_active_input_streams_;
+ // Max number of open output streams, modified by
+ // SetMaxOutputStreamsAllowed().
+ int max_num_output_streams_;
+
+ // Number of currently open output streams.
+ int num_output_streams_;
+
DISALLOW_COPY_AND_ASSIGN(AudioManagerBase);
};
diff --git a/media/audio/linux/alsa_input.cc b/media/audio/linux/alsa_input.cc
index 101c198..994c065 100644
--- a/media/audio/linux/alsa_input.cc
+++ b/media/audio/linux/alsa_input.cc
@@ -247,25 +247,25 @@ void AlsaPcmInputStream::Stop() {
}
void AlsaPcmInputStream::Close() {
- scoped_ptr<AlsaPcmInputStream> self_deleter(this);
+ if (device_handle_) {
+ weak_factory_.InvalidateWeakPtrs(); // Cancel the next scheduled read.
+ int error = alsa_util::CloseDevice(wrapper_, device_handle_);
+ if (error < 0)
+ HandleError("PcmClose", error);
- // Check in case we were already closed or not initialized yet.
- if (!device_handle_)
- return;
+ if (mixer_handle_)
+ alsa_util::CloseMixer(wrapper_, mixer_handle_, device_name_);
- weak_factory_.InvalidateWeakPtrs(); // Cancel the next scheduled read.
- int error = alsa_util::CloseDevice(wrapper_, device_handle_);
- if (error < 0)
- HandleError("PcmClose", error);
-
- if (mixer_handle_)
- alsa_util::CloseMixer(wrapper_, mixer_handle_, device_name_);
+ audio_packet_.reset();
+ device_handle_ = NULL;
+ mixer_handle_ = NULL;
+ mixer_element_handle_ = NULL;
- audio_packet_.reset();
- device_handle_ = NULL;
+ if (callback_)
+ callback_->OnClose(this);
+ }
- if (callback_)
- callback_->OnClose(this);
+ audio_manager_->ReleaseInputStream(this);
}
double AlsaPcmInputStream::GetMaxVolume() {
diff --git a/media/audio/linux/alsa_input.h b/media/audio/linux/alsa_input.h
index 4db2b9a..f5f216b 100644
--- a/media/audio/linux/alsa_input.h
+++ b/media/audio/linux/alsa_input.h
@@ -34,6 +34,7 @@ class AlsaPcmInputStream : public AudioInputStream {
const std::string& device_name,
const AudioParameters& params,
AlsaWrapper* wrapper);
+
virtual ~AlsaPcmInputStream();
// Implementation of AudioInputStream.
diff --git a/media/audio/linux/alsa_output.cc b/media/audio/linux/alsa_output.cc
index a57c276..8394c56 100644
--- a/media/audio/linux/alsa_output.cc
+++ b/media/audio/linux/alsa_output.cc
@@ -295,14 +295,12 @@ bool AlsaPcmOutputStream::Open() {
void AlsaPcmOutputStream::Close() {
DCHECK(IsOnAudioThread());
- // Sanity check that the transition occurs correctly. It is safe to
- // continue anyways because all operations for closing are idempotent.
- if (TransitionTo(kIsClosed) != kIsClosed) {
- NOTREACHED() << "Unable to transition Closed.";
- } else {
- // Shutdown the audio device.
- if (playback_handle_ &&
- alsa_util::CloseDevice(wrapper_, playback_handle_) < 0) {
+ if (state() != kIsClosed)
+ TransitionTo(kIsClosed);
+
+ // Shutdown the audio device.
+ if (playback_handle_) {
+ if (alsa_util::CloseDevice(wrapper_, playback_handle_) < 0) {
LOG(WARNING) << "Unable to close audio device. Leaking handle.";
}
playback_handle_ = NULL;
@@ -313,12 +311,13 @@ void AlsaPcmOutputStream::Close() {
// Signal anything that might already be scheduled to stop.
stop_stream_ = true; // Not necessary in production, but unit tests
// uses the flag to verify that stream was closed.
- weak_factory_.InvalidateWeakPtrs();
-
- // Signal to the manager that we're closed and can be removed.
- // Should be last call in the method as it deletes "this".
- manager_->ReleaseOutputStream(this);
}
+
+ weak_factory_.InvalidateWeakPtrs();
+
+ // Signal to the manager that we're closed and can be removed.
+ // Should be last call in the method as it deletes "this".
+ manager_->ReleaseOutputStream(this);
}
void AlsaPcmOutputStream::Start(AudioSourceCallback* callback) {
diff --git a/media/audio/linux/alsa_output_unittest.cc b/media/audio/linux/alsa_output_unittest.cc
index bcf2e3d..8658996 100644
--- a/media/audio/linux/alsa_output_unittest.cc
+++ b/media/audio/linux/alsa_output_unittest.cc
@@ -78,13 +78,25 @@ class MockAudioManagerLinux : public AudioManagerLinux {
MOCK_METHOD0(Init, void());
MOCK_METHOD0(HasAudioOutputDevices, bool());
MOCK_METHOD0(HasAudioInputDevices, bool());
- MOCK_METHOD1(MakeAudioOutputStream, AudioOutputStream*(
- const AudioParameters& params));
- MOCK_METHOD2(MakeAudioInputStream, AudioInputStream*(
- const AudioParameters& params, const std::string& device_id));
MOCK_METHOD0(MuteAll, void());
MOCK_METHOD0(UnMuteAll, void());
- MOCK_METHOD1(ReleaseOutputStream, void(AudioOutputStream* stream));
+ MOCK_METHOD1(MakeLinearOutputStream, AudioOutputStream*(
+ const AudioParameters& params));
+ MOCK_METHOD1(MakeLowLatencyOutputStream, AudioOutputStream*(
+ const AudioParameters& params));
+ MOCK_METHOD2(MakeLinearOutputStream, AudioInputStream*(
+ const AudioParameters& params, const std::string& device_id));
+ MOCK_METHOD2(MakeLowLatencyInputStream, AudioInputStream*(
+ const AudioParameters& params, const std::string& device_id));
+
+ // We need to override this function in order to skip the checking the number
+ // of active output streams. It is because the number of active streams
+ // is managed inside MakeAudioOutputStream, and we don't use
+ // MakeAudioOutputStream to create the stream in the tests.
+ virtual void ReleaseOutputStream(AudioOutputStream* stream) OVERRIDE {
+ DCHECK(stream);
+ delete stream;
+ }
// We don't mock this method since all tests will do the same thing
// and use the current message loop.
@@ -97,11 +109,9 @@ class AlsaPcmOutputStreamTest : public testing::Test {
protected:
AlsaPcmOutputStreamTest() {
mock_manager_.reset(new StrictMock<MockAudioManagerLinux>());
- test_stream_.reset(CreateStream(kTestChannelLayout));
}
virtual ~AlsaPcmOutputStreamTest() {
- test_stream_.reset(NULL);
}
AlsaPcmOutputStream* CreateStream(ChannelLayout layout) {
@@ -128,13 +138,14 @@ class AlsaPcmOutputStreamTest : public testing::Test {
return strdup("Output");
}
- // Helper function to initialize |test_stream_->buffer_|. Must be called
+ // Helper function to initialize |test_stream->buffer_|. Must be called
// in all tests that use buffer_ without opening the stream.
- void InitBuffer() {
+ void InitBuffer(AlsaPcmOutputStream* test_stream) {
+ DCHECK(test_stream);
packet_ = new media::DataBuffer(kTestPacketSize);
packet_->SetDataSize(kTestPacketSize);
- test_stream_->buffer_.reset(new media::SeekableBuffer(0, kTestPacketSize));
- test_stream_->buffer_->Append(packet_.get());
+ test_stream->buffer_.reset(new media::SeekableBuffer(0, kTestPacketSize));
+ test_stream->buffer_->Append(packet_.get());
}
MockAudioManagerLinux& mock_manager() {
@@ -165,7 +176,6 @@ class AlsaPcmOutputStreamTest : public testing::Test {
StrictMock<MockAlsaWrapper> mock_alsa_wrapper_;
scoped_ptr<StrictMock<MockAudioManagerLinux> > mock_manager_;
MessageLoop message_loop_;
- scoped_ptr<AlsaPcmOutputStream> test_stream_;
scoped_refptr<media::DataBuffer> packet_;
private:
@@ -203,35 +213,41 @@ void* AlsaPcmOutputStreamTest::kFakeHints[] = {
kSurround70, kSurround71, NULL };
TEST_F(AlsaPcmOutputStreamTest, ConstructedState) {
- EXPECT_EQ(AlsaPcmOutputStream::kCreated, test_stream_->state());
+ AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout);
+ EXPECT_EQ(AlsaPcmOutputStream::kCreated, test_stream->state());
+ test_stream->Close();
// Should support mono.
- test_stream_.reset(CreateStream(CHANNEL_LAYOUT_MONO));
- EXPECT_EQ(AlsaPcmOutputStream::kCreated, test_stream_->state());
+ test_stream = CreateStream(CHANNEL_LAYOUT_MONO);
+ EXPECT_EQ(AlsaPcmOutputStream::kCreated, test_stream->state());
+ test_stream->Close();
// Should support multi-channel.
- test_stream_.reset(CreateStream(CHANNEL_LAYOUT_SURROUND));
- EXPECT_EQ(AlsaPcmOutputStream::kCreated, test_stream_->state());
+ test_stream = CreateStream(CHANNEL_LAYOUT_SURROUND);
+ EXPECT_EQ(AlsaPcmOutputStream::kCreated, test_stream->state());
+ test_stream->Close();
// Bad bits per sample.
AudioParameters bad_bps_params(kTestFormat, kTestChannelLayout,
kTestSampleRate, kTestBitsPerSample - 1,
kTestFramesPerPacket);
- test_stream_.reset(new AlsaPcmOutputStream(kTestDeviceName,
- bad_bps_params,
- &mock_alsa_wrapper_,
- mock_manager_.get()));
- EXPECT_EQ(AlsaPcmOutputStream::kInError, test_stream_->state());
+ test_stream = new AlsaPcmOutputStream(kTestDeviceName,
+ bad_bps_params,
+ &mock_alsa_wrapper_,
+ mock_manager_.get());
+ EXPECT_EQ(AlsaPcmOutputStream::kInError, test_stream->state());
+ test_stream->Close();
// Bad format.
AudioParameters bad_format_params(
AudioParameters::AUDIO_LAST_FORMAT, kTestChannelLayout, kTestSampleRate,
kTestBitsPerSample, kTestFramesPerPacket);
- test_stream_.reset(new AlsaPcmOutputStream(kTestDeviceName,
- bad_format_params,
- &mock_alsa_wrapper_,
- mock_manager_.get()));
- EXPECT_EQ(AlsaPcmOutputStream::kInError, test_stream_->state());
+ test_stream = new AlsaPcmOutputStream(kTestDeviceName,
+ bad_format_params,
+ &mock_alsa_wrapper_,
+ mock_manager_.get());
+ EXPECT_EQ(AlsaPcmOutputStream::kInError, test_stream->state());
+ test_stream->Close();
}
TEST_F(AlsaPcmOutputStreamTest, LatencyFloor) {
@@ -255,16 +271,15 @@ TEST_F(AlsaPcmOutputStreamTest, LatencyFloor) {
SetArgumentPointee<2>(kTestFramesPerPacket / 2),
Return(0)));
- test_stream_.reset(CreateStream(kTestChannelLayout,
- kPacketFramesInMinLatency));
- ASSERT_TRUE(test_stream_->Open());
+ AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout,
+ kPacketFramesInMinLatency);
+ ASSERT_TRUE(test_stream->Open());
// Now close it and test that everything was released.
EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle)).WillOnce(Return(0));
EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle))
.WillOnce(Return(kTestDeviceName));
- EXPECT_CALL(mock_manager(), ReleaseOutputStream(test_stream_.get()));
- test_stream_->Close();
+ test_stream->Close();
Mock::VerifyAndClear(&mock_alsa_wrapper_);
Mock::VerifyAndClear(mock_manager_.get());
@@ -284,17 +299,16 @@ TEST_F(AlsaPcmOutputStreamTest, LatencyFloor) {
SetArgumentPointee<2>(kTestFramesPerPacket / 2),
Return(0)));
- test_stream_.reset(CreateStream(kTestChannelLayout,
- kOverMinLatencyPacketSize));
- ASSERT_TRUE(test_stream_->Open());
+ test_stream = CreateStream(kTestChannelLayout,
+ kOverMinLatencyPacketSize);
+ ASSERT_TRUE(test_stream->Open());
// Now close it and test that everything was released.
EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle))
.WillOnce(Return(0));
EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle))
.WillOnce(Return(kTestDeviceName));
- EXPECT_CALL(mock_manager(), ReleaseOutputStream(test_stream_.get()));
- test_stream_->Close();
+ test_stream->Close();
Mock::VerifyAndClear(&mock_alsa_wrapper_);
Mock::VerifyAndClear(mock_manager_.get());
@@ -328,25 +342,21 @@ TEST_F(AlsaPcmOutputStreamTest, OpenClose) {
Return(0)));
// Open the stream.
- ASSERT_TRUE(test_stream_->Open());
+ AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout);
+ ASSERT_TRUE(test_stream->Open());
- EXPECT_EQ(AlsaPcmOutputStream::kIsOpened, test_stream_->state());
- EXPECT_EQ(kFakeHandle, test_stream_->playback_handle_);
- EXPECT_EQ(kTestFramesPerPacket, test_stream_->frames_per_packet_);
- EXPECT_TRUE(test_stream_->buffer_.get());
- EXPECT_FALSE(test_stream_->stop_stream_);
+ EXPECT_EQ(AlsaPcmOutputStream::kIsOpened, test_stream->state());
+ EXPECT_EQ(kFakeHandle, test_stream->playback_handle_);
+ EXPECT_EQ(kTestFramesPerPacket, test_stream->frames_per_packet_);
+ EXPECT_TRUE(test_stream->buffer_.get());
+ EXPECT_FALSE(test_stream->stop_stream_);
// Now close it and test that everything was released.
EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle))
.WillOnce(Return(0));
EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle))
.WillOnce(Return(kTestDeviceName));
- EXPECT_CALL(mock_manager(), ReleaseOutputStream(test_stream_.get()));
- test_stream_->Close();
-
- EXPECT_TRUE(test_stream_->playback_handle_ == NULL);
- EXPECT_FALSE(test_stream_->buffer_.get());
- EXPECT_TRUE(test_stream_->stop_stream_);
+ test_stream->Close();
}
TEST_F(AlsaPcmOutputStreamTest, PcmOpenFailed) {
@@ -355,17 +365,17 @@ TEST_F(AlsaPcmOutputStreamTest, PcmOpenFailed) {
EXPECT_CALL(mock_alsa_wrapper_, StrError(kTestFailedErrno))
.WillOnce(Return(kDummyMessage));
- ASSERT_FALSE(test_stream_->Open());
- ASSERT_EQ(AlsaPcmOutputStream::kInError, test_stream_->state());
+ AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout);
+ ASSERT_FALSE(test_stream->Open());
+ ASSERT_EQ(AlsaPcmOutputStream::kInError, test_stream->state());
// Ensure internal state is set for a no-op stream if PcmOpen() failes.
- EXPECT_TRUE(test_stream_->stop_stream_);
- EXPECT_TRUE(test_stream_->playback_handle_ == NULL);
- EXPECT_FALSE(test_stream_->buffer_.get());
+ EXPECT_TRUE(test_stream->stop_stream_);
+ EXPECT_TRUE(test_stream->playback_handle_ == NULL);
+ EXPECT_FALSE(test_stream->buffer_.get());
// Close the stream since we opened it to make destruction happy.
- EXPECT_CALL(mock_manager(), ReleaseOutputStream(test_stream_.get()));
- test_stream_->Close();
+ test_stream->Close();
}
TEST_F(AlsaPcmOutputStreamTest, PcmSetParamsFailed) {
@@ -383,17 +393,17 @@ TEST_F(AlsaPcmOutputStreamTest, PcmSetParamsFailed) {
// If open fails, the stream stays in kCreated because it has effectively had
// no changes.
- ASSERT_FALSE(test_stream_->Open());
- EXPECT_EQ(AlsaPcmOutputStream::kInError, test_stream_->state());
+ AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout);
+ ASSERT_FALSE(test_stream->Open());
+ EXPECT_EQ(AlsaPcmOutputStream::kInError, test_stream->state());
// Ensure internal state is set for a no-op stream if PcmSetParams() failes.
- EXPECT_TRUE(test_stream_->stop_stream_);
- EXPECT_TRUE(test_stream_->playback_handle_ == NULL);
- EXPECT_FALSE(test_stream_->buffer_.get());
+ EXPECT_TRUE(test_stream->stop_stream_);
+ EXPECT_TRUE(test_stream->playback_handle_ == NULL);
+ EXPECT_FALSE(test_stream->buffer_.get());
// Close the stream since we opened it to make destruction happy.
- EXPECT_CALL(mock_manager(), ReleaseOutputStream(test_stream_.get()));
- test_stream_->Close();
+ test_stream->Close();
}
TEST_F(AlsaPcmOutputStreamTest, StartStop) {
@@ -411,7 +421,8 @@ TEST_F(AlsaPcmOutputStreamTest, StartStop) {
Return(0)));
// Open the stream.
- ASSERT_TRUE(test_stream_->Open());
+ AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout);
+ ASSERT_TRUE(test_stream->Open());
// Expect Device setup.
EXPECT_CALL(mock_alsa_wrapper_, PcmDrop(kFakeHandle))
@@ -428,7 +439,7 @@ TEST_F(AlsaPcmOutputStreamTest, StartStop) {
.Times(2)
.WillRepeatedly(DoAll(SetArgumentPointee<1>(0), Return(0)));
EXPECT_CALL(mock_callback,
- OnMoreData(test_stream_.get(), _, kTestPacketSize, _))
+ OnMoreData(test_stream, _, kTestPacketSize, _))
.Times(2)
.WillOnce(Return(kTestPacketSize))
.WillOnce(Return(0));
@@ -444,39 +455,41 @@ TEST_F(AlsaPcmOutputStreamTest, StartStop) {
&MessageLoop::QuitNow),
Return(0))); // Buffer is full.
- test_stream_->Start(&mock_callback);
+ test_stream->Start(&mock_callback);
message_loop_.RunAllPending();
- EXPECT_CALL(mock_manager(), ReleaseOutputStream(test_stream_.get()));
EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle))
.WillOnce(Return(0));
EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle))
.WillOnce(Return(kTestDeviceName));
- test_stream_->Close();
+ test_stream->Close();
}
TEST_F(AlsaPcmOutputStreamTest, WritePacket_FinishedPacket) {
- InitBuffer();
+ AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout);
+ InitBuffer(test_stream);
// Nothing should happen. Don't set any expectations and Our strict mocks
// should verify most of this.
// Test empty buffer.
- test_stream_->buffer_->Clear();
- test_stream_->WritePacket();
+ test_stream->buffer_->Clear();
+ test_stream->WritePacket();
+ test_stream->Close();
}
TEST_F(AlsaPcmOutputStreamTest, WritePacket_NormalPacket) {
- InitBuffer();
+ AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout);
+ InitBuffer(test_stream);
// Write a little less than half the data.
int written = packet_->GetDataSize() / kTestBytesPerFrame / 2 - 1;
EXPECT_CALL(mock_alsa_wrapper_, PcmWritei(_, packet_->GetData(), _))
.WillOnce(Return(written));
- test_stream_->WritePacket();
+ test_stream->WritePacket();
- ASSERT_EQ(test_stream_->buffer_->forward_bytes(),
+ ASSERT_EQ(test_stream->buffer_->forward_bytes(),
packet_->GetDataSize() - written * kTestBytesPerFrame);
// Write the rest.
@@ -484,12 +497,14 @@ TEST_F(AlsaPcmOutputStreamTest, WritePacket_NormalPacket) {
PcmWritei(_, packet_->GetData() + written * kTestBytesPerFrame,
_))
.WillOnce(Return(packet_->GetDataSize() / kTestBytesPerFrame - written));
- test_stream_->WritePacket();
- EXPECT_EQ(0u, test_stream_->buffer_->forward_bytes());
+ test_stream->WritePacket();
+ EXPECT_EQ(0u, test_stream->buffer_->forward_bytes());
+ test_stream->Close();
}
TEST_F(AlsaPcmOutputStreamTest, WritePacket_WriteFails) {
- InitBuffer();
+ AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout);
+ InitBuffer(test_stream);
// Fail due to a recoverable error and see that PcmRecover code path
// continues normally.
@@ -498,9 +513,9 @@ TEST_F(AlsaPcmOutputStreamTest, WritePacket_WriteFails) {
EXPECT_CALL(mock_alsa_wrapper_, PcmRecover(_, _, _))
.WillOnce(Return(packet_->GetDataSize() / kTestBytesPerFrame / 2 - 1));
- test_stream_->WritePacket();
+ test_stream->WritePacket();
- ASSERT_EQ(test_stream_->buffer_->forward_bytes(),
+ ASSERT_EQ(test_stream->buffer_->forward_bytes(),
packet_->GetDataSize() / 2 + kTestBytesPerFrame);
// Fail the next write, and see that stop_stream_ is set.
@@ -510,24 +525,28 @@ TEST_F(AlsaPcmOutputStreamTest, WritePacket_WriteFails) {
.WillOnce(Return(kTestFailedErrno));
EXPECT_CALL(mock_alsa_wrapper_, StrError(kTestFailedErrno))
.WillOnce(Return(kDummyMessage));
- test_stream_->WritePacket();
- EXPECT_EQ(test_stream_->buffer_->forward_bytes(),
+ test_stream->WritePacket();
+ EXPECT_EQ(test_stream->buffer_->forward_bytes(),
packet_->GetDataSize() / 2 + kTestBytesPerFrame);
- EXPECT_TRUE(test_stream_->stop_stream_);
+ EXPECT_TRUE(test_stream->stop_stream_);
+ test_stream->Close();
}
TEST_F(AlsaPcmOutputStreamTest, WritePacket_StopStream) {
- InitBuffer();
+ AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout);
+ InitBuffer(test_stream);
// No expectations set on the strict mock because nothing should be called.
- test_stream_->stop_stream_ = true;
- test_stream_->WritePacket();
- EXPECT_EQ(0u, test_stream_->buffer_->forward_bytes());
+ test_stream->stop_stream_ = true;
+ test_stream->WritePacket();
+ EXPECT_EQ(0u, test_stream->buffer_->forward_bytes());
+ test_stream->Close();
}
TEST_F(AlsaPcmOutputStreamTest, BufferPacket) {
- InitBuffer();
- test_stream_->buffer_->Clear();
+ AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout);
+ InitBuffer(test_stream);
+ test_stream->buffer_->Clear();
MockAudioSourceCallback mock_callback;
EXPECT_CALL(mock_alsa_wrapper_, PcmState(_))
@@ -539,21 +558,23 @@ TEST_F(AlsaPcmOutputStreamTest, BufferPacket) {
// Return a partially filled packet.
EXPECT_CALL(mock_callback,
- OnMoreData(test_stream_.get(), _, _, _))
+ OnMoreData(test_stream, _, _, _))
.WillOnce(Return(10));
bool source_exhausted;
- test_stream_->set_source_callback(&mock_callback);
- test_stream_->packet_size_ = kTestPacketSize;
- test_stream_->BufferPacket(&source_exhausted);
+ test_stream->set_source_callback(&mock_callback);
+ test_stream->packet_size_ = kTestPacketSize;
+ test_stream->BufferPacket(&source_exhausted);
- EXPECT_EQ(10u, test_stream_->buffer_->forward_bytes());
+ EXPECT_EQ(10u, test_stream->buffer_->forward_bytes());
EXPECT_FALSE(source_exhausted);
+ test_stream->Close();
}
TEST_F(AlsaPcmOutputStreamTest, BufferPacket_Negative) {
- InitBuffer();
- test_stream_->buffer_->Clear();
+ AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout);
+ InitBuffer(test_stream);
+ test_stream->buffer_->Clear();
// Simulate where the underrun has occurred right after checking the delay.
MockAudioSourceCallback mock_callback;
@@ -563,22 +584,23 @@ TEST_F(AlsaPcmOutputStreamTest, BufferPacket_Negative) {
.WillOnce(DoAll(SetArgumentPointee<1>(-1), Return(0)));
EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_))
.WillRepeatedly(Return(0)); // Buffer is full.
- EXPECT_CALL(mock_callback,
- OnMoreData(test_stream_.get(), _, _, _))
+ EXPECT_CALL(mock_callback, OnMoreData(test_stream, _, _, _))
.WillOnce(Return(10));
bool source_exhausted;
- test_stream_->set_source_callback(&mock_callback);
- test_stream_->packet_size_ = kTestPacketSize;
- test_stream_->BufferPacket(&source_exhausted);
+ test_stream->set_source_callback(&mock_callback);
+ test_stream->packet_size_ = kTestPacketSize;
+ test_stream->BufferPacket(&source_exhausted);
- EXPECT_EQ(10u, test_stream_->buffer_->forward_bytes());
+ EXPECT_EQ(10u, test_stream->buffer_->forward_bytes());
EXPECT_FALSE(source_exhausted);
+ test_stream->Close();
}
TEST_F(AlsaPcmOutputStreamTest, BufferPacket_Underrun) {
- InitBuffer();
- test_stream_->buffer_->Clear();
+ AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout);
+ InitBuffer(test_stream);
+ test_stream->buffer_->Clear();
// If ALSA has underrun then we should assume a delay of zero.
MockAudioSourceCallback mock_callback;
@@ -587,28 +609,31 @@ TEST_F(AlsaPcmOutputStreamTest, BufferPacket_Underrun) {
EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_))
.WillRepeatedly(Return(0)); // Buffer is full.
EXPECT_CALL(mock_callback,
- OnMoreData(test_stream_.get(), _, _, AllOf(
+ OnMoreData(test_stream, _, _, AllOf(
Field(&AudioBuffersState::pending_bytes, 0),
Field(&AudioBuffersState::hardware_delay_bytes, 0))))
.WillOnce(Return(10));
bool source_exhausted;
- test_stream_->set_source_callback(&mock_callback);
- test_stream_->packet_size_ = kTestPacketSize;
- test_stream_->BufferPacket(&source_exhausted);
+ test_stream->set_source_callback(&mock_callback);
+ test_stream->packet_size_ = kTestPacketSize;
+ test_stream->BufferPacket(&source_exhausted);
- EXPECT_EQ(10u, test_stream_->buffer_->forward_bytes());
+ EXPECT_EQ(10u, test_stream->buffer_->forward_bytes());
EXPECT_FALSE(source_exhausted);
+ test_stream->Close();
}
TEST_F(AlsaPcmOutputStreamTest, BufferPacket_FullBuffer) {
- InitBuffer();
+ AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout);
+ InitBuffer(test_stream);
// No expectations set on the strict mock because nothing should be called.
bool source_exhausted;
- test_stream_->packet_size_ = kTestPacketSize;
- test_stream_->BufferPacket(&source_exhausted);
- EXPECT_EQ(kTestPacketSize, test_stream_->buffer_->forward_bytes());
+ test_stream->packet_size_ = kTestPacketSize;
+ test_stream->BufferPacket(&source_exhausted);
+ EXPECT_EQ(kTestPacketSize, test_stream->buffer_->forward_bytes());
EXPECT_FALSE(source_exhausted);
+ test_stream->Close();
}
TEST_F(AlsaPcmOutputStreamTest, AutoSelectDevice_DeviceSelect) {
@@ -670,12 +695,13 @@ TEST_F(AlsaPcmOutputStreamTest, AutoSelectDevice_DeviceSelect) {
EXPECT_CALL(mock_alsa_wrapper_, DeviceNameGetHint(_, StrEq("NAME")))
.WillRepeatedly(Invoke(EchoHint));
- test_stream_.reset(CreateStream(kExpectedLayouts[i]));
- EXPECT_TRUE(test_stream_->AutoSelectDevice(i));
- EXPECT_EQ(kExpectedDownmix[i], test_stream_->should_downmix_);
+ AlsaPcmOutputStream* test_stream = CreateStream(kExpectedLayouts[i]);
+ EXPECT_TRUE(test_stream->AutoSelectDevice(i));
+ EXPECT_EQ(kExpectedDownmix[i], test_stream->should_downmix_);
Mock::VerifyAndClearExpectations(&mock_alsa_wrapper_);
Mock::VerifyAndClearExpectations(mock_manager_.get());
+ test_stream->Close();
}
}
@@ -720,8 +746,9 @@ TEST_F(AlsaPcmOutputStreamTest, AutoSelectDevice_FallbackDevices) {
EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, StrEq(fourth_try.c_str()), _, _))
.WillOnce(Return(kTestFailedErrno));
- test_stream_.reset(CreateStream(CHANNEL_LAYOUT_5POINT0));
- EXPECT_FALSE(test_stream_->AutoSelectDevice(5));
+ AlsaPcmOutputStream* test_stream = CreateStream(CHANNEL_LAYOUT_5POINT0);
+ EXPECT_FALSE(test_stream->AutoSelectDevice(5));
+ test_stream->Close();
}
TEST_F(AlsaPcmOutputStreamTest, AutoSelectDevice_HintFail) {
@@ -738,53 +765,62 @@ TEST_F(AlsaPcmOutputStreamTest, AutoSelectDevice_HintFail) {
EXPECT_CALL(mock_alsa_wrapper_, StrError(kTestFailedErrno))
.WillOnce(Return(kDummyMessage));
- test_stream_.reset(CreateStream(CHANNEL_LAYOUT_5POINT0));
- EXPECT_TRUE(test_stream_->AutoSelectDevice(5));
- EXPECT_TRUE(test_stream_->should_downmix_);
+ AlsaPcmOutputStream* test_stream = CreateStream(CHANNEL_LAYOUT_5POINT0);
+ EXPECT_TRUE(test_stream->AutoSelectDevice(5));
+ EXPECT_TRUE(test_stream->should_downmix_);
+ test_stream->Close();
}
TEST_F(AlsaPcmOutputStreamTest, BufferPacket_StopStream) {
- InitBuffer();
- test_stream_->stop_stream_ = true;
+ AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout);
+ InitBuffer(test_stream);
+ test_stream->stop_stream_ = true;
bool source_exhausted;
- test_stream_->BufferPacket(&source_exhausted);
- EXPECT_EQ(0u, test_stream_->buffer_->forward_bytes());
+ test_stream->BufferPacket(&source_exhausted);
+ EXPECT_EQ(0u, test_stream->buffer_->forward_bytes());
EXPECT_TRUE(source_exhausted);
+ test_stream->Close();
}
TEST_F(AlsaPcmOutputStreamTest, ScheduleNextWrite) {
- test_stream_->TransitionTo(AlsaPcmOutputStream::kIsOpened);
- test_stream_->TransitionTo(AlsaPcmOutputStream::kIsPlaying);
-
- InitBuffer();
-
+ AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout);
+ test_stream->TransitionTo(AlsaPcmOutputStream::kIsOpened);
+ test_stream->TransitionTo(AlsaPcmOutputStream::kIsPlaying);
+DLOG(WARNING) << test_stream->state();
+ InitBuffer(test_stream);
+ DLOG(WARNING) << test_stream->state();
EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_))
.WillOnce(Return(10));
- test_stream_->ScheduleNextWrite(false);
-
+ test_stream->ScheduleNextWrite(false);
+ DLOG(WARNING) << test_stream->state();
// TODO(sergeyu): Figure out how to check that the task has been added to the
// message loop.
// Cleanup the message queue. Currently ~MessageQueue() doesn't free pending
// tasks unless running on valgrind. The code below is needed to keep
// heapcheck happy.
- test_stream_->stop_stream_ = true;
- test_stream_->TransitionTo(AlsaPcmOutputStream::kIsClosed);
+ test_stream->stop_stream_ = true;
+ DLOG(WARNING) << test_stream->state();
+ test_stream->TransitionTo(AlsaPcmOutputStream::kIsClosed);
+ DLOG(WARNING) << test_stream->state();
+ test_stream->Close();
}
TEST_F(AlsaPcmOutputStreamTest, ScheduleNextWrite_StopStream) {
- test_stream_->TransitionTo(AlsaPcmOutputStream::kIsOpened);
- test_stream_->TransitionTo(AlsaPcmOutputStream::kIsPlaying);
+ AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout);
+ test_stream->TransitionTo(AlsaPcmOutputStream::kIsOpened);
+ test_stream->TransitionTo(AlsaPcmOutputStream::kIsPlaying);
- InitBuffer();
+ InitBuffer(test_stream);
- test_stream_->stop_stream_ = true;
- test_stream_->ScheduleNextWrite(true);
+ test_stream->stop_stream_ = true;
+ test_stream->ScheduleNextWrite(true);
// TODO(ajwong): Find a way to test whether or not another task has been
// posted so we can verify that the Alsa code will indeed break the task
// posting loop.
- test_stream_->TransitionTo(AlsaPcmOutputStream::kIsClosed);
+ test_stream->TransitionTo(AlsaPcmOutputStream::kIsClosed);
+ test_stream->Close();
}
diff --git a/media/audio/linux/audio_manager_linux.cc b/media/audio/linux/audio_manager_linux.cc
index da24f12..3af14b2 100644
--- a/media/audio/linux/audio_manager_linux.cc
+++ b/media/audio/linux/audio_manager_linux.cc
@@ -11,8 +11,6 @@
#include "base/process_util.h"
#include "base/stl_util.h"
#include "media/audio/audio_output_dispatcher.h"
-#include "media/audio/fake_audio_input_stream.h"
-#include "media/audio/fake_audio_output_stream.h"
#include "media/audio/linux/alsa_input.h"
#include "media/audio/linux/alsa_output.h"
#include "media/audio/linux/alsa_wrapper.h"
@@ -23,9 +21,7 @@
#include "media/base/media_switches.h"
// Maximum number of output streams that can be open simultaneously.
-static const size_t kMaxOutputStreams = 50;
-
-static const int kMaxInputChannels = 2;
+static const int kMaxOutputStreams = 50;
// Since "default", "pulse" and "dmix" devices are virtual devices mapped to
// real devices, we remove them from the list to avoiding duplicate counting.
@@ -47,67 +43,12 @@ bool AudioManagerLinux::HasAudioInputDevices() {
return HasAnyAlsaAudioDevice(kStreamCapture);
}
-AudioOutputStream* AudioManagerLinux::MakeAudioOutputStream(
- const AudioParameters& params) {
- // Early return for testing hook.
- if (params.format == AudioParameters::AUDIO_MOCK)
- return FakeAudioOutputStream::MakeFakeStream(params);
-
- // Don't allow opening more than |kMaxOutputStreams| streams.
- if (active_output_stream_count_ >= kMaxOutputStreams)
- return NULL;
-
- AudioOutputStream* stream = NULL;
-#if defined(USE_PULSEAUDIO)
- if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUsePulseAudio)) {
- stream = new PulseAudioOutputStream(params, this);
- } else {
-#endif
- std::string device_name = AlsaPcmOutputStream::kAutoSelectDevice;
- if (CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kAlsaOutputDevice)) {
- device_name = CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
- switches::kAlsaOutputDevice);
- }
- stream = new AlsaPcmOutputStream(device_name, params, wrapper_.get(), this);
-#if defined(USE_PULSEAUDIO)
- }
-#endif
- ++active_output_stream_count_;
- DCHECK(stream);
- return stream;
+AudioManagerLinux::AudioManagerLinux() {
+ SetMaxOutputStreamsAllowed(kMaxOutputStreams);
}
-AudioInputStream* AudioManagerLinux::MakeAudioInputStream(
- const AudioParameters& params, const std::string& device_id) {
- if (!params.IsValid() || params.channels > kMaxInputChannels ||
- device_id.empty()) {
- return NULL;
- }
-
- if (params.format == AudioParameters::AUDIO_MOCK) {
- return FakeAudioInputStream::MakeFakeStream(params);
- }
-
- std::string device_name = (device_id == AudioManagerBase::kDefaultDeviceId) ?
- AlsaPcmInputStream::kAutoSelectDevice : device_id;
- if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAlsaInputDevice)) {
- device_name = CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
- switches::kAlsaInputDevice);
- }
-
- AlsaPcmInputStream* stream = new AlsaPcmInputStream(this,
- device_name, params, wrapper_.get());
-
- return stream;
-}
-
-AudioManagerLinux::AudioManagerLinux() : active_output_stream_count_(0U) {}
-
AudioManagerLinux::~AudioManagerLinux() {
Shutdown();
- // All the streams should have been deleted on the audio thread via Shutdown.
- CHECK_EQ(active_output_stream_count_, 0U);
}
void AudioManagerLinux::Init() {
@@ -123,14 +64,6 @@ void AudioManagerLinux::UnMuteAll() {
NOTIMPLEMENTED();
}
-void AudioManagerLinux::ReleaseOutputStream(AudioOutputStream* stream) {
- if (stream) {
- delete stream;
- --active_output_stream_count_;
- DCHECK_GE(active_output_stream_count_, 0U);
- }
-}
-
bool AudioManagerLinux::CanShowAudioInputSettings() {
scoped_ptr<base::Environment> env(base::Environment::Create());
base::nix::DesktopEnvironment desktop = base::nix::GetDesktopEnvironment(
@@ -303,6 +236,65 @@ bool AudioManagerLinux::HasAnyAlsaAudioDevice(StreamType stream) {
return has_device;
}
+AudioOutputStream* AudioManagerLinux::MakeLinearOutputStream(
+ const AudioParameters& params) {
+ DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format);
+ return MakeOutputStream(params);
+}
+
+AudioOutputStream* AudioManagerLinux::MakeLowLatencyOutputStream(
+ const AudioParameters& params) {
+ DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format);
+ return MakeOutputStream(params);
+}
+
+AudioInputStream* AudioManagerLinux::MakeLinearInputStream(
+ const AudioParameters& params, const std::string& device_id) {
+ DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format);
+ return MakeInputStream(params, device_id);
+}
+
+AudioInputStream* AudioManagerLinux::MakeLowLatencyInputStream(
+ const AudioParameters& params, const std::string& device_id) {
+ DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format);
+ return MakeInputStream(params, device_id);
+}
+
+AudioOutputStream* AudioManagerLinux::MakeOutputStream(
+ const AudioParameters& params) {
+ AudioOutputStream* stream = NULL;
+#if defined(USE_PULSEAUDIO)
+ if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUsePulseAudio)) {
+ stream = new PulseAudioOutputStream(params, this);
+ } else {
+#endif
+ std::string device_name = AlsaPcmOutputStream::kAutoSelectDevice;
+ if (CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kAlsaOutputDevice)) {
+ device_name = CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+ switches::kAlsaOutputDevice);
+ }
+ stream = new AlsaPcmOutputStream(device_name, params, wrapper_.get(), this);
+#if defined(USE_PULSEAUDIO)
+ }
+#endif
+ DCHECK(stream);
+ return stream;
+}
+
+AudioInputStream* AudioManagerLinux::MakeInputStream(
+ const AudioParameters& params, const std::string& device_id) {
+
+ std::string device_name = (device_id == AudioManagerBase::kDefaultDeviceId) ?
+ AlsaPcmInputStream::kAutoSelectDevice : device_id;
+ if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAlsaInputDevice)) {
+ device_name = CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+ switches::kAlsaInputDevice);
+ }
+
+ return new AlsaPcmInputStream(this, device_name, params, wrapper_.get());
+}
+
AudioManager* CreateAudioManager() {
return new AudioManagerLinux();
}
diff --git a/media/audio/linux/audio_manager_linux.h b/media/audio/linux/audio_manager_linux.h
index d4d4bb1..81e53c4 100644
--- a/media/audio/linux/audio_manager_linux.h
+++ b/media/audio/linux/audio_manager_linux.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -23,19 +23,22 @@ class MEDIA_EXPORT AudioManagerLinux : public AudioManagerBase {
// Implementation of AudioManager.
virtual bool HasAudioOutputDevices() OVERRIDE;
virtual bool HasAudioInputDevices() OVERRIDE;
- virtual AudioOutputStream* MakeAudioOutputStream(
- const AudioParameters& params) OVERRIDE;
- virtual AudioInputStream* MakeAudioInputStream(
- const AudioParameters& params, const std::string& device_id) OVERRIDE;
virtual bool CanShowAudioInputSettings() OVERRIDE;
virtual void ShowAudioInputSettings() OVERRIDE;
virtual void GetAudioInputDeviceNames(media::AudioDeviceNames* device_names)
OVERRIDE;
-
virtual void MuteAll() OVERRIDE;
virtual void UnMuteAll() OVERRIDE;
- virtual void ReleaseOutputStream(AudioOutputStream* stream);
+ // Implementation of AudioManagerBase.
+ virtual AudioOutputStream* MakeLinearOutputStream(
+ const AudioParameters& params) OVERRIDE;
+ virtual AudioOutputStream* MakeLowLatencyOutputStream(
+ const AudioParameters& params) OVERRIDE;
+ virtual AudioInputStream* MakeLinearInputStream(
+ const AudioParameters& params, const std::string& device_id) OVERRIDE;
+ virtual AudioInputStream* MakeLowLatencyInputStream(
+ const AudioParameters& params, const std::string& device_id) OVERRIDE;
protected:
virtual ~AudioManagerLinux();
@@ -58,9 +61,14 @@ class MEDIA_EXPORT AudioManagerLinux : public AudioManagerBase {
// Returns true if a device is present for the given stream type.
bool HasAnyAlsaAudioDevice(StreamType stream);
- scoped_ptr<AlsaWrapper> wrapper_;
+ // Called by MakeLinearOutputStream and MakeLowLatencyOutputStream.
+ AudioOutputStream* MakeOutputStream(const AudioParameters& params);
- size_t active_output_stream_count_;
+ // Called by MakeLinearInputStream and MakeLowLatencyInputStream.
+ AudioInputStream* MakeInputStream(const AudioParameters& params,
+ const std::string& device_id);
+
+ scoped_ptr<AlsaWrapper> wrapper_;
DISALLOW_COPY_AND_ASSIGN(AudioManagerLinux);
};
diff --git a/media/audio/mac/audio_manager_mac.cc b/media/audio/mac/audio_manager_mac.cc
index 3751460..fdaf5a1 100644
--- a/media/audio/mac/audio_manager_mac.cc
+++ b/media/audio/mac/audio_manager_mac.cc
@@ -8,8 +8,6 @@
#include "base/mac/mac_util.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/sys_string_conversions.h"
-#include "media/audio/fake_audio_input_stream.h"
-#include "media/audio/fake_audio_output_stream.h"
#include "media/audio/mac/audio_input_mac.h"
#include "media/audio/mac/audio_low_latency_input_mac.h"
#include "media/audio/mac/audio_low_latency_output_mac.h"
@@ -17,38 +15,12 @@
#include "media/audio/mac/audio_output_mac.h"
#include "media/base/limits.h"
-static const int kMaxInputChannels = 2;
-
// Maximum number of output streams that can be open simultaneously.
-static const size_t kMaxOutputStreams = 50;
+static const int kMaxOutputStreams = 50;
// By experiment the maximum number of audio streams allowed in Leopard
// is 18. But we put a slightly smaller number just to be safe.
-static const size_t kMaxOutputStreamsLeopard = 15;
-
-// Initialized to ether |kMaxOutputStreams| or |kMaxOutputStreamsLeopard|.
-static size_t g_max_output_streams = 0;
-
-// Returns the number of audio streams allowed. This is a practical limit to
-// prevent failure caused by too many audio streams opened.
-static size_t GetMaxAudioOutputStreamsAllowed() {
- if (g_max_output_streams == 0) {
- // We are hitting a bug in Leopard where too many audio streams will cause
- // a deadlock in the AudioQueue API when starting the stream. Unfortunately
- // there's no way to detect it within the AudioQueue API, so we put a
- // special hard limit only for Leopard.
- // See bug: http://crbug.com/30242
- if (base::mac::IsOSLeopardOrEarlier()) {
- g_max_output_streams = kMaxOutputStreamsLeopard;
- } else {
- // In OS other than OSX Leopard, the number of audio streams
- // allowed is a lot more.
- g_max_output_streams = kMaxOutputStreams;
- }
- }
-
- return g_max_output_streams;
-}
+static const int kMaxOutputStreamsLeopard = 15;
static bool HasAudioHardware(AudioObjectPropertySelector selector) {
AudioDeviceID output_device_id = kAudioObjectUnknown;
@@ -235,8 +207,17 @@ static AudioDeviceID GetAudioDeviceIdByUId(bool is_input,
return audio_device_id;
}
-AudioManagerMac::AudioManagerMac()
- : num_output_streams_(0) {
+AudioManagerMac::AudioManagerMac() {
+ // We are hitting a bug in Leopard where too many audio streams will cause
+ // a deadlock in the AudioQueue API when starting the stream. Unfortunately
+ // there's no way to detect it within the AudioQueue API, so we put a
+ // special hard limit only for Leopard.
+ // See bug: http://crbug.com/30242
+ // In OS other than OSX Leopard, the number of audio streams
+ // allowed is a lot more.
+ int max_output_stream = base::mac::IsOSLeopardOrEarlier() ?
+ kMaxOutputStreamsLeopard : kMaxOutputStreams;
+ SetMaxOutputStreamsAllowed(max_output_stream);
}
AudioManagerMac::~AudioManagerMac() {
@@ -269,51 +250,6 @@ void AudioManagerMac::GetAudioInputDeviceNames(
}
}
-AudioOutputStream* AudioManagerMac::MakeAudioOutputStream(
- const AudioParameters& params) {
- if (!params.IsValid())
- return NULL;
-
- // Limit the number of audio streams opened. This is to prevent using
- // excessive resources for a large number of audio streams. More
- // importantly it prevents instability on certain systems.
- // See bug: http://crbug.com/30242
- if (num_output_streams_ >= GetMaxAudioOutputStreamsAllowed()) {
- return NULL;
- }
-
- if (params.format == AudioParameters::AUDIO_MOCK) {
- return FakeAudioOutputStream::MakeFakeStream(params);
- } else if (params.format == AudioParameters::AUDIO_PCM_LINEAR) {
- num_output_streams_++;
- return new PCMQueueOutAudioOutputStream(this, params);
- } else if (params.format == AudioParameters::AUDIO_PCM_LOW_LATENCY) {
- num_output_streams_++;
- return new AUAudioOutputStream(this, params);
- }
- return NULL;
-}
-
-AudioInputStream* AudioManagerMac::MakeAudioInputStream(
- const AudioParameters& params, const std::string& device_id) {
- if (!params.IsValid() || (params.channels > kMaxInputChannels) ||
- device_id.empty())
- return NULL;
-
- if (params.format == AudioParameters::AUDIO_MOCK) {
- return FakeAudioInputStream::MakeFakeStream(params);
- } else if (params.format == AudioParameters::AUDIO_PCM_LINEAR) {
- return new PCMQueueInAudioInputStream(this, params);
- } else if (params.format == AudioParameters::AUDIO_PCM_LOW_LATENCY) {
- // Gets the AudioDeviceID that refers to the AudioDevice with the device
- // unique id. This AudioDeviceID is used to set the device for Audio Unit.
- AudioDeviceID audio_device_id = GetAudioDeviceIdByUId(true, device_id);
- if (audio_device_id != kAudioObjectUnknown)
- return new AUAudioInputStream(this, params, audio_device_id);
- }
- return NULL;
-}
-
void AudioManagerMac::MuteAll() {
// TODO(cpu): implement.
}
@@ -322,16 +258,35 @@ void AudioManagerMac::UnMuteAll() {
// TODO(cpu): implement.
}
-// Called by the stream when it has been released by calling Close().
-void AudioManagerMac::ReleaseOutputStream(AudioOutputStream* stream) {
- DCHECK(stream);
- num_output_streams_--;
- delete stream;
+AudioOutputStream* AudioManagerMac::MakeLinearOutputStream(
+ const AudioParameters& params) {
+ DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format);
+ return new PCMQueueOutAudioOutputStream(this, params);
}
-// Called by the stream when it has been released by calling Close().
-void AudioManagerMac::ReleaseInputStream(AudioInputStream* stream) {
- delete stream;
+AudioOutputStream* AudioManagerMac::MakeLowLatencyOutputStream(
+ const AudioParameters& params) {
+ DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format);
+ return new AUAudioOutputStream(this, params);
+}
+
+AudioInputStream* AudioManagerMac::MakeLinearInputStream(
+ const AudioParameters& params, const std::string& device_id) {
+ DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format);
+ return new PCMQueueInAudioInputStream(this, params);
+}
+
+AudioInputStream* AudioManagerMac::MakeLowLatencyInputStream(
+ const AudioParameters& params, const std::string& device_id) {
+ DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format);
+ // Gets the AudioDeviceID that refers to the AudioDevice with the device
+ // unique id. This AudioDeviceID is used to set the device for Audio Unit.
+ AudioDeviceID audio_device_id = GetAudioDeviceIdByUId(true, device_id);
+ AudioInputStream* stream = NULL;
+ if (audio_device_id != kAudioObjectUnknown)
+ stream = new AUAudioInputStream(this, params, audio_device_id);
+
+ return stream;
}
AudioManager* CreateAudioManager() {
diff --git a/media/audio/mac/audio_manager_mac.h b/media/audio/mac/audio_manager_mac.h
index 2060b66..f535415 100644
--- a/media/audio/mac/audio_manager_mac.h
+++ b/media/audio/mac/audio_manager_mac.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -21,27 +21,23 @@ class AudioManagerMac : public AudioManagerBase {
virtual bool HasAudioInputDevices() OVERRIDE;
virtual void GetAudioInputDeviceNames(media::AudioDeviceNames* device_names)
OVERRIDE;
- virtual AudioOutputStream* MakeAudioOutputStream(
- const AudioParameters& params) OVERRIDE;
- virtual AudioInputStream* MakeAudioInputStream(
- const AudioParameters& params, const std::string& device_id) OVERRIDE;
virtual void MuteAll() OVERRIDE;
virtual void UnMuteAll() OVERRIDE;
- // Mac-only method to free the streams created by above facoty methods.
- // They are called internally by the respective audio stream when it has
- // been closed.
- void ReleaseOutputStream(AudioOutputStream* stream);
- void ReleaseInputStream(AudioInputStream* stream);
+ // Implementation of AudioManagerBase.
+ virtual AudioOutputStream* MakeLinearOutputStream(
+ const AudioParameters& params) OVERRIDE;
+ virtual AudioOutputStream* MakeLowLatencyOutputStream(
+ const AudioParameters& params) OVERRIDE;
+ virtual AudioInputStream* MakeLinearInputStream(
+ const AudioParameters& params, const std::string& device_id) OVERRIDE;
+ virtual AudioInputStream* MakeLowLatencyInputStream(
+ const AudioParameters& params, const std::string& device_id) OVERRIDE;
protected:
virtual ~AudioManagerMac();
private:
-
- // Number of currently open output streams.
- size_t num_output_streams_;
-
DISALLOW_COPY_AND_ASSIGN(AudioManagerMac);
};
diff --git a/media/audio/openbsd/audio_manager_openbsd.cc b/media/audio/openbsd/audio_manager_openbsd.cc
index 7222748..1ef9398 100644
--- a/media/audio/openbsd/audio_manager_openbsd.cc
+++ b/media/audio/openbsd/audio_manager_openbsd.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -7,8 +7,6 @@
#include "base/command_line.h"
#include "base/stl_util.h"
#include "media/audio/audio_output_dispatcher.h"
-#include "media/audio/fake_audio_input_stream.h"
-#include "media/audio/fake_audio_output_stream.h"
#if defined(USE_PULSEAUDIO)
#include "media/audio/pulse/pulse_output.h"
#endif
@@ -18,7 +16,7 @@
#include <fcntl.h>
// Maximum number of output streams that can be open simultaneously.
-static const size_t kMaxOutputStreams = 50;
+static const int kMaxOutputStreams = 50;
// Implementation of AudioManager.
static bool HasAudioHardware() {
@@ -43,43 +41,8 @@ bool AudioManagerOpenBSD::HasAudioInputDevices() {
return HasAudioHardware();
}
-AudioOutputStream* AudioManagerOpenBSD::MakeAudioOutputStream(
- const AudioParameters& params) {
- // Early return for testing hook. Do this before checking for
- // |initialized_|.
- if (params.format == AudioParameters::AUDIO_MOCK) {
- return FakeAudioOutputStream::MakeFakeStream(params);
- }
-
- if (!initialized()) {
- return NULL;
- }
-
- // Don't allow opening more than |kMaxOutputStreams| streams.
- if (active_streams_.size() >= kMaxOutputStreams) {
- return NULL;
- }
-
- AudioOutputStream* stream;
-#if defined(USE_PULSEAUDIO)
- if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUsePulseAudio)) {
- stream = new PulseAudioOutputStream(params, this);
- active_streams_.insert(stream);
- return stream;
- }
-#endif
-
- NOTIMPLEMENTED();
- return NULL;
-}
-
-AudioInputStream* AudioManagerOpenBSD::MakeAudioInputStream(
- const AudioParameters& params, const std::string& device_id) {
- NOTIMPLEMENTED();
- return NULL;
-}
-
AudioManagerOpenBSD::AudioManagerOpenBSD() {
+ SetMaxOutputStreamsAllowed(kMaxOutputStreams);
}
AudioManagerOpenBSD::~AudioManagerOpenBSD() {
@@ -92,10 +55,6 @@ AudioManagerOpenBSD::~AudioManagerOpenBSD() {
// Free output dispatchers, closing all remaining open streams.
output_dispatchers_.clear();
-
- // Delete all the streams. Have to do it manually, we don't have ScopedSet<>,
- // and we are not using ScopedVector<> because search there is slow.
- STLDeleteElements(&active_streams_);
}
void AudioManagerOpenBSD::Init() {
@@ -110,11 +69,46 @@ void AudioManagerOpenBSD::UnMuteAll() {
NOTIMPLEMENTED();
}
-void AudioManagerOpenBSD::ReleaseOutputStream(AudioOutputStream* stream) {
- if (stream) {
- active_streams_.erase(stream);
- delete stream;
+AudioOutputStream* AudioManagerOpenBSD::MakeLinearOutputStream(
+ const AudioParameters& params) {
+ DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format);
+ return MakeOutputStream(params);
+}
+
+AudioOutputStream* AudioManagerOpenBSD::MakeLowLatencyOutputStream(
+ const AudioParameters& params) {
+ DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format);
+ return MakeOutputStream(params);
+}
+
+AudioInputStream* AudioManagerOpenBSD::MakeLinearInputStream(
+ const AudioParameters& params, const std::string& device_id) {
+ DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format);
+ NOTIMPLEMENTED();
+ return NULL;
+}
+
+AudioInputStream* AudioManagerOpenBSD::MakeLowLatencyInputStream(
+ const AudioParameters& params, const std::string& device_id) {
+ DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format);
+ NOTIMPLEMENTED();
+ return NULL;
+}
+
+AudioOutputStream* AudioManagerOpenBSD::MakeOutputStream(
+ const AudioParameters& params) {
+ if (!initialized()) {
+ return NULL;
}
+
+#if defined(USE_PULSEAUDIO)
+ if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUsePulseAudio)) {
+ return new PulseAudioOutputStream(params, this);
+ }
+#endif
+
+ NOTIMPLEMENTED();
+ return NULL;
}
// static
diff --git a/media/audio/openbsd/audio_manager_openbsd.h b/media/audio/openbsd/audio_manager_openbsd.h
index fa49203..86b56c0 100644
--- a/media/audio/openbsd/audio_manager_openbsd.h
+++ b/media/audio/openbsd/audio_manager_openbsd.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -20,21 +20,25 @@ class MEDIA_EXPORT AudioManagerOpenBSD : public AudioManagerBase {
// Implementation of AudioManager.
virtual bool HasAudioOutputDevices() OVERRIDE;
virtual bool HasAudioInputDevices() OVERRIDE;
- virtual AudioOutputStream* MakeAudioOutputStream(
- const AudioParameters& params) OVERRIDE;
- virtual AudioInputStream* MakeAudioInputStream(
- const AudioParameters& params, const std::string& device_id) OVERRIDE;
-
virtual void MuteAll() OVERRIDE;
virtual void UnMuteAll() OVERRIDE;
- virtual void ReleaseOutputStream(AudioOutputStream* stream);
+ // Implementation of AudioManagerBase.
+ virtual AudioOutputStream* MakeLinearOutputStream(
+ const AudioParameters& params) OVERRIDE;
+ virtual AudioOutputStream* MakeLowLatencyOutputStream(
+ const AudioParameters& params) OVERRIDE;
+ virtual AudioInputStream* MakeLinearInputStream(
+ const AudioParameters& params, const std::string& device_id) OVERRIDE;
+ virtual AudioInputStream* MakeLowLatencyInputStream(
+ const AudioParameters& params, const std::string& device_id) OVERRIDE;
protected:
virtual ~AudioManagerOpenBSD();
private:
- std::set<AudioOutputStream*> active_streams_;
+ // Called by MakeLinearOutputStream and MakeLowLatencyOutputStream.
+ AudioOutputStream* MakeOutputStream(const AudioParameters& params);
DISALLOW_COPY_AND_ASSIGN(AudioManagerOpenBSD);
};
diff --git a/media/audio/win/audio_manager_win.cc b/media/audio/win/audio_manager_win.cc
index 7ee2a76..2827d11 100644
--- a/media/audio/win/audio_manager_win.cc
+++ b/media/audio/win/audio_manager_win.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -19,8 +19,6 @@
#include "base/string_number_conversions.h"
#include "base/string_util.h"
#include "media/audio/audio_util.h"
-#include "media/audio/fake_audio_input_stream.h"
-#include "media/audio/fake_audio_output_stream.h"
#include "media/audio/win/audio_low_latency_input_win.h"
#include "media/audio/win/audio_low_latency_output_win.h"
#include "media/audio/win/audio_manager_win.h"
@@ -41,14 +39,13 @@ DEFINE_GUID(AM_KSCATEGORY_AUDIO, 0x6994ad04, 0x93ef, 0x11d0,
0xa3, 0xcc, 0x00, 0xa0, 0xc9, 0x22, 0x31, 0x96);
// Maximum number of output streams that can be open simultaneously.
-static const size_t kMaxOutputStreams = 50;
+static const int kMaxOutputStreams = 50;
// Up to 8 channels can be passed to the driver.
// This should work, given the right drivers, but graceful error handling is
// needed.
static const int kWinMaxChannels = 8;
-static const int kWinMaxInputChannels = 2;
// We use 3 buffers for recording audio so that if a recording callback takes
// some time to return we won't lose audio. More buffers while recording are
// ok because they don't introduce any delay in recording, unlike in playback
@@ -98,8 +95,7 @@ static string16 GetDeviceAndDriverInfo(HDEVINFO device_info,
return device_and_driver_info;
}
-AudioManagerWin::AudioManagerWin()
- : num_output_streams_(0) {
+AudioManagerWin::AudioManagerWin() {
if (!media::IsWASAPISupported()) {
// Use the Wave API for device enumeration if XP or lower.
enumeration_type_ = kWaveEnumeration;
@@ -107,11 +103,11 @@ AudioManagerWin::AudioManagerWin()
// Use the MMDevice API for device enumeration if Vista or higher.
enumeration_type_ = kMMDeviceEnumeration;
}
+
+ SetMaxOutputStreamsAllowed(kMaxOutputStreams);
}
AudioManagerWin::~AudioManagerWin() {
- // All output streams should be released upon termination.
- DCHECK_EQ(0, num_output_streams_);
}
bool AudioManagerWin::HasAudioOutputDevices() {
@@ -122,75 +118,6 @@ bool AudioManagerWin::HasAudioInputDevices() {
return (::waveInGetNumDevs() != 0);
}
-// Factory for the implementations of AudioOutputStream. Two implementations
-// should suffice most windows user's needs.
-// - PCMWaveOutAudioOutputStream: Based on the waveOut API.
-// - WASAPIAudioOutputStream: Based on Core Audio (WASAPI) API.
-AudioOutputStream* AudioManagerWin::MakeAudioOutputStream(
- const AudioParameters& params) {
- if (!params.IsValid() || (params.channels > kWinMaxChannels))
- return NULL;
-
- // Limit the number of audio streams opened.
- if (num_output_streams_ >= kMaxOutputStreams) {
- return NULL;
- }
-
- if (params.format == AudioParameters::AUDIO_MOCK) {
- return FakeAudioOutputStream::MakeFakeStream(params);
- } else if (params.format == AudioParameters::AUDIO_PCM_LINEAR) {
- num_output_streams_++;
- return new PCMWaveOutAudioOutputStream(this, params, 3, WAVE_MAPPER);
- } else if (params.format == AudioParameters::AUDIO_PCM_LOW_LATENCY) {
- num_output_streams_++;
- if (!media::IsWASAPISupported()) {
- // Fall back to Windows Wave implementation on Windows XP or lower.
- DLOG(INFO) << "Using WaveOut since WASAPI requires at least Vista.";
- return new PCMWaveOutAudioOutputStream(this, params, 2, WAVE_MAPPER);
- } else {
- // TODO(henrika): improve possibility to specify audio endpoint.
- // Use the default device (same as for Wave) for now to be compatible.
- return new WASAPIAudioOutputStream(this, params, eConsole);
- }
- }
- return NULL;
-}
-
-// Factory for the implementations of AudioInputStream.
-AudioInputStream* AudioManagerWin::MakeAudioInputStream(
- const AudioParameters& params, const std::string& device_id) {
- if (!params.IsValid() || (params.channels > kWinMaxInputChannels) ||
- device_id.empty())
- return NULL;
-
- if (params.format == AudioParameters::AUDIO_MOCK) {
- return FakeAudioInputStream::MakeFakeStream(params);
- } else if (params.format == AudioParameters::AUDIO_PCM_LINEAR) {
- return new PCMWaveInAudioInputStream(this, params, kNumInputBuffers,
- AudioManagerBase::kDefaultDeviceId);
- } else if (params.format == AudioParameters::AUDIO_PCM_LOW_LATENCY) {
- if (!media::IsWASAPISupported()) {
- // Fall back to Windows Wave implementation on Windows XP or lower.
- DLOG(INFO) << "Using WaveIn since WASAPI requires at least Vista.";
- return new PCMWaveInAudioInputStream(this, params, kNumInputBuffers,
- device_id);
- } else {
- return new WASAPIAudioInputStream(this, params, device_id);
- }
- }
- return NULL;
-}
-
-void AudioManagerWin::ReleaseOutputStream(AudioOutputStream* stream) {
- DCHECK(stream);
- num_output_streams_--;
- delete stream;
-}
-
-void AudioManagerWin::ReleaseInputStream(AudioInputStream* stream) {
- delete stream;
-}
-
void AudioManagerWin::MuteAll() {
}
@@ -305,6 +232,70 @@ void AudioManagerWin::GetAudioInputDeviceNames(
}
}
+// Factory for the implementations of AudioOutputStream for AUDIO_PCM_LINEAR
+// mode.
+// - PCMWaveOutAudioOutputStream: Based on the waveOut API.
+AudioOutputStream* AudioManagerWin::MakeLinearOutputStream(
+ const AudioParameters& params) {
+ DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format);
+ if (params.channels > kWinMaxChannels)
+ return NULL;
+
+ return new PCMWaveOutAudioOutputStream(this, params, 3, WAVE_MAPPER);
+}
+
+// Factory for the implementations of AudioOutputStream for
+// AUDIO_PCM_LOW_LATENCY mode. Two implementations should suffice most
+// windows user's needs.
+// - PCMWaveOutAudioOutputStream: Based on the waveOut API.
+// - WASAPIAudioOutputStream: Based on Core Audio (WASAPI) API.
+AudioOutputStream* AudioManagerWin::MakeLowLatencyOutputStream(
+ const AudioParameters& params) {
+ DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format);
+ if (params.channels > kWinMaxChannels)
+ return NULL;
+
+ AudioOutputStream* stream = NULL;
+ if (!media::IsWASAPISupported()) {
+ // Fall back to Windows Wave implementation on Windows XP or lower.
+ DVLOG(1) << "Using WaveOut since WASAPI requires at least Vista.";
+ stream = new PCMWaveOutAudioOutputStream(this, params, 2, WAVE_MAPPER);
+ } else {
+ // TODO(henrika): improve possibility to specify audio endpoint.
+ // Use the default device (same as for Wave) for now to be compatible.
+ stream = new WASAPIAudioOutputStream(this, params, eConsole);
+ }
+
+ return stream;
+}
+
+// Factory for the implementations of AudioInputStream for AUDIO_PCM_LINEAR
+// mode.
+AudioInputStream* AudioManagerWin::MakeLinearInputStream(
+ const AudioParameters& params, const std::string& device_id) {
+ DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format);
+ return new PCMWaveInAudioInputStream(this, params, kNumInputBuffers,
+ AudioManagerBase::kDefaultDeviceId);
+}
+
+// Factory for the implementations of AudioInputStream for
+// AUDIO_PCM_LOW_LATENCY mode.
+AudioInputStream* AudioManagerWin::MakeLowLatencyInputStream(
+ const AudioParameters& params, const std::string& device_id) {
+ DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format);
+ AudioInputStream* stream = NULL;
+ if (!media::IsWASAPISupported()) {
+ // Fall back to Windows Wave implementation on Windows XP or lower.
+ DVLOG(1) << "Using WaveIn since WASAPI requires at least Vista.";
+ stream = new PCMWaveInAudioInputStream(this, params, kNumInputBuffers,
+ device_id);
+ } else {
+ stream = new WASAPIAudioInputStream(this, params, device_id);
+ }
+
+ return stream;
+}
+
/// static
AudioManager* CreateAudioManager() {
return new AudioManagerWin();
diff --git a/media/audio/win/audio_manager_win.h b/media/audio/win/audio_manager_win.h
index dd41699..3539ef0 100644
--- a/media/audio/win/audio_manager_win.h
+++ b/media/audio/win/audio_manager_win.h
@@ -22,10 +22,6 @@ class MEDIA_EXPORT AudioManagerWin : public AudioManagerBase {
// Implementation of AudioManager.
virtual bool HasAudioOutputDevices() OVERRIDE;
virtual bool HasAudioInputDevices() OVERRIDE;
- virtual AudioOutputStream* MakeAudioOutputStream(
- const AudioParameters& params) OVERRIDE;
- virtual AudioInputStream* MakeAudioInputStream(
- const AudioParameters& params, const std::string& device_id) OVERRIDE;
virtual void MuteAll() OVERRIDE;
virtual void UnMuteAll() OVERRIDE;
virtual string16 GetAudioInputDeviceModel() OVERRIDE;
@@ -34,12 +30,15 @@ class MEDIA_EXPORT AudioManagerWin : public AudioManagerBase {
virtual void GetAudioInputDeviceNames(media::AudioDeviceNames* device_names)
OVERRIDE;
- // Windows-only methods to free a stream created in MakeAudioStream. These
- // are called internally by the audio stream when it has been closed.
- void ReleaseOutputStream(AudioOutputStream* stream);
-
- // Called internally by the audio stream when it has been closed.
- void ReleaseInputStream(AudioInputStream* stream);
+ // Implementation of AudioManagerBase.
+ virtual AudioOutputStream* MakeLinearOutputStream(
+ const AudioParameters& params) OVERRIDE;
+ virtual AudioOutputStream* MakeLowLatencyOutputStream(
+ const AudioParameters& params) OVERRIDE;
+ virtual AudioInputStream* MakeLinearInputStream(
+ const AudioParameters& params, const std::string& device_id) OVERRIDE;
+ virtual AudioInputStream* MakeLowLatencyInputStream(
+ const AudioParameters& params, const std::string& device_id) OVERRIDE;
protected:
virtual ~AudioManagerWin();
@@ -60,9 +59,6 @@ class MEDIA_EXPORT AudioManagerWin : public AudioManagerBase {
enumeration_type_ = type;
}
- // Number of currently open output streams.
- int num_output_streams_;
-
DISALLOW_COPY_AND_ASSIGN(AudioManagerWin);
};