xref: /aosp_15_r20/external/webrtc/modules/audio_processing/aec3/render_delay_controller_metrics.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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 
15 #include "modules/audio_processing/aec3/aec3_common.h"
16 #include "rtc_base/checks.h"
17 #include "system_wrappers/include/metrics.h"
18 
19 namespace webrtc {
20 
21 namespace {
22 
23 enum class DelayReliabilityCategory {
24   kNone,
25   kPoor,
26   kMedium,
27   kGood,
28   kExcellent,
29   kNumCategories
30 };
31 enum class DelayChangesCategory {
32   kNone,
33   kFew,
34   kSeveral,
35   kMany,
36   kConstant,
37   kNumCategories
38 };
39 
40 }  // namespace
41 
42 RenderDelayControllerMetrics::RenderDelayControllerMetrics() = default;
43 
Update(absl::optional<size_t> delay_samples,absl::optional<size_t> buffer_delay_blocks,ClockdriftDetector::Level clockdrift)44 void RenderDelayControllerMetrics::Update(
45     absl::optional<size_t> delay_samples,
46     absl::optional<size_t> buffer_delay_blocks,
47     ClockdriftDetector::Level clockdrift) {
48   ++call_counter_;
49 
50   if (!initial_update) {
51     size_t delay_blocks;
52     if (delay_samples) {
53       ++reliable_delay_estimate_counter_;
54       // Add an offset by 1 (metric is halved before reporting) to reserve 0 for
55       // absent delay.
56       delay_blocks = (*delay_samples) / kBlockSize + 2;
57     } else {
58       delay_blocks = 0;
59     }
60 
61     if (delay_blocks != delay_blocks_) {
62       ++delay_change_counter_;
63       delay_blocks_ = delay_blocks;
64     }
65 
66   } else if (++initial_call_counter_ == 5 * kNumBlocksPerSecond) {
67     initial_update = false;
68   }
69 
70   if (call_counter_ == kMetricsReportingIntervalBlocks) {
71     int value_to_report = static_cast<int>(delay_blocks_);
72     // Divide by 2 to compress metric range.
73     value_to_report = std::min(124, value_to_report >> 1);
74     RTC_HISTOGRAM_COUNTS_LINEAR("WebRTC.Audio.EchoCanceller.EchoPathDelay",
75                                 value_to_report, 0, 124, 125);
76 
77     // Divide by 2 to compress metric range.
78     // Offset by 1 to reserve 0 for absent delay.
79     value_to_report = buffer_delay_blocks ? (*buffer_delay_blocks + 2) >> 1 : 0;
80     value_to_report = std::min(124, value_to_report);
81     RTC_HISTOGRAM_COUNTS_LINEAR("WebRTC.Audio.EchoCanceller.BufferDelay",
82                                 value_to_report, 0, 124, 125);
83 
84     DelayReliabilityCategory delay_reliability;
85     if (reliable_delay_estimate_counter_ == 0) {
86       delay_reliability = DelayReliabilityCategory::kNone;
87     } else if (reliable_delay_estimate_counter_ > (call_counter_ >> 1)) {
88       delay_reliability = DelayReliabilityCategory::kExcellent;
89     } else if (reliable_delay_estimate_counter_ > 100) {
90       delay_reliability = DelayReliabilityCategory::kGood;
91     } else if (reliable_delay_estimate_counter_ > 10) {
92       delay_reliability = DelayReliabilityCategory::kMedium;
93     } else {
94       delay_reliability = DelayReliabilityCategory::kPoor;
95     }
96     RTC_HISTOGRAM_ENUMERATION(
97         "WebRTC.Audio.EchoCanceller.ReliableDelayEstimates",
98         static_cast<int>(delay_reliability),
99         static_cast<int>(DelayReliabilityCategory::kNumCategories));
100 
101     DelayChangesCategory delay_changes;
102     if (delay_change_counter_ == 0) {
103       delay_changes = DelayChangesCategory::kNone;
104     } else if (delay_change_counter_ > 10) {
105       delay_changes = DelayChangesCategory::kConstant;
106     } else if (delay_change_counter_ > 5) {
107       delay_changes = DelayChangesCategory::kMany;
108     } else if (delay_change_counter_ > 2) {
109       delay_changes = DelayChangesCategory::kSeveral;
110     } else {
111       delay_changes = DelayChangesCategory::kFew;
112     }
113     RTC_HISTOGRAM_ENUMERATION(
114         "WebRTC.Audio.EchoCanceller.DelayChanges",
115         static_cast<int>(delay_changes),
116         static_cast<int>(DelayChangesCategory::kNumCategories));
117 
118     RTC_HISTOGRAM_ENUMERATION(
119         "WebRTC.Audio.EchoCanceller.Clockdrift", static_cast<int>(clockdrift),
120         static_cast<int>(ClockdriftDetector::Level::kNumCategories));
121 
122     call_counter_ = 0;
123     ResetMetrics();
124   }
125 }
126 
ResetMetrics()127 void RenderDelayControllerMetrics::ResetMetrics() {
128   delay_change_counter_ = 0;
129   reliable_delay_estimate_counter_ = 0;
130 }
131 
132 }  // namespace webrtc
133