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

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: 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 NUM_STREAM_OPEN_RESULT.
Ilya Sherman 2014/08/12 17:30:48 nit: Please update the name "NUM_STREAM_OPEN_RESUL
Henrik Grunell 2014/08/13 12:31:30 Done.
55 enum CaptureStartupResult {
56 CAPTURE_STARTUP_NO_DATA_CALLBACK = 0,
57 CAPTURE_STARTUP_OK = 1,
58 CAPTURE_STARTUP_CREATE_STREAM_FAILED = 2,
59 CAPTURE_STARTUP_OPEN_STREAM_FAILED = 3,
60 CAPTURE_STARTUP_RESULT_MAX = CAPTURE_STARTUP_OPEN_STREAM_FAILED
Ilya Sherman 2014/08/12 17:30:48 Optional nit: It's a little cleaner, IMO, to have
Henrik Grunell 2014/08/13 12:31:30 The presubmit check actually complained about that
61 };
62
63 void LogStreamOpenResult(CaptureStartupResult result) {
64 UMA_HISTOGRAM_ENUMERATION("Media.AudioInputControllerCaptureStartupSuccess",
65 result,
66 CAPTURE_STARTUP_RESULT_MAX + 1);
67
68 }
69
50 namespace media { 70 namespace media {
51 71
52 // static 72 // static
53 AudioInputController::Factory* AudioInputController::factory_ = NULL; 73 AudioInputController::Factory* AudioInputController::factory_ = NULL;
54 74
55 AudioInputController::AudioInputController(EventHandler* handler, 75 AudioInputController::AudioInputController(EventHandler* handler,
56 SyncWriter* sync_writer, 76 SyncWriter* sync_writer,
57 UserInputMonitor* user_input_monitor) 77 UserInputMonitor* user_input_monitor)
58 : creator_task_runner_(base::MessageLoopProxy::current()), 78 : creator_task_runner_(base::MessageLoopProxy::current()),
59 handler_(handler), 79 handler_(handler),
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 new AudioInputController(event_handler, sync_writer, user_input_monitor)); 170 new AudioInputController(event_handler, sync_writer, user_input_monitor));
151 controller->task_runner_ = task_runner; 171 controller->task_runner_ = task_runner;
152 172
153 // TODO(miu): See TODO at top of file. Until that's resolved, we need to 173 // 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 174 // disable the error auto-detection here (since the audio mirroring
155 // implementation will reliably report error and close events). Note, of 175 // implementation will reliably report error and close events). Note, of
156 // course, that we're assuming CreateForStream() has been called for the audio 176 // course, that we're assuming CreateForStream() has been called for the audio
157 // mirroring use case only. 177 // mirroring use case only.
158 if (!controller->task_runner_->PostTask( 178 if (!controller->task_runner_->PostTask(
159 FROM_HERE, 179 FROM_HERE,
160 base::Bind(&AudioInputController::DoCreateForStream, controller, 180 base::Bind(&AudioInputController::DoCreateForStream,
161 stream, false))) { 181 controller,
182 stream))) {
162 controller = NULL; 183 controller = NULL;
163 } 184 }
164 185
165 return controller; 186 return controller;
166 } 187 }
167 188
168 void AudioInputController::Record() { 189 void AudioInputController::Record() {
169 task_runner_->PostTask(FROM_HERE, base::Bind( 190 task_runner_->PostTask(FROM_HERE, base::Bind(
170 &AudioInputController::DoRecord, this)); 191 &AudioInputController::DoRecord, this));
171 } 192 }
(...skipping 30 matching lines...) Expand all
202 audio_level_.reset(new media::AudioPowerMonitor( 223 audio_level_.reset(new media::AudioPowerMonitor(
203 params.sample_rate(), 224 params.sample_rate(),
204 TimeDelta::FromMilliseconds(kPowerMeasurementTimeConstantMilliseconds))); 225 TimeDelta::FromMilliseconds(kPowerMeasurementTimeConstantMilliseconds)));
205 audio_params_ = params; 226 audio_params_ = params;
206 #endif 227 #endif
207 228
208 // TODO(miu): See TODO at top of file. Until that's resolved, assume all 229 // 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 230 // 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 231 // errors. In reality, probably only Windows needs to be treated as
211 // unreliable here. 232 // unreliable here.
212 DoCreateForStream(audio_manager->MakeAudioInputStream(params, device_id), 233 DoCreateForStream(audio_manager->MakeAudioInputStream(params, device_id));
213 true);
214 } 234 }
215 235
216 void AudioInputController::DoCreateForStream( 236 void AudioInputController::DoCreateForStream(
217 AudioInputStream* stream_to_control, bool enable_nodata_timer) { 237 AudioInputStream* stream_to_control) {
218 DCHECK(task_runner_->BelongsToCurrentThread()); 238 DCHECK(task_runner_->BelongsToCurrentThread());
219 239
220 DCHECK(!stream_); 240 DCHECK(!stream_);
221 stream_ = stream_to_control; 241 stream_ = stream_to_control;
222 242
223 if (!stream_) { 243 if (!stream_) {
224 if (handler_) 244 if (handler_)
225 handler_->OnError(this, STREAM_CREATE_ERROR); 245 handler_->OnError(this, STREAM_CREATE_ERROR);
246 LogStreamOpenResult(CAPTURE_STARTUP_CREATE_STREAM_FAILED);
226 return; 247 return;
227 } 248 }
228 249
229 if (stream_ && !stream_->Open()) { 250 if (stream_ && !stream_->Open()) {
230 stream_->Close(); 251 stream_->Close();
231 stream_ = NULL; 252 stream_ = NULL;
232 if (handler_) 253 if (handler_)
233 handler_->OnError(this, STREAM_OPEN_ERROR); 254 handler_->OnError(this, STREAM_OPEN_ERROR);
255 LogStreamOpenResult(CAPTURE_STARTUP_OPEN_STREAM_FAILED);
234 return; 256 return;
235 } 257 }
236 258
237 DCHECK(!no_data_timer_.get()); 259 DCHECK(!no_data_timer_.get());
238 260
261 // Create the data timer which will call FirstCheckForNoData(). The timer
262 // is started in DoRecord() and restarted in each DoCheckForNoData()
263 // callback.
239 // The timer is enabled for logging purposes. The NO_DATA_ERROR triggered 264 // The timer is enabled for logging purposes. The NO_DATA_ERROR triggered
240 // from the timer must be ignored by the EventHandler. 265 // from the timer must be ignored by the EventHandler.
241 // TODO(henrika): remove usage of timer when it has been verified on Canary 266 // 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 267 // 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. 268 // everything that is tied to it. crbug.com/357569.
244 enable_nodata_timer = true; 269 no_data_timer_.reset(new base::Timer(
245 270 FROM_HERE, base::TimeDelta::FromSeconds(kTimerInitialIntervalSeconds),
246 if (enable_nodata_timer) { 271 base::Bind(&AudioInputController::FirstCheckForNoData,
247 // Create the data timer which will call FirstCheckForNoData(). The timer 272 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 273
258 state_ = CREATED; 274 state_ = CREATED;
259 if (handler_) 275 if (handler_)
260 handler_->OnCreated(this); 276 handler_->OnCreated(this);
261 277
262 if (user_input_monitor_) { 278 if (user_input_monitor_) {
263 user_input_monitor_->EnableKeyPressMonitoring(); 279 user_input_monitor_->EnableKeyPressMonitoring();
264 prev_key_down_count_ = user_input_monitor_->GetKeyPressCount(); 280 prev_key_down_count_ = user_input_monitor_->GetKeyPressCount();
265 } 281 }
266 } 282 }
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 361
346 // Ensure that the AGC state only can be modified before streaming starts. 362 // Ensure that the AGC state only can be modified before streaming starts.
347 if (state_ != CREATED) 363 if (state_ != CREATED)
348 return; 364 return;
349 365
350 stream_->SetAutomaticGainControl(enabled); 366 stream_->SetAutomaticGainControl(enabled);
351 } 367 }
352 368
353 void AudioInputController::FirstCheckForNoData() { 369 void AudioInputController::FirstCheckForNoData() {
354 DCHECK(task_runner_->BelongsToCurrentThread()); 370 DCHECK(task_runner_->BelongsToCurrentThread());
355 UMA_HISTOGRAM_BOOLEAN("Media.AudioInputControllerCaptureStartupSuccess", 371 LogStreamOpenResult(GetDataIsActive() ?
356 GetDataIsActive()); 372 CAPTURE_STARTUP_OK :
373 CAPTURE_STARTUP_NO_DATA_CALLBACK);
357 DoCheckForNoData(); 374 DoCheckForNoData();
358 } 375 }
359 376
360 void AudioInputController::DoCheckForNoData() { 377 void AudioInputController::DoCheckForNoData() {
361 DCHECK(task_runner_->BelongsToCurrentThread()); 378 DCHECK(task_runner_->BelongsToCurrentThread());
362 379
363 if (!GetDataIsActive()) { 380 if (!GetDataIsActive()) {
364 // The data-is-active marker will be false only if it has been more than 381 // 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 382 // one second since a data packet was recorded. This can happen if a
366 // capture device has been removed or disabled. 383 // capture device has been removed or disabled.
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 520
504 void AudioInputController::SetDataIsActive(bool enabled) { 521 void AudioInputController::SetDataIsActive(bool enabled) {
505 base::subtle::Release_Store(&data_is_active_, enabled); 522 base::subtle::Release_Store(&data_is_active_, enabled);
506 } 523 }
507 524
508 bool AudioInputController::GetDataIsActive() { 525 bool AudioInputController::GetDataIsActive() {
509 return (base::subtle::Acquire_Load(&data_is_active_) != false); 526 return (base::subtle::Acquire_Load(&data_is_active_) != false);
510 } 527 }
511 528
512 } // namespace media 529 } // 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