Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(55)

Side by Side Diff: webrtc/modules/audio_coding/neteq/statistics_calculator.cc

Issue 1296633002: NetEq/ACM: Refactor how packet waiting times are calculated (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Rebasing Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/modules/audio_coding/neteq/statistics_calculator.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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>
15 16
16 #include "webrtc/base/checks.h" 17 #include "webrtc/base/checks.h"
17 #include "webrtc/base/safe_conversions.h" 18 #include "webrtc/base/safe_conversions.h"
18 #include "webrtc/modules/audio_coding/neteq/decision_logic.h" 19 #include "webrtc/modules/audio_coding/neteq/decision_logic.h"
19 #include "webrtc/modules/audio_coding/neteq/delay_manager.h" 20 #include "webrtc/modules/audio_coding/neteq/delay_manager.h"
20 #include "webrtc/system_wrappers/interface/metrics.h" 21 #include "webrtc/system_wrappers/interface/metrics.h"
21 22
22 namespace webrtc { 23 namespace webrtc {
23 24
25 // Allocating the static const so that it can be passed by reference to DCHECK.
26 const size_t StatisticsCalculator::kLenWaitingTimes;
27
24 StatisticsCalculator::PeriodicUmaLogger::PeriodicUmaLogger( 28 StatisticsCalculator::PeriodicUmaLogger::PeriodicUmaLogger(
25 const std::string& uma_name, 29 const std::string& uma_name,
26 int report_interval_ms, 30 int report_interval_ms,
27 int max_value) 31 int max_value)
28 : uma_name_(uma_name), 32 : uma_name_(uma_name),
29 report_interval_ms_(report_interval_ms), 33 report_interval_ms_(report_interval_ms),
30 max_value_(max_value), 34 max_value_(max_value),
31 timer_(0) { 35 timer_(0) {
32 } 36 }
33 37
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 104
101 StatisticsCalculator::StatisticsCalculator() 105 StatisticsCalculator::StatisticsCalculator()
102 : preemptive_samples_(0), 106 : preemptive_samples_(0),
103 accelerate_samples_(0), 107 accelerate_samples_(0),
104 added_zero_samples_(0), 108 added_zero_samples_(0),
105 expanded_speech_samples_(0), 109 expanded_speech_samples_(0),
106 expanded_noise_samples_(0), 110 expanded_noise_samples_(0),
107 discarded_packets_(0), 111 discarded_packets_(0),
108 lost_timestamps_(0), 112 lost_timestamps_(0),
109 timestamps_since_last_report_(0), 113 timestamps_since_last_report_(0),
110 len_waiting_times_(0),
111 next_waiting_time_index_(0),
112 secondary_decoded_samples_(0), 114 secondary_decoded_samples_(0),
113 delayed_packet_outage_counter_( 115 delayed_packet_outage_counter_(
114 "WebRTC.Audio.DelayedPacketOutageEventsPerMinute", 116 "WebRTC.Audio.DelayedPacketOutageEventsPerMinute",
115 60000, // 60 seconds report interval. 117 60000, // 60 seconds report interval.
116 100), 118 100),
117 excess_buffer_delay_("WebRTC.Audio.AverageExcessBufferDelayMs", 119 excess_buffer_delay_("WebRTC.Audio.AverageExcessBufferDelayMs",
118 60000, // 60 seconds report interval. 120 60000, // 60 seconds report interval.
119 1000) { 121 1000) {
120 memset(waiting_times_, 0, kLenWaitingTimes * sizeof(waiting_times_[0]));
121 } 122 }
122 123
124 StatisticsCalculator::~StatisticsCalculator() = default;
125
123 void StatisticsCalculator::Reset() { 126 void StatisticsCalculator::Reset() {
124 preemptive_samples_ = 0; 127 preemptive_samples_ = 0;
125 accelerate_samples_ = 0; 128 accelerate_samples_ = 0;
126 added_zero_samples_ = 0; 129 added_zero_samples_ = 0;
127 expanded_speech_samples_ = 0; 130 expanded_speech_samples_ = 0;
128 expanded_noise_samples_ = 0; 131 expanded_noise_samples_ = 0;
129 secondary_decoded_samples_ = 0; 132 secondary_decoded_samples_ = 0;
133 waiting_times_.clear();
130 } 134 }
131 135
132 void StatisticsCalculator::ResetMcu() { 136 void StatisticsCalculator::ResetMcu() {
133 discarded_packets_ = 0; 137 discarded_packets_ = 0;
134 lost_timestamps_ = 0; 138 lost_timestamps_ = 0;
135 timestamps_since_last_report_ = 0; 139 timestamps_since_last_report_ = 0;
136 } 140 }
137 141
138 void StatisticsCalculator::ResetWaitingTimeStatistics() {
139 memset(waiting_times_, 0, kLenWaitingTimes * sizeof(waiting_times_[0]));
140 len_waiting_times_ = 0;
141 next_waiting_time_index_ = 0;
142 }
143
144 void StatisticsCalculator::ExpandedVoiceSamples(size_t num_samples) { 142 void StatisticsCalculator::ExpandedVoiceSamples(size_t num_samples) {
145 expanded_speech_samples_ += num_samples; 143 expanded_speech_samples_ += num_samples;
146 } 144 }
147 145
148 void StatisticsCalculator::ExpandedNoiseSamples(size_t num_samples) { 146 void StatisticsCalculator::ExpandedNoiseSamples(size_t num_samples) {
149 expanded_noise_samples_ += num_samples; 147 expanded_noise_samples_ += num_samples;
150 } 148 }
151 149
152 void StatisticsCalculator::PreemptiveExpandedSamples(size_t num_samples) { 150 void StatisticsCalculator::PreemptiveExpandedSamples(size_t num_samples) {
153 preemptive_samples_ += num_samples; 151 preemptive_samples_ += num_samples;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 187
190 void StatisticsCalculator::LogDelayedPacketOutageEvent(int outage_duration_ms) { 188 void StatisticsCalculator::LogDelayedPacketOutageEvent(int outage_duration_ms) {
191 RTC_HISTOGRAM_COUNTS("WebRTC.Audio.DelayedPacketOutageEventMs", 189 RTC_HISTOGRAM_COUNTS("WebRTC.Audio.DelayedPacketOutageEventMs",
192 outage_duration_ms, 1 /* min */, 2000 /* max */, 190 outage_duration_ms, 1 /* min */, 2000 /* max */,
193 100 /* bucket count */); 191 100 /* bucket count */);
194 delayed_packet_outage_counter_.RegisterSample(); 192 delayed_packet_outage_counter_.RegisterSample();
195 } 193 }
196 194
197 void StatisticsCalculator::StoreWaitingTime(int waiting_time_ms) { 195 void StatisticsCalculator::StoreWaitingTime(int waiting_time_ms) {
198 excess_buffer_delay_.RegisterSample(waiting_time_ms); 196 excess_buffer_delay_.RegisterSample(waiting_time_ms);
199 assert(next_waiting_time_index_ < kLenWaitingTimes); 197 DCHECK_LE(waiting_times_.size(), kLenWaitingTimes);
200 waiting_times_[next_waiting_time_index_] = waiting_time_ms; 198 while (waiting_times_.size() >= kLenWaitingTimes) {
Peter Kasting 2015/08/25 22:00:02 Drive-by nit: This would violate the Chromium styl
hlundin-webrtc 2015/08/27 11:51:54 Fixed in https://codereview.webrtc.org/1319953002/
201 next_waiting_time_index_++; 199 // Erase first value.
202 if (next_waiting_time_index_ >= kLenWaitingTimes) { 200 waiting_times_.pop_front();
203 next_waiting_time_index_ = 0;
204 } 201 }
205 if (len_waiting_times_ < kLenWaitingTimes) { 202 waiting_times_.push_back(waiting_time_ms);
206 len_waiting_times_++;
207 }
208 } 203 }
209 204
210 void StatisticsCalculator::GetNetworkStatistics( 205 void StatisticsCalculator::GetNetworkStatistics(
211 int fs_hz, 206 int fs_hz,
212 size_t num_samples_in_buffers, 207 size_t num_samples_in_buffers,
213 size_t samples_per_packet, 208 size_t samples_per_packet,
214 const DelayManager& delay_manager, 209 const DelayManager& delay_manager,
215 const DecisionLogic& decision_logic, 210 const DecisionLogic& decision_logic,
216 NetEqNetworkStatistics *stats) { 211 NetEqNetworkStatistics *stats) {
217 if (fs_hz <= 0 || !stats) { 212 if (fs_hz <= 0 || !stats) {
(...skipping 29 matching lines...) Expand all
247 timestamps_since_last_report_); 242 timestamps_since_last_report_);
248 243
249 stats->speech_expand_rate = 244 stats->speech_expand_rate =
250 CalculateQ14Ratio(expanded_speech_samples_, 245 CalculateQ14Ratio(expanded_speech_samples_,
251 timestamps_since_last_report_); 246 timestamps_since_last_report_);
252 247
253 stats->secondary_decoded_rate = 248 stats->secondary_decoded_rate =
254 CalculateQ14Ratio(secondary_decoded_samples_, 249 CalculateQ14Ratio(secondary_decoded_samples_,
255 timestamps_since_last_report_); 250 timestamps_since_last_report_);
256 251
252 if (waiting_times_.size() == 0) {
253 stats->mean_waiting_time_ms = -1;
254 stats->median_waiting_time_ms = -1;
255 stats->min_waiting_time_ms = -1;
256 stats->max_waiting_time_ms = -1;
257 } else {
258 std::sort(waiting_times_.begin(), waiting_times_.end());
259 // Find mid-point elements. If the size is odd, the two values
260 // |middle_left| and |middle_right| will both be the one middle element; if
261 // the size is even, they will be the the two neighboring elements at the
262 // middle of the list.
263 const int middle_left = waiting_times_[(waiting_times_.size() - 1) / 2];
264 const int middle_right = waiting_times_[waiting_times_.size() / 2];
265 // Calculate the average of the two. (Works also for odd sizes.)
266 stats->median_waiting_time_ms = (middle_left + middle_right) / 2;
267 stats->min_waiting_time_ms = waiting_times_.front();
268 stats->max_waiting_time_ms = waiting_times_.back();
269 double sum = 0;
270 for (auto time : waiting_times_) {
271 sum += time;
272 }
273 stats->mean_waiting_time_ms = static_cast<int>(sum / waiting_times_.size());
274 }
275
257 // Reset counters. 276 // Reset counters.
258 ResetMcu(); 277 ResetMcu();
259 Reset(); 278 Reset();
260 } 279 }
261 280
262 void StatisticsCalculator::WaitingTimes(std::vector<int>* waiting_times) {
263 if (!waiting_times) {
264 return;
265 }
266 waiting_times->assign(waiting_times_, waiting_times_ + len_waiting_times_);
267 ResetWaitingTimeStatistics();
268 }
269
270 uint16_t StatisticsCalculator::CalculateQ14Ratio(size_t numerator, 281 uint16_t StatisticsCalculator::CalculateQ14Ratio(size_t numerator,
271 uint32_t denominator) { 282 uint32_t denominator) {
272 if (numerator == 0) { 283 if (numerator == 0) {
273 return 0; 284 return 0;
274 } else if (numerator < denominator) { 285 } else if (numerator < denominator) {
275 // Ratio must be smaller than 1 in Q14. 286 // Ratio must be smaller than 1 in Q14.
276 assert((numerator << 14) / denominator < (1 << 14)); 287 assert((numerator << 14) / denominator < (1 << 14));
277 return static_cast<uint16_t>((numerator << 14) / denominator); 288 return static_cast<uint16_t>((numerator << 14) / denominator);
278 } else { 289 } else {
279 // Will not produce a ratio larger than 1, since this is probably an error. 290 // Will not produce a ratio larger than 1, since this is probably an error.
280 return 1 << 14; 291 return 1 << 14;
281 } 292 }
282 } 293 }
283 294
284 } // namespace webrtc 295 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/audio_coding/neteq/statistics_calculator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698