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

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

Issue 460993002: Add UMA stats for open audio input device failure. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Code review. Created 6 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « media/audio/audio_input_controller.h ('k') | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/stringprintf.h" 8 #include "base/strings/stringprintf.h"
9 #include "base/threading/thread_restrictions.h" 9 #include "base/threading/thread_restrictions.h"
10 #include "base/time/time.h" 10 #include "base/time/time.h"
(...skipping 29 matching lines...) Expand all
40 // A large smoothing factor corresponds to a faster filter response to input 40 // A large smoothing factor corresponds to a faster filter response to input
41 // changes since y(n)=alpha*x(n)+(1-alpha)*y(n-1), where x(n) is the input 41 // changes since y(n)=alpha*x(n)+(1-alpha)*y(n-1), where x(n) is the input
42 // and y(n) is the output. 42 // and y(n) is the output.
43 const int kPowerMeasurementTimeConstantMilliseconds = 10; 43 const int kPowerMeasurementTimeConstantMilliseconds = 10;
44 44
45 // Time in seconds between two successive measurements of audio power levels. 45 // Time in seconds between two successive measurements of audio power levels.
46 const int kPowerMonitorLogIntervalSeconds = 5; 46 const int kPowerMonitorLogIntervalSeconds = 5;
47 #endif 47 #endif
48 } 48 }
49 49
50 // Used to log the result of capture startup.
51 // This was previously logged as a boolean with only the no callback and OK
52 // options. The enum order is kept to ensure backwards compatibility.
53 // Elements in this enum should not be deleted or rearranged; the only
54 // permitted operation is to add new elements before CAPTURE_STARTUP_RESULT_MAX
55 // and update CAPTURE_STARTUP_RESULT_MAX.
56 enum CaptureStartupResult {
57 CAPTURE_STARTUP_NO_DATA_CALLBACK = 0,
58 CAPTURE_STARTUP_OK = 1,
59 CAPTURE_STARTUP_CREATE_STREAM_FAILED = 2,
60 CAPTURE_STARTUP_OPEN_STREAM_FAILED = 3,
61 CAPTURE_STARTUP_RESULT_MAX = CAPTURE_STARTUP_OPEN_STREAM_FAILED
62 };
63
64 void LogCaptureStartupResult(CaptureStartupResult result) {
65 UMA_HISTOGRAM_ENUMERATION("Media.AudioInputControllerCaptureStartupSuccess",
66 result,
67 CAPTURE_STARTUP_RESULT_MAX + 1);
68
69 }
70
50 namespace media { 71 namespace media {
51 72
52 // static 73 // static
53 AudioInputController::Factory* AudioInputController::factory_ = NULL; 74 AudioInputController::Factory* AudioInputController::factory_ = NULL;
54 75
55 AudioInputController::AudioInputController(EventHandler* handler, 76 AudioInputController::AudioInputController(EventHandler* handler,
56 SyncWriter* sync_writer, 77 SyncWriter* sync_writer,
57 UserInputMonitor* user_input_monitor) 78 UserInputMonitor* user_input_monitor)
58 : creator_task_runner_(base::MessageLoopProxy::current()), 79 : creator_task_runner_(base::MessageLoopProxy::current()),
59 handler_(handler), 80 handler_(handler),
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 new AudioInputController(event_handler, sync_writer, user_input_monitor)); 171 new AudioInputController(event_handler, sync_writer, user_input_monitor));
151 controller->task_runner_ = task_runner; 172 controller->task_runner_ = task_runner;
152 173
153 // TODO(miu): See TODO at top of file. Until that's resolved, we need to 174 // TODO(miu): See TODO at top of file. Until that's resolved, we need to
154 // disable the error auto-detection here (since the audio mirroring 175 // disable the error auto-detection here (since the audio mirroring
155 // implementation will reliably report error and close events). Note, of 176 // implementation will reliably report error and close events). Note, of
156 // course, that we're assuming CreateForStream() has been called for the audio 177 // course, that we're assuming CreateForStream() has been called for the audio
157 // mirroring use case only. 178 // mirroring use case only.
158 if (!controller->task_runner_->PostTask( 179 if (!controller->task_runner_->PostTask(
159 FROM_HERE, 180 FROM_HERE,
160 base::Bind(&AudioInputController::DoCreateForStream, controller, 181 base::Bind(&AudioInputController::DoCreateForStream,
161 stream, false))) { 182 controller,
183 stream))) {
162 controller = NULL; 184 controller = NULL;
163 } 185 }
164 186
165 return controller; 187 return controller;
166 } 188 }
167 189
168 void AudioInputController::Record() { 190 void AudioInputController::Record() {
169 task_runner_->PostTask(FROM_HERE, base::Bind( 191 task_runner_->PostTask(FROM_HERE, base::Bind(
170 &AudioInputController::DoRecord, this)); 192 &AudioInputController::DoRecord, this));
171 } 193 }
(...skipping 30 matching lines...) Expand all
202 audio_level_.reset(new media::AudioPowerMonitor( 224 audio_level_.reset(new media::AudioPowerMonitor(
203 params.sample_rate(), 225 params.sample_rate(),
204 TimeDelta::FromMilliseconds(kPowerMeasurementTimeConstantMilliseconds))); 226 TimeDelta::FromMilliseconds(kPowerMeasurementTimeConstantMilliseconds)));
205 audio_params_ = params; 227 audio_params_ = params;
206 #endif 228 #endif
207 229
208 // TODO(miu): See TODO at top of file. Until that's resolved, assume all 230 // TODO(miu): See TODO at top of file. Until that's resolved, assume all
209 // platform audio input requires the |no_data_timer_| be used to auto-detect 231 // platform audio input requires the |no_data_timer_| be used to auto-detect
210 // errors. In reality, probably only Windows needs to be treated as 232 // errors. In reality, probably only Windows needs to be treated as
211 // unreliable here. 233 // unreliable here.
212 DoCreateForStream(audio_manager->MakeAudioInputStream(params, device_id), 234 DoCreateForStream(audio_manager->MakeAudioInputStream(params, device_id));
213 true);
214 } 235 }
215 236
216 void AudioInputController::DoCreateForStream( 237 void AudioInputController::DoCreateForStream(
217 AudioInputStream* stream_to_control, bool enable_nodata_timer) { 238 AudioInputStream* stream_to_control) {
218 DCHECK(task_runner_->BelongsToCurrentThread()); 239 DCHECK(task_runner_->BelongsToCurrentThread());
219 240
220 DCHECK(!stream_); 241 DCHECK(!stream_);
221 stream_ = stream_to_control; 242 stream_ = stream_to_control;
222 243
223 if (!stream_) { 244 if (!stream_) {
224 if (handler_) 245 if (handler_)
225 handler_->OnError(this, STREAM_CREATE_ERROR); 246 handler_->OnError(this, STREAM_CREATE_ERROR);
247 LogCaptureStartupResult(CAPTURE_STARTUP_CREATE_STREAM_FAILED);
226 return; 248 return;
227 } 249 }
228 250
229 if (stream_ && !stream_->Open()) { 251 if (stream_ && !stream_->Open()) {
230 stream_->Close(); 252 stream_->Close();
231 stream_ = NULL; 253 stream_ = NULL;
232 if (handler_) 254 if (handler_)
233 handler_->OnError(this, STREAM_OPEN_ERROR); 255 handler_->OnError(this, STREAM_OPEN_ERROR);
256 LogCaptureStartupResult(CAPTURE_STARTUP_OPEN_STREAM_FAILED);
234 return; 257 return;
235 } 258 }
236 259
237 DCHECK(!no_data_timer_.get()); 260 DCHECK(!no_data_timer_.get());
238 261
262 // Create the data timer which will call FirstCheckForNoData(). The timer
263 // is started in DoRecord() and restarted in each DoCheckForNoData()
264 // callback.
239 // The timer is enabled for logging purposes. The NO_DATA_ERROR triggered 265 // The timer is enabled for logging purposes. The NO_DATA_ERROR triggered
240 // from the timer must be ignored by the EventHandler. 266 // from the timer must be ignored by the EventHandler.
241 // TODO(henrika): remove usage of timer when it has been verified on Canary 267 // TODO(henrika): remove usage of timer when it has been verified on Canary
242 // that we are safe doing so. Goal is to get rid of |no_data_timer_| and 268 // that we are safe doing so. Goal is to get rid of |no_data_timer_| and
243 // everything that is tied to it. crbug.com/357569. 269 // everything that is tied to it. crbug.com/357569.
244 enable_nodata_timer = true; 270 no_data_timer_.reset(new base::Timer(
245 271 FROM_HERE, base::TimeDelta::FromSeconds(kTimerInitialIntervalSeconds),
246 if (enable_nodata_timer) { 272 base::Bind(&AudioInputController::FirstCheckForNoData,
247 // Create the data timer which will call FirstCheckForNoData(). The timer 273 base::Unretained(this)), false));
248 // is started in DoRecord() and restarted in each DoCheckForNoData()
249 // callback.
250 no_data_timer_.reset(new base::Timer(
251 FROM_HERE, base::TimeDelta::FromSeconds(kTimerInitialIntervalSeconds),
252 base::Bind(&AudioInputController::FirstCheckForNoData,
253 base::Unretained(this)), false));
254 } else {
255 DVLOG(1) << "Disabled: timer check for no data.";
256 }
257 274
258 state_ = CREATED; 275 state_ = CREATED;
259 if (handler_) 276 if (handler_)
260 handler_->OnCreated(this); 277 handler_->OnCreated(this);
261 278
262 if (user_input_monitor_) { 279 if (user_input_monitor_) {
263 user_input_monitor_->EnableKeyPressMonitoring(); 280 user_input_monitor_->EnableKeyPressMonitoring();
264 prev_key_down_count_ = user_input_monitor_->GetKeyPressCount(); 281 prev_key_down_count_ = user_input_monitor_->GetKeyPressCount();
265 } 282 }
266 } 283 }
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 362
346 // Ensure that the AGC state only can be modified before streaming starts. 363 // Ensure that the AGC state only can be modified before streaming starts.
347 if (state_ != CREATED) 364 if (state_ != CREATED)
348 return; 365 return;
349 366
350 stream_->SetAutomaticGainControl(enabled); 367 stream_->SetAutomaticGainControl(enabled);
351 } 368 }
352 369
353 void AudioInputController::FirstCheckForNoData() { 370 void AudioInputController::FirstCheckForNoData() {
354 DCHECK(task_runner_->BelongsToCurrentThread()); 371 DCHECK(task_runner_->BelongsToCurrentThread());
355 UMA_HISTOGRAM_BOOLEAN("Media.AudioInputControllerCaptureStartupSuccess", 372 LogCaptureStartupResult(GetDataIsActive() ?
356 GetDataIsActive()); 373 CAPTURE_STARTUP_OK :
374 CAPTURE_STARTUP_NO_DATA_CALLBACK);
357 DoCheckForNoData(); 375 DoCheckForNoData();
358 } 376 }
359 377
360 void AudioInputController::DoCheckForNoData() { 378 void AudioInputController::DoCheckForNoData() {
361 DCHECK(task_runner_->BelongsToCurrentThread()); 379 DCHECK(task_runner_->BelongsToCurrentThread());
362 380
363 if (!GetDataIsActive()) { 381 if (!GetDataIsActive()) {
364 // The data-is-active marker will be false only if it has been more than 382 // The data-is-active marker will be false only if it has been more than
365 // one second since a data packet was recorded. This can happen if a 383 // one second since a data packet was recorded. This can happen if a
366 // capture device has been removed or disabled. 384 // capture device has been removed or disabled.
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 521
504 void AudioInputController::SetDataIsActive(bool enabled) { 522 void AudioInputController::SetDataIsActive(bool enabled) {
505 base::subtle::Release_Store(&data_is_active_, enabled); 523 base::subtle::Release_Store(&data_is_active_, enabled);
506 } 524 }
507 525
508 bool AudioInputController::GetDataIsActive() { 526 bool AudioInputController::GetDataIsActive() {
509 return (base::subtle::Acquire_Load(&data_is_active_) != false); 527 return (base::subtle::Acquire_Load(&data_is_active_) != false);
510 } 528 }
511 529
512 } // namespace media 530 } // namespace media
OLDNEW
« no previous file with comments | « media/audio/audio_input_controller.h ('k') | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698