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

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

Issue 495983002: Improve logging related to start/stop and failure of audio input streams in Chrome (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Experimental version of AudioManagerBase logging Created 6 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 unified diff | Download patch | Annotate | Revision Log
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_input_controller.h" 5 #include "media/audio/audio_input_controller.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/strings/stringprintf.h" 8 #include "base/strings/stringprintf.h"
9 #include "base/threading/thread_restrictions.h" 9 #include "base/threading/thread_restrictions.h"
10 #include "base/time/time.h" 10 #include "base/time/time.h"
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 result, 66 result,
67 CAPTURE_STARTUP_RESULT_MAX + 1); 67 CAPTURE_STARTUP_RESULT_MAX + 1);
68 68
69 } 69 }
70 70
71 namespace media { 71 namespace media {
72 72
73 // static 73 // static
74 AudioInputController::Factory* AudioInputController::factory_ = NULL; 74 AudioInputController::Factory* AudioInputController::factory_ = NULL;
75 75
76 AudioInputController::AudioInputController(EventHandler* handler, 76 AudioInputController::AudioInputController(AudioManager* audio_manager,
77 EventHandler* handler,
77 SyncWriter* sync_writer, 78 SyncWriter* sync_writer,
78 UserInputMonitor* user_input_monitor) 79 UserInputMonitor* user_input_monitor)
79 : creator_task_runner_(base::MessageLoopProxy::current()), 80 : creator_task_runner_(base::MessageLoopProxy::current()),
80 handler_(handler), 81 handler_(handler),
82 audio_manager_(audio_manager),
81 stream_(NULL), 83 stream_(NULL),
82 data_is_active_(false), 84 data_is_active_(false),
83 state_(CLOSED), 85 state_(CLOSED),
84 sync_writer_(sync_writer), 86 sync_writer_(sync_writer),
85 max_volume_(0.0), 87 max_volume_(0.0),
86 user_input_monitor_(user_input_monitor), 88 user_input_monitor_(user_input_monitor),
87 #if defined(AUDIO_POWER_MONITORING) 89 #if defined(AUDIO_POWER_MONITORING)
88 silence_state_(SILENCE_STATE_NO_MEASUREMENT), 90 silence_state_(SILENCE_STATE_NO_MEASUREMENT),
89 #endif 91 #endif
90 prev_key_down_count_(0) { 92 prev_key_down_count_(0) {
(...skipping 13 matching lines...) Expand all
104 UserInputMonitor* user_input_monitor) { 106 UserInputMonitor* user_input_monitor) {
105 DCHECK(audio_manager); 107 DCHECK(audio_manager);
106 108
107 if (!params.IsValid() || (params.channels() > kMaxInputChannels)) 109 if (!params.IsValid() || (params.channels() > kMaxInputChannels))
108 return NULL; 110 return NULL;
109 111
110 if (factory_) { 112 if (factory_) {
111 return factory_->Create( 113 return factory_->Create(
112 audio_manager, event_handler, params, user_input_monitor); 114 audio_manager, event_handler, params, user_input_monitor);
113 } 115 }
114 scoped_refptr<AudioInputController> controller( 116 scoped_refptr<AudioInputController> controller(new AudioInputController(
115 new AudioInputController(event_handler, NULL, user_input_monitor)); 117 audio_manager, event_handler, NULL, user_input_monitor));
116 118
117 controller->task_runner_ = audio_manager->GetTaskRunner(); 119 controller->task_runner_ = audio_manager->GetTaskRunner();
118 120
119 // Create and open a new audio input stream from the existing 121 // Create and open a new audio input stream from the existing
120 // audio-device thread. 122 // audio-device thread.
121 if (!controller->task_runner_->PostTask(FROM_HERE, 123 if (!controller->task_runner_->PostTask(
122 base::Bind(&AudioInputController::DoCreate, controller, 124 FROM_HERE,
123 base::Unretained(audio_manager), params, device_id))) { 125 base::Bind(&AudioInputController::DoCreate,
126 controller,
127 params,
128 device_id))) {
124 controller = NULL; 129 controller = NULL;
125 } 130 }
126 131
127 return controller; 132 return controller;
128 } 133 }
129 134
130 // static 135 // static
131 scoped_refptr<AudioInputController> AudioInputController::CreateLowLatency( 136 scoped_refptr<AudioInputController> AudioInputController::CreateLowLatency(
132 AudioManager* audio_manager, 137 AudioManager* audio_manager,
133 EventHandler* event_handler, 138 EventHandler* event_handler,
134 const AudioParameters& params, 139 const AudioParameters& params,
135 const std::string& device_id, 140 const std::string& device_id,
136 SyncWriter* sync_writer, 141 SyncWriter* sync_writer,
137 UserInputMonitor* user_input_monitor) { 142 UserInputMonitor* user_input_monitor) {
138 DCHECK(audio_manager); 143 DCHECK(audio_manager);
139 DCHECK(sync_writer); 144 DCHECK(sync_writer);
140 145
141 if (!params.IsValid() || (params.channels() > kMaxInputChannels)) 146 if (!params.IsValid() || (params.channels() > kMaxInputChannels))
142 return NULL; 147 return NULL;
143 148
144 // Create the AudioInputController object and ensure that it runs on 149 // Create the AudioInputController object and ensure that it runs on
145 // the audio-manager thread. 150 // the audio-manager thread.
146 scoped_refptr<AudioInputController> controller( 151 scoped_refptr<AudioInputController> controller(new AudioInputController(
147 new AudioInputController(event_handler, sync_writer, user_input_monitor)); 152 audio_manager, event_handler, sync_writer, user_input_monitor));
148 controller->task_runner_ = audio_manager->GetTaskRunner(); 153 controller->task_runner_ = audio_manager->GetTaskRunner();
149 154
150 // Create and open a new audio input stream from the existing 155 // Create and open a new audio input stream from the existing
151 // audio-device thread. Use the provided audio-input device. 156 // audio-device thread. Use the provided audio-input device.
152 if (!controller->task_runner_->PostTask(FROM_HERE, 157 if (!controller->task_runner_->PostTask(
153 base::Bind(&AudioInputController::DoCreate, controller, 158 FROM_HERE,
154 base::Unretained(audio_manager), params, device_id))) { 159 base::Bind(&AudioInputController::DoCreate,
160 controller,
161 params,
162 device_id))) {
155 controller = NULL; 163 controller = NULL;
156 } 164 }
157 165
158 return controller; 166 return controller;
159 } 167 }
160 168
161 // static 169 // static
162 scoped_refptr<AudioInputController> AudioInputController::CreateForStream( 170 scoped_refptr<AudioInputController> AudioInputController::CreateForStream(
163 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, 171 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
164 EventHandler* event_handler, 172 EventHandler* event_handler,
165 AudioInputStream* stream, 173 AudioInputStream* stream,
166 SyncWriter* sync_writer, 174 SyncWriter* sync_writer,
167 UserInputMonitor* user_input_monitor) { 175 UserInputMonitor* user_input_monitor) {
168 DCHECK(sync_writer); 176 DCHECK(sync_writer);
169 DCHECK(stream); 177 DCHECK(stream);
170 178
171 // Create the AudioInputController object and ensure that it runs on 179 // Create the AudioInputController object and ensure that it runs on
172 // the audio-manager thread. 180 // the audio-manager thread.
173 scoped_refptr<AudioInputController> controller( 181 scoped_refptr<AudioInputController> controller(new AudioInputController(
174 new AudioInputController(event_handler, sync_writer, user_input_monitor)); 182 NULL, event_handler, sync_writer, user_input_monitor));
175 controller->task_runner_ = task_runner; 183 controller->task_runner_ = task_runner;
176 184
177 // TODO(miu): See TODO at top of file. Until that's resolved, we need to 185 // TODO(miu): See TODO at top of file. Until that's resolved, we need to
178 // disable the error auto-detection here (since the audio mirroring 186 // disable the error auto-detection here (since the audio mirroring
179 // implementation will reliably report error and close events). Note, of 187 // implementation will reliably report error and close events). Note, of
180 // course, that we're assuming CreateForStream() has been called for the audio 188 // course, that we're assuming CreateForStream() has been called for the audio
181 // mirroring use case only. 189 // mirroring use case only.
182 if (!controller->task_runner_->PostTask( 190 if (!controller->task_runner_->PostTask(
183 FROM_HERE, 191 FROM_HERE,
184 base::Bind(&AudioInputController::DoCreateForStream, 192 base::Bind(&AudioInputController::DoCreateForStream,
(...skipping 21 matching lines...) Expand all
206 void AudioInputController::SetVolume(double volume) { 214 void AudioInputController::SetVolume(double volume) {
207 task_runner_->PostTask(FROM_HERE, base::Bind( 215 task_runner_->PostTask(FROM_HERE, base::Bind(
208 &AudioInputController::DoSetVolume, this, volume)); 216 &AudioInputController::DoSetVolume, this, volume));
209 } 217 }
210 218
211 void AudioInputController::SetAutomaticGainControl(bool enabled) { 219 void AudioInputController::SetAutomaticGainControl(bool enabled) {
212 task_runner_->PostTask(FROM_HERE, base::Bind( 220 task_runner_->PostTask(FROM_HERE, base::Bind(
213 &AudioInputController::DoSetAutomaticGainControl, this, enabled)); 221 &AudioInputController::DoSetAutomaticGainControl, this, enabled));
214 } 222 }
215 223
216 void AudioInputController::DoCreate(AudioManager* audio_manager, 224 void AudioInputController::DoCreate(const AudioParameters& params,
217 const AudioParameters& params,
218 const std::string& device_id) { 225 const std::string& device_id) {
219 DCHECK(task_runner_->BelongsToCurrentThread()); 226 DCHECK(task_runner_->BelongsToCurrentThread());
220 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.CreateTime"); 227 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.CreateTime");
228 if (handler_) {
229 std::string log_string =
230 base::StringPrintf("AIC::DoCreate(device_id=%s)", device_id.c_str());
Henrik Grunell 2014/08/22 16:14:42 What device id is this? Unique in what way? Can it
no longer working on chromium 2014/08/25 08:20:05 This is the uniqie id of the device, we can't log
henrika (OOO until Aug 14) 2014/08/25 12:47:44 Removing. Thanks.
231 handler_->OnLog(this, log_string);
232 }
221 233
222 #if defined(AUDIO_POWER_MONITORING) 234 #if defined(AUDIO_POWER_MONITORING)
223 // Create the audio (power) level meter given the provided audio parameters. 235 // Create the audio (power) level meter given the provided audio parameters.
224 // An AudioBus is also needed to wrap the raw data buffer from the native 236 // An AudioBus is also needed to wrap the raw data buffer from the native
225 // layer to match AudioPowerMonitor::Scan(). 237 // layer to match AudioPowerMonitor::Scan().
226 // TODO(henrika): Remove use of extra AudioBus. See http://crbug.com/375155. 238 // TODO(henrika): Remove use of extra AudioBus. See http://crbug.com/375155.
227 audio_level_.reset(new media::AudioPowerMonitor( 239 audio_level_.reset(new media::AudioPowerMonitor(
228 params.sample_rate(), 240 params.sample_rate(),
229 TimeDelta::FromMilliseconds(kPowerMeasurementTimeConstantMilliseconds))); 241 TimeDelta::FromMilliseconds(kPowerMeasurementTimeConstantMilliseconds)));
230 audio_params_ = params; 242 audio_params_ = params;
231 silence_state_ = SILENCE_STATE_NO_MEASUREMENT; 243 silence_state_ = SILENCE_STATE_NO_MEASUREMENT;
232 #endif 244 #endif
233 245
246 if (audio_manager_)
247 audio_manager_->AddStateChangeListener(this);
248
234 // TODO(miu): See TODO at top of file. Until that's resolved, assume all 249 // TODO(miu): See TODO at top of file. Until that's resolved, assume all
235 // platform audio input requires the |no_data_timer_| be used to auto-detect 250 // platform audio input requires the |no_data_timer_| be used to auto-detect
236 // errors. In reality, probably only Windows needs to be treated as 251 // errors. In reality, probably only Windows needs to be treated as
237 // unreliable here. 252 // unreliable here.
238 DoCreateForStream(audio_manager->MakeAudioInputStream(params, device_id)); 253 DoCreateForStream(audio_manager_->MakeAudioInputStream(params, device_id));
239 } 254 }
240 255
241 void AudioInputController::DoCreateForStream( 256 void AudioInputController::DoCreateForStream(
242 AudioInputStream* stream_to_control) { 257 AudioInputStream* stream_to_control) {
243 DCHECK(task_runner_->BelongsToCurrentThread()); 258 DCHECK(task_runner_->BelongsToCurrentThread());
244 259
245 DCHECK(!stream_); 260 DCHECK(!stream_);
246 stream_ = stream_to_control; 261 stream_ = stream_to_control;
247 262
248 if (!stream_) { 263 if (!stream_) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.RecordTime"); 306 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.RecordTime");
292 307
293 if (state_ != CREATED) 308 if (state_ != CREATED)
294 return; 309 return;
295 310
296 { 311 {
297 base::AutoLock auto_lock(lock_); 312 base::AutoLock auto_lock(lock_);
298 state_ = RECORDING; 313 state_ = RECORDING;
299 } 314 }
300 315
316 if (handler_)
317 handler_->OnLog(this, "AIC::DoRecord");
no longer working on chromium 2014/08/25 08:20:05 I don't really think you should log these, DoRecor
henrika (OOO until Aug 14) 2014/08/25 12:47:44 Well, if it does that may very well be a reason wh
318
301 if (no_data_timer_) { 319 if (no_data_timer_) {
302 // Start the data timer. Once |kTimerResetIntervalSeconds| have passed, 320 // Start the data timer. Once |kTimerResetIntervalSeconds| have passed,
303 // a callback to FirstCheckForNoData() is made. 321 // a callback to FirstCheckForNoData() is made.
304 no_data_timer_->Reset(); 322 no_data_timer_->Reset();
305 } 323 }
306 324
307 stream_->Start(this); 325 stream_->Start(this);
308 if (handler_) 326 if (handler_)
309 handler_->OnRecording(this); 327 handler_->OnRecording(this);
310 } 328 }
311 329
312 void AudioInputController::DoClose() { 330 void AudioInputController::DoClose() {
313 DCHECK(task_runner_->BelongsToCurrentThread()); 331 DCHECK(task_runner_->BelongsToCurrentThread());
314 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.CloseTime"); 332 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.CloseTime");
315 333
316 if (state_ == CLOSED) 334 if (state_ == CLOSED)
317 return; 335 return;
318 336
337 if (handler_)
338 handler_->OnLog(this, "AIC::DoClose");
339
319 // Delete the timer on the same thread that created it. 340 // Delete the timer on the same thread that created it.
320 no_data_timer_.reset(); 341 no_data_timer_.reset();
321 342
322 DoStopCloseAndClearStream(); 343 DoStopCloseAndClearStream();
323 SetDataIsActive(false); 344 SetDataIsActive(false);
324 345
346 if (audio_manager_)
347 audio_manager_->RemoveStateChangeListener(this);
Henrik Grunell 2014/08/22 16:14:43 Should the raw |audio_manager_| pointer be set to
henrika (OOO until Aug 14) 2014/08/25 12:47:44 It could but I can't really see the gain actually
348
325 if (SharedMemoryAndSyncSocketMode()) 349 if (SharedMemoryAndSyncSocketMode())
326 sync_writer_->Close(); 350 sync_writer_->Close();
327 351
328 if (user_input_monitor_) 352 if (user_input_monitor_)
329 user_input_monitor_->DisableKeyPressMonitoring(); 353 user_input_monitor_->DisableKeyPressMonitoring();
330 354
331 #if defined(AUDIO_POWER_MONITORING) 355 #if defined(AUDIO_POWER_MONITORING)
332 // Send UMA stats if we have enabled power monitoring. 356 // Send UMA stats if we have enabled power monitoring.
333 if (audio_level_) { 357 if (audio_level_) {
334 LogSilenceState(silence_state_); 358 LogSilenceState(silence_state_);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 return; 400 return;
377 401
378 stream_->SetAutomaticGainControl(enabled); 402 stream_->SetAutomaticGainControl(enabled);
379 } 403 }
380 404
381 void AudioInputController::FirstCheckForNoData() { 405 void AudioInputController::FirstCheckForNoData() {
382 DCHECK(task_runner_->BelongsToCurrentThread()); 406 DCHECK(task_runner_->BelongsToCurrentThread());
383 LogCaptureStartupResult(GetDataIsActive() ? 407 LogCaptureStartupResult(GetDataIsActive() ?
384 CAPTURE_STARTUP_OK : 408 CAPTURE_STARTUP_OK :
385 CAPTURE_STARTUP_NO_DATA_CALLBACK); 409 CAPTURE_STARTUP_NO_DATA_CALLBACK);
410 if (handler_) {
411 GetDataIsActive()
412 ? handler_->OnLog(this, "AIC::FirstCheckForNoData => data is active")
no longer working on chromium 2014/08/25 08:20:05 this does not look like clang format, could you pl
henrika (OOO until Aug 14) 2014/08/25 12:47:44 I did run git cl format and this is what it gives
413 : handler_->OnLog(this,
414 "AIC::FirstCheckForNoData => data is NOT active");
415 }
386 DoCheckForNoData(); 416 DoCheckForNoData();
387 } 417 }
388 418
389 void AudioInputController::DoCheckForNoData() { 419 void AudioInputController::DoCheckForNoData() {
390 DCHECK(task_runner_->BelongsToCurrentThread()); 420 DCHECK(task_runner_->BelongsToCurrentThread());
391 421
392 if (!GetDataIsActive()) { 422 if (!GetDataIsActive()) {
393 // The data-is-active marker will be false only if it has been more than 423 // The data-is-active marker will be false only if it has been more than
394 // one second since a data packet was recorded. This can happen if a 424 // one second since a data packet was recorded. This can happen if a
395 // capture device has been removed or disabled. 425 // capture device has been removed or disabled.
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
519 silence_state_ = SILENCE_STATE_AUDIO_AND_SILENCE; 549 silence_state_ = SILENCE_STATE_AUDIO_AND_SILENCE;
520 else 550 else
521 DCHECK(silence_state_ == SILENCE_STATE_ONLY_AUDIO || 551 DCHECK(silence_state_ == SILENCE_STATE_ONLY_AUDIO ||
522 silence_state_ == SILENCE_STATE_AUDIO_AND_SILENCE); 552 silence_state_ == SILENCE_STATE_AUDIO_AND_SILENCE);
523 } 553 }
524 554
525 handler_->OnLog(this, log_string); 555 handler_->OnLog(this, log_string);
526 #endif 556 #endif
527 } 557 }
528 558
559 void AudioInputController::OnStateChange(const std::string state) {
560 DCHECK(task_runner_->BelongsToCurrentThread());
561 if (handler_)
562 handler_->OnLog(this, state);
563 }
564
529 void AudioInputController::OnError(AudioInputStream* stream) { 565 void AudioInputController::OnError(AudioInputStream* stream) {
530 // Handle error on the audio-manager thread. 566 // Handle error on the audio-manager thread.
531 task_runner_->PostTask(FROM_HERE, base::Bind( 567 task_runner_->PostTask(FROM_HERE, base::Bind(
532 &AudioInputController::DoReportError, this)); 568 &AudioInputController::DoReportError, this));
533 } 569 }
534 570
535 void AudioInputController::DoStopCloseAndClearStream() { 571 void AudioInputController::DoStopCloseAndClearStream() {
536 DCHECK(task_runner_->BelongsToCurrentThread()); 572 DCHECK(task_runner_->BelongsToCurrentThread());
537 573
538 // Allow calling unconditionally and bail if we don't have a stream to close. 574 // Allow calling unconditionally and bail if we don't have a stream to close.
(...skipping 17 matching lines...) Expand all
556 592
557 #if defined(AUDIO_POWER_MONITORING) 593 #if defined(AUDIO_POWER_MONITORING)
558 void AudioInputController::LogSilenceState(SilenceState value) { 594 void AudioInputController::LogSilenceState(SilenceState value) {
559 UMA_HISTOGRAM_ENUMERATION("Media.AudioInputControllerSessionSilenceReport", 595 UMA_HISTOGRAM_ENUMERATION("Media.AudioInputControllerSessionSilenceReport",
560 value, 596 value,
561 SILENCE_STATE_MAX + 1); 597 SILENCE_STATE_MAX + 1);
562 } 598 }
563 #endif 599 #endif
564 600
565 } // namespace media 601 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698