Chromium Code Reviews| 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 |