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 <iterator> | |
15 | 16 |
17 #include "webrtc/base/checks.h" | |
16 #include "webrtc/modules/audio_coding/neteq/decision_logic.h" | 18 #include "webrtc/modules/audio_coding/neteq/decision_logic.h" |
17 #include "webrtc/modules/audio_coding/neteq/delay_manager.h" | 19 #include "webrtc/modules/audio_coding/neteq/delay_manager.h" |
18 | 20 |
19 namespace webrtc { | 21 namespace webrtc { |
20 | 22 |
23 // Allocating the static const so that it can be passed by reference to DCHECK. | |
24 const size_t StatisticsCalculator::kLenWaitingTimes; | |
25 | |
21 StatisticsCalculator::StatisticsCalculator() | 26 StatisticsCalculator::StatisticsCalculator() |
22 : preemptive_samples_(0), | 27 : preemptive_samples_(0), |
23 accelerate_samples_(0), | 28 accelerate_samples_(0), |
24 added_zero_samples_(0), | 29 added_zero_samples_(0), |
25 expanded_speech_samples_(0), | 30 expanded_speech_samples_(0), |
26 expanded_noise_samples_(0), | 31 expanded_noise_samples_(0), |
27 discarded_packets_(0), | 32 discarded_packets_(0), |
28 lost_timestamps_(0), | 33 lost_timestamps_(0), |
29 timestamps_since_last_report_(0), | 34 timestamps_since_last_report_(0), |
30 len_waiting_times_(0), | |
31 next_waiting_time_index_(0), | |
32 secondary_decoded_samples_(0) { | 35 secondary_decoded_samples_(0) { |
33 memset(waiting_times_, 0, kLenWaitingTimes * sizeof(waiting_times_[0])); | |
34 } | 36 } |
35 | 37 |
38 StatisticsCalculator::~StatisticsCalculator() = default; | |
39 | |
36 void StatisticsCalculator::Reset() { | 40 void StatisticsCalculator::Reset() { |
37 preemptive_samples_ = 0; | 41 preemptive_samples_ = 0; |
38 accelerate_samples_ = 0; | 42 accelerate_samples_ = 0; |
39 added_zero_samples_ = 0; | 43 added_zero_samples_ = 0; |
40 expanded_speech_samples_ = 0; | 44 expanded_speech_samples_ = 0; |
41 expanded_noise_samples_ = 0; | 45 expanded_noise_samples_ = 0; |
42 secondary_decoded_samples_ = 0; | 46 secondary_decoded_samples_ = 0; |
47 waiting_times_.clear(); | |
43 } | 48 } |
44 | 49 |
45 void StatisticsCalculator::ResetMcu() { | 50 void StatisticsCalculator::ResetMcu() { |
46 discarded_packets_ = 0; | 51 discarded_packets_ = 0; |
47 lost_timestamps_ = 0; | 52 lost_timestamps_ = 0; |
48 timestamps_since_last_report_ = 0; | 53 timestamps_since_last_report_ = 0; |
49 } | 54 } |
50 | 55 |
51 void StatisticsCalculator::ResetWaitingTimeStatistics() { | |
52 memset(waiting_times_, 0, kLenWaitingTimes * sizeof(waiting_times_[0])); | |
53 len_waiting_times_ = 0; | |
54 next_waiting_time_index_ = 0; | |
55 } | |
56 | |
57 void StatisticsCalculator::ExpandedVoiceSamples(int num_samples) { | 56 void StatisticsCalculator::ExpandedVoiceSamples(int num_samples) { |
58 expanded_speech_samples_ += num_samples; | 57 expanded_speech_samples_ += num_samples; |
59 } | 58 } |
60 | 59 |
61 void StatisticsCalculator::ExpandedNoiseSamples(int num_samples) { | 60 void StatisticsCalculator::ExpandedNoiseSamples(int num_samples) { |
62 expanded_noise_samples_ += num_samples; | 61 expanded_noise_samples_ += num_samples; |
63 } | 62 } |
64 | 63 |
65 void StatisticsCalculator::PreemptiveExpandedSamples(int num_samples) { | 64 void StatisticsCalculator::PreemptiveExpandedSamples(int num_samples) { |
66 preemptive_samples_ += num_samples; | 65 preemptive_samples_ += num_samples; |
(...skipping 23 matching lines...) Expand all Loading... | |
90 timestamps_since_last_report_ = 0; | 89 timestamps_since_last_report_ = 0; |
91 discarded_packets_ = 0; | 90 discarded_packets_ = 0; |
92 } | 91 } |
93 } | 92 } |
94 | 93 |
95 void StatisticsCalculator::SecondaryDecodedSamples(int num_samples) { | 94 void StatisticsCalculator::SecondaryDecodedSamples(int num_samples) { |
96 secondary_decoded_samples_ += num_samples; | 95 secondary_decoded_samples_ += num_samples; |
97 } | 96 } |
98 | 97 |
99 void StatisticsCalculator::StoreWaitingTime(int waiting_time_ms) { | 98 void StatisticsCalculator::StoreWaitingTime(int waiting_time_ms) { |
100 assert(next_waiting_time_index_ < kLenWaitingTimes); | 99 DCHECK_LE(waiting_times_.size(), kLenWaitingTimes); |
101 waiting_times_[next_waiting_time_index_] = waiting_time_ms; | 100 while (waiting_times_.size() >= kLenWaitingTimes) { |
102 next_waiting_time_index_++; | 101 // Erase first value. |
103 if (next_waiting_time_index_ >= kLenWaitingTimes) { | 102 waiting_times_.pop_front(); |
minyue-webrtc
2015/08/19 11:21:52
Ok, I see the deletion according to age here.
| |
104 next_waiting_time_index_ = 0; | |
105 } | 103 } |
106 if (len_waiting_times_ < kLenWaitingTimes) { | 104 waiting_times_.push_back(waiting_time_ms); |
107 len_waiting_times_++; | |
108 } | |
109 } | 105 } |
110 | 106 |
111 void StatisticsCalculator::GetNetworkStatistics( | 107 void StatisticsCalculator::GetNetworkStatistics( |
112 int fs_hz, | 108 int fs_hz, |
113 int num_samples_in_buffers, | 109 int num_samples_in_buffers, |
114 int samples_per_packet, | 110 int samples_per_packet, |
115 const DelayManager& delay_manager, | 111 const DelayManager& delay_manager, |
116 const DecisionLogic& decision_logic, | 112 const DecisionLogic& decision_logic, |
117 NetEqNetworkStatistics *stats) { | 113 NetEqNetworkStatistics *stats) { |
118 if (fs_hz <= 0 || !stats) { | 114 if (fs_hz <= 0 || !stats) { |
(...skipping 29 matching lines...) Expand all Loading... | |
148 timestamps_since_last_report_); | 144 timestamps_since_last_report_); |
149 | 145 |
150 stats->speech_expand_rate = | 146 stats->speech_expand_rate = |
151 CalculateQ14Ratio(expanded_speech_samples_, | 147 CalculateQ14Ratio(expanded_speech_samples_, |
152 timestamps_since_last_report_); | 148 timestamps_since_last_report_); |
153 | 149 |
154 stats->secondary_decoded_rate = | 150 stats->secondary_decoded_rate = |
155 CalculateQ14Ratio(secondary_decoded_samples_, | 151 CalculateQ14Ratio(secondary_decoded_samples_, |
156 timestamps_since_last_report_); | 152 timestamps_since_last_report_); |
157 | 153 |
154 if (waiting_times_.size() == 0) { | |
155 stats->mean_waiting_time_ms = -1; | |
156 stats->median_waiting_time_ms = -1; | |
157 stats->min_waiting_time_ms = -1; | |
158 stats->max_waiting_time_ms = -1; | |
159 } else { | |
160 waiting_times_.sort(); | |
minyue-webrtc
2015/08/18 12:55:34
std::vector may be faster than std::list in sortin
hlundin-webrtc
2015/08/19 08:28:39
That won't work. The list is sorted in time order,
minyue-webrtc
2015/08/19 11:21:52
Acknowledged.
| |
161 // Find mid-point elements. If the size is odd, the two iterators | |
162 // |middle_left| and |middle_right| will both point to the middle element | |
163 // after these operations; if the size is even, they will point to the two | |
164 // neighboring elements at the middle of the list. | |
165 auto middle_left = waiting_times_.begin(); | |
166 std::advance(middle_left, (waiting_times_.size() - 1) / 2); | |
167 auto middle_right = waiting_times_.rbegin(); | |
168 std::advance(middle_right, (waiting_times_.size() - 1) / 2); | |
169 // Calculate the average of the two. (Works also for odd sizes.) | |
170 stats->median_waiting_time_ms = (*middle_left + *middle_right) / 2; | |
171 stats->min_waiting_time_ms = waiting_times_.front(); | |
172 stats->max_waiting_time_ms = waiting_times_.back(); | |
173 double sum = 0; | |
174 for (auto time : waiting_times_) { | |
175 sum += time; | |
minyue-webrtc
2015/08/18 12:55:34
can also sum when adding.
hlundin-webrtc
2015/08/19 08:28:39
I'm worried about numerical stability. We would ha
minyue-webrtc
2015/08/19 11:21:52
Acknowledged.
| |
176 } | |
177 stats->mean_waiting_time_ms = static_cast<int>(sum / waiting_times_.size()); | |
178 } | |
179 | |
158 // Reset counters. | 180 // Reset counters. |
159 ResetMcu(); | 181 ResetMcu(); |
160 Reset(); | 182 Reset(); |
161 } | 183 } |
162 | 184 |
163 void StatisticsCalculator::WaitingTimes(std::vector<int>* waiting_times) { | |
164 if (!waiting_times) { | |
165 return; | |
166 } | |
167 waiting_times->assign(waiting_times_, waiting_times_ + len_waiting_times_); | |
168 ResetWaitingTimeStatistics(); | |
169 } | |
170 | |
171 uint16_t StatisticsCalculator::CalculateQ14Ratio(uint32_t numerator, | 185 uint16_t StatisticsCalculator::CalculateQ14Ratio(uint32_t numerator, |
172 uint32_t denominator) { | 186 uint32_t denominator) { |
173 if (numerator == 0) { | 187 if (numerator == 0) { |
174 return 0; | 188 return 0; |
175 } else if (numerator < denominator) { | 189 } else if (numerator < denominator) { |
176 // Ratio must be smaller than 1 in Q14. | 190 // Ratio must be smaller than 1 in Q14. |
177 assert((numerator << 14) / denominator < (1 << 14)); | 191 assert((numerator << 14) / denominator < (1 << 14)); |
178 return static_cast<uint16_t>((numerator << 14) / denominator); | 192 return static_cast<uint16_t>((numerator << 14) / denominator); |
179 } else { | 193 } else { |
180 // Will not produce a ratio larger than 1, since this is probably an error. | 194 // Will not produce a ratio larger than 1, since this is probably an error. |
181 return 1 << 14; | 195 return 1 << 14; |
182 } | 196 } |
183 } | 197 } |
184 | 198 |
185 } // namespace webrtc | 199 } // namespace webrtc |
OLD | NEW |