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

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

Issue 663123002: Reduce power logging and UMA stats when AGC is disabled (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebased Created 6 years, 2 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 "base/bind.h" 7 #include "base/bind.h"
8 #include "base/strings/string_number_conversions.h" 8 #include "base/strings/string_number_conversions.h"
9 #include "base/strings/stringprintf.h" 9 #include "base/strings/stringprintf.h"
10 #include "base/threading/thread_restrictions.h" 10 #include "base/threading/thread_restrictions.h"
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 110
111 } 111 }
112 112
113 namespace media { 113 namespace media {
114 114
115 // static 115 // static
116 AudioInputController::Factory* AudioInputController::factory_ = NULL; 116 AudioInputController::Factory* AudioInputController::factory_ = NULL;
117 117
118 AudioInputController::AudioInputController(EventHandler* handler, 118 AudioInputController::AudioInputController(EventHandler* handler,
119 SyncWriter* sync_writer, 119 SyncWriter* sync_writer,
120 UserInputMonitor* user_input_monitor) 120 UserInputMonitor* user_input_monitor,
121 const bool agc_is_enabled)
121 : creator_task_runner_(base::MessageLoopProxy::current()), 122 : creator_task_runner_(base::MessageLoopProxy::current()),
122 handler_(handler), 123 handler_(handler),
123 stream_(NULL), 124 stream_(NULL),
124 data_is_active_(false), 125 data_is_active_(false),
125 state_(CLOSED), 126 state_(CLOSED),
126 sync_writer_(sync_writer), 127 sync_writer_(sync_writer),
127 max_volume_(0.0), 128 max_volume_(0.0),
128 user_input_monitor_(user_input_monitor), 129 user_input_monitor_(user_input_monitor),
130 agc_is_enabled_(agc_is_enabled),
129 #if defined(AUDIO_POWER_MONITORING) 131 #if defined(AUDIO_POWER_MONITORING)
130 power_measurement_is_enabled_(false), 132 power_measurement_is_enabled_(false),
131 log_silence_state_(false), 133 log_silence_state_(false),
132 silence_state_(SILENCE_STATE_NO_MEASUREMENT), 134 silence_state_(SILENCE_STATE_NO_MEASUREMENT),
133 #endif 135 #endif
134 prev_key_down_count_(0) { 136 prev_key_down_count_(0) {
135 DCHECK(creator_task_runner_.get()); 137 DCHECK(creator_task_runner_.get());
136 } 138 }
137 139
138 AudioInputController::~AudioInputController() { 140 AudioInputController::~AudioInputController() {
(...skipping 10 matching lines...) Expand all
149 DCHECK(audio_manager); 151 DCHECK(audio_manager);
150 152
151 if (!params.IsValid() || (params.channels() > kMaxInputChannels)) 153 if (!params.IsValid() || (params.channels() > kMaxInputChannels))
152 return NULL; 154 return NULL;
153 155
154 if (factory_) { 156 if (factory_) {
155 return factory_->Create( 157 return factory_->Create(
156 audio_manager, event_handler, params, user_input_monitor); 158 audio_manager, event_handler, params, user_input_monitor);
157 } 159 }
158 scoped_refptr<AudioInputController> controller( 160 scoped_refptr<AudioInputController> controller(
159 new AudioInputController(event_handler, NULL, user_input_monitor)); 161 new AudioInputController(event_handler, NULL, user_input_monitor, false));
160 162
161 controller->task_runner_ = audio_manager->GetTaskRunner(); 163 controller->task_runner_ = audio_manager->GetTaskRunner();
162 164
163 // Create and open a new audio input stream from the existing 165 // Create and open a new audio input stream from the existing
164 // audio-device thread. 166 // audio-device thread.
165 if (!controller->task_runner_->PostTask( 167 if (!controller->task_runner_->PostTask(
166 FROM_HERE, 168 FROM_HERE,
167 base::Bind(&AudioInputController::DoCreate, 169 base::Bind(&AudioInputController::DoCreate,
168 controller, 170 controller,
169 base::Unretained(audio_manager), 171 base::Unretained(audio_manager),
170 params, 172 params,
171 device_id))) { 173 device_id))) {
172 controller = NULL; 174 controller = NULL;
173 } 175 }
174 176
175 return controller; 177 return controller;
176 } 178 }
177 179
178 // static 180 // static
179 scoped_refptr<AudioInputController> AudioInputController::CreateLowLatency( 181 scoped_refptr<AudioInputController> AudioInputController::CreateLowLatency(
180 AudioManager* audio_manager, 182 AudioManager* audio_manager,
181 EventHandler* event_handler, 183 EventHandler* event_handler,
182 const AudioParameters& params, 184 const AudioParameters& params,
183 const std::string& device_id, 185 const std::string& device_id,
184 SyncWriter* sync_writer, 186 SyncWriter* sync_writer,
185 UserInputMonitor* user_input_monitor) { 187 UserInputMonitor* user_input_monitor,
188 const bool agc_is_enabled) {
186 DCHECK(audio_manager); 189 DCHECK(audio_manager);
187 DCHECK(sync_writer); 190 DCHECK(sync_writer);
188 191
189 if (!params.IsValid() || (params.channels() > kMaxInputChannels)) 192 if (!params.IsValid() || (params.channels() > kMaxInputChannels))
190 return NULL; 193 return NULL;
191 194
192 // Create the AudioInputController object and ensure that it runs on 195 // Create the AudioInputController object and ensure that it runs on
193 // the audio-manager thread. 196 // the audio-manager thread.
194 scoped_refptr<AudioInputController> controller( 197 scoped_refptr<AudioInputController> controller(new AudioInputController(
195 new AudioInputController(event_handler, sync_writer, user_input_monitor)); 198 event_handler, sync_writer, user_input_monitor, agc_is_enabled));
196 controller->task_runner_ = audio_manager->GetTaskRunner(); 199 controller->task_runner_ = audio_manager->GetTaskRunner();
197 200
198 // Create and open a new audio input stream from the existing 201 // Create and open a new audio input stream from the existing
199 // audio-device thread. Use the provided audio-input device. 202 // audio-device thread. Use the provided audio-input device.
200 if (!controller->task_runner_->PostTask( 203 if (!controller->task_runner_->PostTask(
201 FROM_HERE, 204 FROM_HERE,
202 base::Bind(&AudioInputController::DoCreateForLowLatency, 205 base::Bind(&AudioInputController::DoCreateForLowLatency,
203 controller, 206 controller,
204 base::Unretained(audio_manager), 207 base::Unretained(audio_manager),
205 params, 208 params,
206 device_id))) { 209 device_id))) {
207 controller = NULL; 210 controller = NULL;
208 } 211 }
209 212
210 return controller; 213 return controller;
211 } 214 }
212 215
213 // static 216 // static
214 scoped_refptr<AudioInputController> AudioInputController::CreateForStream( 217 scoped_refptr<AudioInputController> AudioInputController::CreateForStream(
215 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, 218 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
216 EventHandler* event_handler, 219 EventHandler* event_handler,
217 AudioInputStream* stream, 220 AudioInputStream* stream,
218 SyncWriter* sync_writer, 221 SyncWriter* sync_writer,
219 UserInputMonitor* user_input_monitor) { 222 UserInputMonitor* user_input_monitor) {
220 DCHECK(sync_writer); 223 DCHECK(sync_writer);
221 DCHECK(stream); 224 DCHECK(stream);
222 225
223 // Create the AudioInputController object and ensure that it runs on 226 // Create the AudioInputController object and ensure that it runs on
224 // the audio-manager thread. 227 // the audio-manager thread.
225 scoped_refptr<AudioInputController> controller( 228 scoped_refptr<AudioInputController> controller(new AudioInputController(
226 new AudioInputController(event_handler, sync_writer, user_input_monitor)); 229 event_handler, sync_writer, user_input_monitor, false));
227 controller->task_runner_ = task_runner; 230 controller->task_runner_ = task_runner;
228 231
229 // TODO(miu): See TODO at top of file. Until that's resolved, we need to 232 // TODO(miu): See TODO at top of file. Until that's resolved, we need to
230 // disable the error auto-detection here (since the audio mirroring 233 // disable the error auto-detection here (since the audio mirroring
231 // implementation will reliably report error and close events). Note, of 234 // implementation will reliably report error and close events). Note, of
232 // course, that we're assuming CreateForStream() has been called for the audio 235 // course, that we're assuming CreateForStream() has been called for the audio
233 // mirroring use case only. 236 // mirroring use case only.
234 if (!controller->task_runner_->PostTask( 237 if (!controller->task_runner_->PostTask(
235 FROM_HERE, 238 FROM_HERE,
236 base::Bind(&AudioInputController::DoCreateForStream, 239 base::Bind(&AudioInputController::DoCreateForStream,
(...skipping 16 matching lines...) Expand all
253 256
254 task_runner_->PostTaskAndReply( 257 task_runner_->PostTaskAndReply(
255 FROM_HERE, base::Bind(&AudioInputController::DoClose, this), closed_task); 258 FROM_HERE, base::Bind(&AudioInputController::DoClose, this), closed_task);
256 } 259 }
257 260
258 void AudioInputController::SetVolume(double volume) { 261 void AudioInputController::SetVolume(double volume) {
259 task_runner_->PostTask(FROM_HERE, base::Bind( 262 task_runner_->PostTask(FROM_HERE, base::Bind(
260 &AudioInputController::DoSetVolume, this, volume)); 263 &AudioInputController::DoSetVolume, this, volume));
261 } 264 }
262 265
263 void AudioInputController::SetAutomaticGainControl(bool enabled) {
264 task_runner_->PostTask(FROM_HERE, base::Bind(
265 &AudioInputController::DoSetAutomaticGainControl, this, enabled));
266 }
267
268 void AudioInputController::DoCreate(AudioManager* audio_manager, 266 void AudioInputController::DoCreate(AudioManager* audio_manager,
269 const AudioParameters& params, 267 const AudioParameters& params,
270 const std::string& device_id) { 268 const std::string& device_id) {
271 DCHECK(task_runner_->BelongsToCurrentThread()); 269 DCHECK(task_runner_->BelongsToCurrentThread());
272 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.CreateTime"); 270 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.CreateTime");
273 if (handler_) 271 if (handler_)
274 handler_->OnLog(this, "AIC::DoCreate"); 272 handler_->OnLog(this, "AIC::DoCreate");
275 273
276 #if defined(AUDIO_POWER_MONITORING) 274 #if defined(AUDIO_POWER_MONITORING)
277 power_measurement_is_enabled_ = true; 275 // Disable power monitoring for streams that run without AGC enabled to
276 // avoid adding logs and UMA for non-WebRTC clients.
277 power_measurement_is_enabled_ = agc_is_enabled_;
278 last_audio_level_log_time_ = base::TimeTicks::Now(); 278 last_audio_level_log_time_ = base::TimeTicks::Now();
279 silence_state_ = SILENCE_STATE_NO_MEASUREMENT; 279 silence_state_ = SILENCE_STATE_NO_MEASUREMENT;
280 #endif 280 #endif
281 281
282 // TODO(miu): See TODO at top of file. Until that's resolved, assume all 282 // TODO(miu): See TODO at top of file. Until that's resolved, assume all
283 // platform audio input requires the |no_data_timer_| be used to auto-detect 283 // platform audio input requires the |no_data_timer_| be used to auto-detect
284 // errors. In reality, probably only Windows needs to be treated as 284 // errors. In reality, probably only Windows needs to be treated as
285 // unreliable here. 285 // unreliable here.
286 DoCreateForStream(audio_manager->MakeAudioInputStream(params, device_id)); 286 DoCreateForStream(audio_manager->MakeAudioInputStream(params, device_id));
287 } 287 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 stream_->Close(); 320 stream_->Close();
321 stream_ = NULL; 321 stream_ = NULL;
322 if (handler_) 322 if (handler_)
323 handler_->OnError(this, STREAM_OPEN_ERROR); 323 handler_->OnError(this, STREAM_OPEN_ERROR);
324 LogCaptureStartupResult(CAPTURE_STARTUP_OPEN_STREAM_FAILED); 324 LogCaptureStartupResult(CAPTURE_STARTUP_OPEN_STREAM_FAILED);
325 return; 325 return;
326 } 326 }
327 327
328 DCHECK(!no_data_timer_.get()); 328 DCHECK(!no_data_timer_.get());
329 329
330 // Set AGC state using mode in |agc_is_enabled_| which can only be enabled in
331 // CreateLowLatency().
332 stream_->SetAutomaticGainControl(agc_is_enabled_);
333
330 // Create the data timer which will call FirstCheckForNoData(). The timer 334 // Create the data timer which will call FirstCheckForNoData(). The timer
331 // is started in DoRecord() and restarted in each DoCheckForNoData() 335 // is started in DoRecord() and restarted in each DoCheckForNoData()
332 // callback. 336 // callback.
333 // The timer is enabled for logging purposes. The NO_DATA_ERROR triggered 337 // The timer is enabled for logging purposes. The NO_DATA_ERROR triggered
334 // from the timer must be ignored by the EventHandler. 338 // from the timer must be ignored by the EventHandler.
335 // TODO(henrika): remove usage of timer when it has been verified on Canary 339 // TODO(henrika): remove usage of timer when it has been verified on Canary
336 // that we are safe doing so. Goal is to get rid of |no_data_timer_| and 340 // that we are safe doing so. Goal is to get rid of |no_data_timer_| and
337 // everything that is tied to it. crbug.com/357569. 341 // everything that is tied to it. crbug.com/357569.
338 no_data_timer_.reset(new base::Timer( 342 no_data_timer_.reset(new base::Timer(
339 FROM_HERE, base::TimeDelta::FromSeconds(kTimerInitialIntervalSeconds), 343 FROM_HERE, base::TimeDelta::FromSeconds(kTimerInitialIntervalSeconds),
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 446
443 if (max_volume_ == 0.0) { 447 if (max_volume_ == 0.0) {
444 DLOG(WARNING) << "Failed to access input volume control"; 448 DLOG(WARNING) << "Failed to access input volume control";
445 return; 449 return;
446 } 450 }
447 451
448 // Set the stream volume and scale to a range matched to the platform. 452 // Set the stream volume and scale to a range matched to the platform.
449 stream_->SetVolume(max_volume_ * volume); 453 stream_->SetVolume(max_volume_ * volume);
450 } 454 }
451 455
452 void AudioInputController::DoSetAutomaticGainControl(bool enabled) {
453 DCHECK(task_runner_->BelongsToCurrentThread());
454 DCHECK_NE(state_, RECORDING);
455
456 // Ensure that the AGC state only can be modified before streaming starts.
457 if (state_ != CREATED)
458 return;
459
460 stream_->SetAutomaticGainControl(enabled);
461 }
462
463 void AudioInputController::FirstCheckForNoData() { 456 void AudioInputController::FirstCheckForNoData() {
464 DCHECK(task_runner_->BelongsToCurrentThread()); 457 DCHECK(task_runner_->BelongsToCurrentThread());
465 LogCaptureStartupResult(GetDataIsActive() ? 458 LogCaptureStartupResult(GetDataIsActive() ?
466 CAPTURE_STARTUP_OK : 459 CAPTURE_STARTUP_OK :
467 CAPTURE_STARTUP_NO_DATA_CALLBACK); 460 CAPTURE_STARTUP_NO_DATA_CALLBACK);
468 if (handler_) { 461 if (handler_) {
469 handler_->OnLog(this, GetDataIsActive() ? 462 handler_->OnLog(this, GetDataIsActive() ?
470 "AIC::FirstCheckForNoData => data is active" : 463 "AIC::FirstCheckForNoData => data is active" :
471 "AIC::FirstCheckForNoData => data is NOT active"); 464 "AIC::FirstCheckForNoData => data is NOT active");
472 } 465 }
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
666 } 659 }
667 660
668 void AudioInputController::LogSilenceState(SilenceState value) { 661 void AudioInputController::LogSilenceState(SilenceState value) {
669 UMA_HISTOGRAM_ENUMERATION("Media.AudioInputControllerSessionSilenceReport", 662 UMA_HISTOGRAM_ENUMERATION("Media.AudioInputControllerSessionSilenceReport",
670 value, 663 value,
671 SILENCE_STATE_MAX + 1); 664 SILENCE_STATE_MAX + 1);
672 } 665 }
673 #endif 666 #endif
674 667
675 } // namespace media 668 } // namespace media
OLDNEW
« no previous file with comments | « media/audio/audio_input_controller.h ('k') | media/audio/test_audio_input_controller_factory.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698