Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1200)

Unified Diff: media/audio/audio_output_controller.cc

Issue 3185022: Share one thread between all AudioOutputControllers instead of creating one per stream. (Closed)
Patch Set: - Created 10 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/audio/audio_output_controller.h ('k') | media/audio/audio_output_controller_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/audio/audio_output_controller.cc
diff --git a/media/audio/audio_output_controller.cc b/media/audio/audio_output_controller.cc
index 74e2261d6978e83075139d5661c68332f37eec89..27938f98fdd5b8e974ffdbfc6c50e305406cdcba 100644
--- a/media/audio/audio_output_controller.cc
+++ b/media/audio/audio_output_controller.cc
@@ -4,6 +4,8 @@
#include "media/audio/audio_output_controller.h"
+#include "base/message_loop.h"
+
// The following parameters limit the request buffer and packet size from the
// renderer to avoid renderer from requesting too much memory.
static const uint32 kMegabytes = 1024 * 1024;
@@ -35,12 +37,12 @@ AudioOutputController::AudioOutputController(EventHandler* handler,
uint32 capacity,
SyncReader* sync_reader)
: handler_(handler),
+ stream_(NULL),
volume_(1.0),
state_(kEmpty),
hardware_pending_bytes_(0),
buffer_capacity_(capacity),
- sync_reader_(sync_reader),
- thread_("AudioOutputControllerThread") {
+ sync_reader_(sync_reader) {
}
AudioOutputController::~AudioOutputController() {
@@ -65,10 +67,9 @@ scoped_refptr<AudioOutputController> AudioOutputController::Create(
scoped_refptr<AudioOutputController> controller = new AudioOutputController(
event_handler, buffer_capacity, NULL);
- // Start the audio controller thread and post a task to create the
- // audio stream.
- controller->thread_.Start();
- controller->thread_.message_loop()->PostTask(
+ controller->message_loop_ =
+ AudioManager::GetAudioManager()->GetMessageLoop();
+ controller->message_loop_->PostTask(
FROM_HERE,
NewRunnableMethod(controller.get(), &AudioOutputController::DoCreate,
format, channels, sample_rate, bits_per_sample,
@@ -96,10 +97,9 @@ scoped_refptr<AudioOutputController> AudioOutputController::CreateLowLatency(
scoped_refptr<AudioOutputController> controller = new AudioOutputController(
event_handler, 0, sync_reader);
- // Start the audio controller thread and post a task to create the
- // audio stream.
- controller->thread_.Start();
- controller->thread_.message_loop()->PostTask(
+ controller->message_loop_ =
+ AudioManager::GetAudioManager()->GetMessageLoop();
+ controller->message_loop_->PostTask(
FROM_HERE,
NewRunnableMethod(controller.get(), &AudioOutputController::DoCreate,
format, channels, sample_rate, bits_per_sample,
@@ -108,43 +108,43 @@ scoped_refptr<AudioOutputController> AudioOutputController::CreateLowLatency(
}
void AudioOutputController::Play() {
- DCHECK(thread_.IsRunning());
- thread_.message_loop()->PostTask(
+ DCHECK(message_loop_);
+ message_loop_->PostTask(
FROM_HERE,
NewRunnableMethod(this, &AudioOutputController::DoPlay));
}
void AudioOutputController::Pause() {
- DCHECK(thread_.IsRunning());
- thread_.message_loop()->PostTask(
+ DCHECK(message_loop_);
+ message_loop_->PostTask(
FROM_HERE,
NewRunnableMethod(this, &AudioOutputController::DoPause));
}
void AudioOutputController::Flush() {
- DCHECK(thread_.IsRunning());
- thread_.message_loop()->PostTask(
+ DCHECK(message_loop_);
+ message_loop_->PostTask(
FROM_HERE,
NewRunnableMethod(this, &AudioOutputController::DoFlush));
}
void AudioOutputController::Close() {
- if (!thread_.IsRunning()) {
- // If the thread is not running make sure we are stopped.
- DCHECK_EQ(kClosed, state_);
- return;
+ {
+ AutoLock auto_lock(lock_);
+ // Don't do anything if the stream is already closed.
+ if (state_ == kClosed)
+ return;
+ state_ = kClosed;
}
- // Wait for all tasks to complete on the audio thread.
- thread_.message_loop()->PostTask(
+ message_loop_->PostTask(
FROM_HERE,
NewRunnableMethod(this, &AudioOutputController::DoClose));
- thread_.Stop();
}
void AudioOutputController::SetVolume(double volume) {
- DCHECK(thread_.IsRunning());
- thread_.message_loop()->PostTask(
+ DCHECK(message_loop_);
+ message_loop_->PostTask(
FROM_HERE,
NewRunnableMethod(this, &AudioOutputController::DoSetVolume, volume));
}
@@ -159,8 +159,14 @@ void AudioOutputController::EnqueueData(const uint8* data, uint32 size) {
void AudioOutputController::DoCreate(AudioManager::Format format, int channels,
int sample_rate, int bits_per_sample,
uint32 hardware_buffer_size) {
- DCHECK_EQ(thread_.message_loop(), MessageLoop::current());
- DCHECK_EQ(kEmpty, state_);
+ DCHECK_EQ(message_loop_, MessageLoop::current());
+
+ AutoLock auto_lock(lock_);
+
+ // Close() can be called before DoCreate() is executed.
+ if (state_ == kClosed)
+ return;
+ DCHECK(state_ == kEmpty);
// Create the stream in the first place.
stream_ = AudioManager::GetAudioManager()->MakeAudioOutputStream(
@@ -191,22 +197,20 @@ void AudioOutputController::DoCreate(AudioManager::Format format, int channels,
// If in normal latency mode then start buffering.
if (!LowLatencyMode()) {
- AutoLock auto_lock(lock_);
SubmitOnMoreData_Locked();
}
}
void AudioOutputController::DoPlay() {
- DCHECK_EQ(thread_.message_loop(), MessageLoop::current());
-
- // We can start from created or paused state.
- if (state_ != kCreated && state_ != kPaused)
- return;
+ DCHECK_EQ(message_loop_, MessageLoop::current());
State old_state;
// Update the |state_| to kPlaying.
{
AutoLock auto_lock(lock_);
+ // We can start from created or paused state.
+ if (state_ != kCreated && state_ != kPaused)
+ return;
old_state = state_;
state_ = kPlaying;
}
@@ -219,15 +223,14 @@ void AudioOutputController::DoPlay() {
}
void AudioOutputController::DoPause() {
- DCHECK_EQ(thread_.message_loop(), MessageLoop::current());
-
- // We can pause from started state.
- if (state_ != kPlaying)
- return;
+ DCHECK_EQ(message_loop_, MessageLoop::current());
// Sets the |state_| to kPaused so we don't draw more audio data.
{
AutoLock auto_lock(lock_);
+ // We can pause from started state.
+ if (state_ != kPlaying)
+ return;
state_ = kPaused;
}
@@ -240,24 +243,22 @@ void AudioOutputController::DoPause() {
}
void AudioOutputController::DoFlush() {
- DCHECK_EQ(thread_.message_loop(), MessageLoop::current());
-
- if (state_ != kPaused)
- return;
+ DCHECK_EQ(message_loop_, MessageLoop::current());
// TODO(hclam): Actually flush the audio device.
// If we are in the regular latency mode then flush the push source.
if (!sync_reader_) {
AutoLock auto_lock(lock_);
+ if (state_ != kPaused)
+ return;
push_source_.ClearAll();
}
}
void AudioOutputController::DoClose() {
- DCHECK_EQ(thread_.message_loop(), MessageLoop::current());
- DCHECK_NE(kClosed, state_);
-
+ DCHECK_EQ(message_loop_, MessageLoop::current());
+ DCHECK_EQ(kClosed, state_);
// |stream_| can be null if creating the device failed in DoCreate().
if (stream_) {
stream_->Stop();
@@ -265,27 +266,26 @@ void AudioOutputController::DoClose() {
// After stream is closed it is destroyed, so don't keep a reference to it.
stream_ = NULL;
}
-
- // Update the current state. Since the stream is closed at this point
- // there's no other threads reading |state_| so we don't need to lock.
- state_ = kClosed;
}
void AudioOutputController::DoSetVolume(double volume) {
- DCHECK_EQ(thread_.message_loop(), MessageLoop::current());
+ DCHECK_EQ(message_loop_, MessageLoop::current());
// Saves the volume to a member first. We may not be able to set the volume
// right away but when the stream is created we'll set the volume.
volume_ = volume;
- if (state_ != kPlaying && state_ != kPaused && state_ != kCreated)
- return;
+ {
+ AutoLock auto_lock(lock_);
+ if (state_ != kPlaying && state_ != kPaused && state_ != kCreated)
+ return;
+ }
stream_->SetVolume(volume_);
}
void AudioOutputController::DoReportError(int code) {
- DCHECK_EQ(thread_.message_loop(), MessageLoop::current());
+ DCHECK_EQ(message_loop_, MessageLoop::current());
handler_->OnError(this, code);
}
@@ -332,7 +332,7 @@ void AudioOutputController::OnClose(AudioOutputStream* stream) {
void AudioOutputController::OnError(AudioOutputStream* stream, int code) {
// Handle error on the audio controller thread.
- thread_.message_loop()->PostTask(
+ message_loop_->PostTask(
FROM_HERE,
NewRunnableMethod(this, &AudioOutputController::DoReportError, code));
}
« no previous file with comments | « media/audio/audio_output_controller.h ('k') | media/audio/audio_output_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698