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

Side by Side Diff: content/renderer/media/media_stream_audio_processor_options.cc

Issue 2103483002: Add UMA stats for AEC filter divergence metric. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Code review fix (minyue@). Created 4 years, 5 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "content/renderer/media/media_stream_audio_processor_options.h" 5 #include "content/renderer/media/media_stream_audio_processor_options.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/files/file_path.h" 10 #include "base/files/file_path.h"
(...skipping 30 matching lines...) Expand all
41 "googExperimentalNoiseSuppression"; 41 "googExperimentalNoiseSuppression";
42 const char MediaAudioConstraints::kGoogBeamforming[] = "googBeamforming"; 42 const char MediaAudioConstraints::kGoogBeamforming[] = "googBeamforming";
43 const char MediaAudioConstraints::kGoogArrayGeometry[] = "googArrayGeometry"; 43 const char MediaAudioConstraints::kGoogArrayGeometry[] = "googArrayGeometry";
44 const char MediaAudioConstraints::kGoogHighpassFilter[] = "googHighpassFilter"; 44 const char MediaAudioConstraints::kGoogHighpassFilter[] = "googHighpassFilter";
45 const char MediaAudioConstraints::kGoogTypingNoiseDetection[] = 45 const char MediaAudioConstraints::kGoogTypingNoiseDetection[] =
46 "googTypingNoiseDetection"; 46 "googTypingNoiseDetection";
47 const char MediaAudioConstraints::kGoogAudioMirroring[] = "googAudioMirroring"; 47 const char MediaAudioConstraints::kGoogAudioMirroring[] = "googAudioMirroring";
48 48
49 namespace { 49 namespace {
50 50
51 // The interval of which the AEC stats update functions should be called. This
52 // is the buffer size that the AP and AEC work on.
53 const int kChunkDurationMs = 10;
tommi (sloooow) - chröme 2016/06/28 11:43:56 If this value is defined somewhere else (as I susp
Henrik Grunell 2016/06/29 08:47:58 It is! In AudioProcessing. :) Done.
54
51 // Controls whether the hotword audio stream is used on supported platforms. 55 // Controls whether the hotword audio stream is used on supported platforms.
52 const char kMediaStreamAudioHotword[] = "googHotword"; 56 const char kMediaStreamAudioHotword[] = "googHotword";
53 57
54 // Constant constraint keys which enables default audio constraints on 58 // Constant constraint keys which enables default audio constraints on
55 // mediastreams with audio. 59 // mediastreams with audio.
56 struct { 60 struct {
57 const char* key; 61 const char* key;
58 bool value; 62 bool value;
59 } const kDefaultAudioConstraints[] = { 63 } const kDefaultAudioConstraints[] = {
60 { MediaAudioConstraints::kEchoCancellation, true }, 64 { MediaAudioConstraints::kEchoCancellation, true },
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 std::string the_value; 297 std::string the_value;
294 if (GetConstraintValueAsString( 298 if (GetConstraintValueAsString(
295 constraints_, &blink::WebMediaTrackConstraintSet::googArrayGeometry, 299 constraints_, &blink::WebMediaTrackConstraintSet::googArrayGeometry,
296 &the_value)) { 300 &the_value)) {
297 return the_value; 301 return the_value;
298 } 302 }
299 return ""; 303 return "";
300 } 304 }
301 305
302 EchoInformation::EchoInformation() 306 EchoInformation::EchoInformation()
303 : num_chunks_(0), echo_frames_received_(false) { 307 : delay_stats_time_ms_(0),
308 echo_frames_received_(false),
309 divergent_filter_stats_time_ms_(0),
310 num_divergent_filter_fraction_(0),
311 num_non_zero_divergent_filter_fraction_(0) {}
312
313 EchoInformation::~EchoInformation() {
314 ReportAndResetAecDivergentFilterStats();
304 } 315 }
305 316
306 EchoInformation::~EchoInformation() {}
307
308 void EchoInformation::UpdateAecDelayStats( 317 void EchoInformation::UpdateAecDelayStats(
309 webrtc::EchoCancellation* echo_cancellation) { 318 webrtc::EchoCancellation* echo_cancellation) {
310 // Only start collecting stats if we know echo cancellation has measured an 319 // Only start collecting stats if we know echo cancellation has measured an
311 // echo. Otherwise we clutter the stats with for example cases where only the 320 // echo. Otherwise we clutter the stats with for example cases where only the
312 // microphone is used. 321 // microphone is used.
313 if (!echo_frames_received_ & !echo_cancellation->stream_has_echo()) 322 if (!echo_frames_received_ & !echo_cancellation->stream_has_echo())
314 return; 323 return;
315 324
316 echo_frames_received_ = true; 325 echo_frames_received_ = true;
317 // In WebRTC, three echo delay metrics are calculated and updated every 326 // In WebRTC, three echo delay metrics are calculated and updated every
318 // five seconds. We use one of them, |fraction_poor_delays| to log in a UMA 327 // five seconds. We use one of them, |fraction_poor_delays| to log in a UMA
319 // histogram an Echo Cancellation quality metric. The stat in WebRTC has a 328 // histogram an Echo Cancellation quality metric. The stat in WebRTC has a
320 // fixed aggregation window of five seconds, so we use the same query 329 // fixed aggregation window of five seconds, so we use the same query
321 // frequency to avoid logging old values. 330 // frequency to avoid logging old values.
322 const int kNumChunksInFiveSeconds = 500;
323 if (!echo_cancellation->is_delay_logging_enabled() || 331 if (!echo_cancellation->is_delay_logging_enabled() ||
324 !echo_cancellation->is_enabled()) { 332 !echo_cancellation->is_enabled()) {
325 return; 333 return;
326 } 334 }
327 335
328 num_chunks_++; 336 delay_stats_time_ms_ += kChunkDurationMs;
329 if (num_chunks_ < kNumChunksInFiveSeconds) { 337 if (delay_stats_time_ms_ < 500 * kChunkDurationMs) // 5 seconds
330 return; 338 return;
331 }
332 339
333 int dummy_median = 0, dummy_std = 0; 340 int dummy_median = 0, dummy_std = 0;
334 float fraction_poor_delays = 0; 341 float fraction_poor_delays = 0;
335 if (echo_cancellation->GetDelayMetrics( 342 if (echo_cancellation->GetDelayMetrics(
336 &dummy_median, &dummy_std, &fraction_poor_delays) == 343 &dummy_median, &dummy_std, &fraction_poor_delays) ==
337 webrtc::AudioProcessing::kNoError) { 344 webrtc::AudioProcessing::kNoError) {
338 num_chunks_ = 0; 345 delay_stats_time_ms_ = 0;
339 // Map |fraction_poor_delays| to an Echo Cancellation quality and log in UMA 346 // Map |fraction_poor_delays| to an Echo Cancellation quality and log in UMA
340 // histogram. See DelayBasedEchoQuality for information on histogram 347 // histogram. See DelayBasedEchoQuality for information on histogram
341 // buckets. 348 // buckets.
342 UMA_HISTOGRAM_ENUMERATION("WebRTC.AecDelayBasedQuality", 349 UMA_HISTOGRAM_ENUMERATION("WebRTC.AecDelayBasedQuality",
343 EchoDelayFrequencyToQuality(fraction_poor_delays), 350 EchoDelayFrequencyToQuality(fraction_poor_delays),
344 DELAY_BASED_ECHO_QUALITY_MAX); 351 DELAY_BASED_ECHO_QUALITY_MAX);
345 } 352 }
346 } 353 }
347 354
355 void EchoInformation::UpdateAecDivergentFilterStats(
356 webrtc::EchoCancellation* echo_cancellation) {
357 if (!echo_cancellation->is_enabled() ||
358 !echo_cancellation->are_metrics_enabled()) {
359 return;
360 }
361
362 divergent_filter_stats_time_ms_ += kChunkDurationMs;
363 if (divergent_filter_stats_time_ms_ < 100 * kChunkDurationMs) // 1 second
364 return;
365
366 webrtc::EchoCancellation::Metrics metrics;
367 if (echo_cancellation->GetMetrics(&metrics) ==
368 webrtc::AudioProcessing::kNoError) {
369 // If not yet calculated, |metrics.divergent_filter_fraction| is -1.0. After
370 // being calculated the first time, it is updated periodically.
371 if (metrics.divergent_filter_fraction < 0.0f) {
372 DCHECK_EQ(num_divergent_filter_fraction_, 0);
373 return;
374 }
375 if (metrics.divergent_filter_fraction > 0.0f) {
376 ++num_non_zero_divergent_filter_fraction_;
377 }
378 } else {
379 DLOG(WARNING) << "Get echo cancellation metrics failed.";
380 }
381 ++num_divergent_filter_fraction_;
382 divergent_filter_stats_time_ms_ = 0;
383 }
384
385 void EchoInformation::ReportAndResetAecDivergentFilterStats() {
tommi (sloooow) - chröme 2016/06/28 11:43:56 can you add thread checks to these methods? As is,
Henrik Grunell 2016/06/29 08:47:58 Hmm, they are not accessed on the same thread. Tha
386 if (num_divergent_filter_fraction_ == 0)
387 return;
388
389 int non_zero_percent = 100 * num_non_zero_divergent_filter_fraction_ /
390 num_divergent_filter_fraction_;
391 UMA_HISTOGRAM_PERCENTAGE("WebRTC.AecFilterHasDivergence",
392 non_zero_percent);
393
394 divergent_filter_stats_time_ms_ = 0;
395 num_non_zero_divergent_filter_fraction_ = 0;
396 num_divergent_filter_fraction_ = 0;
397 }
398
348 void EnableEchoCancellation(AudioProcessing* audio_processing) { 399 void EnableEchoCancellation(AudioProcessing* audio_processing) {
349 #if defined(OS_ANDROID) 400 #if defined(OS_ANDROID)
350 // Mobile devices are using AECM. 401 // Mobile devices are using AECM.
351 CHECK_EQ(0, audio_processing->echo_control_mobile()->set_routing_mode( 402 CHECK_EQ(0, audio_processing->echo_control_mobile()->set_routing_mode(
352 webrtc::EchoControlMobile::kSpeakerphone)); 403 webrtc::EchoControlMobile::kSpeakerphone));
353 CHECK_EQ(0, audio_processing->echo_control_mobile()->Enable(true)); 404 CHECK_EQ(0, audio_processing->echo_control_mobile()->Enable(true));
354 return; 405 return;
355 #endif 406 #endif
356 int err = audio_processing->echo_cancellation()->set_suppression_level( 407 int err = audio_processing->echo_cancellation()->set_suppression_level(
357 webrtc::EchoCancellation::kHighSuppression); 408 webrtc::EchoCancellation::kHighSuppression);
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
466 517
467 // Give preference to the audio constraint over the device-supplied mic 518 // Give preference to the audio constraint over the device-supplied mic
468 // positions. This is mainly for testing purposes. 519 // positions. This is mainly for testing purposes.
469 return WebrtcPointsFromMediaPoints( 520 return WebrtcPointsFromMediaPoints(
470 constraints_geometry.empty() 521 constraints_geometry.empty()
471 ? input_params.mic_positions 522 ? input_params.mic_positions
472 : media::ParsePointsFromString(constraints_geometry)); 523 : media::ParsePointsFromString(constraints_geometry));
473 } 524 }
474 525
475 } // namespace content 526 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698