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

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

Issue 2665163002: Refactor AudioInputController and split stat by stream type. (Closed)
Patch Set: Tommi's comments 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 StreamType 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, ParamsToStreamType(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, ParamsToStreamType(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)
374 // Disable power monitoring for streams that run without AGC enabled to 325 // We only do power measurements for UMA stats for low latency streams, and
375 // avoid adding logs and UMA for non-WebRTC clients. 326 // only if agc is requested, to avoid adding logs and UMA for non-WebRTC
376 power_measurement_is_enabled_ = agc_is_enabled_; 327 // clients.
328 power_measurement_is_enabled_ = (type_ == LOW_LATENCY && enable_agc);
377 last_audio_level_log_time_ = base::TimeTicks::Now(); 329 last_audio_level_log_time_ = base::TimeTicks::Now();
378 silence_state_ = SILENCE_STATE_NO_MEASUREMENT;
379 #endif 330 #endif
380 331
381 // MakeAudioInputStream might fail and return nullptr. If so, 332 // MakeAudioInputStream might fail and return nullptr. If so,
382 // DoCreateForStream will handle and report it. 333 // DoCreateForStream will handle and report it.
383 auto* stream = audio_manager->MakeAudioInputStream( 334 auto* stream = audio_manager->MakeAudioInputStream(
384 params, device_id, base::Bind(&AudioInputController::LogMessage, this)); 335 params, device_id, base::Bind(&AudioInputController::LogMessage, this));
385 DoCreateForStream(stream, 336 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 } 337 }
405 338
406 void AudioInputController::DoCreateForStream( 339 void AudioInputController::DoCreateForStream(
407 AudioInputStream* stream_to_control, 340 AudioInputStream* stream_to_control,
408 bool low_latency) { 341 bool enable_agc) {
409 DCHECK(task_runner_->BelongsToCurrentThread()); 342 DCHECK(task_runner_->BelongsToCurrentThread());
410 DCHECK(!stream_); 343 DCHECK(!stream_);
411 344
412 if (!stream_to_control) { 345 if (!stream_to_control) {
413 LogCaptureStartupResult( 346 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); 347 handler_->OnError(this, STREAM_CREATE_ERROR);
417 return; 348 return;
418 } 349 }
419 350
420 if (!stream_to_control->Open()) { 351 if (!stream_to_control->Open()) {
421 stream_to_control->Close(); 352 stream_to_control->Close();
422 LogCaptureStartupResult(low_latency 353 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); 354 handler_->OnError(this, STREAM_OPEN_ERROR);
426 return; 355 return;
427 } 356 }
428 357
429 // Set AGC state using mode in |agc_is_enabled_| which can only be enabled in
430 // CreateLowLatency().
431 #if defined(AUDIO_POWER_MONITORING) 358 #if defined(AUDIO_POWER_MONITORING)
432 bool agc_is_supported = 359 bool agc_is_supported =
433 stream_to_control->SetAutomaticGainControl(agc_is_enabled_); 360 stream_to_control->SetAutomaticGainControl(enable_agc);
434 // Disable power measurements on platforms that does not support AGC at a 361 // 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 362 // 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 363 // functionality to modify the input volume slider. One such example is
437 // Windows XP. 364 // Windows XP.
438 power_measurement_is_enabled_ &= agc_is_supported; 365 power_measurement_is_enabled_ &= agc_is_supported;
439 #else 366 #else
440 stream_to_control->SetAutomaticGainControl(agc_is_enabled_); 367 stream_to_control->SetAutomaticGainControl(enable_agc);
441 #endif 368 #endif
442 369
443 // Finally, keep the stream pointer around, update the state and notify. 370 // Finally, keep the stream pointer around, update the state and notify.
444 stream_ = stream_to_control; 371 stream_ = stream_to_control;
445 handler_->OnCreated(this); 372 handler_->OnCreated(this);
446 } 373 }
447 374
448 void AudioInputController::DoRecord() { 375 void AudioInputController::DoRecord() {
449 DCHECK(task_runner_->BelongsToCurrentThread()); 376 DCHECK(task_runner_->BelongsToCurrentThread());
450 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.RecordTime"); 377 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.RecordTime");
451 378
452 if (!stream_ || audio_callback_) 379 if (!stream_ || audio_callback_)
453 return; 380 return;
454 381
455 handler_->OnLog(this, "AIC::DoRecord"); 382 handler_->OnLog(this, "AIC::DoRecord");
456 383
457 if (user_input_monitor_) { 384 if (user_input_monitor_) {
458 user_input_monitor_->EnableKeyPressMonitoring(); 385 user_input_monitor_->EnableKeyPressMonitoring();
459 prev_key_down_count_ = user_input_monitor_->GetKeyPressCount(); 386 prev_key_down_count_ = user_input_monitor_->GetKeyPressCount();
460 } 387 }
461 388
462 if (!low_latency_create_time_.is_null()) 389 stream_create_time_ = base::TimeTicks::Now();
463 low_latency_create_time_ = base::TimeTicks::Now();
464 390
465 audio_callback_.reset(new AudioCallback(this)); 391 audio_callback_.reset(new AudioCallback(this));
466 stream_->Start(audio_callback_.get()); 392 stream_->Start(audio_callback_.get());
467 } 393 }
468 394
469 void AudioInputController::DoClose() { 395 void AudioInputController::DoClose() {
470 DCHECK(task_runner_->BelongsToCurrentThread()); 396 DCHECK(task_runner_->BelongsToCurrentThread());
471 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.CloseTime"); 397 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.CloseTime");
472 398
473 if (!stream_) 399 if (!stream_)
474 return; 400 return;
475 401
476 // Allow calling unconditionally and bail if we don't have a stream to close. 402 // Allow calling unconditionally and bail if we don't have a stream to close.
477 if (audio_callback_) { 403 if (audio_callback_) {
478 stream_->Stop(); 404 stream_->Stop();
479 405
480 if (!low_latency_create_time_.is_null()) { 406 // Sometimes a stream (and accompanying audio track) is created and
481 // Since the usage pattern of getUserMedia commonly is that a stream 407 // immediately closed or discarded. In this case they are registered as
482 // (and accompanied audio track) is created and immediately closed or 408 // 'stopped early' rather than 'never got data'.
483 // discarded, we collect stats separately for short lived audio streams 409 const base::TimeDelta duration =
484 // (500ms or less) that we did not receive a callback for, as 410 base::TimeTicks::Now() - stream_create_time_;
485 // 'stopped early' and 'never got data'. 411 CaptureStartupResult capture_startup_result =
486 const base::TimeDelta duration = 412 audio_callback_->received_callback()
487 base::TimeTicks::Now() - low_latency_create_time_; 413 ? CAPTURE_STARTUP_OK
488 LogCaptureStartupResult(audio_callback_->received_callback() 414 : (duration.InMilliseconds() < 500
489 ? CAPTURE_STARTUP_OK 415 ? CAPTURE_STARTUP_STOPPED_EARLY
490 : (duration.InMilliseconds() < 500 416 : CAPTURE_STARTUP_NEVER_GOT_DATA);
491 ? CAPTURE_STARTUP_STOPPED_EARLY 417 LogCaptureStartupResult(capture_startup_result);
492 : CAPTURE_STARTUP_NEVER_GOT_DATA)); 418 LogCallbackError();
493 UMA_HISTOGRAM_BOOLEAN("Media.Audio.Capture.CallbackError", 419 if (type_ == LOW_LATENCY) {
494 audio_callback_->error_during_callback());
495 if (audio_callback_->received_callback()) { 420 if (audio_callback_->received_callback()) {
496 // Log the total duration (since DoCreate) and update the histogram. 421 // Log the total duration (since DoCreate) and update the histogram.
497 UMA_HISTOGRAM_LONG_TIMES("Media.InputStreamDuration", duration); 422 UMA_HISTOGRAM_LONG_TIMES("Media.InputStreamDuration", duration);
498 const std::string log_string = base::StringPrintf( 423 const std::string log_string = base::StringPrintf(
499 "AIC::DoClose: stream duration=%" PRId64 " seconds", 424 "AIC::DoClose: stream duration=%" PRId64 " seconds",
500 duration.InSeconds()); 425 duration.InSeconds());
501 handler_->OnLog(this, log_string); 426 handler_->OnLog(this, log_string);
427 } else {
428 UMA_HISTOGRAM_LONG_TIMES("Media.InputStreamWithoutCallbackDuration",
tommi (sloooow) - chröme 2017/02/02 14:14:21 thanks - what about "InputStreamDurationWithoutCal
Max Morin 2017/02/02 15:37:52 Done.
429 duration);
502 } 430 }
503 } 431 }
504 432
505 audio_callback_.reset(); 433 audio_callback_.reset();
506 } 434 }
507 435
508 stream_->Close(); 436 stream_->Close();
509 stream_ = nullptr; 437 stream_ = nullptr;
510 438
511 sync_writer_->Close(); 439 sync_writer_->Close();
512 440
513 if (user_input_monitor_) 441 if (user_input_monitor_)
514 user_input_monitor_->DisableKeyPressMonitoring(); 442 user_input_monitor_->DisableKeyPressMonitoring();
515 443
516 #if defined(AUDIO_POWER_MONITORING) 444 #if defined(AUDIO_POWER_MONITORING)
517 // Send UMA stats if enabled. 445 // Send UMA stats if enabled.
518 if (log_silence_state_) 446 if (power_measurement_is_enabled_)
519 LogSilenceState(silence_state_); 447 LogSilenceState(silence_state_);
520 log_silence_state_ = false;
521 #endif 448 #endif
522 449
523 if (debug_writer_) 450 if (debug_writer_)
524 debug_writer_->Stop(); 451 debug_writer_->Stop();
525 452
526 max_volume_ = 0.0; 453 max_volume_ = 0.0;
527 weak_ptr_factory_.InvalidateWeakPtrs(); 454 weak_ptr_factory_.InvalidateWeakPtrs();
528 } 455 }
529 456
530 void AudioInputController::DoReportError() { 457 void AudioInputController::DoReportError() {
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
633 560
634 void AudioInputController::LogSilenceState(SilenceState value) { 561 void AudioInputController::LogSilenceState(SilenceState value) {
635 UMA_HISTOGRAM_ENUMERATION("Media.AudioInputControllerSessionSilenceReport", 562 UMA_HISTOGRAM_ENUMERATION("Media.AudioInputControllerSessionSilenceReport",
636 value, 563 value,
637 SILENCE_STATE_MAX + 1); 564 SILENCE_STATE_MAX + 1);
638 } 565 }
639 #endif 566 #endif
640 567
641 void AudioInputController::LogCaptureStartupResult( 568 void AudioInputController::LogCaptureStartupResult(
642 CaptureStartupResult result) { 569 CaptureStartupResult result) {
643 UMA_HISTOGRAM_ENUMERATION("Media.AudioInputControllerCaptureStartupSuccess", 570 switch (type_) {
644 result, CAPTURE_STARTUP_RESULT_MAX + 1); 571 case LOW_LATENCY:
572 UMA_HISTOGRAM_ENUMERATION("Media.LowLatencyAudioCaptureStartupSuccess",
573 result, CAPTURE_STARTUP_RESULT_MAX + 1);
574 break;
575 case HIGH_LATENCY:
576 UMA_HISTOGRAM_ENUMERATION("Media.HighLatencyAudioCaptureStartupSuccess",
577 result, CAPTURE_STARTUP_RESULT_MAX + 1);
578 break;
579 case VIRTUAL:
580 UMA_HISTOGRAM_ENUMERATION("Media.VirtualAudioCaptureStartupSuccess",
581 result, CAPTURE_STARTUP_RESULT_MAX + 1);
582 break;
583 default:
584 break;
585 }
586 }
587
588 void AudioInputController::LogCallbackError() {
589 bool error_during_callback = audio_callback_->error_during_callback();
590 switch (type_) {
591 case LOW_LATENCY:
592 UMA_HISTOGRAM_BOOLEAN("Media.Audio.Capture.LowLatencyCallbackError",
593 error_during_callback);
594 break;
595 case HIGH_LATENCY:
596 UMA_HISTOGRAM_BOOLEAN("Media.Audio.Capture.HighLatencyCallbackError",
597 error_during_callback);
598 break;
599 case VIRTUAL:
600 UMA_HISTOGRAM_BOOLEAN("Media.Audio.Capture.VirtualCallbackError",
601 error_during_callback);
602 break;
603 default:
604 break;
605 }
645 } 606 }
646 607
647 void AudioInputController::DoEnableDebugRecording( 608 void AudioInputController::DoEnableDebugRecording(
648 const base::FilePath& file_name) { 609 const base::FilePath& file_name) {
649 DCHECK(task_runner_->BelongsToCurrentThread()); 610 DCHECK(task_runner_->BelongsToCurrentThread());
650 if (debug_writer_) 611 if (debug_writer_)
651 debug_writer_->Start(file_name); 612 debug_writer_->Start(file_name);
652 } 613 }
653 614
654 void AudioInputController::DoDisableDebugRecording() { 615 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); 664 *mic_volume_percent = static_cast<int>(100.0 * volume);
704 665
705 last_audio_level_log_time_ = now; 666 last_audio_level_log_time_ = now;
706 667
707 return true; 668 return true;
708 #else 669 #else
709 return false; 670 return false;
710 #endif 671 #endif
711 } 672 }
712 673
674 // static
675 AudioInputController::StreamType AudioInputController::ParamsToStreamType(
676 const AudioParameters& params) {
677 switch (params.format()) {
678 case AudioParameters::Format::AUDIO_PCM_LINEAR:
679 return AudioInputController::StreamType::HIGH_LATENCY;
680 case AudioParameters::Format::AUDIO_PCM_LOW_LATENCY:
681 return AudioInputController::StreamType::LOW_LATENCY;
682 default:
683 // Currently, the remaining supported type is fake. Reconsider if other
684 // formats become supported.
685 return AudioInputController::StreamType::FAKE;
686 }
687 return AudioInputController::StreamType::FAKE;
688 }
689
713 } // namespace media 690 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698