| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "media/audio/audio_manager_base.h" | 5 #include "media/audio/audio_manager_base.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/macros.h" | 10 #include "base/macros.h" |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 75 }; | 75 }; |
| 76 | 76 |
| 77 AudioManagerBase::AudioManagerBase( | 77 AudioManagerBase::AudioManagerBase( |
| 78 scoped_refptr<base::SingleThreadTaskRunner> task_runner, | 78 scoped_refptr<base::SingleThreadTaskRunner> task_runner, |
| 79 scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner, | 79 scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner, |
| 80 AudioLogFactory* audio_log_factory) | 80 AudioLogFactory* audio_log_factory) |
| 81 : AudioManager(std::move(task_runner), std::move(worker_task_runner)), | 81 : AudioManager(std::move(task_runner), std::move(worker_task_runner)), |
| 82 max_num_output_streams_(kDefaultMaxOutputStreams), | 82 max_num_output_streams_(kDefaultMaxOutputStreams), |
| 83 max_num_input_streams_(kDefaultMaxInputStreams), | 83 max_num_input_streams_(kDefaultMaxInputStreams), |
| 84 num_output_streams_(0), | 84 num_output_streams_(0), |
| 85 num_input_streams_(0), | |
| 86 // TODO(dalecurtis): Switch this to an base::ObserverListThreadSafe, so we | 85 // TODO(dalecurtis): Switch this to an base::ObserverListThreadSafe, so we |
| 87 // don't | 86 // don't |
| 88 // block the UI thread when swapping devices. | 87 // block the UI thread when swapping devices. |
| 89 output_listeners_( | 88 output_listeners_( |
| 90 base::ObserverList<AudioDeviceListener>::NOTIFY_EXISTING_ONLY), | 89 base::ObserverList<AudioDeviceListener>::NOTIFY_EXISTING_ONLY), |
| 91 audio_log_factory_(audio_log_factory) {} | 90 audio_log_factory_(audio_log_factory) {} |
| 92 | 91 |
| 93 AudioManagerBase::~AudioManagerBase() { | 92 AudioManagerBase::~AudioManagerBase() { |
| 94 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); | 93 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); |
| 95 | 94 |
| 96 // All the output streams should have been deleted. | 95 // All the output streams should have been deleted. |
| 97 CHECK_EQ(0, num_output_streams_); | 96 CHECK_EQ(0, num_output_streams_); |
| 98 // All the input streams should have been deleted. | 97 // All the input streams should have been deleted. |
| 99 CHECK_EQ(0, num_input_streams_); | 98 CHECK(input_streams_.empty()); |
| 100 } | 99 } |
| 101 | 100 |
| 102 base::string16 AudioManagerBase::GetAudioInputDeviceModel() { | 101 base::string16 AudioManagerBase::GetAudioInputDeviceModel() { |
| 103 return base::string16(); | 102 return base::string16(); |
| 104 } | 103 } |
| 105 | 104 |
| 106 AudioOutputStream* AudioManagerBase::MakeAudioOutputStream( | 105 AudioOutputStream* AudioManagerBase::MakeAudioOutputStream( |
| 107 const AudioParameters& params, | 106 const AudioParameters& params, |
| 108 const std::string& device_id, | 107 const std::string& device_id, |
| 109 const LogCallback& log_callback) { | 108 const LogCallback& log_callback) { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 156 const std::string& device_id, | 155 const std::string& device_id, |
| 157 const LogCallback& log_callback) { | 156 const LogCallback& log_callback) { |
| 158 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); | 157 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); |
| 159 | 158 |
| 160 if (!params.IsValid() || (params.channels() > kMaxInputChannels) || | 159 if (!params.IsValid() || (params.channels() > kMaxInputChannels) || |
| 161 device_id.empty()) { | 160 device_id.empty()) { |
| 162 DLOG(ERROR) << "Audio parameters are invalid for device " << device_id; | 161 DLOG(ERROR) << "Audio parameters are invalid for device " << device_id; |
| 163 return NULL; | 162 return NULL; |
| 164 } | 163 } |
| 165 | 164 |
| 166 if (num_input_streams_ >= max_num_input_streams_) { | 165 if (input_stream_count() >= max_num_input_streams_) { |
| 167 DLOG(ERROR) << "Number of opened input audio streams " | 166 DLOG(ERROR) << "Number of opened input audio streams " |
| 168 << num_input_streams_ | 167 << input_stream_count() << " exceed the max allowed number " |
| 169 << " exceed the max allowed number " << max_num_input_streams_; | 168 << max_num_input_streams_; |
| 170 return NULL; | 169 return NULL; |
| 171 } | 170 } |
| 172 | 171 |
| 173 DVLOG(2) << "Creating a new AudioInputStream with buffer size = " | 172 DVLOG(2) << "Creating a new AudioInputStream with buffer size = " |
| 174 << params.frames_per_buffer(); | 173 << params.frames_per_buffer(); |
| 175 | 174 |
| 176 AudioInputStream* stream; | 175 AudioInputStream* stream; |
| 177 switch (params.format()) { | 176 switch (params.format()) { |
| 178 case AudioParameters::AUDIO_PCM_LINEAR: | 177 case AudioParameters::AUDIO_PCM_LINEAR: |
| 179 stream = MakeLinearInputStream(params, device_id, log_callback); | 178 stream = MakeLinearInputStream(params, device_id, log_callback); |
| 180 break; | 179 break; |
| 181 case AudioParameters::AUDIO_PCM_LOW_LATENCY: | 180 case AudioParameters::AUDIO_PCM_LOW_LATENCY: |
| 182 stream = MakeLowLatencyInputStream(params, device_id, log_callback); | 181 stream = MakeLowLatencyInputStream(params, device_id, log_callback); |
| 183 break; | 182 break; |
| 184 case AudioParameters::AUDIO_FAKE: | 183 case AudioParameters::AUDIO_FAKE: |
| 185 stream = FakeAudioInputStream::MakeFakeStream(this, params); | 184 stream = FakeAudioInputStream::MakeFakeStream(this, params); |
| 186 break; | 185 break; |
| 187 default: | 186 default: |
| 188 stream = NULL; | 187 stream = NULL; |
| 189 break; | 188 break; |
| 190 } | 189 } |
| 191 | 190 |
| 192 if (stream) { | 191 if (stream) { |
| 193 ++num_input_streams_; | 192 input_streams_.insert(stream); |
| 194 } | 193 } |
| 195 | 194 |
| 196 return stream; | 195 return stream; |
| 197 } | 196 } |
| 198 | 197 |
| 199 AudioOutputStream* AudioManagerBase::MakeAudioOutputStreamProxy( | 198 AudioOutputStream* AudioManagerBase::MakeAudioOutputStreamProxy( |
| 200 const AudioParameters& params, | 199 const AudioParameters& params, |
| 201 const std::string& device_id) { | 200 const std::string& device_id) { |
| 202 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); | 201 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); |
| 203 | 202 |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 275 void AudioManagerBase::GetAudioInputDeviceNames( | 274 void AudioManagerBase::GetAudioInputDeviceNames( |
| 276 AudioDeviceNames* device_names) { | 275 AudioDeviceNames* device_names) { |
| 277 } | 276 } |
| 278 | 277 |
| 279 void AudioManagerBase::GetAudioOutputDeviceNames( | 278 void AudioManagerBase::GetAudioOutputDeviceNames( |
| 280 AudioDeviceNames* device_names) { | 279 AudioDeviceNames* device_names) { |
| 281 } | 280 } |
| 282 | 281 |
| 283 void AudioManagerBase::ReleaseOutputStream(AudioOutputStream* stream) { | 282 void AudioManagerBase::ReleaseOutputStream(AudioOutputStream* stream) { |
| 284 DCHECK(stream); | 283 DCHECK(stream); |
| 284 CHECK_GT(num_output_streams_, 0); |
| 285 // TODO(xians) : Have a clearer destruction path for the AudioOutputStream. | 285 // TODO(xians) : Have a clearer destruction path for the AudioOutputStream. |
| 286 // For example, pass the ownership to AudioManager so it can delete the | 286 // For example, pass the ownership to AudioManager so it can delete the |
| 287 // streams. | 287 // streams. |
| 288 --num_output_streams_; | 288 --num_output_streams_; |
| 289 delete stream; | 289 delete stream; |
| 290 } | 290 } |
| 291 | 291 |
| 292 void AudioManagerBase::ReleaseInputStream(AudioInputStream* stream) { | 292 void AudioManagerBase::ReleaseInputStream(AudioInputStream* stream) { |
| 293 DCHECK(stream); | 293 DCHECK(stream); |
| 294 // TODO(xians) : Have a clearer destruction path for the AudioInputStream. | 294 // TODO(xians) : Have a clearer destruction path for the AudioInputStream. |
| 295 --num_input_streams_; | 295 CHECK_EQ(1u, input_streams_.erase(stream)); |
| 296 delete stream; | 296 delete stream; |
| 297 } | 297 } |
| 298 | 298 |
| 299 void AudioManagerBase::Shutdown() { | 299 void AudioManagerBase::Shutdown() { |
| 300 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); | 300 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); |
| 301 // Close all output streams. | 301 // Close all output streams. |
| 302 while (!output_dispatchers_.empty()) { | 302 while (!output_dispatchers_.empty()) { |
| 303 output_dispatchers_.back()->dispatcher->Shutdown(); | 303 output_dispatchers_.back()->dispatcher->Shutdown(); |
| 304 output_dispatchers_.pop_back(); | 304 output_dispatchers_.pop_back(); |
| 305 } | 305 } |
| 306 |
| 307 #if defined(OS_MACOSX) |
| 308 // On mac, AudioManager runs on the main thread, loop for which stops |
| 309 // processing task queue at this point. So even if tasks to close the |
| 310 // streams are enqueued, they would not run leading to CHECKs getting hit |
| 311 // in the destructor about open streams. Close them explicitly here. |
| 312 // crbug.com/608049. |
| 313 for (auto iter = input_streams_.begin(); iter != input_streams_.end();) { |
| 314 // Note: Closing the stream will invalidate the iterator. |
| 315 // Increment the iterator before closing the stream. |
| 316 AudioInputStream* stream = *iter++; |
| 317 stream->Close(); |
| 318 } |
| 319 #endif // OS_MACOSX |
| 306 } | 320 } |
| 307 | 321 |
| 308 void AudioManagerBase::AddOutputDeviceChangeListener( | 322 void AudioManagerBase::AddOutputDeviceChangeListener( |
| 309 AudioDeviceListener* listener) { | 323 AudioDeviceListener* listener) { |
| 310 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); | 324 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); |
| 311 output_listeners_.AddObserver(listener); | 325 output_listeners_.AddObserver(listener); |
| 312 } | 326 } |
| 313 | 327 |
| 314 void AudioManagerBase::RemoveOutputDeviceChangeListener( | 328 void AudioManagerBase::RemoveOutputDeviceChangeListener( |
| 315 AudioDeviceListener* listener) { | 329 AudioDeviceListener* listener) { |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 382 | 396 |
| 383 return 0; | 397 return 0; |
| 384 } | 398 } |
| 385 | 399 |
| 386 std::unique_ptr<AudioLog> AudioManagerBase::CreateAudioLog( | 400 std::unique_ptr<AudioLog> AudioManagerBase::CreateAudioLog( |
| 387 AudioLogFactory::AudioComponent component) { | 401 AudioLogFactory::AudioComponent component) { |
| 388 return audio_log_factory_->CreateAudioLog(component); | 402 return audio_log_factory_->CreateAudioLog(component); |
| 389 } | 403 } |
| 390 | 404 |
| 391 } // namespace media | 405 } // namespace media |
| OLD | NEW |