OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2015 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 |
(...skipping 11 matching lines...) Expand all Loading... | |
22 namespace testing { | 22 namespace testing { |
23 namespace bwe { | 23 namespace bwe { |
24 | 24 |
25 // With the assumption that packet loss is lower than 97%, the max gap | 25 // With the assumption that packet loss is lower than 97%, the max gap |
26 // between elements in the set is lower than 0x8000, hence we have a | 26 // between elements in the set is lower than 0x8000, hence we have a |
27 // total order in the set. For (x,y,z) subset of the LinkedSet, | 27 // total order in the set. For (x,y,z) subset of the LinkedSet, |
28 // (x<=y and y<=z) ==> x<=z so the set can be sorted. | 28 // (x<=y and y<=z) ==> x<=z so the set can be sorted. |
29 const int kSetCapacity = 1000; | 29 const int kSetCapacity = 1000; |
30 | 30 |
31 BweReceiver::BweReceiver(int flow_id) | 31 BweReceiver::BweReceiver(int flow_id) |
32 : flow_id_(flow_id), received_packets_(kSetCapacity) { | 32 : flow_id_(flow_id), received_packets_(kSetCapacity), loss_account() { |
33 } | |
34 | |
35 void BweSender::Pause() { | |
36 running_ = false; | |
37 bitrate_kbps_ = 0; | |
stefan-webrtc
2015/07/02 11:03:41
I'm not sure this is the right way to handle a Pau
magalhaesc
2015/07/02 17:06:18
Makes sense, it was set to zero since previously w
| |
38 } | |
39 | |
40 void BweSender::Resume() { | |
41 running_ = true; | |
42 bitrate_kbps_ = kMinBitrateKbps; | |
33 } | 43 } |
34 | 44 |
35 class NullBweSender : public BweSender { | 45 class NullBweSender : public BweSender { |
36 public: | 46 public: |
37 NullBweSender() {} | 47 NullBweSender() {} |
38 virtual ~NullBweSender() {} | 48 virtual ~NullBweSender() {} |
39 | 49 |
40 int GetFeedbackIntervalMs() const override { return 1000; } | 50 int GetFeedbackIntervalMs() const override { return 1000; } |
41 void GiveFeedback(const FeedbackPacket& feedback) override {} | 51 void GiveFeedback(const FeedbackPacket& feedback) override {} |
42 void OnPacketsSent(const Packets& packets) override {} | 52 void OnPacketsSent(const Packets& packets) override {} |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
90 return new NadaBweReceiver(flow_id); | 100 return new NadaBweReceiver(flow_id); |
91 case kTcpEstimator: | 101 case kTcpEstimator: |
92 return new TcpBweReceiver(flow_id); | 102 return new TcpBweReceiver(flow_id); |
93 case kNullEstimator: | 103 case kNullEstimator: |
94 return new BweReceiver(flow_id); | 104 return new BweReceiver(flow_id); |
95 } | 105 } |
96 assert(false); | 106 assert(false); |
97 return NULL; | 107 return NULL; |
98 } | 108 } |
99 | 109 |
100 float BweReceiver::GlobalPacketLossRatio() { | 110 // Take into account all LinkedSet content. |
111 void BweReceiver::UpdateLoss() { | |
112 loss_account.Add(LinkedSetPacketLossRatio()); | |
113 } | |
114 | |
115 void BweReceiver::ClearSet() { | |
116 received_packets_.Clear(); | |
117 } | |
118 | |
119 // Preserve 10% latest packets and update packet loss based on the oldest | |
120 // 90%, that will be removed. | |
121 void BweReceiver::RelieveSetAndUpdateLoss() { | |
122 // Compute Loss for the whole LinkedSet and updates loss_account_. | |
123 UpdateLoss(); | |
124 | |
125 std::vector<PacketIdentifierNode> buffer; | |
126 size_t num_preserved_elements = received_packets_.size() / 10; | |
127 | |
128 PacketNodeIt node_it = received_packets_.begin(); // Latest. | |
129 while (node_it != received_packets_.end() && num_preserved_elements-- > 0) { | |
130 buffer.push_back((*node_it)->copy()); | |
stefan-webrtc
2015/07/02 11:03:41
Just do buffer.push_back(*node_it). In fact, I thi
magalhaesc
2015/07/02 17:06:17
received_packets contains a list and a map, both h
| |
131 ++node_it; | |
132 } | |
133 | |
134 ClearSet(); | |
135 | |
136 // Reverse iteration to optimize insertion. | |
137 for (auto rit = buffer.rbegin(); rit != buffer.rend(); ++rit) { | |
138 received_packets_.Insert(*rit); | |
139 } | |
140 | |
141 // Compute Loss for the preserved elements | |
142 loss_account.Subtract(LinkedSetPacketLossRatio()); | |
143 } | |
144 | |
145 float BweReceiver::GlobalReceiverPacketLossRatio() { | |
146 UpdateLoss(); | |
147 return loss_account.LossRatio(); | |
148 } | |
149 | |
150 // This function considers at most kSetCapacity = 1000 packets. | |
151 LossAccount BweReceiver::LinkedSetPacketLossRatio() { | |
101 if (received_packets_.empty()) { | 152 if (received_packets_.empty()) { |
102 return 0.0f; | 153 return LossAccount(); |
103 } | 154 } |
104 // Possibly there are packets missing. | 155 |
105 const uint16_t kMaxGap = 1.5 * kSetCapacity; | 156 uint16_t oldest_seq_nb = received_packets_.OldestSeqNumber(); |
106 uint16_t min = received_packets_.find_min(); | 157 uint16_t newest_seq_nb = received_packets_.NewestSeqNumber(); |
stefan-webrtc
2015/07/02 11:03:41
nb -> num, it better matches other code in webrtc.
magalhaesc
2015/07/02 17:06:17
Done.
| |
107 uint16_t max = received_packets_.find_max(); | |
108 | 158 |
109 int gap; | 159 int gap; |
110 if (max - min < kMaxGap) { | 160 if (newest_seq_nb >= oldest_seq_nb) { |
111 gap = max - min + 1; | 161 gap = newest_seq_nb - oldest_seq_nb + 1; |
112 } else { // There was an overflow. | 162 } else { // There was an overflow. |
113 max = received_packets_.upper_bound(kMaxGap); | 163 gap = newest_seq_nb + (0xFFFF - oldest_seq_nb) + 2; |
114 min = received_packets_.lower_bound(0xFFFF - kMaxGap); | |
115 gap = max + (0xFFFF - min) + 2; | |
116 } | 164 } |
stefan-webrtc
2015/07/02 11:03:41
This code can be replaced with;
gap = static_cast<
magalhaesc
2015/07/02 17:06:18
Done.
| |
117 return static_cast<float>(received_packets_.size()) / gap; | 165 |
166 float set_loss_ratio = | |
167 static_cast<float>(gap - received_packets_.size()) / gap; | |
168 size_t set_received_packets = received_packets_.size(); | |
stefan-webrtc
2015/07/02 11:03:41
This variable can be defined on line 165 and used
magalhaesc
2015/07/02 17:06:17
Done.
| |
169 size_t set_total_packets = set_received_packets / (1.0f - set_loss_ratio); | |
stefan-webrtc
2015/07/02 11:03:41
This is a bit odd, and I would be worried that you
magalhaesc
2015/07/02 17:06:18
Yes, right. Gap is the total number of packets tha
| |
170 size_t set_lost_packets = set_total_packets - set_received_packets; | |
171 | |
172 return LossAccount(static_cast<uint32_t>(set_total_packets), | |
173 static_cast<uint32_t>(set_lost_packets)); | |
stefan-webrtc
2015/07/02 11:03:41
Why do you have to cast? Change the input types to
magalhaesc
2015/07/02 17:06:17
Done.
| |
174 } | |
175 | |
176 uint32_t BweReceiver::RecentKbps() { | |
177 return (rate_counter_.bits_per_second() + 500) / 1000; | |
118 } | 178 } |
119 | 179 |
120 // Go through a fixed time window of most recent packets received and | 180 // Go through a fixed time window of most recent packets received and |
121 // counts packets missing to obtain the packet loss ratio. If an unordered | 181 // counts packets missing to obtain the packet loss ratio. If an unordered |
122 // packet falls out of the timewindow it will be counted as missing. | 182 // packet falls out of the timewindow it will be counted as missing. |
123 // E.g.: for a timewindow covering 5 packets of the following arrival sequence | 183 // E.g.: for a timewindow covering 5 packets of the following arrival sequence |
124 // {10 7 9 5 6} 8 3 2 4 1, the output will be 1/6 (#8 is considered as missing). | 184 // {10 7 9 5 6} 8 3 2 4 1, the output will be 1/6 (#8 is considered as missing). |
125 float BweReceiver::RecentPacketLossRatio() { | 185 float BweReceiver::RecentPacketLossRatio() { |
126 if (received_packets_.empty()) { | 186 if (received_packets_.empty()) { |
127 return 0.0f; | 187 return 0.0f; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
172 map_[sequence_number] = list_.begin(); | 232 map_[sequence_number] = list_.begin(); |
173 } | 233 } |
174 } else { | 234 } else { |
175 if (size() == capacity_) { | 235 if (size() == capacity_) { |
176 RemoveTail(); | 236 RemoveTail(); |
177 } | 237 } |
178 UpdateHead(new PacketIdentifierNode(sequence_number, send_time_ms, | 238 UpdateHead(new PacketIdentifierNode(sequence_number, send_time_ms, |
179 arrival_time_ms, payload_size)); | 239 arrival_time_ms, payload_size)); |
180 } | 240 } |
181 } | 241 } |
242 | |
243 void LinkedSet::Insert(PacketIdentifierNode packet_identifier) { | |
244 Insert(packet_identifier.sequence_number, packet_identifier.send_time_ms, | |
245 packet_identifier.arrival_time_ms, packet_identifier.payload_size); | |
246 } | |
247 | |
182 void LinkedSet::RemoveTail() { | 248 void LinkedSet::RemoveTail() { |
183 map_.erase(list_.back()->sequence_number); | 249 map_.erase(list_.back()->sequence_number); |
184 list_.pop_back(); | 250 list_.pop_back(); |
185 } | 251 } |
186 void LinkedSet::UpdateHead(PacketIdentifierNode* new_head) { | 252 void LinkedSet::UpdateHead(PacketIdentifierNode* new_head) { |
187 list_.push_front(new_head); | 253 list_.push_front(new_head); |
188 map_[new_head->sequence_number] = list_.begin(); | 254 map_[new_head->sequence_number] = list_.begin(); |
189 } | 255 } |
190 | 256 |
257 uint16_t LinkedSet::OldestSeqNumber() { | |
258 if (IsNewerSequenceNumber(Max(), Min()) || Max() == Min()) { | |
259 return Min(); // An empty set will return Max = Min = 0. | |
260 } else { // There was an overflow. | |
261 return map_.lower_bound(0x8000)->first; | |
262 } | |
263 } | |
264 | |
265 uint16_t LinkedSet::NewestSeqNumber() { | |
266 if (IsNewerSequenceNumber(Max(), Min()) || Max() == Min()) { | |
267 return Max(); // An empty set will return Max = Min = 0. | |
268 } else { // There was an overflow. | |
269 return (--map_.lower_bound(0x8000))->first; | |
270 } | |
271 } | |
272 | |
273 PacketIdentifierNode PacketIdentifierNode::copy() { | |
274 return PacketIdentifierNode(sequence_number, send_time_ms, arrival_time_ms, | |
275 payload_size); | |
276 } | |
277 | |
278 void LossAccount::Add(LossAccount addend) { | |
279 num_total += addend.num_total; | |
280 num_lost += addend.num_lost; | |
281 } | |
282 void LossAccount::Subtract(LossAccount subtrahend) { | |
283 num_total -= subtrahend.num_total; | |
284 num_lost -= subtrahend.num_lost; | |
285 } | |
286 | |
287 float LossAccount::LossRatio() { | |
288 return static_cast<float>(num_lost) / num_total; | |
289 } | |
290 | |
191 } // namespace bwe | 291 } // namespace bwe |
192 } // namespace testing | 292 } // namespace testing |
193 } // namespace webrtc | 293 } // namespace webrtc |
OLD | NEW |