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

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

Issue 2503693002: Tracks all open input streams in AudioManagerBase. (Closed)
Patch Set: fixes compile error on windows 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
« no previous file with comments | « media/audio/audio_manager_base.h ('k') | media/audio/mac/audio_manager_mac.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
OLDNEW
« no previous file with comments | « media/audio/audio_manager_base.h ('k') | media/audio/mac/audio_manager_mac.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698