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

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: Fixed unit test. 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 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 std::string the_value; 293 std::string the_value;
294 if (GetConstraintValueAsString( 294 if (GetConstraintValueAsString(
295 constraints_, &blink::WebMediaTrackConstraintSet::googArrayGeometry, 295 constraints_, &blink::WebMediaTrackConstraintSet::googArrayGeometry,
296 &the_value)) { 296 &the_value)) {
297 return the_value; 297 return the_value;
298 } 298 }
299 return ""; 299 return "";
300 } 300 }
301 301
302 EchoInformation::EchoInformation() 302 EchoInformation::EchoInformation()
303 : num_chunks_(0), echo_frames_received_(false) { 303 : delay_stats_time_ms_(0),
304 echo_frames_received_(false),
305 divergent_filter_stats_time_ms_(0),
306 num_divergent_filter_fraction_(0),
307 num_non_zero_divergent_filter_fraction_(0) {}
308
309 EchoInformation::~EchoInformation() {
310 DCHECK(thread_checker_.CalledOnValidThread());
311 ReportAndResetAecDivergentFilterStats();
304 } 312 }
305 313
306 EchoInformation::~EchoInformation() {} 314 void EchoInformation::UpdateAecStats(
315 webrtc::EchoCancellation* echo_cancellation) {
316 DCHECK(thread_checker_.CalledOnValidThread());
317
318 if (!echo_cancellation->is_enabled())
319 return;
320
321 UpdateAecDelayStats(echo_cancellation);
322 UpdateAecDivergentFilterStats(echo_cancellation);
323 }
307 324
308 void EchoInformation::UpdateAecDelayStats( 325 void EchoInformation::UpdateAecDelayStats(
309 webrtc::EchoCancellation* echo_cancellation) { 326 webrtc::EchoCancellation* echo_cancellation) {
327 DCHECK(thread_checker_.CalledOnValidThread());
328
310 // Only start collecting stats if we know echo cancellation has measured an 329 // 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 330 // echo. Otherwise we clutter the stats with for example cases where only the
312 // microphone is used. 331 // microphone is used.
313 if (!echo_frames_received_ & !echo_cancellation->stream_has_echo()) 332 if (!echo_frames_received_ & !echo_cancellation->stream_has_echo())
314 return; 333 return;
315 334
316 echo_frames_received_ = true; 335 echo_frames_received_ = true;
336
317 // In WebRTC, three echo delay metrics are calculated and updated every 337 // 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 338 // 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 339 // 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 340 // fixed aggregation window of five seconds, so we use the same query
321 // frequency to avoid logging old values. 341 // frequency to avoid logging old values.
322 const int kNumChunksInFiveSeconds = 500; 342 if (!echo_cancellation->is_delay_logging_enabled())
323 if (!echo_cancellation->is_delay_logging_enabled() || 343 return;
324 !echo_cancellation->is_enabled()) { 344
345 delay_stats_time_ms_ += webrtc::AudioProcessing::kChunkSizeMs;
346 if (delay_stats_time_ms_ <
347 500 * webrtc::AudioProcessing::kChunkSizeMs) { // 5 seconds
325 return; 348 return;
326 } 349 }
327 350
328 num_chunks_++;
329 if (num_chunks_ < kNumChunksInFiveSeconds) {
330 return;
331 }
332
333 int dummy_median = 0, dummy_std = 0; 351 int dummy_median = 0, dummy_std = 0;
334 float fraction_poor_delays = 0; 352 float fraction_poor_delays = 0;
335 if (echo_cancellation->GetDelayMetrics( 353 if (echo_cancellation->GetDelayMetrics(
336 &dummy_median, &dummy_std, &fraction_poor_delays) == 354 &dummy_median, &dummy_std, &fraction_poor_delays) ==
337 webrtc::AudioProcessing::kNoError) { 355 webrtc::AudioProcessing::kNoError) {
338 num_chunks_ = 0; 356 delay_stats_time_ms_ = 0;
339 // Map |fraction_poor_delays| to an Echo Cancellation quality and log in UMA 357 // Map |fraction_poor_delays| to an Echo Cancellation quality and log in UMA
340 // histogram. See DelayBasedEchoQuality for information on histogram 358 // histogram. See DelayBasedEchoQuality for information on histogram
341 // buckets. 359 // buckets.
342 UMA_HISTOGRAM_ENUMERATION("WebRTC.AecDelayBasedQuality", 360 UMA_HISTOGRAM_ENUMERATION("WebRTC.AecDelayBasedQuality",
343 EchoDelayFrequencyToQuality(fraction_poor_delays), 361 EchoDelayFrequencyToQuality(fraction_poor_delays),
344 DELAY_BASED_ECHO_QUALITY_MAX); 362 DELAY_BASED_ECHO_QUALITY_MAX);
345 } 363 }
346 } 364 }
347 365
366 void EchoInformation::UpdateAecDivergentFilterStats(
367 webrtc::EchoCancellation* echo_cancellation) {
368 DCHECK(thread_checker_.CalledOnValidThread());
369
370 if (!echo_cancellation->are_metrics_enabled())
371 return;
372
373 divergent_filter_stats_time_ms_ += webrtc::AudioProcessing::kChunkSizeMs;
374 if (divergent_filter_stats_time_ms_ <
375 100 * webrtc::AudioProcessing::kChunkSizeMs) { // 1 second
376 return;
377 }
378
379 webrtc::EchoCancellation::Metrics metrics;
380 if (echo_cancellation->GetMetrics(&metrics) ==
381 webrtc::AudioProcessing::kNoError) {
382 // If not yet calculated, |metrics.divergent_filter_fraction| is -1.0. After
383 // being calculated the first time, it is updated periodically.
384 if (metrics.divergent_filter_fraction < 0.0f) {
385 DCHECK_EQ(num_divergent_filter_fraction_, 0);
386 return;
387 }
388 if (metrics.divergent_filter_fraction > 0.0f) {
389 ++num_non_zero_divergent_filter_fraction_;
390 }
391 } else {
392 DLOG(WARNING) << "Get echo cancellation metrics failed.";
393 }
394 ++num_divergent_filter_fraction_;
395 divergent_filter_stats_time_ms_ = 0;
396 }
397
398 void EchoInformation::ReportAndResetAecDivergentFilterStats() {
399 DCHECK(thread_checker_.CalledOnValidThread());
400
401 if (num_divergent_filter_fraction_ == 0)
402 return;
403
404 int non_zero_percent = 100 * num_non_zero_divergent_filter_fraction_ /
405 num_divergent_filter_fraction_;
406 UMA_HISTOGRAM_PERCENTAGE("WebRTC.AecFilterHasDivergence", non_zero_percent);
407
408 divergent_filter_stats_time_ms_ = 0;
409 num_non_zero_divergent_filter_fraction_ = 0;
410 num_divergent_filter_fraction_ = 0;
411 }
412
348 void EnableEchoCancellation(AudioProcessing* audio_processing) { 413 void EnableEchoCancellation(AudioProcessing* audio_processing) {
349 #if defined(OS_ANDROID) 414 #if defined(OS_ANDROID)
350 // Mobile devices are using AECM. 415 // Mobile devices are using AECM.
351 CHECK_EQ(0, audio_processing->echo_control_mobile()->set_routing_mode( 416 CHECK_EQ(0, audio_processing->echo_control_mobile()->set_routing_mode(
352 webrtc::EchoControlMobile::kSpeakerphone)); 417 webrtc::EchoControlMobile::kSpeakerphone));
353 CHECK_EQ(0, audio_processing->echo_control_mobile()->Enable(true)); 418 CHECK_EQ(0, audio_processing->echo_control_mobile()->Enable(true));
354 return; 419 return;
355 #endif 420 #endif
356 int err = audio_processing->echo_cancellation()->set_suppression_level( 421 int err = audio_processing->echo_cancellation()->set_suppression_level(
357 webrtc::EchoCancellation::kHighSuppression); 422 webrtc::EchoCancellation::kHighSuppression);
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
466 531
467 // Give preference to the audio constraint over the device-supplied mic 532 // Give preference to the audio constraint over the device-supplied mic
468 // positions. This is mainly for testing purposes. 533 // positions. This is mainly for testing purposes.
469 return WebrtcPointsFromMediaPoints( 534 return WebrtcPointsFromMediaPoints(
470 constraints_geometry.empty() 535 constraints_geometry.empty()
471 ? input_params.mic_positions 536 ? input_params.mic_positions
472 : media::ParsePointsFromString(constraints_geometry)); 537 : media::ParsePointsFromString(constraints_geometry));
473 } 538 }
474 539
475 } // namespace content 540 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698