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

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: 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
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 <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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698