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

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

Issue 2919793002: Detect AudioInputStream muting and propagate to MediaStreamAudioSource. (Closed)
Patch Set: Created 3 years, 6 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/memory/ptr_util.h" 14 #include "base/memory/ptr_util.h"
15 #include "base/metrics/histogram_macros.h" 15 #include "base/metrics/histogram_macros.h"
16 #include "base/single_thread_task_runner.h" 16 #include "base/single_thread_task_runner.h"
17 #include "base/strings/string_number_conversions.h" 17 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/stringprintf.h" 18 #include "base/strings/stringprintf.h"
19 #include "base/threading/thread_restrictions.h" 19 #include "base/threading/thread_restrictions.h"
20 #include "base/threading/thread_task_runner_handle.h" 20 #include "base/threading/thread_task_runner_handle.h"
21 #include "base/time/time.h" 21 #include "base/time/time.h"
22 #include "base/trace_event/trace_event.h" 22 #include "base/trace_event/trace_event.h"
23 #include "media/base/user_input_monitor.h" 23 #include "media/base/user_input_monitor.h"
24 24
25 namespace media { 25 namespace media {
26 namespace { 26 namespace {
27 27
28 const int kMaxInputChannels = 3; 28 const int kMaxInputChannels = 3;
29 constexpr int kCheckMutedStateIntervalSeconds = 1;
29 30
30 #if defined(AUDIO_POWER_MONITORING) 31 #if defined(AUDIO_POWER_MONITORING)
31 // Time in seconds between two successive measurements of audio power levels. 32 // Time in seconds between two successive measurements of audio power levels.
32 const int kPowerMonitorLogIntervalSeconds = 15; 33 const int kPowerMonitorLogIntervalSeconds = 15;
33 34
34 // A warning will be logged when the microphone audio volume is below this 35 // A warning will be logged when the microphone audio volume is below this
35 // threshold. 36 // threshold.
36 const int kLowLevelMicrophoneLevelPercent = 10; 37 const int kLowLevelMicrophoneLevelPercent = 10;
37 38
38 // Logs if the user has enabled the microphone mute or not. This is normally 39 // Logs if the user has enabled the microphone mute or not. This is normally
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 // functionality to modify the input volume slider. One such example is 347 // functionality to modify the input volume slider. One such example is
347 // Windows XP. 348 // Windows XP.
348 power_measurement_is_enabled_ &= agc_is_supported; 349 power_measurement_is_enabled_ &= agc_is_supported;
349 #else 350 #else
350 stream_to_control->SetAutomaticGainControl(enable_agc); 351 stream_to_control->SetAutomaticGainControl(enable_agc);
351 #endif 352 #endif
352 353
353 // Finally, keep the stream pointer around, update the state and notify. 354 // Finally, keep the stream pointer around, update the state and notify.
354 stream_ = stream_to_control; 355 stream_ = stream_to_control;
355 handler_->OnCreated(this); 356 handler_->OnCreated(this);
357
358 // Check the current muted state and start a repeating timer to keep that
359 // updated.
360 CheckMutedState();
361 check_muted_state_timer_.reset(new base::RepeatingTimer());
Max Morin 2017/06/02 09:56:04 If you use unique_ptr, most Chromium people prefer
Guido Urdaneta 2017/06/02 13:33:45 MakeUnique is strongly preferred over raw new, but
362 check_muted_state_timer_->Start(
363 FROM_HERE, base::TimeDelta::FromSeconds(kCheckMutedStateIntervalSeconds),
364 this, &AudioInputController::CheckMutedState);
365 DCHECK(check_muted_state_timer_->IsRunning());
356 } 366 }
357 367
358 void AudioInputController::DoRecord() { 368 void AudioInputController::DoRecord() {
359 DCHECK(task_runner_->BelongsToCurrentThread()); 369 DCHECK(task_runner_->BelongsToCurrentThread());
360 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.RecordTime"); 370 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.RecordTime");
361 371
362 if (!stream_ || audio_callback_) 372 if (!stream_ || audio_callback_)
363 return; 373 return;
364 374
365 handler_->OnLog(this, "AIC::DoRecord"); 375 handler_->OnLog(this, "AIC::DoRecord");
366 376
367 if (user_input_monitor_) { 377 if (user_input_monitor_) {
368 user_input_monitor_->EnableKeyPressMonitoring(); 378 user_input_monitor_->EnableKeyPressMonitoring();
369 prev_key_down_count_ = user_input_monitor_->GetKeyPressCount(); 379 prev_key_down_count_ = user_input_monitor_->GetKeyPressCount();
370 } 380 }
371 381
372 stream_create_time_ = base::TimeTicks::Now(); 382 stream_create_time_ = base::TimeTicks::Now();
373 383
374 audio_callback_.reset(new AudioCallback(this)); 384 audio_callback_.reset(new AudioCallback(this));
375 stream_->Start(audio_callback_.get()); 385 stream_->Start(audio_callback_.get());
376 } 386 }
377 387
378 void AudioInputController::DoClose() { 388 void AudioInputController::DoClose() {
379 DCHECK(task_runner_->BelongsToCurrentThread()); 389 DCHECK(task_runner_->BelongsToCurrentThread());
380 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.CloseTime"); 390 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.CloseTime");
381 391
382 if (!stream_) 392 if (!stream_)
383 return; 393 return;
384 394
395 // Stop the muted check timer.
396 // TODO(ossu): Can't we just reset() it here? Should stop automatically, IIUC.
Max Morin 2017/06/02 09:56:04 Looking at the implementation, yes. Would be nice
ossu-chromium 2017/06/02 10:48:00 The top of timer.h says: "OneShotTimer and Repeati
Guido Urdaneta 2017/06/02 13:33:45 There are also many uses in the codebase that just
397 if (check_muted_state_timer_ != nullptr) {
398 check_muted_state_timer_->Stop();
399 check_muted_state_timer_.reset();
400 }
401
385 // 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.
386 if (audio_callback_) { 403 if (audio_callback_) {
387 stream_->Stop(); 404 stream_->Stop();
388 405
389 // Sometimes a stream (and accompanying audio track) is created and 406 // Sometimes a stream (and accompanying audio track) is created and
390 // immediately closed or discarded. In this case they are registered as 407 // immediately closed or discarded. In this case they are registered as
391 // 'stopped early' rather than 'never got data'. 408 // 'stopped early' rather than 'never got data'.
392 const base::TimeDelta duration = 409 const base::TimeDelta duration =
393 base::TimeTicks::Now() - stream_create_time_; 410 base::TimeTicks::Now() - stream_create_time_;
394 CaptureStartupResult capture_startup_result = 411 CaptureStartupResult capture_startup_result =
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 #if defined(AUDIO_POWER_MONITORING) 488 #if defined(AUDIO_POWER_MONITORING)
472 DCHECK(task_runner_->BelongsToCurrentThread()); 489 DCHECK(task_runner_->BelongsToCurrentThread());
473 if (!stream_) 490 if (!stream_)
474 return; 491 return;
475 492
476 // Detect if the user has enabled hardware mute by pressing the mute 493 // Detect if the user has enabled hardware mute by pressing the mute
477 // button in audio settings for the selected microphone. 494 // button in audio settings for the selected microphone.
478 const bool microphone_is_muted = stream_->IsMuted(); 495 const bool microphone_is_muted = stream_->IsMuted();
479 if (microphone_is_muted) { 496 if (microphone_is_muted) {
480 LogMicrophoneMuteResult(MICROPHONE_IS_MUTED); 497 LogMicrophoneMuteResult(MICROPHONE_IS_MUTED);
481 handler_->OnLog(this, "AIC::OnData: microphone is muted!"); 498 handler_->OnLog(this, "AIC::OnData: microphone is muted!");
Max Morin 2017/06/02 09:56:04 If you log it elsewhere, maybe remove this log?
ossu-chromium 2017/06/02 10:48:00 I think it's probably good to keep this one, since
482 // Return early if microphone is muted. No need to adding logs and UMA stats 499 // Return early if microphone is muted. No need to adding logs and UMA stats
483 // of audio levels if we know that the micropone is muted. 500 // of audio levels if we know that the micropone is muted.
484 return; 501 return;
485 } 502 }
486 503
487 LogMicrophoneMuteResult(MICROPHONE_IS_NOT_MUTED); 504 LogMicrophoneMuteResult(MICROPHONE_IS_NOT_MUTED);
488 505
489 std::string log_string = base::StringPrintf( 506 std::string log_string = base::StringPrintf(
490 "AIC::OnData: average audio level=%.2f dBFS", level_dbfs); 507 "AIC::OnData: average audio level=%.2f dBFS", level_dbfs);
491 static const float kSilenceThresholdDBFS = -72.24719896f; 508 static const float kSilenceThresholdDBFS = -72.24719896f;
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
645 *mic_volume_percent = static_cast<int>(100.0 * volume); 662 *mic_volume_percent = static_cast<int>(100.0 * volume);
646 663
647 last_audio_level_log_time_ = now; 664 last_audio_level_log_time_ = now;
648 665
649 return true; 666 return true;
650 #else 667 #else
651 return false; 668 return false;
652 #endif 669 #endif
653 } 670 }
654 671
672 void AudioInputController::CheckMutedState() {
673 DCHECK(task_runner_->BelongsToCurrentThread());
674 DCHECK(stream_);
675 const bool new_state = stream_->IsMuted();
676 if (new_state != is_muted_) {
677 is_muted_ = new_state;
678 // Don't log this here, AudioInputRendererHost will log instead.
Max Morin 2017/06/02 09:56:04 Does AIRH actually log this?
ossu-chromium 2017/06/02 10:48:00 Aww, shucks. It did until I removed that. I think
679 handler_->OnMuted(this, is_muted_);
680 }
681 }
682
655 // static 683 // static
656 AudioInputController::StreamType AudioInputController::ParamsToStreamType( 684 AudioInputController::StreamType AudioInputController::ParamsToStreamType(
657 const AudioParameters& params) { 685 const AudioParameters& params) {
658 switch (params.format()) { 686 switch (params.format()) {
659 case AudioParameters::Format::AUDIO_PCM_LINEAR: 687 case AudioParameters::Format::AUDIO_PCM_LINEAR:
660 return AudioInputController::StreamType::HIGH_LATENCY; 688 return AudioInputController::StreamType::HIGH_LATENCY;
661 case AudioParameters::Format::AUDIO_PCM_LOW_LATENCY: 689 case AudioParameters::Format::AUDIO_PCM_LOW_LATENCY:
662 return AudioInputController::StreamType::LOW_LATENCY; 690 return AudioInputController::StreamType::LOW_LATENCY;
663 default: 691 default:
664 // Currently, the remaining supported type is fake. Reconsider if other 692 // Currently, the remaining supported type is fake. Reconsider if other
665 // formats become supported. 693 // formats become supported.
666 return AudioInputController::StreamType::FAKE; 694 return AudioInputController::StreamType::FAKE;
667 } 695 }
668 } 696 }
669 697
670 } // namespace media 698 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698