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 "system_wrappers/include/metrics.h"
17 
18 namespace webrtc {
19 
20 namespace {
21 
22 enum class DelayReliabilityCategory {
23   kNone,
24   kPoor,
25   kMedium,
26   kGood,
27   kExcellent,
28   kNumCategories
29 };
30 enum class DelayChangesCategory {
31   kNone,
32   kFew,
33   kSeveral,
34   kMany,
35   kConstant,
36   kNumCategories
37 };
38 
39 }  // namespace
40 
Update(rtc::Optional<size_t> delay_samples,size_t buffer_delay_blocks)41 void RenderDelayControllerMetrics::Update(rtc::Optional<size_t> delay_samples,
42                                           size_t buffer_delay_blocks) {
43   ++call_counter_;
44 
45   if (!initial_update) {
46     if (delay_samples) {
47       ++reliable_delay_estimate_counter_;
48       size_t delay_blocks = (*delay_samples) / kBlockSize;
49 
50       if (delay_blocks != delay_blocks_) {
51         ++delay_change_counter_;
52         delay_blocks_ = delay_blocks;
53       }
54     }
55   } else if (++initial_call_counter_ == 5 * kNumBlocksPerSecond) {
56     initial_update = false;
57   }
58 
59   if (call_counter_ == kMetricsReportingIntervalBlocks) {
60     int value_to_report = static_cast<int>(delay_blocks_);
61     value_to_report = std::min(124, value_to_report);
62     RTC_HISTOGRAM_COUNTS_LINEAR("WebRTC.Audio.EchoCanceller.EchoPathDelay",
63                                 value_to_report, 0, 124, 125);
64 
65     value_to_report = static_cast<int>(buffer_delay_blocks);
66     value_to_report = std::min(124, value_to_report);
67     RTC_HISTOGRAM_COUNTS_LINEAR("WebRTC.Audio.EchoCanceller.BufferDelay",
68                                 value_to_report, 0, 124, 125);
69 
70     DelayReliabilityCategory delay_reliability;
71     if (reliable_delay_estimate_counter_ == 0) {
72       delay_reliability = DelayReliabilityCategory::kNone;
73     } else if (reliable_delay_estimate_counter_ > (call_counter_ >> 1)) {
74       delay_reliability = DelayReliabilityCategory::kExcellent;
75     } else if (reliable_delay_estimate_counter_ > 100) {
76       delay_reliability = DelayReliabilityCategory::kGood;
77     } else if (reliable_delay_estimate_counter_ > 10) {
78       delay_reliability = DelayReliabilityCategory::kMedium;
79     } else {
80       delay_reliability = DelayReliabilityCategory::kPoor;
81     }
82     RTC_HISTOGRAM_ENUMERATION(
83         "WebRTC.Audio.EchoCanceller.ReliableDelayEstimates",
84         static_cast<int>(delay_reliability),
85         static_cast<int>(DelayReliabilityCategory::kNumCategories));
86 
87     DelayChangesCategory delay_changes;
88     if (delay_change_counter_ == 0) {
89       delay_changes = DelayChangesCategory::kNone;
90     } else if (delay_change_counter_ > 10) {
91       delay_changes = DelayChangesCategory::kConstant;
92     } else if (delay_change_counter_ > 5) {
93       delay_changes = DelayChangesCategory::kMany;
94     } else if (delay_change_counter_ > 2) {
95       delay_changes = DelayChangesCategory::kSeveral;
96     } else {
97       delay_changes = DelayChangesCategory::kFew;
98     }
99     RTC_HISTOGRAM_ENUMERATION(
100         "WebRTC.Audio.EchoCanceller.DelayChanges",
101         static_cast<int>(delay_changes),
102         static_cast<int>(DelayChangesCategory::kNumCategories));
103 
104     metrics_reported_ = true;
105     call_counter_ = 0;
106     ResetMetrics();
107   } else {
108     metrics_reported_ = false;
109   }
110 }
111 
ResetMetrics()112 void RenderDelayControllerMetrics::ResetMetrics() {
113   delay_change_counter_ = 0;
114   reliable_delay_estimate_counter_ = 0;
115 }
116 
117 }  // namespace webrtc
118