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

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

Issue 2919793002: Detect AudioInputStream muting and propagate to MediaStreamAudioSource. (Closed)
Patch Set: Implemented tests, addressed comments. 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 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 #if BUILDFLAG(ENABLE_WEBRTC) 191 #if BUILDFLAG(ENABLE_WEBRTC)
191 debug_recording_helper_(params, task_runner_, base::OnceClosure()), 192 debug_recording_helper_(params, task_runner_, base::OnceClosure()),
192 #endif 193 #endif
193 weak_ptr_factory_(this) { 194 weak_ptr_factory_(this) {
194 DCHECK(creator_task_runner_.get()); 195 DCHECK(creator_task_runner_.get());
195 DCHECK(handler_); 196 DCHECK(handler_);
196 DCHECK(sync_writer_); 197 DCHECK(sync_writer_);
197 } 198 }
198 199
199 AudioInputController::~AudioInputController() { 200 AudioInputController::~AudioInputController() {
201 DCHECK(!check_muted_state_timer_);
200 DCHECK(!audio_callback_); 202 DCHECK(!audio_callback_);
201 DCHECK(!stream_); 203 DCHECK(!stream_);
202 } 204 }
203 205
204 // static 206 // static
205 scoped_refptr<AudioInputController> AudioInputController::Create( 207 scoped_refptr<AudioInputController> AudioInputController::Create(
206 AudioManager* audio_manager, 208 AudioManager* audio_manager,
207 EventHandler* event_handler, 209 EventHandler* event_handler,
208 SyncWriter* sync_writer, 210 SyncWriter* sync_writer,
209 UserInputMonitor* user_input_monitor, 211 UserInputMonitor* user_input_monitor,
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 // functionality to modify the input volume slider. One such example is 348 // functionality to modify the input volume slider. One such example is
347 // Windows XP. 349 // Windows XP.
348 power_measurement_is_enabled_ &= agc_is_supported; 350 power_measurement_is_enabled_ &= agc_is_supported;
349 #else 351 #else
350 stream_to_control->SetAutomaticGainControl(enable_agc); 352 stream_to_control->SetAutomaticGainControl(enable_agc);
351 #endif 353 #endif
352 354
353 // Finally, keep the stream pointer around, update the state and notify. 355 // Finally, keep the stream pointer around, update the state and notify.
354 stream_ = stream_to_control; 356 stream_ = stream_to_control;
355 handler_->OnCreated(this); 357 handler_->OnCreated(this);
358
359 // Check the current muted state and create a new repeating timer to keep that
360 // updated.
361 CheckMutedState();
DaleCurtis 2017/06/15 18:44:00 Instead of using a repeating timer like this why n
ossu-chromium 2017/06/20 12:25:15 From looking at the implementations of IsMuted, th
DaleCurtis 2017/06/20 17:08:09 Which implementation are you worried about? I brie
ossu-chromium 2017/06/21 12:51:47 I'm mostly concerned about the PulseAudio implemen
362 check_muted_state_timer_.emplace();
363 check_muted_state_timer_->Start(
364 FROM_HERE, base::TimeDelta::FromSeconds(kCheckMutedStateIntervalSeconds),
365 this, &AudioInputController::CheckMutedState);
366 DCHECK(check_muted_state_timer_->IsRunning());
356 } 367 }
357 368
358 void AudioInputController::DoRecord() { 369 void AudioInputController::DoRecord() {
359 DCHECK(task_runner_->BelongsToCurrentThread()); 370 DCHECK(task_runner_->BelongsToCurrentThread());
360 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.RecordTime"); 371 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.RecordTime");
361 372
362 if (!stream_ || audio_callback_) 373 if (!stream_ || audio_callback_)
363 return; 374 return;
364 375
365 handler_->OnLog(this, "AIC::DoRecord"); 376 handler_->OnLog(this, "AIC::DoRecord");
366 377
367 if (user_input_monitor_) { 378 if (user_input_monitor_) {
368 user_input_monitor_->EnableKeyPressMonitoring(); 379 user_input_monitor_->EnableKeyPressMonitoring();
369 prev_key_down_count_ = user_input_monitor_->GetKeyPressCount(); 380 prev_key_down_count_ = user_input_monitor_->GetKeyPressCount();
370 } 381 }
371 382
372 stream_create_time_ = base::TimeTicks::Now(); 383 stream_create_time_ = base::TimeTicks::Now();
373 384
374 audio_callback_.reset(new AudioCallback(this)); 385 audio_callback_.reset(new AudioCallback(this));
375 stream_->Start(audio_callback_.get()); 386 stream_->Start(audio_callback_.get());
376 } 387 }
377 388
378 void AudioInputController::DoClose() { 389 void AudioInputController::DoClose() {
379 DCHECK(task_runner_->BelongsToCurrentThread()); 390 DCHECK(task_runner_->BelongsToCurrentThread());
380 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.CloseTime"); 391 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.CloseTime");
381 392
382 if (!stream_) 393 if (!stream_)
383 return; 394 return;
384 395
396 // Stop and destroy the muted check timer.
397 check_muted_state_timer_.reset();
398
385 // Allow calling unconditionally and bail if we don't have a stream to close. 399 // Allow calling unconditionally and bail if we don't have a stream to close.
386 if (audio_callback_) { 400 if (audio_callback_) {
387 stream_->Stop(); 401 stream_->Stop();
388 402
389 // Sometimes a stream (and accompanying audio track) is created and 403 // Sometimes a stream (and accompanying audio track) is created and
390 // immediately closed or discarded. In this case they are registered as 404 // immediately closed or discarded. In this case they are registered as
391 // 'stopped early' rather than 'never got data'. 405 // 'stopped early' rather than 'never got data'.
392 const base::TimeDelta duration = 406 const base::TimeDelta duration =
393 base::TimeTicks::Now() - stream_create_time_; 407 base::TimeTicks::Now() - stream_create_time_;
394 CaptureStartupResult capture_startup_result = 408 CaptureStartupResult capture_startup_result =
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
645 *mic_volume_percent = static_cast<int>(100.0 * volume); 659 *mic_volume_percent = static_cast<int>(100.0 * volume);
646 660
647 last_audio_level_log_time_ = now; 661 last_audio_level_log_time_ = now;
648 662
649 return true; 663 return true;
650 #else 664 #else
651 return false; 665 return false;
652 #endif 666 #endif
653 } 667 }
654 668
669 void AudioInputController::CheckMutedState() {
670 DCHECK(task_runner_->BelongsToCurrentThread());
671 DCHECK(stream_);
672 const bool new_state = stream_->IsMuted();
673 if (new_state != is_muted_) {
674 is_muted_ = new_state;
675 // We don't log OnMuted here, but leave that for AudioInputRendererHost.
676 handler_->OnMuted(this, is_muted_);
677 }
678 }
679
655 // static 680 // static
656 AudioInputController::StreamType AudioInputController::ParamsToStreamType( 681 AudioInputController::StreamType AudioInputController::ParamsToStreamType(
657 const AudioParameters& params) { 682 const AudioParameters& params) {
658 switch (params.format()) { 683 switch (params.format()) {
659 case AudioParameters::Format::AUDIO_PCM_LINEAR: 684 case AudioParameters::Format::AUDIO_PCM_LINEAR:
660 return AudioInputController::StreamType::HIGH_LATENCY; 685 return AudioInputController::StreamType::HIGH_LATENCY;
661 case AudioParameters::Format::AUDIO_PCM_LOW_LATENCY: 686 case AudioParameters::Format::AUDIO_PCM_LOW_LATENCY:
662 return AudioInputController::StreamType::LOW_LATENCY; 687 return AudioInputController::StreamType::LOW_LATENCY;
663 default: 688 default:
664 // Currently, the remaining supported type is fake. Reconsider if other 689 // Currently, the remaining supported type is fake. Reconsider if other
665 // formats become supported. 690 // formats become supported.
666 return AudioInputController::StreamType::FAKE; 691 return AudioInputController::StreamType::FAKE;
667 } 692 }
668 } 693 }
669 694
670 } // namespace media 695 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698