OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include "webrtc/modules/audio_coding/neteq/statistics_calculator.h" | 11 #include "webrtc/modules/audio_coding/neteq/statistics_calculator.h" |
12 | 12 |
13 #include <assert.h> | 13 #include <assert.h> |
14 #include <string.h> // memset | 14 #include <string.h> // memset |
15 #include <algorithm> | |
16 #include <iterator> | |
15 | 17 |
16 #include "webrtc/base/checks.h" | 18 #include "webrtc/base/checks.h" |
17 #include "webrtc/modules/audio_coding/neteq/decision_logic.h" | 19 #include "webrtc/modules/audio_coding/neteq/decision_logic.h" |
18 #include "webrtc/modules/audio_coding/neteq/delay_manager.h" | 20 #include "webrtc/modules/audio_coding/neteq/delay_manager.h" |
19 #include "webrtc/system_wrappers/interface/metrics.h" | 21 #include "webrtc/system_wrappers/interface/metrics.h" |
20 | 22 |
21 namespace webrtc { | 23 namespace webrtc { |
22 | 24 |
25 // Allocating the static const so that it can be passed by reference to DCHECK. | |
26 const size_t StatisticsCalculator::kLenWaitingTimes; | |
27 | |
23 StatisticsCalculator::PeriodicUmaLogger::PeriodicUmaLogger( | 28 StatisticsCalculator::PeriodicUmaLogger::PeriodicUmaLogger( |
24 const std::string& uma_name, | 29 const std::string& uma_name, |
25 int report_interval_ms, | 30 int report_interval_ms, |
26 int max_value) | 31 int max_value) |
27 : uma_name_(uma_name), | 32 : uma_name_(uma_name), |
28 report_interval_ms_(report_interval_ms), | 33 report_interval_ms_(report_interval_ms), |
29 max_value_(max_value), | 34 max_value_(max_value), |
30 timer_(0) { | 35 timer_(0) { |
31 } | 36 } |
32 | 37 |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
99 | 104 |
100 StatisticsCalculator::StatisticsCalculator() | 105 StatisticsCalculator::StatisticsCalculator() |
101 : preemptive_samples_(0), | 106 : preemptive_samples_(0), |
102 accelerate_samples_(0), | 107 accelerate_samples_(0), |
103 added_zero_samples_(0), | 108 added_zero_samples_(0), |
104 expanded_speech_samples_(0), | 109 expanded_speech_samples_(0), |
105 expanded_noise_samples_(0), | 110 expanded_noise_samples_(0), |
106 discarded_packets_(0), | 111 discarded_packets_(0), |
107 lost_timestamps_(0), | 112 lost_timestamps_(0), |
108 timestamps_since_last_report_(0), | 113 timestamps_since_last_report_(0), |
109 len_waiting_times_(0), | |
110 next_waiting_time_index_(0), | |
111 secondary_decoded_samples_(0), | 114 secondary_decoded_samples_(0), |
112 delayed_packet_outage_counter_( | 115 delayed_packet_outage_counter_( |
113 "WebRTC.Audio.DelayedPacketOutageEventsPerMinute", | 116 "WebRTC.Audio.DelayedPacketOutageEventsPerMinute", |
114 60000, // 60 seconds report interval. | 117 60000, // 60 seconds report interval. |
115 100), | 118 100), |
116 excess_buffer_delay_("WebRTC.Audio.AverageExcessBufferDelayMs", | 119 excess_buffer_delay_("WebRTC.Audio.AverageExcessBufferDelayMs", |
117 60000, // 60 seconds report interval. | 120 60000, // 60 seconds report interval. |
118 1000) { | 121 1000) { |
119 memset(waiting_times_, 0, kLenWaitingTimes * sizeof(waiting_times_[0])); | |
120 } | 122 } |
121 | 123 |
124 StatisticsCalculator::~StatisticsCalculator() = default; | |
125 | |
122 void StatisticsCalculator::Reset() { | 126 void StatisticsCalculator::Reset() { |
123 preemptive_samples_ = 0; | 127 preemptive_samples_ = 0; |
124 accelerate_samples_ = 0; | 128 accelerate_samples_ = 0; |
125 added_zero_samples_ = 0; | 129 added_zero_samples_ = 0; |
126 expanded_speech_samples_ = 0; | 130 expanded_speech_samples_ = 0; |
127 expanded_noise_samples_ = 0; | 131 expanded_noise_samples_ = 0; |
128 secondary_decoded_samples_ = 0; | 132 secondary_decoded_samples_ = 0; |
133 waiting_times_.clear(); | |
129 } | 134 } |
130 | 135 |
131 void StatisticsCalculator::ResetMcu() { | 136 void StatisticsCalculator::ResetMcu() { |
132 discarded_packets_ = 0; | 137 discarded_packets_ = 0; |
133 lost_timestamps_ = 0; | 138 lost_timestamps_ = 0; |
134 timestamps_since_last_report_ = 0; | 139 timestamps_since_last_report_ = 0; |
135 } | 140 } |
136 | 141 |
137 void StatisticsCalculator::ResetWaitingTimeStatistics() { | |
138 memset(waiting_times_, 0, kLenWaitingTimes * sizeof(waiting_times_[0])); | |
139 len_waiting_times_ = 0; | |
140 next_waiting_time_index_ = 0; | |
141 } | |
142 | |
143 void StatisticsCalculator::ExpandedVoiceSamples(int num_samples) { | 142 void StatisticsCalculator::ExpandedVoiceSamples(int num_samples) { |
144 expanded_speech_samples_ += num_samples; | 143 expanded_speech_samples_ += num_samples; |
145 } | 144 } |
146 | 145 |
147 void StatisticsCalculator::ExpandedNoiseSamples(int num_samples) { | 146 void StatisticsCalculator::ExpandedNoiseSamples(int num_samples) { |
148 expanded_noise_samples_ += num_samples; | 147 expanded_noise_samples_ += num_samples; |
149 } | 148 } |
150 | 149 |
151 void StatisticsCalculator::PreemptiveExpandedSamples(int num_samples) { | 150 void StatisticsCalculator::PreemptiveExpandedSamples(int num_samples) { |
152 preemptive_samples_ += num_samples; | 151 preemptive_samples_ += num_samples; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
187 | 186 |
188 void StatisticsCalculator::LogDelayedPacketOutageEvent(int outage_duration_ms) { | 187 void StatisticsCalculator::LogDelayedPacketOutageEvent(int outage_duration_ms) { |
189 RTC_HISTOGRAM_COUNTS("WebRTC.Audio.DelayedPacketOutageEventMs", | 188 RTC_HISTOGRAM_COUNTS("WebRTC.Audio.DelayedPacketOutageEventMs", |
190 outage_duration_ms, 1 /* min */, 2000 /* max */, | 189 outage_duration_ms, 1 /* min */, 2000 /* max */, |
191 100 /* bucket count */); | 190 100 /* bucket count */); |
192 delayed_packet_outage_counter_.RegisterSample(); | 191 delayed_packet_outage_counter_.RegisterSample(); |
193 } | 192 } |
194 | 193 |
195 void StatisticsCalculator::StoreWaitingTime(int waiting_time_ms) { | 194 void StatisticsCalculator::StoreWaitingTime(int waiting_time_ms) { |
196 excess_buffer_delay_.RegisterSample(waiting_time_ms); | 195 excess_buffer_delay_.RegisterSample(waiting_time_ms); |
197 assert(next_waiting_time_index_ < kLenWaitingTimes); | 196 DCHECK_LE(waiting_times_.size(), kLenWaitingTimes); |
198 waiting_times_[next_waiting_time_index_] = waiting_time_ms; | 197 while (waiting_times_.size() >= kLenWaitingTimes) { |
199 next_waiting_time_index_++; | 198 // Erase first value. |
200 if (next_waiting_time_index_ >= kLenWaitingTimes) { | 199 waiting_times_.pop_front(); |
201 next_waiting_time_index_ = 0; | |
202 } | 200 } |
203 if (len_waiting_times_ < kLenWaitingTimes) { | 201 waiting_times_.push_back(waiting_time_ms); |
204 len_waiting_times_++; | |
205 } | |
206 } | 202 } |
207 | 203 |
208 void StatisticsCalculator::GetNetworkStatistics( | 204 void StatisticsCalculator::GetNetworkStatistics( |
209 int fs_hz, | 205 int fs_hz, |
210 int num_samples_in_buffers, | 206 int num_samples_in_buffers, |
211 int samples_per_packet, | 207 int samples_per_packet, |
212 const DelayManager& delay_manager, | 208 const DelayManager& delay_manager, |
213 const DecisionLogic& decision_logic, | 209 const DecisionLogic& decision_logic, |
214 NetEqNetworkStatistics *stats) { | 210 NetEqNetworkStatistics *stats) { |
215 if (fs_hz <= 0 || !stats) { | 211 if (fs_hz <= 0 || !stats) { |
(...skipping 29 matching lines...) Expand all Loading... | |
245 timestamps_since_last_report_); | 241 timestamps_since_last_report_); |
246 | 242 |
247 stats->speech_expand_rate = | 243 stats->speech_expand_rate = |
248 CalculateQ14Ratio(expanded_speech_samples_, | 244 CalculateQ14Ratio(expanded_speech_samples_, |
249 timestamps_since_last_report_); | 245 timestamps_since_last_report_); |
250 | 246 |
251 stats->secondary_decoded_rate = | 247 stats->secondary_decoded_rate = |
252 CalculateQ14Ratio(secondary_decoded_samples_, | 248 CalculateQ14Ratio(secondary_decoded_samples_, |
253 timestamps_since_last_report_); | 249 timestamps_since_last_report_); |
254 | 250 |
251 if (waiting_times_.size() == 0) { | |
252 stats->mean_waiting_time_ms = -1; | |
253 stats->median_waiting_time_ms = -1; | |
254 stats->min_waiting_time_ms = -1; | |
255 stats->max_waiting_time_ms = -1; | |
256 } else { | |
257 std::sort(waiting_times_.begin(), waiting_times_.end()); | |
258 // Find mid-point elements. If the size is odd, the two iterators | |
259 // |middle_left| and |middle_right| will both point to the middle element | |
260 // after these operations; if the size is even, they will point to the two | |
261 // neighboring elements at the middle of the list. | |
262 auto middle_left = waiting_times_.begin(); | |
263 std::advance(middle_left, (waiting_times_.size() - 1) / 2); | |
ivoc
2015/08/24 14:22:17
I think this can be simplified to:
int middle_left
minyue-webrtc
2015/08/24 15:02:54
+1
hlundin-webrtc
2015/08/24 15:27:50
Thanks! I had to use std::advance when I used std:
| |
264 auto middle_right = waiting_times_.rbegin(); | |
265 std::advance(middle_right, (waiting_times_.size() - 1) / 2); | |
266 // Calculate the average of the two. (Works also for odd sizes.) | |
267 stats->median_waiting_time_ms = (*middle_left + *middle_right) / 2; | |
268 stats->min_waiting_time_ms = waiting_times_.front(); | |
269 stats->max_waiting_time_ms = waiting_times_.back(); | |
270 double sum = 0; | |
271 for (auto time : waiting_times_) { | |
272 sum += time; | |
273 } | |
274 stats->mean_waiting_time_ms = static_cast<int>(sum / waiting_times_.size()); | |
275 } | |
276 | |
255 // Reset counters. | 277 // Reset counters. |
256 ResetMcu(); | 278 ResetMcu(); |
257 Reset(); | 279 Reset(); |
258 } | 280 } |
259 | 281 |
260 void StatisticsCalculator::WaitingTimes(std::vector<int>* waiting_times) { | |
261 if (!waiting_times) { | |
262 return; | |
263 } | |
264 waiting_times->assign(waiting_times_, waiting_times_ + len_waiting_times_); | |
265 ResetWaitingTimeStatistics(); | |
266 } | |
267 | |
268 uint16_t StatisticsCalculator::CalculateQ14Ratio(uint32_t numerator, | 282 uint16_t StatisticsCalculator::CalculateQ14Ratio(uint32_t numerator, |
269 uint32_t denominator) { | 283 uint32_t denominator) { |
270 if (numerator == 0) { | 284 if (numerator == 0) { |
271 return 0; | 285 return 0; |
272 } else if (numerator < denominator) { | 286 } else if (numerator < denominator) { |
273 // Ratio must be smaller than 1 in Q14. | 287 // Ratio must be smaller than 1 in Q14. |
274 assert((numerator << 14) / denominator < (1 << 14)); | 288 assert((numerator << 14) / denominator < (1 << 14)); |
275 return static_cast<uint16_t>((numerator << 14) / denominator); | 289 return static_cast<uint16_t>((numerator << 14) / denominator); |
276 } else { | 290 } else { |
277 // Will not produce a ratio larger than 1, since this is probably an error. | 291 // Will not produce a ratio larger than 1, since this is probably an error. |
278 return 1 << 14; | 292 return 1 << 14; |
279 } | 293 } |
280 } | 294 } |
281 | 295 |
282 } // namespace webrtc | 296 } // namespace webrtc |
OLD | NEW |