OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2017 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 <limits> | 11 #include <limits> |
12 #include <memory> | 12 #include <memory> |
13 #include <numeric> | |
13 #include <vector> | 14 #include <vector> |
14 | 15 |
15 #include "webrtc/base/checks.h" | 16 #include "webrtc/base/checks.h" |
16 #include "webrtc/base/mod_ops.h" | 17 #include "webrtc/base/mod_ops.h" |
17 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" | 18 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" |
18 #include "webrtc/test/gmock.h" | 19 #include "webrtc/test/gmock.h" |
19 #include "webrtc/test/gtest.h" | 20 #include "webrtc/test/gtest.h" |
20 #include "webrtc/voice_engine/transport_feedback_packet_loss_tracker.h" | 21 #include "webrtc/voice_engine/transport_feedback_packet_loss_tracker.h" |
21 | 22 |
22 using webrtc::rtcp::TransportFeedback; | 23 using webrtc::rtcp::TransportFeedback; |
23 using testing::Return; | 24 using testing::Return; |
24 using testing::StrictMock; | 25 using testing::StrictMock; |
25 | 26 |
26 namespace webrtc { | 27 namespace webrtc { |
27 | 28 |
28 namespace { | 29 namespace { |
29 | 30 |
30 constexpr size_t kMaxConsecutiveOldReports = 4; | |
31 | |
32 // All tests are run multiple times with various baseline sequence number, | 31 // All tests are run multiple times with various baseline sequence number, |
33 // to weed out potential bugs with wrap-around handling. | 32 // to weed out potential bugs with wrap-around handling. |
34 constexpr uint16_t kBases[] = {0x0000, 0x3456, 0xc032, 0xfffe}; | 33 constexpr uint16_t kBases[] = {0x0000, 0x3456, 0xc032, 0xfffe}; |
35 | 34 |
35 void SendPackets(TransportFeedbackPacketLossTracker* tracker, | |
36 const std::vector<uint16_t>& seq_nums, | |
37 bool validate_all = true) { | |
38 for (uint16_t seq_num : seq_nums) { | |
39 tracker->OnPacketAdded(seq_num); | |
40 if (validate_all) { | |
41 tracker->Validate(); | |
42 } | |
43 } | |
44 | |
45 // We've either validated after each packet, or, for making sure the UT | |
46 // doesn't run too long, we might validate only at the end of the range. | |
47 if (!validate_all) { | |
48 tracker->Validate(); | |
49 } | |
50 } | |
51 | |
52 void SendPacketRange(TransportFeedbackPacketLossTracker* tracker, | |
53 uint16_t first_seq_num, | |
54 size_t num_of_seq_nums, | |
55 bool validate_all = true) { | |
56 std::vector<uint16_t> seq_nums(num_of_seq_nums); | |
57 std::iota(seq_nums.begin(), seq_nums.end(), first_seq_num); | |
58 SendPackets(tracker, seq_nums, validate_all); | |
59 } | |
60 | |
36 void AddTransportFeedbackAndValidate( | 61 void AddTransportFeedbackAndValidate( |
37 TransportFeedbackPacketLossTracker* tracker, | 62 TransportFeedbackPacketLossTracker* tracker, |
38 uint16_t base_sequence_num, | 63 uint16_t base_sequence_num, |
39 const std::vector<bool>& reception_status_vec) { | 64 const std::vector<bool>& reception_status_vec) { |
40 const int64_t kBaseTimeUs = 1234; // Irrelevant to this test. | 65 const int64_t kBaseTimeUs = 1234; // Irrelevant to this test. |
41 TransportFeedback test_feedback; | 66 TransportFeedback test_feedback; |
42 test_feedback.SetBase(base_sequence_num, kBaseTimeUs); | 67 test_feedback.SetBase(base_sequence_num, kBaseTimeUs); |
43 uint16_t sequence_num = base_sequence_num; | 68 uint16_t sequence_num = base_sequence_num; |
44 for (bool status : reception_status_vec) { | 69 for (bool status : reception_status_vec) { |
45 if (status) | 70 if (status) |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
100 TEST(TransportFeedbackPacketLossTrackerTest, EmptyWindow) { | 125 TEST(TransportFeedbackPacketLossTrackerTest, EmptyWindow) { |
101 std::unique_ptr<TransportFeedback> feedback; | 126 std::unique_ptr<TransportFeedback> feedback; |
102 TransportFeedbackPacketLossTracker tracker(10, 5, 5); | 127 TransportFeedbackPacketLossTracker tracker(10, 5, 5); |
103 | 128 |
104 // PLR and RPLR reported as unknown before reception of first feedback. | 129 // PLR and RPLR reported as unknown before reception of first feedback. |
105 ValidatePacketLossStatistics(tracker, | 130 ValidatePacketLossStatistics(tracker, |
106 rtc::Optional<float>(), | 131 rtc::Optional<float>(), |
107 rtc::Optional<float>()); | 132 rtc::Optional<float>()); |
108 } | 133 } |
109 | 134 |
135 // A feedback received for an empty window has no effect. | |
136 TEST(TransportFeedbackPacketLossTrackerTest, EmptyWindowFeedback) { | |
137 for (uint16_t base : kBases) { | |
138 std::unique_ptr<TransportFeedback> feedback; | |
139 TransportFeedbackPacketLossTracker tracker(3, 3, 2); | |
140 | |
141 // Feedback doesn't correspond to any packets - ignored. | |
142 AddTransportFeedbackAndValidate(&tracker, base, {true, false, true}); | |
143 ValidatePacketLossStatistics(tracker, | |
144 rtc::Optional<float>(), | |
145 rtc::Optional<float>()); | |
146 | |
147 // After the packets are transmitted, acking them would have an effect. | |
148 SendPacketRange(&tracker, base, 3); | |
149 AddTransportFeedbackAndValidate(&tracker, base, {true, false, true}); | |
150 ValidatePacketLossStatistics(tracker, 1.0 / 3.0, 0.5); | |
151 } | |
152 } | |
153 | |
110 // Sanity check on partially filled window. | 154 // Sanity check on partially filled window. |
111 TEST(TransportFeedbackPacketLossTrackerTest, PlrPartiallyFilledWindow) { | 155 TEST(TransportFeedbackPacketLossTrackerTest, PlrPartiallyFilledWindow) { |
112 for (uint16_t base : kBases) { | 156 for (uint16_t base : kBases) { |
113 TransportFeedbackPacketLossTracker tracker(10, 5, 4); | 157 TransportFeedbackPacketLossTracker tracker(10, 5, 4); |
114 | 158 |
115 // PLR unknown before minimum window size reached. | 159 // PLR unknown before minimum window size reached. |
116 // RPLR unknown before minimum pairs reached. | 160 // RPLR unknown before minimum pairs reached. |
117 // Expected window contents: [] -> [1001]. | 161 // Expected window contents: [] -> [1001]. |
118 AddTransportFeedbackAndValidate(&tracker, base, {true, false, false, true}); | 162 AddTransportFeedbackAndValidate(&tracker, base, {true, false, false, true}); |
119 ValidatePacketLossStatistics(tracker, | 163 ValidatePacketLossStatistics(tracker, |
120 rtc::Optional<float>(), | 164 rtc::Optional<float>(), |
121 rtc::Optional<float>()); | 165 rtc::Optional<float>()); |
122 } | 166 } |
123 } | 167 } |
124 | 168 |
125 // Sanity check on minimum filled window - PLR known, RPLR unknown. | 169 // Sanity check on minimum filled window - PLR known, RPLR unknown. |
126 TEST(TransportFeedbackPacketLossTrackerTest, PlrMinimumFilledWindow) { | 170 TEST(TransportFeedbackPacketLossTrackerTest, PlrMinimumFilledWindow) { |
127 for (uint16_t base : kBases) { | 171 for (uint16_t base : kBases) { |
128 TransportFeedbackPacketLossTracker tracker(10, 5, 5); | 172 TransportFeedbackPacketLossTracker tracker(10, 5, 5); |
129 | 173 |
130 // PLR correctly calculated after minimum window size reached. | 174 // PLR correctly calculated after minimum window size reached. |
131 // RPLR not necessarily known at that time (not if min-pairs not reached). | 175 // RPLR not necessarily known at that time (not if min-pairs not reached). |
132 // Expected window contents: [] -> [10011]. | 176 // Expected window contents: [] -> [10011]. |
177 SendPacketRange(&tracker, base, 5); | |
133 AddTransportFeedbackAndValidate(&tracker, base, | 178 AddTransportFeedbackAndValidate(&tracker, base, |
134 {true, false, false, true, true}); | 179 {true, false, false, true, true}); |
135 ValidatePacketLossStatistics(tracker, | 180 ValidatePacketLossStatistics(tracker, |
136 rtc::Optional<float>(2.0f / 5.0f), | 181 rtc::Optional<float>(2.0f / 5.0f), |
137 rtc::Optional<float>()); | 182 rtc::Optional<float>()); |
138 } | 183 } |
139 } | 184 } |
140 | 185 |
141 // Sanity check on minimum filled window - PLR unknown, RPLR known. | 186 // Sanity check on minimum filled window - PLR unknown, RPLR known. |
142 TEST(TransportFeedbackPacketLossTrackerTest, RplrMinimumFilledWindow) { | 187 TEST(TransportFeedbackPacketLossTrackerTest, RplrMinimumFilledWindow) { |
143 for (uint16_t base : kBases) { | 188 for (uint16_t base : kBases) { |
144 TransportFeedbackPacketLossTracker tracker(10, 6, 4); | 189 TransportFeedbackPacketLossTracker tracker(10, 6, 4); |
145 | 190 |
146 // RPLR correctly calculated after minimum pairs reached. | 191 // RPLR correctly calculated after minimum pairs reached. |
147 // PLR not necessarily known at that time (not if min window not reached). | 192 // PLR not necessarily known at that time (not if min window not reached). |
148 // Expected window contents: [] -> [10011]. | 193 // Expected window contents: [] -> [10011]. |
194 SendPacketRange(&tracker, base, 5); | |
149 AddTransportFeedbackAndValidate(&tracker, base, | 195 AddTransportFeedbackAndValidate(&tracker, base, |
150 {true, false, false, true, true}); | 196 {true, false, false, true, true}); |
151 ValidatePacketLossStatistics(tracker, | 197 ValidatePacketLossStatistics(tracker, |
152 rtc::Optional<float>(), | 198 rtc::Optional<float>(), |
153 rtc::Optional<float>(1.0f / 4.0f)); | 199 rtc::Optional<float>(1.0f / 4.0f)); |
154 } | 200 } |
155 } | 201 } |
156 | 202 |
157 // Additional reports update PLR and RPLR. | 203 // Additional reports update PLR and RPLR. |
158 TEST(TransportFeedbackPacketLossTrackerTest, ExtendWindow) { | 204 TEST(TransportFeedbackPacketLossTrackerTest, ExtendWindow) { |
159 for (uint16_t base : kBases) { | 205 for (uint16_t base : kBases) { |
160 TransportFeedbackPacketLossTracker tracker(20, 5, 5); | 206 TransportFeedbackPacketLossTracker tracker(20, 5, 5); |
161 | 207 |
208 SendPacketRange(&tracker, base, 25); | |
209 | |
162 // Expected window contents: [] -> [10011]. | 210 // Expected window contents: [] -> [10011]. |
163 AddTransportFeedbackAndValidate(&tracker, base, | 211 AddTransportFeedbackAndValidate(&tracker, base, |
164 {true, false, false, true, true}); | 212 {true, false, false, true, true}); |
165 ValidatePacketLossStatistics(tracker, | 213 ValidatePacketLossStatistics(tracker, |
166 rtc::Optional<float>(2.0f / 5.0f), | 214 rtc::Optional<float>(2.0f / 5.0f), |
167 rtc::Optional<float>()); | 215 rtc::Optional<float>()); |
168 | 216 |
169 // Expected window contents: [10011] -> [1001110101]. | 217 // Expected window contents: [10011] -> [1001110101]. |
170 AddTransportFeedbackAndValidate(&tracker, base + 5, | 218 AddTransportFeedbackAndValidate(&tracker, base + 5, |
171 {true, false, true, false, true}); | 219 {true, false, true, false, true}); |
172 ValidatePacketLossStatistics(tracker, 4.0f / 10.0f, 3.0f / 9.0f); | 220 ValidatePacketLossStatistics(tracker, 4.0f / 10.0f, 3.0f / 9.0f); |
173 | 221 |
174 // Expected window contents: [1001110101] -> [1001110101-GAP-10001]. | 222 // Expected window contents: [1001110101] -> [1001110101-GAP-10001]. |
175 AddTransportFeedbackAndValidate(&tracker, base + 20, | 223 AddTransportFeedbackAndValidate(&tracker, base + 20, |
176 {true, false, false, false, true}); | 224 {true, false, false, false, true}); |
177 ValidatePacketLossStatistics(tracker, 7.0f / 15.0f, 4.0f / 13.0f); | 225 ValidatePacketLossStatistics(tracker, 7.0f / 15.0f, 4.0f / 13.0f); |
178 } | 226 } |
179 } | 227 } |
180 | 228 |
181 // All packets correctly received. | 229 // Sanity - all packets correctly received. |
182 TEST(TransportFeedbackPacketLossTrackerTest, AllReceived) { | 230 TEST(TransportFeedbackPacketLossTrackerTest, AllReceived) { |
183 for (uint16_t base : kBases) { | 231 for (uint16_t base : kBases) { |
184 TransportFeedbackPacketLossTracker tracker(10, 5, 4); | 232 TransportFeedbackPacketLossTracker tracker(10, 5, 4); |
185 | 233 |
186 // PLR and RPLR correctly calculated after minimum window size reached. | 234 // PLR and RPLR correctly calculated after minimum window size reached. |
187 // Expected window contents: [] -> [11111]. | 235 // Expected window contents: [] -> [11111]. |
236 SendPacketRange(&tracker, base, 5); | |
188 AddTransportFeedbackAndValidate(&tracker, base, | 237 AddTransportFeedbackAndValidate(&tracker, base, |
189 {true, true, true, true, true}); | 238 {true, true, true, true, true}); |
190 ValidatePacketLossStatistics(tracker, 0.0f, 0.0f); | 239 ValidatePacketLossStatistics(tracker, 0.0f, 0.0f); |
191 } | 240 } |
192 } | 241 } |
193 | 242 |
194 // Repeated reports are ignored. | 243 // Repeated reports are ignored. |
195 TEST(TransportFeedbackPacketLossTrackerTest, ReportRepetition) { | 244 TEST(TransportFeedbackPacketLossTrackerTest, ReportRepetition) { |
196 for (uint16_t base : kBases) { | 245 for (uint16_t base : kBases) { |
197 TransportFeedbackPacketLossTracker tracker(10, 5, 4); | 246 TransportFeedbackPacketLossTracker tracker(10, 5, 4); |
198 | 247 |
248 SendPacketRange(&tracker, base, 5); | |
249 | |
199 // Expected window contents: [] -> [10011]. | 250 // Expected window contents: [] -> [10011]. |
200 AddTransportFeedbackAndValidate(&tracker, base, | 251 AddTransportFeedbackAndValidate(&tracker, base, |
201 {true, false, false, true, true}); | 252 {true, false, false, true, true}); |
202 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); | 253 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); |
203 | 254 |
204 // Repeat entire previous feedback | 255 // Repeat entire previous feedback |
205 // Expected window contents: [10011] -> [10011]. | 256 // Expected window contents: [10011] -> [10011]. |
206 AddTransportFeedbackAndValidate(&tracker, base, | 257 AddTransportFeedbackAndValidate(&tracker, base, |
207 {true, false, false, true, true}); | 258 {true, false, false, true, true}); |
208 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); | 259 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); |
209 } | 260 } |
210 } | 261 } |
211 | 262 |
212 // Report overlap. | 263 // Report overlap. |
213 TEST(TransportFeedbackPacketLossTrackerTest, ReportOverlap) { | 264 TEST(TransportFeedbackPacketLossTrackerTest, ReportOverlap) { |
214 for (uint16_t base : kBases) { | 265 for (uint16_t base : kBases) { |
215 TransportFeedbackPacketLossTracker tracker(10, 5, 1); | 266 TransportFeedbackPacketLossTracker tracker(10, 5, 1); |
216 | 267 |
268 SendPacketRange(&tracker, base, 15); | |
269 | |
217 // Expected window contents: [] -> [10011]. | 270 // Expected window contents: [] -> [10011]. |
218 AddTransportFeedbackAndValidate(&tracker, base, | 271 AddTransportFeedbackAndValidate(&tracker, base, |
219 {true, false, false, true, true}); | 272 {true, false, false, true, true}); |
220 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); | 273 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); |
221 | 274 |
222 // Expected window contents: [10011] -> [1001101]. | 275 // Expected window contents: [10011] -> [1001101]. |
223 AddTransportFeedbackAndValidate(&tracker, base + 3, | 276 AddTransportFeedbackAndValidate(&tracker, base + 3, |
224 {true, true, false, true}); | 277 {true, true, false, true}); |
225 ValidatePacketLossStatistics(tracker, 3.0f / 7.0f, 2.0f / 6.0f); | 278 ValidatePacketLossStatistics(tracker, 3.0f / 7.0f, 2.0f / 6.0f); |
226 } | 279 } |
227 } | 280 } |
228 | 281 |
229 // Report conflict. | 282 // Report conflict. |
230 TEST(TransportFeedbackPacketLossTrackerTest, ReportConflict) { | 283 TEST(TransportFeedbackPacketLossTrackerTest, ReportConflict) { |
231 for (uint16_t base : kBases) { | 284 for (uint16_t base : kBases) { |
232 TransportFeedbackPacketLossTracker tracker(10, 5, 4); | 285 TransportFeedbackPacketLossTracker tracker(10, 5, 4); |
233 | 286 |
287 SendPacketRange(&tracker, base, 15); | |
288 | |
234 // Expected window contents: [] -> [01001]. | 289 // Expected window contents: [] -> [01001]. |
235 AddTransportFeedbackAndValidate(&tracker, base, | 290 AddTransportFeedbackAndValidate(&tracker, base, |
236 {false, true, false, false, true}); | 291 {false, true, false, false, true}); |
237 ValidatePacketLossStatistics(tracker, 3.0f / 5.0f, 2.0f / 4.0f); | 292 ValidatePacketLossStatistics(tracker, 3.0f / 5.0f, 2.0f / 4.0f); |
238 | 293 |
239 // Expected window contents: [01001] -> [11101]. | 294 // Expected window contents: [01001] -> [11101]. |
240 // While false->true will be applied, true -> false will be ignored. | 295 // While false->true will be applied, true -> false will be ignored. |
241 AddTransportFeedbackAndValidate(&tracker, base, {true, false, true}); | 296 AddTransportFeedbackAndValidate(&tracker, base, {true, false, true}); |
242 ValidatePacketLossStatistics(tracker, 1.0f / 5.0f, 1.0f / 4.0f); | 297 ValidatePacketLossStatistics(tracker, 1.0f / 5.0f, 1.0f / 4.0f); |
243 } | 298 } |
244 } | 299 } |
245 | 300 |
246 // Skipped packets treated as unknown (not lost). | 301 // Skipped packets treated as unknown (not lost). |
247 TEST(TransportFeedbackPacketLossTrackerTest, SkippedPackets) { | 302 TEST(TransportFeedbackPacketLossTrackerTest, SkippedPackets) { |
248 for (uint16_t base : kBases) { | 303 for (uint16_t base : kBases) { |
249 TransportFeedbackPacketLossTracker tracker(10, 5, 1); | 304 TransportFeedbackPacketLossTracker tracker(10, 5, 1); |
250 | 305 |
306 SendPacketRange(&tracker, base, 200); | |
307 | |
251 // Expected window contents: [] -> [10011]. | 308 // Expected window contents: [] -> [10011]. |
252 AddTransportFeedbackAndValidate(&tracker, base, | 309 AddTransportFeedbackAndValidate(&tracker, base, |
253 {true, false, false, true, true}); | 310 {true, false, false, true, true}); |
254 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); | 311 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); |
255 | 312 |
256 // Expected window contents: [10011] -> [10011-GAP-101]. | 313 // Expected window contents: [10011] -> [10011-GAP-101]. |
257 AddTransportFeedbackAndValidate(&tracker, base + 100, {true, false, true}); | 314 AddTransportFeedbackAndValidate(&tracker, base + 100, {true, false, true}); |
258 ValidatePacketLossStatistics(tracker, 3.0f / 8.0f, 2.0f / 6.0f); | 315 ValidatePacketLossStatistics(tracker, 3.0f / 8.0f, 2.0f / 6.0f); |
259 } | 316 } |
260 } | 317 } |
261 | 318 |
262 // The window retain information up to the configured max-window-size, but | 319 // The window retain information up to the configured max-window-size, but |
263 // starts discarding after that. | 320 // starts discarding after that. (Sent packets are not counted.) |
264 TEST(TransportFeedbackPacketLossTrackerTest, MaxWindowSize) { | 321 TEST(TransportFeedbackPacketLossTrackerTest, MaxWindowSize) { |
265 for (uint16_t base : kBases) { | 322 for (uint16_t base : kBases) { |
266 TransportFeedbackPacketLossTracker tracker(10, 10, 1); | 323 TransportFeedbackPacketLossTracker tracker(10, 10, 1); |
267 | 324 |
325 SendPacketRange(&tracker, base, 200); | |
326 | |
268 // Up to max-window-size retained. | 327 // Up to max-window-size retained. |
269 // Expected window contents: [] -> [1010100001]. | 328 // Expected window contents: [] -> [1010100001]. |
270 AddTransportFeedbackAndValidate( | 329 AddTransportFeedbackAndValidate( |
271 &tracker, base, | 330 &tracker, base, |
272 {true, false, true, false, true, false, false, false, false, true}); | 331 {true, false, true, false, true, false, false, false, false, true}); |
273 ValidatePacketLossStatistics(tracker, 6.0f / 10.0f, 3.0f / 9.0f); | 332 ValidatePacketLossStatistics(tracker, 6.0f / 10.0f, 3.0f / 9.0f); |
274 | 333 |
275 // After max-window-size, older entries discarded to accommodate newer ones. | 334 // After max-window-size, older entries discarded to accommodate newer ones. |
276 // Expected window contents: [1010100001] -> [0000110111]. | 335 // Expected window contents: [1010100001] -> [0000110111]. |
277 AddTransportFeedbackAndValidate(&tracker, base + 10, | 336 AddTransportFeedbackAndValidate(&tracker, base + 10, |
278 {true, false, true, true, true}); | 337 {true, false, true, true, true}); |
279 ValidatePacketLossStatistics(tracker, 5.0f / 10.0f, 2.0f / 9.0f); | 338 ValidatePacketLossStatistics(tracker, 5.0f / 10.0f, 2.0f / 9.0f); |
280 } | 339 } |
281 } | 340 } |
282 | 341 |
283 // Inserting into the middle of a full window works correctly. | 342 // Inserting feedback into the middle of a full window works correctly. |
284 TEST(TransportFeedbackPacketLossTrackerTest, InsertIntoMiddle) { | 343 TEST(TransportFeedbackPacketLossTrackerTest, InsertIntoMiddle) { |
285 for (uint16_t base : kBases) { | 344 for (uint16_t base : kBases) { |
286 TransportFeedbackPacketLossTracker tracker(10, 5, 1); | 345 TransportFeedbackPacketLossTracker tracker(10, 5, 1); |
287 | 346 |
347 SendPacketRange(&tracker, base, 300); | |
348 | |
288 // Expected window contents: [] -> [10101]. | 349 // Expected window contents: [] -> [10101]. |
289 AddTransportFeedbackAndValidate(&tracker, base, | 350 AddTransportFeedbackAndValidate(&tracker, base, |
290 {true, false, true, false, true}); | 351 {true, false, true, false, true}); |
291 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 2.0f / 4.0f); | 352 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 2.0f / 4.0f); |
292 | 353 |
293 // Expected window contents: [10101] -> [10101-GAP-10001]. | 354 // Expected window contents: [10101] -> [10101-GAP-10001]. |
294 AddTransportFeedbackAndValidate(&tracker, base + 100, | 355 AddTransportFeedbackAndValidate(&tracker, base + 100, |
295 {true, false, false, false, true}); | 356 {true, false, false, false, true}); |
296 ValidatePacketLossStatistics(tracker, 5.0f / 10.0f, 3.0f / 8.0f); | 357 ValidatePacketLossStatistics(tracker, 5.0f / 10.0f, 3.0f / 8.0f); |
297 | 358 |
298 // Insert into the middle of this full window - it discards the older data. | 359 // Insert into the middle of this full window - it discards the older data. |
299 // Expected window contents: [10101-GAP-10001] -> [11111-GAP-10001]. | 360 // Expected window contents: [10101-GAP-10001] -> [11111-GAP-10001]. |
300 AddTransportFeedbackAndValidate(&tracker, base + 50, | 361 AddTransportFeedbackAndValidate(&tracker, base + 50, |
301 {true, true, true, true, true}); | 362 {true, true, true, true, true}); |
302 ValidatePacketLossStatistics(tracker, 3.0f / 10.0f, 1.0f / 8.0f); | 363 ValidatePacketLossStatistics(tracker, 3.0f / 10.0f, 1.0f / 8.0f); |
303 } | 364 } |
304 } | 365 } |
305 | 366 |
306 // Inserting into the middle of a full window works correctly. | 367 // Inserting feedback into the middle of a full window works correctly - can |
368 // complete two pairs. | |
307 TEST(TransportFeedbackPacketLossTrackerTest, InsertionCompletesTwoPairs) { | 369 TEST(TransportFeedbackPacketLossTrackerTest, InsertionCompletesTwoPairs) { |
308 for (uint16_t base : kBases) { | 370 for (uint16_t base : kBases) { |
309 TransportFeedbackPacketLossTracker tracker(15, 5, 1); | 371 TransportFeedbackPacketLossTracker tracker(15, 5, 1); |
310 | 372 |
373 SendPacketRange(&tracker, base, 300); | |
374 | |
311 // Expected window contents: [] -> [10111]. | 375 // Expected window contents: [] -> [10111]. |
312 AddTransportFeedbackAndValidate(&tracker, base, | 376 AddTransportFeedbackAndValidate(&tracker, base, |
313 {true, false, true, true, true}); | 377 {true, false, true, true, true}); |
314 ValidatePacketLossStatistics(tracker, 1.0f / 5.0f, 1.0f / 4.0f); | 378 ValidatePacketLossStatistics(tracker, 1.0f / 5.0f, 1.0f / 4.0f); |
315 | 379 |
316 // Expected window contents: [10111] -> [10111-GAP-10101]. | 380 // Expected window contents: [10111] -> [10111-GAP-10101]. |
317 AddTransportFeedbackAndValidate(&tracker, base + 7, | 381 AddTransportFeedbackAndValidate(&tracker, base + 7, |
318 {true, false, true, false, true}); | 382 {true, false, true, false, true}); |
319 ValidatePacketLossStatistics(tracker, 3.0f / 10.0f, 3.0f / 8.0f); | 383 ValidatePacketLossStatistics(tracker, 3.0f / 10.0f, 3.0f / 8.0f); |
320 | 384 |
321 // Insert in between, closing the gap completely. | 385 // Insert in between, closing the gap completely. |
322 // Expected window contents: [10111-GAP-10101] -> [101111010101]. | 386 // Expected window contents: [10111-GAP-10101] -> [101111010101]. |
323 AddTransportFeedbackAndValidate(&tracker, base + 5, {false, true}); | 387 AddTransportFeedbackAndValidate(&tracker, base + 5, {false, true}); |
324 ValidatePacketLossStatistics(tracker, 4.0f / 12.0f, 4.0f / 11.0f); | 388 ValidatePacketLossStatistics(tracker, 4.0f / 12.0f, 4.0f / 11.0f); |
325 } | 389 } |
326 } | 390 } |
327 | 391 |
328 // Entries in the second quadrant treated like those in the first. | 392 // The window can meaningfully hold up to 0x8000 SENT packetts (of which only |
329 // The sequence number is used in a looped manner. 0xFFFF is followed by 0x0000. | 393 // up to max-window acked messages will be kept and regarded). |
330 // In many tests, we divide the circle of sequence number into 4 quadrants, and | |
331 // verify the behavior of TransportFeedbackPacketLossTracker over them. | |
332 TEST(TransportFeedbackPacketLossTrackerTest, SecondQuadrant) { | 394 TEST(TransportFeedbackPacketLossTrackerTest, SecondQuadrant) { |
333 for (uint16_t base : kBases) { | 395 for (uint16_t base : kBases) { |
334 TransportFeedbackPacketLossTracker tracker(20, 5, 1); | 396 TransportFeedbackPacketLossTracker tracker(20, 5, 1); |
335 | 397 |
398 SendPacketRange(&tracker, base, 0x8000, false); | |
399 | |
336 // Expected window contents: [] -> [10011]. | 400 // Expected window contents: [] -> [10011]. |
337 AddTransportFeedbackAndValidate(&tracker, base, | 401 AddTransportFeedbackAndValidate(&tracker, base, |
338 {true, false, false, true, true}); | 402 {true, false, false, true, true}); |
339 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); | 403 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); |
340 | 404 |
341 // Window *does* get updated with inputs from quadrant #2. | 405 // Window *does* get updated with inputs from quadrant #2. |
342 // Expected window contents: [10011] -> [100111]. | 406 // Expected window contents: [10011] -> [100111]. |
343 AddTransportFeedbackAndValidate(&tracker, base + 0x4321, {true}); | 407 AddTransportFeedbackAndValidate(&tracker, base + 0x4321, {true}); |
344 ValidatePacketLossStatistics(tracker, 2.0f / 6.0f, 1.0f / 4.0f); | 408 ValidatePacketLossStatistics(tracker, 2.0f / 6.0f, 1.0f / 4.0f); |
345 | 409 |
346 // Correct recognition of quadrant #2: up to, but not including, base + | 410 // Correct recognition of quadrant #2: up to, but not including, base + |
347 // 0x8000 | 411 // 0x8000 |
348 // Expected window contents: [100111] -> [1001111]. | 412 // Expected window contents: [100111] -> [1001111]. |
349 AddTransportFeedbackAndValidate(&tracker, base + 0x7fff, {true}); | 413 AddTransportFeedbackAndValidate(&tracker, base + 0x7fff, {true}); |
350 ValidatePacketLossStatistics(tracker, 2.0f / 7.0f, 1.0f / 4.0f); | 414 ValidatePacketLossStatistics(tracker, 2.0f / 7.0f, 1.0f / 4.0f); |
351 } | 415 } |
352 } | 416 } |
353 | 417 |
354 // Insertion into the third quadrant moves the base of the window. | |
355 TEST(TransportFeedbackPacketLossTrackerTest, ThirdQuadrantMovesBase) { | |
356 for (uint16_t base : kBases) { | |
357 TransportFeedbackPacketLossTracker tracker(20, 5, 1); | |
358 | |
359 // Seed the test. | |
360 // Expected window contents: [] -> [1001101]. | |
361 AddTransportFeedbackAndValidate( | |
362 &tracker, base, {true, false, false, true, true, false, true}); | |
363 ValidatePacketLossStatistics(tracker, 3.0f / 7.0f, 2.0f / 6.0f); | |
364 | |
365 // Quadrant #3 begins at base + 0x8000. It triggers moving the window so | |
366 // that | |
367 // at least one (oldest) report shifts out of window. | |
368 // Expected window contents: [1001101] -> [101-GAP-1001]. | |
369 AddTransportFeedbackAndValidate(&tracker, base + 0x8000, | |
370 {true, false, false, true}); | |
371 ValidatePacketLossStatistics(tracker, 3.0f / 7.0f, 2.0f / 5.0f); | |
372 | |
373 // The base can move more than once, because the minimum quadrant-1 packets | |
374 // were dropped out of the window, and some remain. | |
375 // Expected window contents: [101-GAP-1001] -> [1-GAP-100111]. | |
376 AddTransportFeedbackAndValidate(&tracker, base + 0x8000 + 4, {true, true}); | |
377 ValidatePacketLossStatistics(tracker, 2.0f / 7.0f, 1.0f / 5.0f); | |
378 } | |
379 } | |
380 | |
381 // After the base has moved due to insertion into the third quadrant, it is | 418 // After the base has moved due to insertion into the third quadrant, it is |
382 // still possible to insert into the middle of the window and obtain the correct | 419 // still possible to get feedbacks in the middle of the window and obtain the |
383 // PLR and RPLR. Insertion into the middle before the max window size has been | 420 // correct PLR and RPLR. Insertion into the middle before the max window size |
384 // achieved does not cause older packets to be dropped. | 421 // has been achieved does not cause older packets to be dropped. |
385 TEST(TransportFeedbackPacketLossTrackerTest, InsertIntoMiddleAfterBaseMove) { | 422 TEST(TransportFeedbackPacketLossTrackerTest, InsertIntoMiddleAfterBaseMoved) { |
386 for (uint16_t base : kBases) { | 423 for (uint16_t base : kBases) { |
387 TransportFeedbackPacketLossTracker tracker(20, 5, 1); | 424 TransportFeedbackPacketLossTracker tracker(20, 5, 1); |
388 | 425 |
389 // Seed the test. | 426 SendPacketRange(&tracker, base, 20); |
427 SendPacketRange(&tracker, base + 0x5000, 20); | |
428 | |
390 // Expected window contents: [] -> [1001101]. | 429 // Expected window contents: [] -> [1001101]. |
391 AddTransportFeedbackAndValidate( | 430 AddTransportFeedbackAndValidate( |
392 &tracker, base, {true, false, false, true, true, false, true}); | 431 &tracker, base, {true, false, false, true, true, false, true}); |
393 ValidatePacketLossStatistics(tracker, 3.0f / 7.0f, 2.0f / 6.0f); | 432 ValidatePacketLossStatistics(tracker, 3.0f / 7.0f, 2.0f / 6.0f); |
394 | 433 |
395 // Expected window contents: [1001101] -> [101-GAP-1001]. | 434 // Expected window contents: [1001101] -> [101-GAP-1001]. |
435 SendPacketRange(&tracker, base + 0x8000, 4); | |
396 AddTransportFeedbackAndValidate(&tracker, base + 0x8000, | 436 AddTransportFeedbackAndValidate(&tracker, base + 0x8000, |
397 {true, false, false, true}); | 437 {true, false, false, true}); |
398 ValidatePacketLossStatistics(tracker, 3.0f / 7.0f, 2.0f / 5.0f); | 438 ValidatePacketLossStatistics(tracker, 3.0f / 7.0f, 2.0f / 5.0f); |
399 | 439 |
400 // Inserting into the middle still works after the base has shifted. | 440 // Inserting into the middle still works after the base has shifted. |
401 // Expected window contents: | 441 // Expected window contents: |
402 // [101-GAP-1001] -> [101-GAP-100101-GAP-1001] | 442 // [101-GAP-1001] -> [101-GAP-100101-GAP-1001] |
403 AddTransportFeedbackAndValidate(&tracker, base + 0x5000, | 443 AddTransportFeedbackAndValidate(&tracker, base + 0x5000, |
404 {true, false, false, true, false, true}); | 444 {true, false, false, true, false, true}); |
405 ValidatePacketLossStatistics(tracker, 6.0f / 13.0f, 4.0f / 10.0f); | 445 ValidatePacketLossStatistics(tracker, 6.0f / 13.0f, 4.0f / 10.0f); |
406 | 446 |
407 // The base can keep moving after inserting into the middle. | 447 // The base can keep moving after inserting into the middle. |
408 // Expected window contents: | 448 // Expected window contents: |
409 // [101-GAP-100101-GAP-1001] -> [1-GAP-100101-GAP-100111]. | 449 // [101-GAP-100101-GAP-1001] -> [1-GAP-100101-GAP-100111]. |
450 SendPacketRange(&tracker, base + 0x8000 + 4, 2); | |
410 AddTransportFeedbackAndValidate(&tracker, base + 0x8000 + 4, {true, true}); | 451 AddTransportFeedbackAndValidate(&tracker, base + 0x8000 + 4, {true, true}); |
411 ValidatePacketLossStatistics(tracker, 5.0f / 13.0f, 3.0f / 10.0f); | 452 ValidatePacketLossStatistics(tracker, 5.0f / 13.0f, 3.0f / 10.0f); |
412 } | 453 } |
413 } | 454 } |
414 | 455 |
415 // After moving the base of the window, the max window size is still observed. | 456 // After moving the base of the window, the max window size is still observed. |
416 TEST(TransportFeedbackPacketLossTrackerTest, ThirdQuadrantObservesMaxWindow) { | 457 TEST(TransportFeedbackPacketLossTrackerTest, MaxWindowObservedAfterBaseMoved) { |
417 for (uint16_t base : kBases) { | 458 for (uint16_t base : kBases) { |
418 TransportFeedbackPacketLossTracker tracker(15, 10, 1); | 459 TransportFeedbackPacketLossTracker tracker(15, 10, 1); |
419 | 460 |
420 // Expected window contents: [] -> [1001110101]. | 461 // Expected window contents: [] -> [1001110101]. |
462 SendPacketRange(&tracker, base, 10); | |
421 AddTransportFeedbackAndValidate( | 463 AddTransportFeedbackAndValidate( |
422 &tracker, base, | 464 &tracker, base, |
423 {true, false, false, true, true, true, false, true, false, true}); | 465 {true, false, false, true, true, true, false, true, false, true}); |
424 ValidatePacketLossStatistics(tracker, 4.0f / 10.0f, 3.0f / 9.0f); | 466 ValidatePacketLossStatistics(tracker, 4.0f / 10.0f, 3.0f / 9.0f); |
425 | 467 |
468 // Create gap (on both sides). | |
469 SendPacketRange(&tracker, base + 0x4000, 20); | |
470 | |
426 // Expected window contents: [1001110101] -> [1110101-GAP-101]. | 471 // Expected window contents: [1001110101] -> [1110101-GAP-101]. |
472 SendPacketRange(&tracker, base + 0x8000, 3); | |
427 AddTransportFeedbackAndValidate(&tracker, base + 0x8000, | 473 AddTransportFeedbackAndValidate(&tracker, base + 0x8000, |
428 {true, false, true}); | 474 {true, false, true}); |
429 ValidatePacketLossStatistics(tracker, 3.0f / 10.0f, 3.0f / 8.0f); | 475 ValidatePacketLossStatistics(tracker, 3.0f / 10.0f, 3.0f / 8.0f); |
430 | 476 |
431 // Push into middle until max window is reached. | 477 // Push into middle until max window is reached. The gap is NOT completed. |
432 // Expected window contents: | 478 // Expected window contents: |
433 // [1110101-GAP-101] -> [1110101-GAP-10001-GAP-101] | 479 // [1110101-GAP-101] -> [1110101-GAP-10001-GAP-101] |
434 AddTransportFeedbackAndValidate(&tracker, base + 0x4000, | 480 AddTransportFeedbackAndValidate(&tracker, base + 0x4000 + 2, |
435 {true, false, false, false, true}); | 481 {true, false, false, false, true}); |
436 ValidatePacketLossStatistics(tracker, 6.0f / 15.0f, 4.0f / 12.0f); | 482 ValidatePacketLossStatistics(tracker, 6.0f / 15.0f, 4.0f / 12.0f); |
437 | 483 |
438 // Pushing new packets into the middle would discard older packets. | 484 // Pushing new packets into the middle would discard older packets. |
439 // Expected window contents: | 485 // Expected window contents: |
440 // [1110101-GAP-10001-GAP-101] -> [0101-GAP-10001101-GAP-101] | 486 // [1110101-GAP-10001-GAP-101] -> [0101-GAP-10001101-GAP-101] |
441 AddTransportFeedbackAndValidate(&tracker, base + 0x4000 + 5, | 487 AddTransportFeedbackAndValidate(&tracker, base + 0x4000 + 2 + 5, |
442 {true, false, true}); | 488 {true, false, true}); |
443 ValidatePacketLossStatistics(tracker, 7.0f / 15.0f, 5.0f / 12.0f); | 489 ValidatePacketLossStatistics(tracker, 7.0f / 15.0f, 5.0f / 12.0f); |
444 } | 490 } |
445 } | 491 } |
446 | 492 |
447 // A new feedback in quadrant #3 might shift enough old feedbacks out of window, | 493 // A packet with a new enough sequence number might shift enough old feedbacks |
448 // that we'd go back to an unknown PLR and RPLR. | 494 // out window, that we'd go back to an unknown PLR and RPLR. |
449 TEST(TransportFeedbackPacketLossTrackerTest, QuadrantThreeMovedBaseMinWindow) { | 495 TEST(TransportFeedbackPacketLossTrackerTest, NewPacketMovesWindowBase) { |
450 for (uint16_t base : kBases) { | 496 for (uint16_t base : kBases) { |
451 TransportFeedbackPacketLossTracker tracker(20, 5, 1); | 497 TransportFeedbackPacketLossTracker tracker(20, 5, 3); |
498 | |
499 SendPacketRange(&tracker, base, 50); | |
500 SendPacketRange(&tracker, base + 0x4000 - 1, 6); // Gap | |
452 | 501 |
453 // Expected window contents: [] -> [1001110101]. | 502 // Expected window contents: [] -> [1001110101]. |
454 AddTransportFeedbackAndValidate( | 503 AddTransportFeedbackAndValidate( |
455 &tracker, base, | 504 &tracker, base, |
456 {true, false, false, true, true, true, false, true, false, true}); | 505 {true, false, false, true, true, true, false, true, false, true}); |
457 ValidatePacketLossStatistics(tracker, 4.0f / 10.0f, 3.0f / 9.0f); | 506 ValidatePacketLossStatistics(tracker, 4.0f / 10.0f, 3.0f / 9.0f); |
458 | 507 |
459 // A new feedback in quadrant #3 might shift enough old feedbacks out of | 508 // A new sent packet with a new enough sequence number could shift enough |
460 // window, that we'd go back to an unknown PLR and RPLR. This *doesn't* | 509 // acked packets out of window, that we'd go back to an unknown PLR |
461 // necessarily mean all of the old ones were discarded, though. | 510 // and RPLR. This *doesn't* // necessarily mean all of the old ones |
462 // Expected window contents: [1001110101] -> [01-GAP-11]. | 511 // were discarded, though. |
512 // Expected window contents: [1001110101] -> [01]. | |
513 SendPacketRange(&tracker, base + 0x8006, 2); | |
514 ValidatePacketLossStatistics(tracker, | |
515 rtc::Optional<float>(), // Still invalid. | |
516 rtc::Optional<float>()); | |
517 | |
518 // Even if those messages are acked, we'd still might be in unknown PLR | |
519 // and RPLR, because we might have shifted more packets out of the window | |
520 // than we have inserted. | |
521 // Expected window contents: [01] -> [01-GAP-11]. | |
463 AddTransportFeedbackAndValidate(&tracker, base + 0x8006, {true, true}); | 522 AddTransportFeedbackAndValidate(&tracker, base + 0x8006, {true, true}); |
464 ValidatePacketLossStatistics(tracker, | 523 ValidatePacketLossStatistics(tracker, |
465 rtc::Optional<float>(), // Still invalid. | 524 rtc::Optional<float>(), // Still invalid. |
466 rtc::Optional<float>(1.0f / 2.0f)); | 525 rtc::Optional<float>()); |
467 | 526 |
468 // Inserting in the middle shows that though some of the elements were | 527 // Inserting in the middle shows that though some of the elements were |
469 // ejected, some were retained. | 528 // ejected, some were retained. |
470 // Expected window contents: [01-GAP-11] -> [01-GAP-1001-GAP-11]. | 529 // Expected window contents: [01-GAP-11] -> [01-GAP-1001-GAP-11]. |
471 AddTransportFeedbackAndValidate(&tracker, base + 0x4000, | 530 AddTransportFeedbackAndValidate(&tracker, base + 0x4000, |
472 {true, false, false, true}); | 531 {true, false, false, true}); |
473 ValidatePacketLossStatistics(tracker, 3.0f / 8.0f, 2.0f / 5.0f); | 532 ValidatePacketLossStatistics(tracker, 3.0f / 8.0f, 2.0f / 5.0f); |
474 } | 533 } |
475 } | 534 } |
476 | 535 |
477 // Quadrant four reports ignored for up to kMaxConsecutiveOldReports times. | 536 // Sequence number gaps are not gaps in reception. However, gaps in reception |
478 TEST(TransportFeedbackPacketLossTrackerTest, QuadrantFourInitiallyIgnored) { | 537 // are still possible, if a packet which WAS sent on the stream is not acked. |
538 TEST(TransportFeedbackPacketLossTrackerTest, SanityGapsInSequenceNumbers) { | |
479 for (uint16_t base : kBases) { | 539 for (uint16_t base : kBases) { |
480 TransportFeedbackPacketLossTracker tracker(20, 5, 1); | 540 TransportFeedbackPacketLossTracker tracker(20, 5, 1); |
481 | 541 |
482 // Expected window contents: [] -> [10011]. | 542 SendPackets(&tracker, {base, base + 2, base + 4, base + 6, base + 8}); |
483 AddTransportFeedbackAndValidate(&tracker, base, | |
484 {true, false, false, true, true}); | |
485 | 543 |
486 // Feedbacks in quadrant #4 are discarded (up to kMaxConsecutiveOldReports | 544 // Gaps in sequence numbers not considered as gaps in window, because only |
487 // consecutive reports). | 545 // those sequence numbers which were associated with the stream count. |
488 // Expected window contents: [10011] -> [10011]. | 546 // Expected window contents: [] -> [11011]. |
489 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { | 547 AddTransportFeedbackAndValidate( |
490 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, {true, true}); | 548 // Note: Left packets belong to this stream, odd ones ignored. |
491 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); | 549 &tracker, base, {true, false, |
492 } | 550 true, false, |
551 false, false, | |
552 true, false, | |
553 true, true}); | |
554 ValidatePacketLossStatistics(tracker, 1.0f / 5.0f, 1.0f / 4.0f); | |
555 | |
556 // Create gap by sending [base + 10] but not acking it. | |
557 // Note: Acks for [base + 11] and [base + 13] ignored (other stream). | |
558 // Expected window contents: [11011] -> [11011-GAP-01]. | |
559 SendPackets(&tracker, {base + 10, base + 12, base + 14}); | |
560 AddTransportFeedbackAndValidate(&tracker, base + 11, | |
561 {false, false, false, true, true}); | |
562 ValidatePacketLossStatistics(tracker, 2.0f / 7.0f, 2.0f / 5.0f); | |
493 } | 563 } |
494 } | 564 } |
495 | 565 |
496 // Receiving a packet from quadrant #1 resets the counter for quadrant #4. | 566 // Sending a packet which is less than 0x8000 away from the baseline does |
497 TEST(TransportFeedbackPacketLossTrackerTest, QuadrantFourCounterResetByQ1) { | 567 // not move the window. |
568 TEST(TransportFeedbackPacketLossTrackerTest, UnackedInWindowDoesNotMoveWindow) { | |
498 for (uint16_t base : kBases) { | 569 for (uint16_t base : kBases) { |
499 TransportFeedbackPacketLossTracker tracker(20, 5, 1); | 570 TransportFeedbackPacketLossTracker tracker(5, 3, 1); |
500 | 571 |
501 // Expected window contents: [] -> [10011]. | 572 // Baseline - window has acked messages. |
573 // Expected window contents: [] -> [10101]. | |
574 SendPacketRange(&tracker, base, 5); | |
502 AddTransportFeedbackAndValidate(&tracker, base, | 575 AddTransportFeedbackAndValidate(&tracker, base, |
503 {true, false, false, true, true}); | 576 {true, false, true, false, true}); |
577 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 2.0f / 4.0f); | |
504 | 578 |
505 // Feedbacks in quadrant #4 are discarded (up to kMaxConsecutiveOldReports | 579 // Test - window not moved. |
506 // consecutive reports). | 580 // Expected window contents: [10101] -> [10101]. |
507 // Expected window contents: [10011] -> [10011]. | 581 SendPackets(&tracker, {base + 0x7fff}); |
508 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { | 582 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 2.0f / 4.0f); |
509 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, {true, true}); | |
510 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); | |
511 } | |
512 | |
513 // If we receive a feedback in quadrant #1, the above counter is reset. | |
514 // Expected window contents: [10011] -> [100111]. | |
515 AddTransportFeedbackAndValidate(&tracker, base + 5, {true}); | |
516 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { | |
517 // Note: though the feedback message reports three packets, it only gets | |
518 // counted once. | |
519 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, | |
520 {true, false, true}); | |
521 ValidatePacketLossStatistics(tracker, 2.0f / 6.0f, 1.0f / 5.0f); | |
522 } | |
523 | |
524 // The same is true for reports which create a gap - they still reset. | |
525 // Expected window contents: [10011] -> [100111-GAP-01]. | |
526 AddTransportFeedbackAndValidate(&tracker, base + 0x00ff, {false, true}); | |
527 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { | |
528 // Note: though the feedback message reports three packets, it only gets | |
529 // counted once. | |
530 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, | |
531 {true, false, true}); | |
532 ValidatePacketLossStatistics(tracker, 3.0f / 8.0f, 2.0f / 6.0f); | |
533 } | |
534 } | 583 } |
535 } | 584 } |
536 | 585 |
537 // Receiving a packet from quadrant #2 resets the counter for quadrant #4. | 586 // Sending a packet which is at least 0x8000 away from the baseline, but not |
538 TEST(TransportFeedbackPacketLossTrackerTest, QuadrantFourCounterResetByQ2) { | 587 // 0x8000 or more away from the newest packet in the window, moves the window, |
588 // but does not reset it. | |
minyue-webrtc
2017/02/17 11:09:15
it looks like _2 include _1, since if a packet tha
elad.alon_webrtc.org
2017/02/17 12:24:42
Please note the difference between baseline (oldes
| |
589 TEST(TransportFeedbackPacketLossTrackerTest, UnackedOutOfWindowMovesWindow_1) { | |
539 for (uint16_t base : kBases) { | 590 for (uint16_t base : kBases) { |
540 TransportFeedbackPacketLossTracker tracker(20, 5, 1); | 591 TransportFeedbackPacketLossTracker tracker(5, 3, 1); |
541 | 592 |
542 // Expected window contents: [] -> [10011]. | 593 // Baseline - window has acked messages. |
594 // Expected window contents: [] -> [10101]. | |
595 SendPacketRange(&tracker, base, 5); | |
543 AddTransportFeedbackAndValidate(&tracker, base, | 596 AddTransportFeedbackAndValidate(&tracker, base, |
544 {true, false, false, true, true}); | 597 {true, false, true, false, true}); |
598 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 2.0f / 4.0f); | |
545 | 599 |
546 // Feedbacks in quadrant #4 are discarded (up to kMaxConsecutiveOldReports | 600 // 0x8000 from baseline, but only 0x7ffc from newest - window moved. |
547 // consecutive reports). | 601 // Expected window contents: [10101] -> [0101]. |
548 // Expected window contents: [10011] -> [10011]. | 602 SendPackets(&tracker, {base + 0x8000}); |
549 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { | 603 ValidatePacketLossStatistics(tracker, 2.0f / 4.0f, 2.0f / 3.0f); |
550 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, {true, true}); | |
551 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); | |
552 } | |
553 | |
554 // If we receive a feedback in quadrant #2, the above counter is reset. | |
555 // Expected window contents: [10011] -> [10011-GAP-11]. | |
556 AddTransportFeedbackAndValidate(&tracker, base + 0x400f, {true, true}); | |
557 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { | |
558 // Note: though the feedback message reports three packets, it only gets | |
559 // counted once. | |
560 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, | |
561 {true, false, true}); | |
562 ValidatePacketLossStatistics(tracker, 2.0f / 7.0f, 1.0f / 5.0f); | |
563 } | |
564 } | 604 } |
565 } | 605 } |
566 | 606 |
567 // Receiving a packet from quadrant #3 resets the counter for quadrant #4. | 607 // Repeats previous test, but this time with the maximum distance from the |
568 TEST(TransportFeedbackPacketLossTrackerTest, QuadrantFourCounterResetByQ3) { | 608 // newest packet, that would still not trigger a reset. |
609 TEST(TransportFeedbackPacketLossTrackerTest, UnackedOutOfWindowMovesWindow_2) { | |
569 for (uint16_t base : kBases) { | 610 for (uint16_t base : kBases) { |
570 TransportFeedbackPacketLossTracker tracker(20, 5, 1); | 611 TransportFeedbackPacketLossTracker tracker(10, 2, 1); |
571 | 612 |
572 // Expected window contents: [] -> [1001110001]. | 613 // Baseline - window has acked messages. |
573 AddTransportFeedbackAndValidate( | 614 // Expected window contents: [] -> [1-GAP-10101]. |
minyue-webrtc
2017/02/17 11:09:15
This test may be made less complicated, how about
elad.alon_webrtc.org
2017/02/17 12:24:42
I think it would be easier to clarify this offline
minyue-webrtc
2017/02/20 12:49:06
let's do
| |
574 &tracker, base, | 615 SendPacketRange(&tracker, base, 1); |
575 {true, false, false, true, true, true, false, false, false, true}); | 616 SendPacketRange(&tracker, base + 0x7fff - 4, 5); |
617 AddTransportFeedbackAndValidate(&tracker, base, {true}); | |
618 AddTransportFeedbackAndValidate(&tracker, base + 0x7fff - 4, | |
619 {true, false, true, false, true}); | |
620 ValidatePacketLossStatistics(tracker, 2.0f / 6.0f, 2.0f / 5.0f); | |
576 | 621 |
577 // Feedbacks in quadrant #4 are discarded (up to kMaxConsecutiveOldReports | 622 // Sending a packet that is less than 0x8000 from the newest does not |
578 // consecutive reports). | 623 // reset the window, although it moves it. |
579 // Expected window contents: [1001110001] -> [1001110001]. | 624 // Expected window contents: [1-GAP-10101] -> [1]. |
580 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { | 625 SendPacketRange(&tracker, base + 0x7fff + 0x7fff, 1); |
581 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, {true, true}); | |
582 ValidatePacketLossStatistics(tracker, 5.0f / 10.0f, 2.0f / 9.0f); | |
583 } | |
584 | 626 |
585 // If we receive a feedback in quadrant #1, the above counter is reset. | 627 // The does not have enough data for R/PLR to be valid. |
586 // Expected window contents: [1001110001] -> [1110001-GAP-111]. | 628 ValidatePacketLossStatistics(tracker, |
587 AddTransportFeedbackAndValidate(&tracker, base + 0x8000, | 629 rtc::Optional<float>(), |
588 {true, true, true}); | 630 rtc::Optional<float>()); |
589 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { | 631 |
590 // Note: though the feedback message reports three packets, it only gets | 632 // Adding more data proves the window was not reset; it still had one |
minyue-webrtc
2017/02/17 11:09:15
proves -> to prove
elad.alon_webrtc.org
2017/02/17 12:24:42
I think it should be "proves". The action (singula
minyue-webrtc
2017/02/20 12:49:06
not grammar. I mean the sentence is to indicates t
elad.alon_webrtc.org
2017/02/27 13:18:05
Acknowledged.
| |
591 // counted once. | 633 // last acked datapoint saved when we sent the previous unacked packet. |
592 AddTransportFeedbackAndValidate(&tracker, base + 0xc000 + 10, | 634 // Expected window contents: [1] -> [11]. |
593 {true, false, true}); | 635 AddTransportFeedbackAndValidate(&tracker, base + 0x7fff + 0x7fff, {true}); |
594 ValidatePacketLossStatistics(tracker, 3.0f / 10.0f, 1.0f / 8.0f); | 636 ValidatePacketLossStatistics(tracker, 0, 0); |
595 } | |
596 } | 637 } |
597 } | 638 } |
598 | 639 |
599 // Quadrant four reports ignored for up to kMaxConsecutiveOldReports times. | 640 // The window is reset by the sending of a packet which is 0x8000 or more |
600 // After that, the window is reset. | 641 // away from the newest packet. |
601 TEST(TransportFeedbackPacketLossTrackerTest, QuadrantFourReset) { | 642 TEST(TransportFeedbackPacketLossTrackerTest, WindowResetByPacketsTooNew) { |
minyue-webrtc
2017/02/17 11:09:15
TooNew may not be good. how about WindowResetAfter
elad.alon_webrtc.org
2017/02/17 12:24:42
Done.
| |
602 for (uint16_t base : kBases) { | 643 for (uint16_t base : kBases) { |
603 TransportFeedbackPacketLossTracker tracker(20, 5, 1); | 644 TransportFeedbackPacketLossTracker tracker(10, 2, 1); |
604 | 645 |
605 // Expected window contents: [] -> [1001110001]. | 646 // Baseline - window has acked messages. |
606 AddTransportFeedbackAndValidate( | 647 // Expected window contents: [] -> [1-GAP-10101]. |
607 &tracker, base, | 648 SendPacketRange(&tracker, base, 1); |
608 {true, false, false, true, true, true, false, false, false, true}); | 649 SendPacketRange(&tracker, base + 0x7fff - 4, 5); |
650 AddTransportFeedbackAndValidate(&tracker, base, {true}); | |
651 AddTransportFeedbackAndValidate(&tracker, base + 0x7fff - 4, | |
652 {true, false, true, false, true}); | |
653 ValidatePacketLossStatistics(tracker, 2.0f / 6.0f, 2.0f / 5.0f); | |
609 | 654 |
610 // Sanity | 655 // Sent packet too new - the entire window is reset. |
611 ValidatePacketLossStatistics(tracker, 5.0f / 10.0f, 2.0f / 9.0f); | 656 // Expected window contents: [1-GAP-10101] -> []. |
657 SendPacketRange(&tracker, base + 0x7fff + 0x8000, 1); | |
658 ValidatePacketLossStatistics(tracker, | |
659 rtc::Optional<float>(), | |
660 rtc::Optional<float>()); | |
612 | 661 |
613 // The first kMaxConsecutiveOldReports quadrant #4 reports are ignored. | 662 // To show it was really reset, prove show that acking the sent packet |
614 // It doesn't matter that they consist of multiple packets - each report | 663 // still leaves us at unknown, because no acked (or unacked) packets were |
615 // is only counted once. | 664 // left in the window. |
616 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { | 665 // Expected window contents: [] -> [1]. |
617 // Expected window contents: [1001110001] -> [1001110001]. | 666 AddTransportFeedbackAndValidate(&tracker, base + 0x7fff + 0x8000, {true}); |
618 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, | 667 ValidatePacketLossStatistics(tracker, |
619 {true, true, false, true}); | 668 rtc::Optional<float>(), |
620 ValidatePacketLossStatistics(tracker, 5.0f / 10.0f, 2.0f / 9.0f); | 669 rtc::Optional<float>()); |
621 } | |
622 | |
623 // One additional feedback in quadrant #4 brings us over | |
624 // kMaxConsecutiveOldReports consecutive "old" reports, resetting the | |
625 // window. | |
626 // The new window is not completely empty - it's been seeded with the | |
627 // packets reported in the feedback that has triggered the reset. | |
628 // Note: The report doesn't have to be the same as the previous ones. | |
629 // Expected window contents: [1001110001] -> [10011]. | |
630 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, | |
631 {true, false, false, true, true}); | |
632 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); | |
633 } | 670 } |
634 } | 671 } |
635 | 672 |
636 // Feedbacks spanning multiple quadrant are treated correctly (Q1-Q2). | |
637 TEST(TransportFeedbackPacketLossTrackerTest, MultiQuadrantQ1Q2) { | |
638 for (uint16_t base : kBases) { | |
639 TransportFeedbackPacketLossTracker tracker(20, 5, 1); | |
640 | |
641 // Expected window contents: [] -> [10011]. | |
642 AddTransportFeedbackAndValidate(&tracker, base, | |
643 {true, false, false, true, true}); | |
644 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); | |
645 | |
646 // A feedback with entries in both quadrant #1 and #2 gets both counted: | |
647 // Expected window contents: [10011] -> [10011-GAP-1001]. | |
648 AddTransportFeedbackAndValidate(&tracker, base + 0x3ffe, | |
649 {true, false, false, true}); | |
650 ValidatePacketLossStatistics(tracker, 4.0f / 9.0f, 2.0f / 7.0f); | |
651 } | |
652 } | |
653 | |
654 // Feedbacks spanning multiple quadrant are treated correctly (Q2-Q3). | |
655 TEST(TransportFeedbackPacketLossTrackerTest, MultiQuadrantQ2Q3) { | |
656 for (uint16_t base : kBases) { | |
657 TransportFeedbackPacketLossTracker tracker(20, 5, 1); | |
658 | |
659 // Expected window contents: [] -> [1001100001]. | |
660 AddTransportFeedbackAndValidate( | |
661 &tracker, base, | |
662 {true, false, false, true, true, false, false, false, false, true}); | |
663 ValidatePacketLossStatistics(tracker, 6.0f / 10.0f, 2.0f / 9.0f); | |
664 | |
665 // A feedback with entries in both quadrant #2 and #3 gets both counted, | |
666 // but only those from #3 trigger throwing out old entries from quadrant #1: | |
667 // Expected window contents: [1001100001] -> [01100001-GAP-1001]. | |
668 AddTransportFeedbackAndValidate(&tracker, base + 0x7ffe, | |
669 {true, false, false, true}); | |
670 ValidatePacketLossStatistics(tracker, 7.0f / 12.0f, 3.0f / 10.0f); | |
671 } | |
672 } | |
673 | |
674 // Feedbacks spanning multiple quadrant are treated correctly (Q3-Q4). | |
675 TEST(TransportFeedbackPacketLossTrackerTest, MultiQuadrantQ3Q4) { | |
676 for (uint16_t base : kBases) { | |
677 TransportFeedbackPacketLossTracker tracker(20, 5, 1); | |
678 | |
679 // Expected window contents: [] -> [1001100001]. | |
680 AddTransportFeedbackAndValidate( | |
681 &tracker, base, | |
682 {true, false, false, true, true, false, false, false, false, true}); | |
683 ValidatePacketLossStatistics(tracker, 6.0f / 10.0f, 2.0f / 9.0f); | |
684 | |
685 // A feedback with entries in both quadrant #3 and #4 would have the entries | |
686 // from quadrant #3 shift enough quadrant #1 entries out of window, that | |
687 // by the time the #4 packets are examined, the moving baseline has made | |
688 // them into quadrant #3 packets. | |
689 // Expected window contents: [1001100001] -> [10011]. | |
690 AddTransportFeedbackAndValidate(&tracker, base + 0xbfff, | |
691 {true, false, false, true, true}); | |
692 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); | |
693 } | |
694 } | |
695 | |
696 } // namespace webrtc | 673 } // namespace webrtc |
OLD | NEW |