render_delay_controller_metrics.cc (4384B)
1 /* 2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "modules/audio_processing/aec3/render_delay_controller_metrics.h" 12 13 #include <algorithm> 14 #include <cstddef> 15 #include <optional> 16 17 #include "modules/audio_processing/aec3/aec3_common.h" 18 #include "modules/audio_processing/aec3/clockdrift_detector.h" 19 #include "system_wrappers/include/metrics.h" 20 21 namespace webrtc { 22 23 namespace { 24 25 enum class DelayReliabilityCategory { 26 kNone, 27 kPoor, 28 kMedium, 29 kGood, 30 kExcellent, 31 kNumCategories 32 }; 33 enum class DelayChangesCategory { 34 kNone, 35 kFew, 36 kSeveral, 37 kMany, 38 kConstant, 39 kNumCategories 40 }; 41 42 } // namespace 43 44 RenderDelayControllerMetrics::RenderDelayControllerMetrics() = default; 45 46 void RenderDelayControllerMetrics::Update( 47 std::optional<size_t> delay_samples, 48 std::optional<size_t> buffer_delay_blocks, 49 ClockdriftDetector::Level clockdrift) { 50 ++call_counter_; 51 52 if (!initial_update) { 53 size_t delay_blocks; 54 if (delay_samples) { 55 ++reliable_delay_estimate_counter_; 56 // Add an offset by 1 (metric is halved before reporting) to reserve 0 for 57 // absent delay. 58 delay_blocks = (*delay_samples) / kBlockSize + 2; 59 } else { 60 delay_blocks = 0; 61 } 62 63 if (delay_blocks != delay_blocks_) { 64 ++delay_change_counter_; 65 delay_blocks_ = delay_blocks; 66 } 67 68 } else if (++initial_call_counter_ == 5 * kNumBlocksPerSecond) { 69 initial_update = false; 70 } 71 72 if (call_counter_ == kMetricsReportingIntervalBlocks) { 73 int value_to_report = static_cast<int>(delay_blocks_); 74 // Divide by 2 to compress metric range. 75 value_to_report = std::min(124, value_to_report >> 1); 76 RTC_HISTOGRAM_COUNTS_LINEAR("WebRTC.Audio.EchoCanceller.EchoPathDelay", 77 value_to_report, 0, 124, 125); 78 79 // Divide by 2 to compress metric range. 80 // Offset by 1 to reserve 0 for absent delay. 81 value_to_report = buffer_delay_blocks ? (*buffer_delay_blocks + 2) >> 1 : 0; 82 value_to_report = std::min(124, value_to_report); 83 RTC_HISTOGRAM_COUNTS_LINEAR("WebRTC.Audio.EchoCanceller.BufferDelay", 84 value_to_report, 0, 124, 125); 85 86 DelayReliabilityCategory delay_reliability; 87 if (reliable_delay_estimate_counter_ == 0) { 88 delay_reliability = DelayReliabilityCategory::kNone; 89 } else if (reliable_delay_estimate_counter_ > (call_counter_ >> 1)) { 90 delay_reliability = DelayReliabilityCategory::kExcellent; 91 } else if (reliable_delay_estimate_counter_ > 100) { 92 delay_reliability = DelayReliabilityCategory::kGood; 93 } else if (reliable_delay_estimate_counter_ > 10) { 94 delay_reliability = DelayReliabilityCategory::kMedium; 95 } else { 96 delay_reliability = DelayReliabilityCategory::kPoor; 97 } 98 RTC_HISTOGRAM_ENUMERATION( 99 "WebRTC.Audio.EchoCanceller.ReliableDelayEstimates", 100 static_cast<int>(delay_reliability), 101 static_cast<int>(DelayReliabilityCategory::kNumCategories)); 102 103 DelayChangesCategory delay_changes; 104 if (delay_change_counter_ == 0) { 105 delay_changes = DelayChangesCategory::kNone; 106 } else if (delay_change_counter_ > 10) { 107 delay_changes = DelayChangesCategory::kConstant; 108 } else if (delay_change_counter_ > 5) { 109 delay_changes = DelayChangesCategory::kMany; 110 } else if (delay_change_counter_ > 2) { 111 delay_changes = DelayChangesCategory::kSeveral; 112 } else { 113 delay_changes = DelayChangesCategory::kFew; 114 } 115 RTC_HISTOGRAM_ENUMERATION( 116 "WebRTC.Audio.EchoCanceller.DelayChanges", 117 static_cast<int>(delay_changes), 118 static_cast<int>(DelayChangesCategory::kNumCategories)); 119 120 RTC_HISTOGRAM_ENUMERATION( 121 "WebRTC.Audio.EchoCanceller.Clockdrift", static_cast<int>(clockdrift), 122 static_cast<int>(ClockdriftDetector::Level::kNumCategories)); 123 124 call_counter_ = 0; 125 ResetMetrics(); 126 } 127 } 128 129 void RenderDelayControllerMetrics::ResetMetrics() { 130 delay_change_counter_ = 0; 131 reliable_delay_estimate_counter_ = 0; 132 } 133 134 } // namespace webrtc