| 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 | 15 |
| 16 #include "webrtc/base/safe_conversions.h" |
| 16 #include "webrtc/modules/audio_coding/neteq/decision_logic.h" | 17 #include "webrtc/modules/audio_coding/neteq/decision_logic.h" |
| 17 #include "webrtc/modules/audio_coding/neteq/delay_manager.h" | 18 #include "webrtc/modules/audio_coding/neteq/delay_manager.h" |
| 18 | 19 |
| 19 namespace webrtc { | 20 namespace webrtc { |
| 20 | 21 |
| 21 StatisticsCalculator::StatisticsCalculator() | 22 StatisticsCalculator::StatisticsCalculator() |
| 22 : preemptive_samples_(0), | 23 : preemptive_samples_(0), |
| 23 accelerate_samples_(0), | 24 accelerate_samples_(0), |
| 24 added_zero_samples_(0), | 25 added_zero_samples_(0), |
| 25 expanded_speech_samples_(0), | 26 expanded_speech_samples_(0), |
| (...skipping 21 matching lines...) Expand all Loading... |
| 47 lost_timestamps_ = 0; | 48 lost_timestamps_ = 0; |
| 48 timestamps_since_last_report_ = 0; | 49 timestamps_since_last_report_ = 0; |
| 49 } | 50 } |
| 50 | 51 |
| 51 void StatisticsCalculator::ResetWaitingTimeStatistics() { | 52 void StatisticsCalculator::ResetWaitingTimeStatistics() { |
| 52 memset(waiting_times_, 0, kLenWaitingTimes * sizeof(waiting_times_[0])); | 53 memset(waiting_times_, 0, kLenWaitingTimes * sizeof(waiting_times_[0])); |
| 53 len_waiting_times_ = 0; | 54 len_waiting_times_ = 0; |
| 54 next_waiting_time_index_ = 0; | 55 next_waiting_time_index_ = 0; |
| 55 } | 56 } |
| 56 | 57 |
| 57 void StatisticsCalculator::ExpandedVoiceSamples(int num_samples) { | 58 void StatisticsCalculator::ExpandedVoiceSamples(size_t num_samples) { |
| 58 expanded_speech_samples_ += num_samples; | 59 expanded_speech_samples_ += num_samples; |
| 59 } | 60 } |
| 60 | 61 |
| 61 void StatisticsCalculator::ExpandedNoiseSamples(int num_samples) { | 62 void StatisticsCalculator::ExpandedNoiseSamples(size_t num_samples) { |
| 62 expanded_noise_samples_ += num_samples; | 63 expanded_noise_samples_ += num_samples; |
| 63 } | 64 } |
| 64 | 65 |
| 65 void StatisticsCalculator::PreemptiveExpandedSamples(int num_samples) { | 66 void StatisticsCalculator::PreemptiveExpandedSamples(size_t num_samples) { |
| 66 preemptive_samples_ += num_samples; | 67 preemptive_samples_ += num_samples; |
| 67 } | 68 } |
| 68 | 69 |
| 69 void StatisticsCalculator::AcceleratedSamples(int num_samples) { | 70 void StatisticsCalculator::AcceleratedSamples(size_t num_samples) { |
| 70 accelerate_samples_ += num_samples; | 71 accelerate_samples_ += num_samples; |
| 71 } | 72 } |
| 72 | 73 |
| 73 void StatisticsCalculator::AddZeros(int num_samples) { | 74 void StatisticsCalculator::AddZeros(size_t num_samples) { |
| 74 added_zero_samples_ += num_samples; | 75 added_zero_samples_ += num_samples; |
| 75 } | 76 } |
| 76 | 77 |
| 77 void StatisticsCalculator::PacketsDiscarded(int num_packets) { | 78 void StatisticsCalculator::PacketsDiscarded(size_t num_packets) { |
| 78 discarded_packets_ += num_packets; | 79 discarded_packets_ += num_packets; |
| 79 } | 80 } |
| 80 | 81 |
| 81 void StatisticsCalculator::LostSamples(int num_samples) { | 82 void StatisticsCalculator::LostSamples(size_t num_samples) { |
| 82 lost_timestamps_ += num_samples; | 83 lost_timestamps_ += num_samples; |
| 83 } | 84 } |
| 84 | 85 |
| 85 void StatisticsCalculator::IncreaseCounter(int num_samples, int fs_hz) { | 86 void StatisticsCalculator::IncreaseCounter(size_t num_samples, int fs_hz) { |
| 86 timestamps_since_last_report_ += static_cast<uint32_t>(num_samples); | 87 timestamps_since_last_report_ += static_cast<uint32_t>(num_samples); |
| 87 if (timestamps_since_last_report_ > | 88 if (timestamps_since_last_report_ > |
| 88 static_cast<uint32_t>(fs_hz * kMaxReportPeriod)) { | 89 static_cast<uint32_t>(fs_hz * kMaxReportPeriod)) { |
| 89 lost_timestamps_ = 0; | 90 lost_timestamps_ = 0; |
| 90 timestamps_since_last_report_ = 0; | 91 timestamps_since_last_report_ = 0; |
| 91 discarded_packets_ = 0; | 92 discarded_packets_ = 0; |
| 92 } | 93 } |
| 93 } | 94 } |
| 94 | 95 |
| 95 void StatisticsCalculator::SecondaryDecodedSamples(int num_samples) { | 96 void StatisticsCalculator::SecondaryDecodedSamples(int num_samples) { |
| 96 secondary_decoded_samples_ += num_samples; | 97 secondary_decoded_samples_ += num_samples; |
| 97 } | 98 } |
| 98 | 99 |
| 99 void StatisticsCalculator::StoreWaitingTime(int waiting_time_ms) { | 100 void StatisticsCalculator::StoreWaitingTime(int waiting_time_ms) { |
| 100 assert(next_waiting_time_index_ < kLenWaitingTimes); | 101 assert(next_waiting_time_index_ < kLenWaitingTimes); |
| 101 waiting_times_[next_waiting_time_index_] = waiting_time_ms; | 102 waiting_times_[next_waiting_time_index_] = waiting_time_ms; |
| 102 next_waiting_time_index_++; | 103 next_waiting_time_index_++; |
| 103 if (next_waiting_time_index_ >= kLenWaitingTimes) { | 104 if (next_waiting_time_index_ >= kLenWaitingTimes) { |
| 104 next_waiting_time_index_ = 0; | 105 next_waiting_time_index_ = 0; |
| 105 } | 106 } |
| 106 if (len_waiting_times_ < kLenWaitingTimes) { | 107 if (len_waiting_times_ < kLenWaitingTimes) { |
| 107 len_waiting_times_++; | 108 len_waiting_times_++; |
| 108 } | 109 } |
| 109 } | 110 } |
| 110 | 111 |
| 111 void StatisticsCalculator::GetNetworkStatistics( | 112 void StatisticsCalculator::GetNetworkStatistics( |
| 112 int fs_hz, | 113 int fs_hz, |
| 113 int num_samples_in_buffers, | 114 size_t num_samples_in_buffers, |
| 114 int samples_per_packet, | 115 size_t samples_per_packet, |
| 115 const DelayManager& delay_manager, | 116 const DelayManager& delay_manager, |
| 116 const DecisionLogic& decision_logic, | 117 const DecisionLogic& decision_logic, |
| 117 NetEqNetworkStatistics *stats) { | 118 NetEqNetworkStatistics *stats) { |
| 118 if (fs_hz <= 0 || !stats) { | 119 if (fs_hz <= 0 || !stats) { |
| 119 assert(false); | 120 assert(false); |
| 120 return; | 121 return; |
| 121 } | 122 } |
| 122 | 123 |
| 123 stats->added_zero_samples = added_zero_samples_; | 124 stats->added_zero_samples = added_zero_samples_; |
| 124 stats->current_buffer_size_ms = | 125 stats->current_buffer_size_ms = |
| 125 static_cast<uint16_t>(num_samples_in_buffers * 1000 / fs_hz); | 126 static_cast<uint16_t>(num_samples_in_buffers * 1000 / fs_hz); |
| 126 const int ms_per_packet = decision_logic.packet_length_samples() / | 127 const int ms_per_packet = rtc::checked_cast<int>( |
| 127 (fs_hz / 1000); | 128 decision_logic.packet_length_samples() / (fs_hz / 1000)); |
| 128 stats->preferred_buffer_size_ms = (delay_manager.TargetLevel() >> 8) * | 129 stats->preferred_buffer_size_ms = (delay_manager.TargetLevel() >> 8) * |
| 129 ms_per_packet; | 130 ms_per_packet; |
| 130 stats->jitter_peaks_found = delay_manager.PeakFound(); | 131 stats->jitter_peaks_found = delay_manager.PeakFound(); |
| 131 stats->clockdrift_ppm = delay_manager.AverageIAT(); | 132 stats->clockdrift_ppm = delay_manager.AverageIAT(); |
| 132 | 133 |
| 133 stats->packet_loss_rate = | 134 stats->packet_loss_rate = |
| 134 CalculateQ14Ratio(lost_timestamps_, timestamps_since_last_report_); | 135 CalculateQ14Ratio(lost_timestamps_, timestamps_since_last_report_); |
| 135 | 136 |
| 136 const unsigned discarded_samples = discarded_packets_ * samples_per_packet; | 137 const size_t discarded_samples = discarded_packets_ * samples_per_packet; |
| 137 stats->packet_discard_rate = | 138 stats->packet_discard_rate = |
| 138 CalculateQ14Ratio(discarded_samples, timestamps_since_last_report_); | 139 CalculateQ14Ratio(discarded_samples, timestamps_since_last_report_); |
| 139 | 140 |
| 140 stats->accelerate_rate = | 141 stats->accelerate_rate = |
| 141 CalculateQ14Ratio(accelerate_samples_, timestamps_since_last_report_); | 142 CalculateQ14Ratio(accelerate_samples_, timestamps_since_last_report_); |
| 142 | 143 |
| 143 stats->preemptive_rate = | 144 stats->preemptive_rate = |
| 144 CalculateQ14Ratio(preemptive_samples_, timestamps_since_last_report_); | 145 CalculateQ14Ratio(preemptive_samples_, timestamps_since_last_report_); |
| 145 | 146 |
| 146 stats->expand_rate = | 147 stats->expand_rate = |
| (...skipping 14 matching lines...) Expand all Loading... |
| 161 } | 162 } |
| 162 | 163 |
| 163 void StatisticsCalculator::WaitingTimes(std::vector<int>* waiting_times) { | 164 void StatisticsCalculator::WaitingTimes(std::vector<int>* waiting_times) { |
| 164 if (!waiting_times) { | 165 if (!waiting_times) { |
| 165 return; | 166 return; |
| 166 } | 167 } |
| 167 waiting_times->assign(waiting_times_, waiting_times_ + len_waiting_times_); | 168 waiting_times->assign(waiting_times_, waiting_times_ + len_waiting_times_); |
| 168 ResetWaitingTimeStatistics(); | 169 ResetWaitingTimeStatistics(); |
| 169 } | 170 } |
| 170 | 171 |
| 171 uint16_t StatisticsCalculator::CalculateQ14Ratio(uint32_t numerator, | 172 uint16_t StatisticsCalculator::CalculateQ14Ratio(size_t numerator, |
| 172 uint32_t denominator) { | 173 uint32_t denominator) { |
| 173 if (numerator == 0) { | 174 if (numerator == 0) { |
| 174 return 0; | 175 return 0; |
| 175 } else if (numerator < denominator) { | 176 } else if (numerator < denominator) { |
| 176 // Ratio must be smaller than 1 in Q14. | 177 // Ratio must be smaller than 1 in Q14. |
| 177 assert((numerator << 14) / denominator < (1 << 14)); | 178 assert((numerator << 14) / denominator < (1 << 14)); |
| 178 return static_cast<uint16_t>((numerator << 14) / denominator); | 179 return static_cast<uint16_t>((numerator << 14) / denominator); |
| 179 } else { | 180 } else { |
| 180 // Will not produce a ratio larger than 1, since this is probably an error. | 181 // Will not produce a ratio larger than 1, since this is probably an error. |
| 181 return 1 << 14; | 182 return 1 << 14; |
| 182 } | 183 } |
| 183 } | 184 } |
| 184 | 185 |
| 185 } // namespace webrtc | 186 } // namespace webrtc |
| OLD | NEW |