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

Side by Side Diff: media/audio/audio_manager_base.cc

Issue 2503693002: Tracks all open input streams in AudioManagerBase. (Closed)
Patch Set: close fake streams explicitly Created 4 years, 1 month 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 unified diff | Download patch
OLDNEW
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 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 // TODO(dalecurtis): Switch this to an base::ObserverListThreadSafe, so we 86 // TODO(dalecurtis): Switch this to an base::ObserverListThreadSafe, so we
87 // don't 87 // don't
88 // block the UI thread when swapping devices. 88 // block the UI thread when swapping devices.
89 output_listeners_( 89 output_listeners_(
90 base::ObserverList<AudioDeviceListener>::NOTIFY_EXISTING_ONLY), 90 base::ObserverList<AudioDeviceListener>::NOTIFY_EXISTING_ONLY),
91 audio_log_factory_(audio_log_factory) {} 91 audio_log_factory_(audio_log_factory) {}
92 92
93 AudioManagerBase::~AudioManagerBase() { 93 AudioManagerBase::~AudioManagerBase() {
94 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); 94 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
95 95
96 // All fake input/output streams should have been deleted.
97 CHECK(fake_output_streams_.empty());
98 CHECK(fake_input_streams_.empty());
99
96 // All the output streams should have been deleted. 100 // All the output streams should have been deleted.
97 CHECK_EQ(0, num_output_streams_); 101 CHECK_EQ(0, num_output_streams_);
98 // All the input streams should have been deleted. 102 // All the input streams should have been deleted.
99 CHECK_EQ(0, num_input_streams_); 103 CHECK_EQ(0, num_input_streams_);
100 } 104 }
101 105
102 base::string16 AudioManagerBase::GetAudioInputDeviceModel() { 106 base::string16 AudioManagerBase::GetAudioInputDeviceModel() {
103 return base::string16(); 107 return base::string16();
104 } 108 }
105 109
(...skipping 25 matching lines...) Expand all
131 case AudioParameters::AUDIO_PCM_LINEAR: 135 case AudioParameters::AUDIO_PCM_LINEAR:
132 DCHECK(AudioDeviceDescription::IsDefaultDevice(device_id)) 136 DCHECK(AudioDeviceDescription::IsDefaultDevice(device_id))
133 << "AUDIO_PCM_LINEAR supports only the default device."; 137 << "AUDIO_PCM_LINEAR supports only the default device.";
134 stream = MakeLinearOutputStream(params, log_callback); 138 stream = MakeLinearOutputStream(params, log_callback);
135 break; 139 break;
136 case AudioParameters::AUDIO_PCM_LOW_LATENCY: 140 case AudioParameters::AUDIO_PCM_LOW_LATENCY:
137 stream = MakeLowLatencyOutputStream(params, device_id, log_callback); 141 stream = MakeLowLatencyOutputStream(params, device_id, log_callback);
138 break; 142 break;
139 case AudioParameters::AUDIO_FAKE: 143 case AudioParameters::AUDIO_FAKE:
140 stream = FakeAudioOutputStream::MakeFakeStream(this, params); 144 stream = FakeAudioOutputStream::MakeFakeStream(this, params);
145 fake_output_streams_.insert(stream);
141 break; 146 break;
142 default: 147 default:
143 stream = NULL; 148 stream = NULL;
144 break; 149 break;
145 } 150 }
146 151
147 if (stream) { 152 if (stream) {
148 ++num_output_streams_; 153 ++num_output_streams_;
149 } 154 }
150 155
(...skipping 25 matching lines...) Expand all
176 AudioInputStream* stream; 181 AudioInputStream* stream;
177 switch (params.format()) { 182 switch (params.format()) {
178 case AudioParameters::AUDIO_PCM_LINEAR: 183 case AudioParameters::AUDIO_PCM_LINEAR:
179 stream = MakeLinearInputStream(params, device_id, log_callback); 184 stream = MakeLinearInputStream(params, device_id, log_callback);
180 break; 185 break;
181 case AudioParameters::AUDIO_PCM_LOW_LATENCY: 186 case AudioParameters::AUDIO_PCM_LOW_LATENCY:
182 stream = MakeLowLatencyInputStream(params, device_id, log_callback); 187 stream = MakeLowLatencyInputStream(params, device_id, log_callback);
183 break; 188 break;
184 case AudioParameters::AUDIO_FAKE: 189 case AudioParameters::AUDIO_FAKE:
185 stream = FakeAudioInputStream::MakeFakeStream(this, params); 190 stream = FakeAudioInputStream::MakeFakeStream(this, params);
191 fake_input_streams_.insert(stream);
186 break; 192 break;
187 default: 193 default:
188 stream = NULL; 194 stream = NULL;
189 break; 195 break;
190 } 196 }
191 197
192 if (stream) { 198 if (stream) {
193 ++num_input_streams_; 199 ++num_input_streams_;
194 } 200 }
195 201
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 void AudioManagerBase::GetAudioInputDeviceNames( 281 void AudioManagerBase::GetAudioInputDeviceNames(
276 AudioDeviceNames* device_names) { 282 AudioDeviceNames* device_names) {
277 } 283 }
278 284
279 void AudioManagerBase::GetAudioOutputDeviceNames( 285 void AudioManagerBase::GetAudioOutputDeviceNames(
280 AudioDeviceNames* device_names) { 286 AudioDeviceNames* device_names) {
281 } 287 }
282 288
283 void AudioManagerBase::ReleaseOutputStream(AudioOutputStream* stream) { 289 void AudioManagerBase::ReleaseOutputStream(AudioOutputStream* stream) {
284 DCHECK(stream); 290 DCHECK(stream);
291 CHECK_GT(num_output_streams_, 0);
285 // TODO(xians) : Have a clearer destruction path for the AudioOutputStream. 292 // TODO(xians) : Have a clearer destruction path for the AudioOutputStream.
286 // For example, pass the ownership to AudioManager so it can delete the 293 // For example, pass the ownership to AudioManager so it can delete the
287 // streams. 294 // streams.
295 fake_output_streams_.erase(stream);
288 --num_output_streams_; 296 --num_output_streams_;
289 delete stream; 297 delete stream;
290 } 298 }
291 299
292 void AudioManagerBase::ReleaseInputStream(AudioInputStream* stream) { 300 void AudioManagerBase::ReleaseInputStream(AudioInputStream* stream) {
293 DCHECK(stream); 301 DCHECK(stream);
302 CHECK_GT(num_input_streams_, 0);
294 // TODO(xians) : Have a clearer destruction path for the AudioInputStream. 303 // TODO(xians) : Have a clearer destruction path for the AudioInputStream.
304 fake_input_streams_.erase(stream);
295 --num_input_streams_; 305 --num_input_streams_;
296 delete stream; 306 delete stream;
297 } 307 }
298 308
299 void AudioManagerBase::Shutdown() { 309 void AudioManagerBase::Shutdown() {
300 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); 310 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
301 // Close all output streams. 311 // Close all output streams.
302 while (!output_dispatchers_.empty()) { 312 while (!output_dispatchers_.empty()) {
303 output_dispatchers_.back()->dispatcher->Shutdown(); 313 output_dispatchers_.back()->dispatcher->Shutdown();
304 output_dispatchers_.pop_back(); 314 output_dispatchers_.pop_back();
305 } 315 }
316
317 #if defined(OS_MACOSX)
318 // On mac, AudioManager runs on the main thread, loop for which stops
319 // processing task queue at this point. So even if tasks to close the
320 // streams are enqueued, they would not run leading to CHECKs getting hit
321 // in the destructor about open streams. Close them explicitly here.
322 // crbug.com/608049.
323 for (auto& iter = fake_output_streams_.begin();
324 iter != fake_output_streams_.end();) {
325 // Note: Closing the stream will invalidate the iterator.
326 // Increment the iterator before closing the stream.
327 AudioOutputStream* stream = *(iter++);
328 stream->close();
329 }
330 for (auto& iter = fake_input_streams_.begin();
331 iter != fake_input_streams_.end();) {
332 // Note: Closing the stream will invalidate the iterator.
333 // Increment the iterator before closing the stream.
334 AudioInputStream* stream = *(iter++);
335 stream->close();
336 }
337 #endif // OS_MACOSX
306 } 338 }
307 339
308 void AudioManagerBase::AddOutputDeviceChangeListener( 340 void AudioManagerBase::AddOutputDeviceChangeListener(
309 AudioDeviceListener* listener) { 341 AudioDeviceListener* listener) {
310 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); 342 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
311 output_listeners_.AddObserver(listener); 343 output_listeners_.AddObserver(listener);
312 } 344 }
313 345
314 void AudioManagerBase::RemoveOutputDeviceChangeListener( 346 void AudioManagerBase::RemoveOutputDeviceChangeListener(
315 AudioDeviceListener* listener) { 347 AudioDeviceListener* listener) {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 414
383 return 0; 415 return 0;
384 } 416 }
385 417
386 std::unique_ptr<AudioLog> AudioManagerBase::CreateAudioLog( 418 std::unique_ptr<AudioLog> AudioManagerBase::CreateAudioLog(
387 AudioLogFactory::AudioComponent component) { 419 AudioLogFactory::AudioComponent component) {
388 return audio_log_factory_->CreateAudioLog(component); 420 return audio_log_factory_->CreateAudioLog(component);
389 } 421 }
390 422
391 } // namespace media 423 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698