• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 constexpr int kMaxSkewShiftCount = 20;
41 
42 }  // namespace
43 
44 RenderDelayControllerMetrics::RenderDelayControllerMetrics() = default;
45 
Update(absl::optional<size_t> delay_samples,size_t buffer_delay_blocks,absl::optional<int> skew_shift_blocks,ClockdriftDetector::Level clockdrift)46 void RenderDelayControllerMetrics::Update(
47     absl::optional<size_t> delay_samples,
48     size_t buffer_delay_blocks,
49     absl::optional<int> skew_shift_blocks,
50     ClockdriftDetector::Level clockdrift) {
51   ++call_counter_;
52 
53   if (!initial_update) {
54     size_t delay_blocks;
55     if (delay_samples) {
56       ++reliable_delay_estimate_counter_;
57       delay_blocks = (*delay_samples) / kBlockSize + 2;
58     } else {
59       delay_blocks = 0;
60     }
61 
62     if (delay_blocks != delay_blocks_) {
63       ++delay_change_counter_;
64       delay_blocks_ = delay_blocks;
65     }
66 
67     if (skew_shift_blocks) {
68       skew_shift_count_ = std::min(kMaxSkewShiftCount, skew_shift_count_);
69     }
70   } else if (++initial_call_counter_ == 5 * kNumBlocksPerSecond) {
71     initial_update = false;
72   }
73 
74   if (call_counter_ == kMetricsReportingIntervalBlocks) {
75     int value_to_report = static_cast<int>(delay_blocks_);
76     value_to_report = std::min(124, value_to_report >> 1);
77     RTC_HISTOGRAM_COUNTS_LINEAR("WebRTC.Audio.EchoCanceller.EchoPathDelay",
78                                 value_to_report, 0, 124, 125);
79 
80     value_to_report = static_cast<int>(buffer_delay_blocks + 2);
81     value_to_report = std::min(124, value_to_report >> 1);
82     RTC_HISTOGRAM_COUNTS_LINEAR("WebRTC.Audio.EchoCanceller.BufferDelay",
83                                 value_to_report, 0, 124, 125);
84 
85     DelayReliabilityCategory delay_reliability;
86     if (reliable_delay_estimate_counter_ == 0) {
87       delay_reliability = DelayReliabilityCategory::kNone;
88     } else if (reliable_delay_estimate_counter_ > (call_counter_ >> 1)) {
89       delay_reliability = DelayReliabilityCategory::kExcellent;
90     } else if (reliable_delay_estimate_counter_ > 100) {
91       delay_reliability = DelayReliabilityCategory::kGood;
92     } else if (reliable_delay_estimate_counter_ > 10) {
93       delay_reliability = DelayReliabilityCategory::kMedium;
94     } else {
95       delay_reliability = DelayReliabilityCategory::kPoor;
96     }
97     RTC_HISTOGRAM_ENUMERATION(
98         "WebRTC.Audio.EchoCanceller.ReliableDelayEstimates",
99         static_cast<int>(delay_reliability),
100         static_cast<int>(DelayReliabilityCategory::kNumCategories));
101 
102     DelayChangesCategory delay_changes;
103     if (delay_change_counter_ == 0) {
104       delay_changes = DelayChangesCategory::kNone;
105     } else if (delay_change_counter_ > 10) {
106       delay_changes = DelayChangesCategory::kConstant;
107     } else if (delay_change_counter_ > 5) {
108       delay_changes = DelayChangesCategory::kMany;
109     } else if (delay_change_counter_ > 2) {
110       delay_changes = DelayChangesCategory::kSeveral;
111     } else {
112       delay_changes = DelayChangesCategory::kFew;
113     }
114     RTC_HISTOGRAM_ENUMERATION(
115         "WebRTC.Audio.EchoCanceller.DelayChanges",
116         static_cast<int>(delay_changes),
117         static_cast<int>(DelayChangesCategory::kNumCategories));
118 
119     RTC_HISTOGRAM_ENUMERATION(
120         "WebRTC.Audio.EchoCanceller.Clockdrift", static_cast<int>(clockdrift),
121         static_cast<int>(ClockdriftDetector::Level::kNumCategories));
122 
123     metrics_reported_ = true;
124     call_counter_ = 0;
125     ResetMetrics();
126   } else {
127     metrics_reported_ = false;
128   }
129 
130   if (!initial_update && ++skew_report_timer_ == 60 * kNumBlocksPerSecond) {
131     RTC_HISTOGRAM_COUNTS_LINEAR("WebRTC.Audio.EchoCanceller.MaxSkewShiftCount",
132                                 skew_shift_count_, 0, kMaxSkewShiftCount,
133                                 kMaxSkewShiftCount + 1);
134 
135     skew_shift_count_ = 0;
136     skew_report_timer_ = 0;
137   }
138 }
139 
ResetMetrics()140 void RenderDelayControllerMetrics::ResetMetrics() {
141   delay_change_counter_ = 0;
142   reliable_delay_estimate_counter_ = 0;
143 }
144 
145 }  // namespace webrtc
146