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

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

Issue 2665163002: Refactor AudioInputController and split stat by stream type. (Closed)
Patch Set: Also split CallbackError Created 3 years, 10 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
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 <inttypes.h> 7 #include <inttypes.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <limits> 10 #include <limits>
11 #include <utility> 11 #include <utility>
12 12
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/metrics/histogram_macros.h" 14 #include "base/metrics/histogram_macros.h"
15 #include "base/single_thread_task_runner.h" 15 #include "base/single_thread_task_runner.h"
16 #include "base/strings/string_number_conversions.h" 16 #include "base/strings/string_number_conversions.h"
17 #include "base/strings/stringprintf.h" 17 #include "base/strings/stringprintf.h"
18 #include "base/threading/thread_restrictions.h" 18 #include "base/threading/thread_restrictions.h"
19 #include "base/threading/thread_task_runner_handle.h" 19 #include "base/threading/thread_task_runner_handle.h"
20 #include "base/time/time.h" 20 #include "base/time/time.h"
21 #include "base/trace_event/trace_event.h" 21 #include "base/trace_event/trace_event.h"
22 #include "media/audio/audio_file_writer.h"
23 #include "media/base/user_input_monitor.h" 22 #include "media/base/user_input_monitor.h"
24 23
25 namespace media { 24 namespace media {
26 namespace { 25 namespace {
27 26
28 const int kMaxInputChannels = 3; 27 const int kMaxInputChannels = 3;
29 28
30 #if defined(AUDIO_POWER_MONITORING) 29 #if defined(AUDIO_POWER_MONITORING)
31 // Time in seconds between two successive measurements of audio power levels. 30 // Time in seconds between two successive measurements of audio power levels.
32 const int kPowerMonitorLogIntervalSeconds = 15; 31 const int kPowerMonitorLogIntervalSeconds = 15;
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 void PerformOptionalDebugRecording(const AudioBus* source) { 135 void PerformOptionalDebugRecording(const AudioBus* source) {
137 // Called on the hw callback thread while recording is enabled. 136 // Called on the hw callback thread while recording is enabled.
138 if (!controller_->debug_writer_ || !controller_->debug_writer_->WillWrite()) 137 if (!controller_->debug_writer_ || !controller_->debug_writer_->WillWrite())
139 return; 138 return;
140 139
141 // TODO(tommi): This is costly. AudioBus heap allocs and we create a new 140 // TODO(tommi): This is costly. AudioBus heap allocs and we create a new
142 // one for every callback. We could instead have a pool of bus objects 141 // one for every callback. We could instead have a pool of bus objects
143 // that get returned to us somehow. 142 // that get returned to us somehow.
144 // We should also avoid calling PostTask here since the implementation 143 // We should also avoid calling PostTask here since the implementation
145 // of the debug writer will basically do a PostTask straight away anyway. 144 // of the debug writer will basically do a PostTask straight away anyway.
146 // Might require some modifications to AudioInputDebugWriter though since 145 // Might require some modifications to AudioFileWriter though since
147 // there are some threading concerns there and AudioInputDebugWriter's 146 // there are some threading concerns there and AudioFileWriter's
148 // lifetime guarantees need to be longer than that of associated active 147 // lifetime guarantees need to be longer than that of associated active
149 // audio streams. 148 // audio streams.
150 std::unique_ptr<AudioBus> source_copy = 149 std::unique_ptr<AudioBus> source_copy =
151 AudioBus::Create(source->channels(), source->frames()); 150 AudioBus::Create(source->channels(), source->frames());
152 source->CopyTo(source_copy.get()); 151 source->CopyTo(source_copy.get());
153 controller_->task_runner_->PostTask( 152 controller_->task_runner_->PostTask(
154 FROM_HERE, base::Bind(&AudioInputController::WriteInputDataForDebugging, 153 FROM_HERE, base::Bind(&AudioInputController::WriteInputDataForDebugging,
155 weak_controller_, base::Passed(&source_copy))); 154 weak_controller_, base::Passed(&source_copy)));
156 } 155 }
157 156
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 190
192 // static 191 // static
193 AudioInputController::Factory* AudioInputController::factory_ = nullptr; 192 AudioInputController::Factory* AudioInputController::factory_ = nullptr;
194 193
195 AudioInputController::AudioInputController( 194 AudioInputController::AudioInputController(
196 scoped_refptr<base::SingleThreadTaskRunner> task_runner, 195 scoped_refptr<base::SingleThreadTaskRunner> task_runner,
197 EventHandler* handler, 196 EventHandler* handler,
198 SyncWriter* sync_writer, 197 SyncWriter* sync_writer,
199 std::unique_ptr<AudioFileWriter> debug_writer, 198 std::unique_ptr<AudioFileWriter> debug_writer,
200 UserInputMonitor* user_input_monitor, 199 UserInputMonitor* user_input_monitor,
201 const bool agc_is_enabled) 200 Type type)
202 : creator_task_runner_(base::ThreadTaskRunnerHandle::Get()), 201 : creator_task_runner_(base::ThreadTaskRunnerHandle::Get()),
203 task_runner_(std::move(task_runner)), 202 task_runner_(std::move(task_runner)),
204 handler_(handler), 203 handler_(handler),
205 stream_(nullptr), 204 stream_(nullptr),
206 sync_writer_(sync_writer), 205 sync_writer_(sync_writer),
207 max_volume_(0.0), 206 type_(type),
208 user_input_monitor_(user_input_monitor), 207 user_input_monitor_(user_input_monitor),
209 agc_is_enabled_(agc_is_enabled),
210 #if defined(AUDIO_POWER_MONITORING)
211 power_measurement_is_enabled_(false),
212 log_silence_state_(false),
213 silence_state_(SILENCE_STATE_NO_MEASUREMENT),
214 #endif
215 prev_key_down_count_(0),
216 debug_writer_(std::move(debug_writer)), 208 debug_writer_(std::move(debug_writer)),
217 weak_ptr_factory_(this) { 209 weak_ptr_factory_(this) {
218 DCHECK(creator_task_runner_.get()); 210 DCHECK(creator_task_runner_.get());
219 DCHECK(handler_); 211 DCHECK(handler_);
220 DCHECK(sync_writer_); 212 DCHECK(sync_writer_);
221 } 213 }
222 214
223 AudioInputController::~AudioInputController() { 215 AudioInputController::~AudioInputController() {
224 DCHECK(!audio_callback_); 216 DCHECK(!audio_callback_);
225 DCHECK(!stream_); 217 DCHECK(!stream_);
226 } 218 }
227 219
228 // static 220 // static
229 scoped_refptr<AudioInputController> AudioInputController::Create( 221 scoped_refptr<AudioInputController> AudioInputController::Create(
230 AudioManager* audio_manager, 222 AudioManager* audio_manager,
231 EventHandler* event_handler, 223 EventHandler* event_handler,
232 SyncWriter* sync_writer, 224 SyncWriter* sync_writer,
225 UserInputMonitor* user_input_monitor,
226 std::unique_ptr<AudioFileWriter> debug_writer,
233 const AudioParameters& params, 227 const AudioParameters& params,
234 const std::string& device_id, 228 const std::string& device_id,
235 UserInputMonitor* user_input_monitor) { 229 bool enable_agc) {
236 DCHECK(audio_manager);
237 DCHECK(event_handler);
238 DCHECK(sync_writer);
239
240 if (!params.IsValid() || (params.channels() > kMaxInputChannels))
241 return nullptr;
242
243 if (factory_) {
244 return factory_->Create(audio_manager->GetTaskRunner(), sync_writer,
245 audio_manager, event_handler, params,
246 user_input_monitor);
247 }
248
249 scoped_refptr<AudioInputController> controller(new AudioInputController(
250 audio_manager->GetTaskRunner(), event_handler, sync_writer, nullptr,
251 user_input_monitor, false));
252
253 // Create and open a new audio input stream from the existing
254 // audio-device thread.
255 if (!controller->task_runner_->PostTask(
256 FROM_HERE,
257 base::Bind(&AudioInputController::DoCreate,
258 controller,
259 base::Unretained(audio_manager),
260 params,
261 device_id))) {
262 controller = nullptr;
263 }
264
265 return controller;
266 }
267
268 // static
269 scoped_refptr<AudioInputController> AudioInputController::CreateLowLatency(
270 AudioManager* audio_manager,
271 EventHandler* event_handler,
272 const AudioParameters& params,
273 const std::string& device_id,
274 SyncWriter* sync_writer,
275 std::unique_ptr<AudioFileWriter> debug_writer,
276 UserInputMonitor* user_input_monitor,
277 const bool agc_is_enabled) {
278 DCHECK(audio_manager); 230 DCHECK(audio_manager);
279 DCHECK(sync_writer); 231 DCHECK(sync_writer);
280 DCHECK(event_handler); 232 DCHECK(event_handler);
281 233
282 if (!params.IsValid() || (params.channels() > kMaxInputChannels)) 234 if (!params.IsValid() || (params.channels() > kMaxInputChannels))
283 return nullptr; 235 return nullptr;
284 236
285 if (factory_) { 237 if (factory_) {
286 return factory_->Create(audio_manager->GetTaskRunner(), sync_writer, 238 return factory_->Create(audio_manager->GetTaskRunner(), sync_writer,
287 audio_manager, event_handler, params, 239 audio_manager, event_handler, params,
288 user_input_monitor); 240 user_input_monitor, ParamsToType(params));
289 } 241 }
290 242
291 // Create the AudioInputController object and ensure that it runs on 243 // Create the AudioInputController object and ensure that it runs on
292 // the audio-manager thread. 244 // the audio-manager thread.
293 scoped_refptr<AudioInputController> controller(new AudioInputController( 245 scoped_refptr<AudioInputController> controller(new AudioInputController(
294 audio_manager->GetTaskRunner(), event_handler, sync_writer, 246 audio_manager->GetTaskRunner(), event_handler, sync_writer,
295 std::move(debug_writer), user_input_monitor, agc_is_enabled)); 247 std::move(debug_writer), user_input_monitor, ParamsToType(params)));
296 248
297 // Create and open a new audio input stream from the existing 249 // Create and open a new audio input stream from the existing
298 // audio-device thread. Use the provided audio-input device. 250 // audio-device thread. Use the provided audio-input device.
299 if (!controller->task_runner_->PostTask( 251 if (!controller->task_runner_->PostTask(
300 FROM_HERE, 252 FROM_HERE, base::Bind(&AudioInputController::DoCreate, controller,
301 base::Bind(&AudioInputController::DoCreateForLowLatency, 253 base::Unretained(audio_manager), params,
302 controller, 254 device_id, enable_agc))) {
303 base::Unretained(audio_manager),
304 params,
305 device_id))) {
306 controller = nullptr; 255 controller = nullptr;
307 } 256 }
308 257
309 return controller; 258 return controller;
310 } 259 }
311 260
312 // static 261 // static
313 scoped_refptr<AudioInputController> AudioInputController::CreateForStream( 262 scoped_refptr<AudioInputController> AudioInputController::CreateForStream(
314 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, 263 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
315 EventHandler* event_handler, 264 EventHandler* event_handler,
316 AudioInputStream* stream, 265 AudioInputStream* stream,
317 SyncWriter* sync_writer, 266 SyncWriter* sync_writer,
318 std::unique_ptr<AudioFileWriter> debug_writer, 267 std::unique_ptr<AudioFileWriter> debug_writer,
319 UserInputMonitor* user_input_monitor) { 268 UserInputMonitor* user_input_monitor) {
320 DCHECK(sync_writer); 269 DCHECK(sync_writer);
321 DCHECK(stream); 270 DCHECK(stream);
322 DCHECK(event_handler); 271 DCHECK(event_handler);
323 272
324 if (factory_) { 273 if (factory_) {
325 return factory_->Create( 274 return factory_->Create(task_runner, sync_writer, AudioManager::Get(),
326 task_runner, sync_writer, AudioManager::Get(), event_handler, 275 event_handler,
327 AudioParameters::UnavailableDeviceParams(), user_input_monitor); 276 AudioParameters::UnavailableDeviceParams(),
277 user_input_monitor, VIRTUAL);
328 } 278 }
329 279
330 // Create the AudioInputController object and ensure that it runs on 280 // Create the AudioInputController object and ensure that it runs on
331 // the audio-manager thread. 281 // the audio-manager thread.
332 scoped_refptr<AudioInputController> controller(new AudioInputController( 282 scoped_refptr<AudioInputController> controller(new AudioInputController(
333 task_runner, event_handler, sync_writer, std::move(debug_writer), 283 task_runner, event_handler, sync_writer, std::move(debug_writer),
334 user_input_monitor, false)); 284 user_input_monitor, VIRTUAL));
335 285
336 if (!controller->task_runner_->PostTask( 286 if (!controller->task_runner_->PostTask(
337 FROM_HERE, base::Bind(&AudioInputController::DoCreateForStream, 287 FROM_HERE, base::Bind(&AudioInputController::DoCreateForStream,
338 controller, stream, false))) { 288 controller, stream, /*enable_agc*/ false))) {
339 controller = nullptr; 289 controller = nullptr;
340 } 290 }
341 291
342 return controller; 292 return controller;
343 } 293 }
344 294
345 void AudioInputController::Record() { 295 void AudioInputController::Record() {
346 DCHECK(creator_task_runner_->BelongsToCurrentThread()); 296 DCHECK(creator_task_runner_->BelongsToCurrentThread());
347 task_runner_->PostTask(FROM_HERE, base::Bind( 297 task_runner_->PostTask(FROM_HERE, base::Bind(
348 &AudioInputController::DoRecord, this)); 298 &AudioInputController::DoRecord, this));
349 } 299 }
350 300
351 void AudioInputController::Close(const base::Closure& closed_task) { 301 void AudioInputController::Close(const base::Closure& closed_task) {
352 DCHECK(!closed_task.is_null()); 302 DCHECK(!closed_task.is_null());
353 DCHECK(creator_task_runner_->BelongsToCurrentThread()); 303 DCHECK(creator_task_runner_->BelongsToCurrentThread());
354 304
355 task_runner_->PostTaskAndReply( 305 task_runner_->PostTaskAndReply(
356 FROM_HERE, base::Bind(&AudioInputController::DoClose, this), closed_task); 306 FROM_HERE, base::Bind(&AudioInputController::DoClose, this), closed_task);
357 } 307 }
358 308
359 void AudioInputController::SetVolume(double volume) { 309 void AudioInputController::SetVolume(double volume) {
360 DCHECK(creator_task_runner_->BelongsToCurrentThread()); 310 DCHECK(creator_task_runner_->BelongsToCurrentThread());
361 task_runner_->PostTask(FROM_HERE, base::Bind( 311 task_runner_->PostTask(FROM_HERE, base::Bind(
362 &AudioInputController::DoSetVolume, this, volume)); 312 &AudioInputController::DoSetVolume, this, volume));
363 } 313 }
364 314
365 void AudioInputController::DoCreate(AudioManager* audio_manager, 315 void AudioInputController::DoCreate(AudioManager* audio_manager,
366 const AudioParameters& params, 316 const AudioParameters& params,
367 const std::string& device_id) { 317 const std::string& device_id,
318 bool enable_agc) {
368 DCHECK(task_runner_->BelongsToCurrentThread()); 319 DCHECK(task_runner_->BelongsToCurrentThread());
369 DCHECK(!stream_); 320 DCHECK(!stream_);
370 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.CreateTime"); 321 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.CreateTime");
371 handler_->OnLog(this, "AIC::DoCreate"); 322 handler_->OnLog(this, "AIC::DoCreate");
372 323
373 #if defined(AUDIO_POWER_MONITORING) 324 #if defined(AUDIO_POWER_MONITORING)
325 // We only log silence state UMA stats for low latency mode and if we use a
326 // real device.
327 if (type_ == LOW_LATENCY)
328 log_silence_state_ = true;
tommi (sloooow) - chröme 2017/02/01 21:07:25 I think we also only want to do this if the APM is
Max Morin 2017/02/02 09:54:56 Probably yes. I'll use enable_agc as an indicator
tommi (sloooow) - chröme 2017/02/02 14:14:21 Acknowledged.
329
374 // Disable power monitoring for streams that run without AGC enabled to 330 // Disable power monitoring for streams that run without AGC enabled to
375 // avoid adding logs and UMA for non-WebRTC clients. 331 // avoid adding logs and UMA for non-WebRTC clients.
376 power_measurement_is_enabled_ = agc_is_enabled_; 332 power_measurement_is_enabled_ = enable_agc;
377 last_audio_level_log_time_ = base::TimeTicks::Now(); 333 last_audio_level_log_time_ = base::TimeTicks::Now();
378 silence_state_ = SILENCE_STATE_NO_MEASUREMENT;
379 #endif 334 #endif
380 335
381 // MakeAudioInputStream might fail and return nullptr. If so, 336 // MakeAudioInputStream might fail and return nullptr. If so,
382 // DoCreateForStream will handle and report it. 337 // DoCreateForStream will handle and report it.
383 auto* stream = audio_manager->MakeAudioInputStream( 338 auto* stream = audio_manager->MakeAudioInputStream(
384 params, device_id, base::Bind(&AudioInputController::LogMessage, this)); 339 params, device_id, base::Bind(&AudioInputController::LogMessage, this));
385 DoCreateForStream(stream, 340 DoCreateForStream(stream, enable_agc);
386 params.format() == AudioParameters::AUDIO_PCM_LOW_LATENCY);
387 }
388
389 void AudioInputController::DoCreateForLowLatency(AudioManager* audio_manager,
390 const AudioParameters& params,
391 const std::string& device_id) {
392 DCHECK(task_runner_->BelongsToCurrentThread());
393
394 #if defined(AUDIO_POWER_MONITORING)
395 // We only log silence state UMA stats for low latency mode and if we use a
396 // real device.
397 if (params.format() != AudioParameters::AUDIO_FAKE)
398 log_silence_state_ = true;
399 #endif
400
401 // Set the low latency timer to non-null. It'll be reset when capture starts.
402 low_latency_create_time_ = base::TimeTicks::Now();
403 DoCreate(audio_manager, params, device_id);
404 } 341 }
405 342
406 void AudioInputController::DoCreateForStream( 343 void AudioInputController::DoCreateForStream(
407 AudioInputStream* stream_to_control, 344 AudioInputStream* stream_to_control,
408 bool low_latency) { 345 bool enable_agc) {
409 DCHECK(task_runner_->BelongsToCurrentThread()); 346 DCHECK(task_runner_->BelongsToCurrentThread());
410 DCHECK(!stream_); 347 DCHECK(!stream_);
411 348
412 if (!stream_to_control) { 349 if (!stream_to_control) {
413 LogCaptureStartupResult( 350 LogCaptureStartupResult(CAPTURE_STARTUP_CREATE_STREAM_FAILED);
414 low_latency ? CAPTURE_STARTUP_CREATE_LOW_LATENCY_STREAM_FAILED
415 : CAPTURE_STARTUP_CREATE_STREAM_FAILED);
416 handler_->OnError(this, STREAM_CREATE_ERROR); 351 handler_->OnError(this, STREAM_CREATE_ERROR);
417 return; 352 return;
418 } 353 }
419 354
420 if (!stream_to_control->Open()) { 355 if (!stream_to_control->Open()) {
421 stream_to_control->Close(); 356 stream_to_control->Close();
422 LogCaptureStartupResult(low_latency 357 LogCaptureStartupResult(CAPTURE_STARTUP_OPEN_STREAM_FAILED);
423 ? CAPTURE_STARTUP_OPEN_LOW_LATENCY_STREAM_FAILED
424 : CAPTURE_STARTUP_OPEN_STREAM_FAILED);
425 handler_->OnError(this, STREAM_OPEN_ERROR); 358 handler_->OnError(this, STREAM_OPEN_ERROR);
426 return; 359 return;
427 } 360 }
428 361
429 // Set AGC state using mode in |agc_is_enabled_| which can only be enabled in 362 // Set AGC state using mode in |enable_agc_| which can only be enabled in
tommi (sloooow) - chröme 2017/02/01 21:07:25 nit: |enable_agc|
430 // CreateLowLatency(). 363 // CreateLowLatency().
tommi (sloooow) - chröme 2017/02/01 21:07:25 CreateLowLatency is now gone
431 #if defined(AUDIO_POWER_MONITORING) 364 #if defined(AUDIO_POWER_MONITORING)
432 bool agc_is_supported = 365 bool agc_is_supported =
433 stream_to_control->SetAutomaticGainControl(agc_is_enabled_); 366 stream_to_control->SetAutomaticGainControl(enable_agc);
434 // Disable power measurements on platforms that does not support AGC at a 367 // Disable power measurements on platforms that does not support AGC at a
435 // lower level. AGC can fail on platforms where we don't support the 368 // lower level. AGC can fail on platforms where we don't support the
436 // functionality to modify the input volume slider. One such example is 369 // functionality to modify the input volume slider. One such example is
437 // Windows XP. 370 // Windows XP.
438 power_measurement_is_enabled_ &= agc_is_supported; 371 power_measurement_is_enabled_ &= agc_is_supported;
439 #else 372 #else
440 stream_to_control->SetAutomaticGainControl(agc_is_enabled_); 373 stream_to_control->SetAutomaticGainControl(enable_agc);
441 #endif 374 #endif
442 375
443 // Finally, keep the stream pointer around, update the state and notify. 376 // Finally, keep the stream pointer around, update the state and notify.
444 stream_ = stream_to_control; 377 stream_ = stream_to_control;
445 handler_->OnCreated(this); 378 handler_->OnCreated(this);
446 } 379 }
447 380
448 void AudioInputController::DoRecord() { 381 void AudioInputController::DoRecord() {
449 DCHECK(task_runner_->BelongsToCurrentThread()); 382 DCHECK(task_runner_->BelongsToCurrentThread());
450 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.RecordTime"); 383 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.RecordTime");
451 384
452 if (!stream_ || audio_callback_) 385 if (!stream_ || audio_callback_)
453 return; 386 return;
454 387
455 handler_->OnLog(this, "AIC::DoRecord"); 388 handler_->OnLog(this, "AIC::DoRecord");
456 389
457 if (user_input_monitor_) { 390 if (user_input_monitor_) {
458 user_input_monitor_->EnableKeyPressMonitoring(); 391 user_input_monitor_->EnableKeyPressMonitoring();
459 prev_key_down_count_ = user_input_monitor_->GetKeyPressCount(); 392 prev_key_down_count_ = user_input_monitor_->GetKeyPressCount();
460 } 393 }
461 394
462 if (!low_latency_create_time_.is_null()) 395 stream_create_time_ = base::TimeTicks::Now();
463 low_latency_create_time_ = base::TimeTicks::Now();
464 396
465 audio_callback_.reset(new AudioCallback(this)); 397 audio_callback_.reset(new AudioCallback(this));
466 stream_->Start(audio_callback_.get()); 398 stream_->Start(audio_callback_.get());
467 } 399 }
468 400
469 void AudioInputController::DoClose() { 401 void AudioInputController::DoClose() {
470 DCHECK(task_runner_->BelongsToCurrentThread()); 402 DCHECK(task_runner_->BelongsToCurrentThread());
471 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.CloseTime"); 403 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.CloseTime");
472 404
473 if (!stream_) 405 if (!stream_)
474 return; 406 return;
475 407
476 // Allow calling unconditionally and bail if we don't have a stream to close. 408 // Allow calling unconditionally and bail if we don't have a stream to close.
477 if (audio_callback_) { 409 if (audio_callback_) {
478 stream_->Stop(); 410 stream_->Stop();
479 411
480 if (!low_latency_create_time_.is_null()) { 412 // Since the usage pattern of getUserMedia commonly is that a stream
tommi (sloooow) - chröme 2017/02/01 21:07:25 nit: since you've removed the if() that checks for
481 // Since the usage pattern of getUserMedia commonly is that a stream 413 // (and accompanied audio track) is created and immediately closed or
482 // (and accompanied audio track) is created and immediately closed or 414 // discarded, we collect stats separately for short lived audio streams
483 // discarded, we collect stats separately for short lived audio streams 415 // (500ms or less) that we did not receive a callback for, as
484 // (500ms or less) that we did not receive a callback for, as 416 // 'stopped early' and 'never got data'.
485 // 'stopped early' and 'never got data'. 417 const base::TimeDelta duration =
486 const base::TimeDelta duration = 418 base::TimeTicks::Now() - stream_create_time_;
487 base::TimeTicks::Now() - low_latency_create_time_; 419 CaptureStartupResult capture_startup_result =
488 LogCaptureStartupResult(audio_callback_->received_callback() 420 audio_callback_->received_callback()
489 ? CAPTURE_STARTUP_OK 421 ? CAPTURE_STARTUP_OK
490 : (duration.InMilliseconds() < 500 422 : (duration.InMilliseconds() < 500
491 ? CAPTURE_STARTUP_STOPPED_EARLY 423 ? CAPTURE_STARTUP_STOPPED_EARLY
492 : CAPTURE_STARTUP_NEVER_GOT_DATA)); 424 : CAPTURE_STARTUP_NEVER_GOT_DATA);
493 UMA_HISTOGRAM_BOOLEAN("Media.Audio.Capture.CallbackError", 425 LogCaptureStartupResult(capture_startup_result);
494 audio_callback_->error_during_callback()); 426 LogCallbackError();
427 if (type_ == LOW_LATENCY) {
495 if (audio_callback_->received_callback()) { 428 if (audio_callback_->received_callback()) {
tommi (sloooow) - chröme 2017/02/01 21:07:25 I wonder if we should add another InputStreamDurat
Max Morin 2017/02/02 09:54:56 Added Media.InputStreamWithoutCallbackDuration.
496 // Log the total duration (since DoCreate) and update the histogram. 429 // Log the total duration (since DoCreate) and update the histogram.
497 UMA_HISTOGRAM_LONG_TIMES("Media.InputStreamDuration", duration); 430 UMA_HISTOGRAM_LONG_TIMES("Media.InputStreamDuration", duration);
498 const std::string log_string = base::StringPrintf( 431 const std::string log_string = base::StringPrintf(
499 "AIC::DoClose: stream duration=%" PRId64 " seconds", 432 "AIC::DoClose: stream duration=%" PRId64 " seconds",
500 duration.InSeconds()); 433 duration.InSeconds());
501 handler_->OnLog(this, log_string); 434 handler_->OnLog(this, log_string);
502 } 435 }
503 } 436 }
504 437
505 audio_callback_.reset(); 438 audio_callback_.reset();
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
633 566
634 void AudioInputController::LogSilenceState(SilenceState value) { 567 void AudioInputController::LogSilenceState(SilenceState value) {
635 UMA_HISTOGRAM_ENUMERATION("Media.AudioInputControllerSessionSilenceReport", 568 UMA_HISTOGRAM_ENUMERATION("Media.AudioInputControllerSessionSilenceReport",
636 value, 569 value,
637 SILENCE_STATE_MAX + 1); 570 SILENCE_STATE_MAX + 1);
638 } 571 }
639 #endif 572 #endif
640 573
641 void AudioInputController::LogCaptureStartupResult( 574 void AudioInputController::LogCaptureStartupResult(
642 CaptureStartupResult result) { 575 CaptureStartupResult result) {
643 UMA_HISTOGRAM_ENUMERATION("Media.AudioInputControllerCaptureStartupSuccess", 576 switch (type_) {
644 result, CAPTURE_STARTUP_RESULT_MAX + 1); 577 case LOW_LATENCY:
578 UMA_HISTOGRAM_ENUMERATION("Media.LowLatencyAudioCaptureStartupSuccess",
579 result, CAPTURE_STARTUP_RESULT_MAX + 1);
580 break;
581 case HIGH_LATENCY:
582 UMA_HISTOGRAM_ENUMERATION("Media.HighLatencyAudioCaptureStartupSuccess",
583 result, CAPTURE_STARTUP_RESULT_MAX + 1);
584 break;
585 case VIRTUAL:
586 UMA_HISTOGRAM_ENUMERATION("Media.VirtualAudioCaptureStartupSuccess",
587 result, CAPTURE_STARTUP_RESULT_MAX + 1);
588 break;
589 default:
590 break;
591 }
592 }
593
594 void AudioInputController::LogCallbackError() {
595 bool error_during_callback = audio_callback_->error_during_callback();
596 switch (type_) {
597 case LOW_LATENCY:
598 UMA_HISTOGRAM_BOOLEAN("Media.Audio.Capture.LowLatencyCallbackError",
599 error_during_callback);
600 break;
601 case HIGH_LATENCY:
602 UMA_HISTOGRAM_BOOLEAN("Media.Audio.Capture.HighLatencyCallbackError",
603 error_during_callback);
604 break;
605 case VIRTUAL:
606 UMA_HISTOGRAM_BOOLEAN("Media.Audio.Capture.VirtualCallbackError",
607 error_during_callback);
608 break;
609 default:
610 break;
611 }
645 } 612 }
646 613
647 void AudioInputController::DoEnableDebugRecording( 614 void AudioInputController::DoEnableDebugRecording(
648 const base::FilePath& file_name) { 615 const base::FilePath& file_name) {
649 DCHECK(task_runner_->BelongsToCurrentThread()); 616 DCHECK(task_runner_->BelongsToCurrentThread());
650 if (debug_writer_) 617 if (debug_writer_)
651 debug_writer_->Start(file_name); 618 debug_writer_->Start(file_name);
652 } 619 }
653 620
654 void AudioInputController::DoDisableDebugRecording() { 621 void AudioInputController::DoDisableDebugRecording() {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
703 *mic_volume_percent = static_cast<int>(100.0 * volume); 670 *mic_volume_percent = static_cast<int>(100.0 * volume);
704 671
705 last_audio_level_log_time_ = now; 672 last_audio_level_log_time_ = now;
706 673
707 return true; 674 return true;
708 #else 675 #else
709 return false; 676 return false;
710 #endif 677 #endif
711 } 678 }
712 679
680 // static
681 AudioInputController::Type AudioInputController::ParamsToType(
682 const AudioParameters& params) {
683 switch (params.format()) {
684 case AudioParameters::Format::AUDIO_PCM_LINEAR:
685 return AudioInputController::Type::HIGH_LATENCY;
686 case AudioParameters::Format::AUDIO_PCM_LOW_LATENCY:
687 return AudioInputController::Type::LOW_LATENCY;
688 default:
689 // Currently, the remaining supported type is fake. Reconsider if other
690 // formats become supported.
691 return AudioInputController::Type::FAKE;
692 }
693 return AudioInputController::Type::FAKE;
694 }
695
713 } // namespace media 696 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698