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

Unified Diff: media/audio/audio_manager_base.cc

Issue 1780333007: AudioManagerBase: Create and run the audio thread lazily. (Closed) Base URL: https://chromium.googlesource.com/chromium/src@master
Patch Set: Created 4 years, 9 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
Index: media/audio/audio_manager_base.cc
diff --git a/media/audio/audio_manager_base.cc b/media/audio/audio_manager_base.cc
index 4f7e676d21aa3188bc42b682bc8f52b71a3388d8..8141d715e5eee0e07762decc3daaedd278d26dd7 100644
--- a/media/audio/audio_manager_base.cc
+++ b/media/audio/audio_manager_base.cc
@@ -91,23 +91,7 @@ AudioManagerBase::AudioManagerBase(AudioLogFactory* audio_log_factory)
// block the UI thread when swapping devices.
output_listeners_(
base::ObserverList<AudioDeviceListener>::NOTIFY_EXISTING_ONLY),
- audio_thread_("AudioThread"),
audio_log_factory_(audio_log_factory) {
-#if defined(OS_WIN)
- audio_thread_.init_com_with_mta(true);
-#elif defined(OS_MACOSX)
- // CoreAudio calls must occur on the main thread of the process, which in our
- // case is sadly the browser UI thread. Failure to execute calls on the right
- // thread leads to crashes and odd behavior. See http://crbug.com/158170.
- // TODO(dalecurtis): We should require the message loop to be passed in.
- if (base::MessageLoopForUI::IsCurrent()) {
- task_runner_ = base::ThreadTaskRunnerHandle::Get();
- return;
- }
-#endif
-
- CHECK(audio_thread_.Start());
- task_runner_ = audio_thread_.task_runner();
}
AudioManagerBase::~AudioManagerBase() {
@@ -116,7 +100,7 @@ AudioManagerBase::~AudioManagerBase() {
// stopping the thread, resulting an unexpected behavior.
// This way we make sure activities of the audio streams are all stopped
// before we destroy them.
- CHECK(!audio_thread_.IsRunning());
+ CHECK(!audio_thread_);
// All the output streams should have been deleted.
DCHECK_EQ(0, num_output_streams_);
// All the input streams should have been deleted.
@@ -127,18 +111,20 @@ base::string16 AudioManagerBase::GetAudioInputDeviceModel() {
return base::string16();
}
-scoped_refptr<base::SingleThreadTaskRunner> AudioManagerBase::GetTaskRunner()
- const {
- return task_runner_;
+scoped_refptr<base::SingleThreadTaskRunner> AudioManagerBase::GetTaskRunner() {
+ if (!audio_thread_) {
+ audio_thread_.reset(new base::Thread("AudioThread"));
+#if defined(OS_WIN)
+ audio_thread_->init_com_with_mta(true);
+#endif
+ CHECK(audio_thread_->Start());
+ }
+ return audio_thread_->task_runner();
}
scoped_refptr<base::SingleThreadTaskRunner>
AudioManagerBase::GetWorkerTaskRunner() {
- // Lazily start the worker thread.
- if (!audio_thread_.IsRunning())
- CHECK(audio_thread_.Start());
-
- return audio_thread_.task_runner();
+ return GetTaskRunner();
}
AudioOutputStream* AudioManagerBase::MakeAudioOutputStream(
@@ -146,7 +132,7 @@ AudioOutputStream* AudioManagerBase::MakeAudioOutputStream(
const std::string& device_id) {
// TODO(miu): Fix ~50 call points across several unit test modules to call
// this method on the audio thread, then uncomment the following:
- // DCHECK(task_runner_->BelongsToCurrentThread());
+ // DCHECK(GetTaskRunner()->BelongsToCurrentThread());
if (!params.IsValid()) {
DLOG(ERROR) << "Audio parameters are invalid";
@@ -195,7 +181,7 @@ AudioInputStream* AudioManagerBase::MakeAudioInputStream(
const std::string& device_id) {
// TODO(miu): Fix ~20 call points across several unit test modules to call
// this method on the audio thread, then uncomment the following:
- // DCHECK(task_runner_->BelongsToCurrentThread());
+ // DCHECK(GetTaskRunner()->BelongsToCurrentThread());
if (!params.IsValid() || (params.channels() > kMaxInputChannels) ||
device_id.empty()) {
@@ -239,7 +225,7 @@ AudioInputStream* AudioManagerBase::MakeAudioInputStream(
AudioOutputStream* AudioManagerBase::MakeAudioOutputStreamProxy(
const AudioParameters& params,
const std::string& device_id) {
- DCHECK(task_runner_->BelongsToCurrentThread());
+ DCHECK(GetTaskRunner()->BelongsToCurrentThread());
// If the caller supplied an empty device id to select the default device,
// we fetch the actual device id of the default device so that the lookup
@@ -337,19 +323,22 @@ void AudioManagerBase::ReleaseInputStream(AudioInputStream* stream) {
void AudioManagerBase::Shutdown() {
// Only true when we're sharing the UI message loop with the browser. The UI
// loop is no longer running at this time and browser destruction is imminent.
- if (task_runner_->BelongsToCurrentThread()) {
+ auto task_runner = GetTaskRunner();
+ if (task_runner->BelongsToCurrentThread()) {
ShutdownOnAudioThread();
} else {
- task_runner_->PostTask(FROM_HERE, base::Bind(
- &AudioManagerBase::ShutdownOnAudioThread, base::Unretained(this)));
+ task_runner->PostTask(FROM_HERE,
+ base::Bind(&AudioManagerBase::ShutdownOnAudioThread,
+ base::Unretained(this)));
}
- // Stop() will wait for any posted messages to be processed first.
- audio_thread_.Stop();
+ // Destryoing the audio thread will stop it if necessary, which in turn
+ // will wait for any posted messages to be processed first.
+ audio_thread_.reset();
}
void AudioManagerBase::ShutdownOnAudioThread() {
- DCHECK(task_runner_->BelongsToCurrentThread());
+ DCHECK(GetTaskRunner()->BelongsToCurrentThread());
while (!output_dispatchers_.empty()) {
output_dispatchers_.back()->dispatcher->Shutdown();
output_dispatchers_.pop_back();
@@ -358,18 +347,18 @@ void AudioManagerBase::ShutdownOnAudioThread() {
void AudioManagerBase::AddOutputDeviceChangeListener(
AudioDeviceListener* listener) {
- DCHECK(task_runner_->BelongsToCurrentThread());
+ DCHECK(GetTaskRunner()->BelongsToCurrentThread());
output_listeners_.AddObserver(listener);
}
void AudioManagerBase::RemoveOutputDeviceChangeListener(
AudioDeviceListener* listener) {
- DCHECK(task_runner_->BelongsToCurrentThread());
+ DCHECK(GetTaskRunner()->BelongsToCurrentThread());
output_listeners_.RemoveObserver(listener);
}
void AudioManagerBase::NotifyAllOutputDeviceChangeListeners() {
- DCHECK(task_runner_->BelongsToCurrentThread());
+ DCHECK(GetTaskRunner()->BelongsToCurrentThread());
DVLOG(1) << "Firing OnDeviceChange() notifications.";
FOR_EACH_OBSERVER(AudioDeviceListener, output_listeners_, OnDeviceChange());
}

Powered by Google App Engine
This is Rietveld 408576698