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

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: Feedback from xians@ Created 6 years, 3 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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 result, 67 result,
68 CAPTURE_STARTUP_RESULT_MAX + 1); 68 CAPTURE_STARTUP_RESULT_MAX + 1);
69 69
70 } 70 }
71 71
72 namespace media { 72 namespace media {
73 73
74 // static 74 // static
75 AudioInputController::Factory* AudioInputController::factory_ = NULL; 75 AudioInputController::Factory* AudioInputController::factory_ = NULL;
76 76
77 AudioInputController::AudioInputController(EventHandler* handler, 77 AudioInputController::AudioInputController(AudioManager* audio_manager,
78 EventHandler* handler,
78 SyncWriter* sync_writer, 79 SyncWriter* sync_writer,
79 UserInputMonitor* user_input_monitor) 80 UserInputMonitor* user_input_monitor)
80 : creator_task_runner_(base::MessageLoopProxy::current()), 81 : creator_task_runner_(base::MessageLoopProxy::current()),
81 handler_(handler), 82 handler_(handler),
83 audio_manager_(audio_manager),
82 stream_(NULL), 84 stream_(NULL),
83 data_is_active_(false), 85 data_is_active_(false),
84 state_(CLOSED), 86 state_(CLOSED),
85 sync_writer_(sync_writer), 87 sync_writer_(sync_writer),
86 max_volume_(0.0), 88 max_volume_(0.0),
87 user_input_monitor_(user_input_monitor), 89 user_input_monitor_(user_input_monitor),
88 #if defined(AUDIO_POWER_MONITORING) 90 #if defined(AUDIO_POWER_MONITORING)
89 log_silence_state_(false), 91 log_silence_state_(false),
90 silence_state_(SILENCE_STATE_NO_MEASUREMENT), 92 silence_state_(SILENCE_STATE_NO_MEASUREMENT),
91 #endif 93 #endif
(...skipping 14 matching lines...) Expand all
106 UserInputMonitor* user_input_monitor) { 108 UserInputMonitor* user_input_monitor) {
107 DCHECK(audio_manager); 109 DCHECK(audio_manager);
108 110
109 if (!params.IsValid() || (params.channels() > kMaxInputChannels)) 111 if (!params.IsValid() || (params.channels() > kMaxInputChannels))
110 return NULL; 112 return NULL;
111 113
112 if (factory_) { 114 if (factory_) {
113 return factory_->Create( 115 return factory_->Create(
114 audio_manager, event_handler, params, user_input_monitor); 116 audio_manager, event_handler, params, user_input_monitor);
115 } 117 }
116 scoped_refptr<AudioInputController> controller( 118 scoped_refptr<AudioInputController> controller(new AudioInputController(
117 new AudioInputController(event_handler, NULL, user_input_monitor)); 119 audio_manager, event_handler, NULL, user_input_monitor));
118 120
119 controller->task_runner_ = audio_manager->GetTaskRunner(); 121 controller->task_runner_ = audio_manager->GetTaskRunner();
120 122
121 // Create and open a new audio input stream from the existing 123 // Create and open a new audio input stream from the existing
122 // audio-device thread. 124 // audio-device thread.
123 if (!controller->task_runner_->PostTask(FROM_HERE, 125 if (!controller->task_runner_->PostTask(
124 base::Bind(&AudioInputController::DoCreate, controller, 126 FROM_HERE,
125 base::Unretained(audio_manager), params, device_id))) { 127 base::Bind(&AudioInputController::DoCreate,
128 controller,
129 params,
130 device_id))) {
126 controller = NULL; 131 controller = NULL;
127 } 132 }
128 133
129 return controller; 134 return controller;
130 } 135 }
131 136
132 // static 137 // static
133 scoped_refptr<AudioInputController> AudioInputController::CreateLowLatency( 138 scoped_refptr<AudioInputController> AudioInputController::CreateLowLatency(
134 AudioManager* audio_manager, 139 AudioManager* audio_manager,
135 EventHandler* event_handler, 140 EventHandler* event_handler,
136 const AudioParameters& params, 141 const AudioParameters& params,
137 const std::string& device_id, 142 const std::string& device_id,
138 SyncWriter* sync_writer, 143 SyncWriter* sync_writer,
139 UserInputMonitor* user_input_monitor) { 144 UserInputMonitor* user_input_monitor) {
140 DCHECK(audio_manager); 145 DCHECK(audio_manager);
141 DCHECK(sync_writer); 146 DCHECK(sync_writer);
142 147
143 if (!params.IsValid() || (params.channels() > kMaxInputChannels)) 148 if (!params.IsValid() || (params.channels() > kMaxInputChannels))
144 return NULL; 149 return NULL;
145 150
146 // Create the AudioInputController object and ensure that it runs on 151 // Create the AudioInputController object and ensure that it runs on
147 // the audio-manager thread. 152 // the audio-manager thread.
148 scoped_refptr<AudioInputController> controller( 153 scoped_refptr<AudioInputController> controller(new AudioInputController(
149 new AudioInputController(event_handler, sync_writer, user_input_monitor)); 154 audio_manager, event_handler, sync_writer, user_input_monitor));
150 controller->task_runner_ = audio_manager->GetTaskRunner(); 155 controller->task_runner_ = audio_manager->GetTaskRunner();
151 156
152 // Create and open a new audio input stream from the existing 157 // Create and open a new audio input stream from the existing
153 // audio-device thread. Use the provided audio-input device. 158 // audio-device thread. Use the provided audio-input device.
154 if (!controller->task_runner_->PostTask(FROM_HERE, 159 if (!controller->task_runner_->PostTask(
155 base::Bind(&AudioInputController::DoCreateForLowLatency, controller, 160 FROM_HERE,
156 base::Unretained(audio_manager), params, device_id))) { 161 base::Bind(&AudioInputController::DoCreate,
162 controller,
163 params,
164 device_id))) {
157 controller = NULL; 165 controller = NULL;
158 } 166 }
159 167
160 return controller; 168 return controller;
161 } 169 }
162 170
163 // static 171 // static
164 scoped_refptr<AudioInputController> AudioInputController::CreateForStream( 172 scoped_refptr<AudioInputController> AudioInputController::CreateForStream(
165 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, 173 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
166 EventHandler* event_handler, 174 EventHandler* event_handler,
167 AudioInputStream* stream, 175 AudioInputStream* stream,
168 SyncWriter* sync_writer, 176 SyncWriter* sync_writer,
169 UserInputMonitor* user_input_monitor) { 177 UserInputMonitor* user_input_monitor) {
170 DCHECK(sync_writer); 178 DCHECK(sync_writer);
171 DCHECK(stream); 179 DCHECK(stream);
172 180
173 // Create the AudioInputController object and ensure that it runs on 181 // Create the AudioInputController object and ensure that it runs on
174 // the audio-manager thread. 182 // the audio-manager thread.
175 scoped_refptr<AudioInputController> controller( 183 scoped_refptr<AudioInputController> controller(new AudioInputController(
176 new AudioInputController(event_handler, sync_writer, user_input_monitor)); 184 NULL, event_handler, sync_writer, user_input_monitor));
177 controller->task_runner_ = task_runner; 185 controller->task_runner_ = task_runner;
178 186
179 // TODO(miu): See TODO at top of file. Until that's resolved, we need to 187 // TODO(miu): See TODO at top of file. Until that's resolved, we need to
180 // disable the error auto-detection here (since the audio mirroring 188 // disable the error auto-detection here (since the audio mirroring
181 // implementation will reliably report error and close events). Note, of 189 // implementation will reliably report error and close events). Note, of
182 // course, that we're assuming CreateForStream() has been called for the audio 190 // course, that we're assuming CreateForStream() has been called for the audio
183 // mirroring use case only. 191 // mirroring use case only.
184 if (!controller->task_runner_->PostTask( 192 if (!controller->task_runner_->PostTask(
185 FROM_HERE, 193 FROM_HERE,
186 base::Bind(&AudioInputController::DoCreateForStream, 194 base::Bind(&AudioInputController::DoCreateForStream,
(...skipping 21 matching lines...) Expand all
208 void AudioInputController::SetVolume(double volume) { 216 void AudioInputController::SetVolume(double volume) {
209 task_runner_->PostTask(FROM_HERE, base::Bind( 217 task_runner_->PostTask(FROM_HERE, base::Bind(
210 &AudioInputController::DoSetVolume, this, volume)); 218 &AudioInputController::DoSetVolume, this, volume));
211 } 219 }
212 220
213 void AudioInputController::SetAutomaticGainControl(bool enabled) { 221 void AudioInputController::SetAutomaticGainControl(bool enabled) {
214 task_runner_->PostTask(FROM_HERE, base::Bind( 222 task_runner_->PostTask(FROM_HERE, base::Bind(
215 &AudioInputController::DoSetAutomaticGainControl, this, enabled)); 223 &AudioInputController::DoSetAutomaticGainControl, this, enabled));
216 } 224 }
217 225
218 void AudioInputController::DoCreate(AudioManager* audio_manager, 226 void AudioInputController::DoCreate(const AudioParameters& params,
219 const AudioParameters& params,
220 const std::string& device_id) { 227 const std::string& device_id) {
221 DCHECK(task_runner_->BelongsToCurrentThread()); 228 DCHECK(task_runner_->BelongsToCurrentThread());
222 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.CreateTime"); 229 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.CreateTime");
230 if (handler_) {
231 handler_->OnLog(this, "AIC::DoCreate()");
232 }
223 233
224 #if defined(AUDIO_POWER_MONITORING) 234 #if defined(AUDIO_POWER_MONITORING)
225 // Create the audio (power) level meter given the provided audio parameters. 235 // Create the audio (power) level meter given the provided audio parameters.
226 // 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
227 // layer to match AudioPowerMonitor::Scan(). 237 // layer to match AudioPowerMonitor::Scan().
228 // 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.
229 audio_level_.reset(new media::AudioPowerMonitor( 239 audio_level_.reset(new media::AudioPowerMonitor(
230 params.sample_rate(), 240 params.sample_rate(),
231 TimeDelta::FromMilliseconds(kPowerMeasurementTimeConstantMilliseconds))); 241 TimeDelta::FromMilliseconds(kPowerMeasurementTimeConstantMilliseconds)));
232 audio_params_ = params; 242 audio_params_ = params;
233 silence_state_ = SILENCE_STATE_NO_MEASUREMENT; 243 silence_state_ = SILENCE_STATE_NO_MEASUREMENT;
234 #endif 244 #endif
235 245
246 if (audio_manager_)
247 audio_manager_->AddStateChangeListener(this);
248
236 // 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
237 // 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
238 // errors. In reality, probably only Windows needs to be treated as 251 // errors. In reality, probably only Windows needs to be treated as
239 // unreliable here. 252 // unreliable here.
240 DoCreateForStream(audio_manager->MakeAudioInputStream(params, device_id)); 253 DoCreateForStream(audio_manager_->MakeAudioInputStream(params, device_id));
241 }
242
243 void AudioInputController::DoCreateForLowLatency(AudioManager* audio_manager,
244 const AudioParameters& params,
245 const std::string& device_id) {
246 DCHECK(task_runner_->BelongsToCurrentThread());
247
248 #if defined(AUDIO_POWER_MONITORING)
249 // We only log silence state UMA stats for low latency mode and if we use a
250 // real device.
251 if (params.format() != AudioParameters::AUDIO_FAKE)
252 log_silence_state_ = true;
253 #endif
254
255 DoCreate(audio_manager, params, device_id);
256 } 254 }
257 255
258 void AudioInputController::DoCreateForStream( 256 void AudioInputController::DoCreateForStream(
259 AudioInputStream* stream_to_control) { 257 AudioInputStream* stream_to_control) {
260 DCHECK(task_runner_->BelongsToCurrentThread()); 258 DCHECK(task_runner_->BelongsToCurrentThread());
261 259
262 DCHECK(!stream_); 260 DCHECK(!stream_);
263 stream_ = stream_to_control; 261 stream_ = stream_to_control;
264 262
265 if (!stream_) { 263 if (!stream_) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.RecordTime"); 306 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.RecordTime");
309 307
310 if (state_ != CREATED) 308 if (state_ != CREATED)
311 return; 309 return;
312 310
313 { 311 {
314 base::AutoLock auto_lock(lock_); 312 base::AutoLock auto_lock(lock_);
315 state_ = RECORDING; 313 state_ = RECORDING;
316 } 314 }
317 315
316 if (handler_)
317 handler_->OnLog(this, "AIC::DoRecord");
318
318 if (no_data_timer_) { 319 if (no_data_timer_) {
319 // Start the data timer. Once |kTimerResetIntervalSeconds| have passed, 320 // Start the data timer. Once |kTimerResetIntervalSeconds| have passed,
320 // a callback to FirstCheckForNoData() is made. 321 // a callback to FirstCheckForNoData() is made.
321 no_data_timer_->Reset(); 322 no_data_timer_->Reset();
322 } 323 }
323 324
324 stream_->Start(this); 325 stream_->Start(this);
325 if (handler_) 326 if (handler_)
326 handler_->OnRecording(this); 327 handler_->OnRecording(this);
327 } 328 }
328 329
329 void AudioInputController::DoClose() { 330 void AudioInputController::DoClose() {
330 DCHECK(task_runner_->BelongsToCurrentThread()); 331 DCHECK(task_runner_->BelongsToCurrentThread());
331 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.CloseTime"); 332 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.CloseTime");
332 333
333 if (state_ == CLOSED) 334 if (state_ == CLOSED)
334 return; 335 return;
335 336
337 if (handler_)
338 handler_->OnLog(this, "AIC::DoClose");
339
336 // Delete the timer on the same thread that created it. 340 // Delete the timer on the same thread that created it.
337 no_data_timer_.reset(); 341 no_data_timer_.reset();
338 342
339 DoStopCloseAndClearStream(); 343 DoStopCloseAndClearStream();
340 SetDataIsActive(false); 344 SetDataIsActive(false);
341 345
346 if (audio_manager_)
347 audio_manager_->RemoveStateChangeListener(this);
348
342 if (SharedMemoryAndSyncSocketMode()) 349 if (SharedMemoryAndSyncSocketMode())
343 sync_writer_->Close(); 350 sync_writer_->Close();
344 351
345 if (user_input_monitor_) 352 if (user_input_monitor_)
346 user_input_monitor_->DisableKeyPressMonitoring(); 353 user_input_monitor_->DisableKeyPressMonitoring();
347 354
348 #if defined(AUDIO_POWER_MONITORING) 355 #if defined(AUDIO_POWER_MONITORING)
349 // Send UMA stats if enabled. 356 // Send UMA stats if enabled.
350 if (log_silence_state_) 357 if (log_silence_state_)
351 LogSilenceState(silence_state_); 358 LogSilenceState(silence_state_);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 return; 400 return;
394 401
395 stream_->SetAutomaticGainControl(enabled); 402 stream_->SetAutomaticGainControl(enabled);
396 } 403 }
397 404
398 void AudioInputController::FirstCheckForNoData() { 405 void AudioInputController::FirstCheckForNoData() {
399 DCHECK(task_runner_->BelongsToCurrentThread()); 406 DCHECK(task_runner_->BelongsToCurrentThread());
400 LogCaptureStartupResult(GetDataIsActive() ? 407 LogCaptureStartupResult(GetDataIsActive() ?
401 CAPTURE_STARTUP_OK : 408 CAPTURE_STARTUP_OK :
402 CAPTURE_STARTUP_NO_DATA_CALLBACK); 409 CAPTURE_STARTUP_NO_DATA_CALLBACK);
410 if (handler_) {
411 GetDataIsActive()
tommi (sloooow) - chröme 2014/08/26 11:42:30 instead of having two call sites for OnLog, do the
henrika (OOO until Aug 14) 2014/08/27 13:44:05 Done.
412 ? handler_->OnLog(this, "AIC::FirstCheckForNoData => data is active")
413 : handler_->OnLog(this,
414 "AIC::FirstCheckForNoData => data is NOT active");
415 }
403 DoCheckForNoData(); 416 DoCheckForNoData();
404 } 417 }
405 418
406 void AudioInputController::DoCheckForNoData() { 419 void AudioInputController::DoCheckForNoData() {
407 DCHECK(task_runner_->BelongsToCurrentThread()); 420 DCHECK(task_runner_->BelongsToCurrentThread());
408 421
409 if (!GetDataIsActive()) { 422 if (!GetDataIsActive()) {
410 // 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
411 // 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
412 // capture device has been removed or disabled. 425 // capture device has been removed or disabled.
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
521 "AIC::OnData: average audio level=%.2f dBFS", level_dbfs); 534 "AIC::OnData: average audio level=%.2f dBFS", level_dbfs);
522 static const float kSilenceThresholdDBFS = -72.24719896f; 535 static const float kSilenceThresholdDBFS = -72.24719896f;
523 if (level_dbfs < kSilenceThresholdDBFS) 536 if (level_dbfs < kSilenceThresholdDBFS)
524 log_string += " <=> no audio input!"; 537 log_string += " <=> no audio input!";
525 handler_->OnLog(this, log_string); 538 handler_->OnLog(this, log_string);
526 539
527 UpdateSilenceState(level_dbfs < kSilenceThresholdDBFS); 540 UpdateSilenceState(level_dbfs < kSilenceThresholdDBFS);
528 #endif 541 #endif
529 } 542 }
530 543
544 void AudioInputController::OnStateChange(const std::string& state) {
545 DCHECK(task_runner_->BelongsToCurrentThread());
546 if (handler_)
547 handler_->OnLog(this, state);
548 }
549
531 void AudioInputController::OnError(AudioInputStream* stream) { 550 void AudioInputController::OnError(AudioInputStream* stream) {
532 // Handle error on the audio-manager thread. 551 // Handle error on the audio-manager thread.
533 task_runner_->PostTask(FROM_HERE, base::Bind( 552 task_runner_->PostTask(FROM_HERE, base::Bind(
534 &AudioInputController::DoReportError, this)); 553 &AudioInputController::DoReportError, this));
535 } 554 }
536 555
537 void AudioInputController::DoStopCloseAndClearStream() { 556 void AudioInputController::DoStopCloseAndClearStream() {
538 DCHECK(task_runner_->BelongsToCurrentThread()); 557 DCHECK(task_runner_->BelongsToCurrentThread());
539 558
540 // Allow calling unconditionally and bail if we don't have a stream to close. 559 // Allow calling unconditionally and bail if we don't have a stream to close.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 } 599 }
581 600
582 void AudioInputController::LogSilenceState(SilenceState value) { 601 void AudioInputController::LogSilenceState(SilenceState value) {
583 UMA_HISTOGRAM_ENUMERATION("Media.AudioInputControllerSessionSilenceReport", 602 UMA_HISTOGRAM_ENUMERATION("Media.AudioInputControllerSessionSilenceReport",
584 value, 603 value,
585 SILENCE_STATE_MAX + 1); 604 SILENCE_STATE_MAX + 1);
586 } 605 }
587 #endif 606 #endif
588 607
589 } // namespace media 608 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698