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 |
(...skipping 28 matching lines...) Expand all Loading... |
39 const std::vector<bool>& reception_status_vec) { | 39 const std::vector<bool>& reception_status_vec) { |
40 const int64_t kBaseTimeUs = 1234; // Irrelevant to this test. | 40 const int64_t kBaseTimeUs = 1234; // Irrelevant to this test. |
41 TransportFeedback test_feedback; | 41 TransportFeedback test_feedback; |
42 test_feedback.SetBase(base_sequence_num, kBaseTimeUs); | 42 test_feedback.SetBase(base_sequence_num, kBaseTimeUs); |
43 uint16_t sequence_num = base_sequence_num; | 43 uint16_t sequence_num = base_sequence_num; |
44 for (bool status : reception_status_vec) { | 44 for (bool status : reception_status_vec) { |
45 if (status) | 45 if (status) |
46 test_feedback.AddReceivedPacket(sequence_num, kBaseTimeUs); | 46 test_feedback.AddReceivedPacket(sequence_num, kBaseTimeUs); |
47 ++sequence_num; | 47 ++sequence_num; |
48 } | 48 } |
| 49 |
| 50 // TransportFeedback imposes some limitations on what constitutes a legal |
| 51 // status vector. For instance, the vector it cannot terminate in a lost |
| 52 // packet. Make sure all limitations are abided by. |
| 53 RTC_CHECK_EQ(base_sequence_num, test_feedback.GetBaseSequence()); |
| 54 const auto& vec = test_feedback.GetStatusVector(); |
| 55 RTC_CHECK_EQ(reception_status_vec.size(), vec.size()); |
| 56 for (size_t i = 0; i < reception_status_vec.size(); i++) { |
| 57 RTC_CHECK_EQ(reception_status_vec[i], |
| 58 vec[i] != TransportFeedback::StatusSymbol::kNotReceived); |
| 59 } |
| 60 |
49 tracker->OnReceivedTransportFeedback(test_feedback); | 61 tracker->OnReceivedTransportFeedback(test_feedback); |
50 tracker->Validate(); | 62 tracker->Validate(); |
51 } | 63 } |
52 | 64 |
| 65 // Checks that validty is as expected. If valid, checks also that |
| 66 // value is as expected. |
| 67 void ValidatePacketLossStatistics( |
| 68 const TransportFeedbackPacketLossTracker& tracker, |
| 69 rtc::Optional<float> expected_plr, |
| 70 rtc::Optional<float> expected_rplr) { |
| 71 // Comparing the rtc::Optional<float> directly would have given concise code, |
| 72 // but less readable error messages. |
| 73 rtc::Optional<float> plr = tracker.GetPacketLossRate(); |
| 74 EXPECT_EQ(bool(expected_plr), bool(plr)); |
| 75 if (expected_plr && plr) { |
| 76 EXPECT_EQ(*expected_plr, *plr); |
| 77 } |
| 78 |
| 79 rtc::Optional<float> rplr = tracker.GetRecoverablePacketLossRate(); |
| 80 EXPECT_EQ(bool(expected_rplr), bool(rplr)); |
| 81 if (expected_rplr && rplr) { |
| 82 EXPECT_EQ(*expected_rplr, *rplr); |
| 83 } |
| 84 } |
| 85 |
| 86 // Convenience function for when both are valid, and explicitly stating |
| 87 // the rtc::Optional<float> constructor is just cumbersome. |
| 88 void ValidatePacketLossStatistics( |
| 89 const TransportFeedbackPacketLossTracker& tracker, |
| 90 float expected_plr, |
| 91 float expected_rplr) { |
| 92 ValidatePacketLossStatistics(tracker, |
| 93 rtc::Optional<float>(expected_plr), |
| 94 rtc::Optional<float>(expected_rplr)); |
| 95 } |
| 96 |
53 } // namespace | 97 } // namespace |
54 | 98 |
55 // Sanity check on an empty window. | 99 // Sanity check on an empty window. |
56 TEST(TransportFeedbackPacketLossTrackerTest, EmptyWindow) { | 100 TEST(TransportFeedbackPacketLossTrackerTest, EmptyWindow) { |
57 std::unique_ptr<TransportFeedback> feedback; | 101 std::unique_ptr<TransportFeedback> feedback; |
58 float plr = 0.0f; // Packet-loss-rate | 102 TransportFeedbackPacketLossTracker tracker(10, 5, 5); |
59 float cplr = 0.0f; // Consecutive-packet-loss-rate | 103 |
60 | 104 // PLR and RPLR reported as unknown before reception of first feedback. |
61 TransportFeedbackPacketLossTracker tracker(5, 10); | 105 ValidatePacketLossStatistics(tracker, |
62 | 106 rtc::Optional<float>(), |
63 // PLR and CPLR reported as unknown before reception of first feedback. | 107 rtc::Optional<float>()); |
64 EXPECT_FALSE(tracker.GetPacketLossRates(&plr, &cplr)); | |
65 } | 108 } |
66 | 109 |
67 // Sanity check on partially filled window. | 110 // Sanity check on partially filled window. |
68 TEST(TransportFeedbackPacketLossTrackerTest, PartiallyFilledWindow) { | 111 TEST(TransportFeedbackPacketLossTrackerTest, PlrPartiallyFilledWindow) { |
69 for (uint16_t base : kBases) { | 112 for (uint16_t base : kBases) { |
70 float plr = 0.0f; // Packet-loss-rate | 113 TransportFeedbackPacketLossTracker tracker(10, 5, 4); |
71 float cplr = 0.0f; // Consecutive-packet-loss-rate | 114 |
72 TransportFeedbackPacketLossTracker tracker(5, 10); | 115 // PLR unknown before minimum window size reached. |
73 | 116 // RPLR unknown before minimum pairs reached. |
74 // PLR and CPLR reported as unknown before minimum window size reached. | |
75 // Expected window contents: [] -> [1001]. | 117 // Expected window contents: [] -> [1001]. |
76 AddTransportFeedbackAndValidate(&tracker, base, {true, false, false, true}); | 118 AddTransportFeedbackAndValidate(&tracker, base, {true, false, false, true}); |
77 EXPECT_FALSE(tracker.GetPacketLossRates(&plr, &cplr)); | 119 ValidatePacketLossStatistics(tracker, |
78 } | 120 rtc::Optional<float>(), |
79 } | 121 rtc::Optional<float>()); |
80 | 122 } |
81 // Sanity check on minimum filled window. | 123 } |
82 TEST(TransportFeedbackPacketLossTrackerTest, MinimumFilledWindow) { | 124 |
83 for (uint16_t base : kBases) { | 125 // Sanity check on minimum filled window - PLR known, RPLR unknown. |
84 float plr = 0.0f; // Packet-loss-rate | 126 TEST(TransportFeedbackPacketLossTrackerTest, PlrMinimumFilledWindow) { |
85 float cplr = 0.0f; // Consecutive-packet-loss-rate | 127 for (uint16_t base : kBases) { |
86 TransportFeedbackPacketLossTracker tracker(5, 10); | 128 TransportFeedbackPacketLossTracker tracker(10, 5, 5); |
87 | 129 |
88 // PLR and CPLR correctly calculated after minimum window size reached. | 130 // PLR correctly calculated after minimum window size reached. |
89 // Expected window contents: [] -> [10011]. | 131 // RPLR not necessarily known at that time (not if min-pairs not reached). |
90 AddTransportFeedbackAndValidate(&tracker, base, | 132 // Expected window contents: [] -> [10011]. |
91 {true, false, false, true, true}); | 133 AddTransportFeedbackAndValidate(&tracker, base, |
92 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | 134 {true, false, false, true, true}); |
93 EXPECT_EQ(plr, 2.0f / 5.0f); | 135 ValidatePacketLossStatistics(tracker, |
94 EXPECT_EQ(cplr, 1.0f / 5.0f); | 136 rtc::Optional<float>(2.0f / 5.0f), |
95 } | 137 rtc::Optional<float>()); |
96 } | 138 } |
97 | 139 } |
98 // Additional reports update PLR and CPLR. | 140 |
| 141 // Sanity check on minimum filled window - PLR unknown, RPLR known. |
| 142 TEST(TransportFeedbackPacketLossTrackerTest, RplrMinimumFilledWindow) { |
| 143 for (uint16_t base : kBases) { |
| 144 TransportFeedbackPacketLossTracker tracker(10, 6, 4); |
| 145 |
| 146 // RPLR correctly calculated after minimum pairs reached. |
| 147 // PLR not necessarily known at that time (not if min window not reached). |
| 148 // Expected window contents: [] -> [10011]. |
| 149 AddTransportFeedbackAndValidate(&tracker, base, |
| 150 {true, false, false, true, true}); |
| 151 ValidatePacketLossStatistics(tracker, |
| 152 rtc::Optional<float>(), |
| 153 rtc::Optional<float>(1.0f / 4.0f)); |
| 154 } |
| 155 } |
| 156 |
| 157 // Additional reports update PLR and RPLR. |
99 TEST(TransportFeedbackPacketLossTrackerTest, ExtendWindow) { | 158 TEST(TransportFeedbackPacketLossTrackerTest, ExtendWindow) { |
100 for (uint16_t base : kBases) { | 159 for (uint16_t base : kBases) { |
101 float plr = 0.0f; // Packet-loss-rate | 160 TransportFeedbackPacketLossTracker tracker(20, 5, 5); |
102 float cplr = 0.0f; // Consecutive-packet-loss-rate | 161 |
103 TransportFeedbackPacketLossTracker tracker(5, 20); | 162 // Expected window contents: [] -> [10011]. |
104 | 163 AddTransportFeedbackAndValidate(&tracker, base, |
105 // Expected window contents: [] -> [10011]. | 164 {true, false, false, true, true}); |
106 AddTransportFeedbackAndValidate(&tracker, base, | 165 ValidatePacketLossStatistics(tracker, |
107 {true, false, false, true, true}); | 166 rtc::Optional<float>(2.0f / 5.0f), |
108 | 167 rtc::Optional<float>()); |
109 // Expected window contents: [10011] -> [10011-10101]. | 168 |
| 169 // Expected window contents: [10011] -> [1001110101]. |
110 AddTransportFeedbackAndValidate(&tracker, base + 5, | 170 AddTransportFeedbackAndValidate(&tracker, base + 5, |
111 {true, false, true, false, true}); | 171 {true, false, true, false, true}); |
112 | 172 ValidatePacketLossStatistics(tracker, 4.0f / 10.0f, 3.0f / 9.0f); |
113 // Expected window contents: [10011-10101] -> [10011-10101-10001]. | 173 |
114 AddTransportFeedbackAndValidate(&tracker, base + 10, | 174 // Expected window contents: [1001110101] -> [1001110101-GAP-10001]. |
| 175 AddTransportFeedbackAndValidate(&tracker, base + 20, |
115 {true, false, false, false, true}); | 176 {true, false, false, false, true}); |
116 | 177 ValidatePacketLossStatistics(tracker, 7.0f / 15.0f, 4.0f / 13.0f); |
117 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | 178 } |
118 EXPECT_EQ(plr, 7.0f / 15.0f); | 179 } |
119 EXPECT_EQ(cplr, 3.0f / 15.0f); | 180 |
120 } | 181 // All packets correctly received. |
121 } | |
122 | |
123 TEST(TransportFeedbackPacketLossTrackerTest, AllReceived) { | 182 TEST(TransportFeedbackPacketLossTrackerTest, AllReceived) { |
124 for (uint16_t base : kBases) { | 183 for (uint16_t base : kBases) { |
125 float plr = 0.0f; // Packet-loss-rate | 184 TransportFeedbackPacketLossTracker tracker(10, 5, 4); |
126 float cplr = 0.0f; // Consecutive-packet-loss-rate | 185 |
127 TransportFeedbackPacketLossTracker tracker(5, 10); | 186 // PLR and RPLR correctly calculated after minimum window size reached. |
128 | |
129 // PLR and CPLR correctly calculated after minimum window size reached. | |
130 // Expected window contents: [] -> [11111]. | 187 // Expected window contents: [] -> [11111]. |
131 AddTransportFeedbackAndValidate(&tracker, base, | 188 AddTransportFeedbackAndValidate(&tracker, base, |
132 {true, true, true, true, true}); | 189 {true, true, true, true, true}); |
133 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | 190 ValidatePacketLossStatistics(tracker, 0.0f, 0.0f); |
134 EXPECT_EQ(plr, 0.0f); | |
135 EXPECT_EQ(cplr, 0.0f); | |
136 } | 191 } |
137 } | 192 } |
138 | 193 |
139 // Repeated reports are ignored. | 194 // Repeated reports are ignored. |
140 TEST(TransportFeedbackPacketLossTrackerTest, ReportRepetition) { | 195 TEST(TransportFeedbackPacketLossTrackerTest, ReportRepetition) { |
141 for (uint16_t base : kBases) { | 196 for (uint16_t base : kBases) { |
142 float plr = 0.0f; // Packet-loss-rate | 197 TransportFeedbackPacketLossTracker tracker(10, 5, 4); |
143 float cplr = 0.0f; // Consecutive-packet-loss-rate | 198 |
144 TransportFeedbackPacketLossTracker tracker(5, 10); | 199 // Expected window contents: [] -> [10011]. |
145 | 200 AddTransportFeedbackAndValidate(&tracker, base, |
146 // Expected window contents: [] -> [10011]. | 201 {true, false, false, true, true}); |
147 AddTransportFeedbackAndValidate(&tracker, base, | 202 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); |
148 {true, false, false, true, true}); | |
149 | 203 |
150 // Repeat entire previous feedback | 204 // Repeat entire previous feedback |
151 // Expected window contents: [10011] -> [10011]. | 205 // Expected window contents: [10011] -> [10011]. |
152 AddTransportFeedbackAndValidate(&tracker, base, | 206 AddTransportFeedbackAndValidate(&tracker, base, |
153 {true, false, false, true, true}); | 207 {true, false, false, true, true}); |
154 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | 208 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); |
155 EXPECT_EQ(plr, 2.0f / 5.0f); | |
156 EXPECT_EQ(cplr, 1.0f / 5.0f); | |
157 } | 209 } |
158 } | 210 } |
159 | 211 |
160 // Report overlap. | 212 // Report overlap. |
161 TEST(TransportFeedbackPacketLossTrackerTest, ReportOverlap) { | 213 TEST(TransportFeedbackPacketLossTrackerTest, ReportOverlap) { |
162 for (uint16_t base : kBases) { | 214 for (uint16_t base : kBases) { |
163 float plr = 0.0f; // Packet-loss-rate | 215 TransportFeedbackPacketLossTracker tracker(10, 5, 1); |
164 float cplr = 0.0f; // Consecutive-packet-loss-rate | 216 |
165 TransportFeedbackPacketLossTracker tracker(5, 10); | 217 // Expected window contents: [] -> [10011]. |
166 | 218 AddTransportFeedbackAndValidate(&tracker, base, |
167 // Expected window contents: [] -> [10011]. | 219 {true, false, false, true, true}); |
168 AddTransportFeedbackAndValidate(&tracker, base, | 220 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); |
169 {true, false, false, true, true}); | 221 |
170 | 222 // Expected window contents: [10011] -> [1001101]. |
171 // Expected window contents: [10011] -> [10011-01]. | |
172 AddTransportFeedbackAndValidate(&tracker, base + 3, | 223 AddTransportFeedbackAndValidate(&tracker, base + 3, |
173 {true, true, false, true}); | 224 {true, true, false, true}); |
174 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | 225 ValidatePacketLossStatistics(tracker, 3.0f / 7.0f, 2.0f / 6.0f); |
175 EXPECT_EQ(plr, 3.0f / 7.0f); | |
176 EXPECT_EQ(cplr, 1.0f / 7.0f); | |
177 } | 226 } |
178 } | 227 } |
179 | 228 |
180 // Report conflict. | 229 // Report conflict. |
181 TEST(TransportFeedbackPacketLossTrackerTest, ReportConflict) { | 230 TEST(TransportFeedbackPacketLossTrackerTest, ReportConflict) { |
182 for (uint16_t base : kBases) { | 231 for (uint16_t base : kBases) { |
183 float plr = 0.0f; // Packet-loss-rate | 232 TransportFeedbackPacketLossTracker tracker(10, 5, 4); |
184 float cplr = 0.0f; // Consecutive-packet-loss-rate | |
185 TransportFeedbackPacketLossTracker tracker(5, 10); | |
186 | 233 |
187 // Expected window contents: [] -> [01001]. | 234 // Expected window contents: [] -> [01001]. |
188 AddTransportFeedbackAndValidate(&tracker, base, | 235 AddTransportFeedbackAndValidate(&tracker, base, |
189 {false, true, false, false, true}); | 236 {false, true, false, false, true}); |
| 237 ValidatePacketLossStatistics(tracker, 3.0f / 5.0f, 2.0f / 4.0f); |
190 | 238 |
191 // Expected window contents: [01001] -> [11101]. | 239 // Expected window contents: [01001] -> [11101]. |
192 // While false->true will be applied, true -> false will be ignored. | 240 // While false->true will be applied, true -> false will be ignored. |
193 AddTransportFeedbackAndValidate(&tracker, base, {true, false, true}); | 241 AddTransportFeedbackAndValidate(&tracker, base, {true, false, true}); |
194 | 242 ValidatePacketLossStatistics(tracker, 1.0f / 5.0f, 1.0f / 4.0f); |
195 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
196 EXPECT_EQ(plr, 1.0f / 5.0f); | |
197 EXPECT_EQ(cplr, 0.0f / 5.0f); | |
198 } | 243 } |
199 } | 244 } |
200 | 245 |
201 // Skipped packets treated as unknown (not lost). | 246 // Skipped packets treated as unknown (not lost). |
202 TEST(TransportFeedbackPacketLossTrackerTest, SkippedPackets) { | 247 TEST(TransportFeedbackPacketLossTrackerTest, SkippedPackets) { |
203 for (uint16_t base : kBases) { | 248 for (uint16_t base : kBases) { |
204 float plr = 0.0f; // Packet-loss-rate | 249 TransportFeedbackPacketLossTracker tracker(10, 5, 1); |
205 float cplr = 0.0f; // Consecutive-packet-loss-rate | 250 |
206 TransportFeedbackPacketLossTracker tracker(5, 10); | 251 // Expected window contents: [] -> [10011]. |
207 | 252 AddTransportFeedbackAndValidate(&tracker, base, |
208 // Expected window contents: [] -> [10011]. | 253 {true, false, false, true, true}); |
209 AddTransportFeedbackAndValidate(&tracker, base, | 254 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); |
210 {true, false, false, true, true}); | 255 |
211 | 256 // Expected window contents: [10011] -> [10011-GAP-101]. |
212 // Expected window contents: [10011] -> [10011-101]. | |
213 AddTransportFeedbackAndValidate(&tracker, base + 100, {true, false, true}); | 257 AddTransportFeedbackAndValidate(&tracker, base + 100, {true, false, true}); |
214 | 258 ValidatePacketLossStatistics(tracker, 3.0f / 8.0f, 2.0f / 6.0f); |
215 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | 259 } |
216 EXPECT_EQ(plr, 3.0f / 8.0f); | 260 } |
217 EXPECT_EQ(cplr, 1.0f / 8.0f); | 261 |
218 } | |
219 } | |
220 | |
221 // The window retain information up to the configured max-window-size, but | 262 // The window retain information up to the configured max-window-size, but |
222 // starts discarding after that. | 263 // starts discarding after that. |
223 TEST(TransportFeedbackPacketLossTrackerTest, MaxWindowSize) { | 264 TEST(TransportFeedbackPacketLossTrackerTest, MaxWindowSize) { |
224 for (uint16_t base : kBases) { | 265 for (uint16_t base : kBases) { |
225 float plr = 0.0f; // Packet-loss-rate | 266 TransportFeedbackPacketLossTracker tracker(10, 10, 1); |
226 float cplr = 0.0f; // Consecutive-packet-loss-rate | 267 |
227 TransportFeedbackPacketLossTracker tracker(10, 10); | 268 // Up to max-window-size retained. |
228 | 269 // Expected window contents: [] -> [1010100001]. |
229 // Expected window contents: [] -> [10101-00001]. | |
230 AddTransportFeedbackAndValidate( | 270 AddTransportFeedbackAndValidate( |
231 &tracker, base, | 271 &tracker, base, |
232 {true, false, true, false, true, false, false, false, false, true}); | 272 {true, false, true, false, true, false, false, false, false, true}); |
233 | 273 ValidatePacketLossStatistics(tracker, 6.0f / 10.0f, 3.0f / 9.0f); |
234 // Up to max-window-size retained. | 274 |
235 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | 275 // After max-window-size, older entries discarded to accommodate newer ones. |
236 EXPECT_EQ(plr, 6.0f / 10.0f); | 276 // Expected window contents: [1010100001] -> [0000110111]. |
237 EXPECT_EQ(cplr, 3.0f / 10.0f); | |
238 | |
239 // Expected window contents: [10101-00001] -> [00001-10111]. | |
240 AddTransportFeedbackAndValidate(&tracker, base + 10, | 277 AddTransportFeedbackAndValidate(&tracker, base + 10, |
241 {true, false, true, true, true}); | 278 {true, false, true, true, true}); |
242 | 279 ValidatePacketLossStatistics(tracker, 5.0f / 10.0f, 2.0f / 9.0f); |
243 // After max-window-size, older entries discarded to accommodate newer ones. | |
244 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
245 EXPECT_EQ(plr, 5.0f / 10.0f); | |
246 EXPECT_EQ(cplr, 3.0f / 10.0f); | |
247 } | 280 } |
248 } | 281 } |
249 | 282 |
250 // Inserting into the middle of a full window works correctly. | 283 // Inserting into the middle of a full window works correctly. |
251 TEST(TransportFeedbackPacketLossTrackerTest, InsertIntoMiddle) { | 284 TEST(TransportFeedbackPacketLossTrackerTest, InsertIntoMiddle) { |
252 for (uint16_t base : kBases) { | 285 for (uint16_t base : kBases) { |
253 float plr = 0.0f; // Packet-loss-rate | 286 TransportFeedbackPacketLossTracker tracker(10, 5, 1); |
254 float cplr = 0.0f; // Consecutive-packet-loss-rate | |
255 TransportFeedbackPacketLossTracker tracker(10, 10); | |
256 | 287 |
257 // Expected window contents: [] -> [10101]. | 288 // Expected window contents: [] -> [10101]. |
258 AddTransportFeedbackAndValidate(&tracker, base, | 289 AddTransportFeedbackAndValidate(&tracker, base, |
259 {true, false, true, false, true}); | 290 {true, false, true, false, true}); |
260 | 291 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 2.0f / 4.0f); |
261 // Expected window contents: [10101] -> [10101-10001]. | 292 |
| 293 // Expected window contents: [10101] -> [10101-GAP-10001]. |
262 AddTransportFeedbackAndValidate(&tracker, base + 100, | 294 AddTransportFeedbackAndValidate(&tracker, base + 100, |
263 {true, false, false, false, true}); | 295 {true, false, false, false, true}); |
264 | 296 ValidatePacketLossStatistics(tracker, 5.0f / 10.0f, 3.0f / 8.0f); |
265 // Setup sanity | |
266 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
267 EXPECT_EQ(plr, 5.0f / 10.0f); | |
268 EXPECT_EQ(cplr, 2.0f / 10.0f); | |
269 | 297 |
270 // Insert into the middle of this full window - it discards the older data. | 298 // Insert into the middle of this full window - it discards the older data. |
271 // Expected window contents: [10101-10001] -> [11111-10001]. | 299 // Expected window contents: [10101-GAP-10001] -> [11111-GAP-10001]. |
272 AddTransportFeedbackAndValidate(&tracker, base + 50, | 300 AddTransportFeedbackAndValidate(&tracker, base + 50, |
273 {true, true, true, true, true}); | 301 {true, true, true, true, true}); |
274 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | 302 ValidatePacketLossStatistics(tracker, 3.0f / 10.0f, 1.0f / 8.0f); |
275 EXPECT_EQ(plr, 3.0f / 10.0f); | 303 } |
276 EXPECT_EQ(cplr, 2.0f / 10.0f); | 304 } |
277 } | 305 |
278 } | 306 // Inserting into the middle of a full window works correctly. |
279 | 307 TEST(TransportFeedbackPacketLossTrackerTest, InsertionCompletesTwoPairs) { |
280 // Test the behavior of TransportFeedbackPacketLossTracker when there is a gap | 308 for (uint16_t base : kBases) { |
281 // of more than 0x4000 in sequence number, i.e., 1/4 of total sequence numbers. | 309 TransportFeedbackPacketLossTracker tracker(15, 5, 1); |
282 // Since the sequence number is used in a circular manner, i.e., after 0xffff, | 310 |
283 // the sequence number wraps back to 0x0000, we refer to 1/4 of total sequence | 311 // Expected window contents: [] -> [10111]. |
284 // numbers as a quadrant. In this test, e.g., three transport feedbacks are | 312 AddTransportFeedbackAndValidate(&tracker, base, |
285 // added, whereas the 2nd and 3rd lie in the second quadrant w.r.t. the 1st | 313 {true, false, true, true, true}); |
286 // feedback. | 314 ValidatePacketLossStatistics(tracker, 1.0f / 5.0f, 1.0f / 4.0f); |
| 315 |
| 316 // Expected window contents: [10111] -> [10111-GAP-10101]. |
| 317 AddTransportFeedbackAndValidate(&tracker, base + 7, |
| 318 {true, false, true, false, true}); |
| 319 ValidatePacketLossStatistics(tracker, 3.0f / 10.0f, 3.0f / 8.0f); |
| 320 |
| 321 // Insert in between, closing the gap completely. |
| 322 // Expected window contents: [10111-GAP-10101] -> [101111010101]. |
| 323 AddTransportFeedbackAndValidate(&tracker, base + 5, {false, true}); |
| 324 ValidatePacketLossStatistics(tracker, 4.0f / 12.0f, 4.0f / 11.0f); |
| 325 } |
| 326 } |
| 327 |
| 328 // Entries in the second quadrant treated like those in the first. |
| 329 // The sequence number is used in a looped manner. 0xFFFF is followed by 0x0000. |
| 330 // In many tests, we divide the circle of sequence number into 4 quadrants, and |
| 331 // verify the behavior of TransportFeedbackPacketLossTracker over them. |
287 TEST(TransportFeedbackPacketLossTrackerTest, SecondQuadrant) { | 332 TEST(TransportFeedbackPacketLossTrackerTest, SecondQuadrant) { |
288 for (uint16_t base : kBases) { | 333 for (uint16_t base : kBases) { |
289 float plr = 0.0f; // Packet-loss-rate | 334 TransportFeedbackPacketLossTracker tracker(20, 5, 1); |
290 float cplr = 0.0f; // Consecutive-packet-loss-rate | |
291 TransportFeedbackPacketLossTracker tracker(5, 20); | |
292 | 335 |
293 // Expected window contents: [] -> [10011]. | 336 // Expected window contents: [] -> [10011]. |
294 AddTransportFeedbackAndValidate(&tracker, base, | 337 AddTransportFeedbackAndValidate(&tracker, base, |
295 {true, false, false, true, true}); | 338 {true, false, false, true, true}); |
| 339 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); |
296 | 340 |
297 // Window *does* get updated with inputs from quadrant #2. | 341 // Window *does* get updated with inputs from quadrant #2. |
298 // Expected window contents: [10011] -> [10011-1]. | 342 // Expected window contents: [10011] -> [100111]. |
299 AddTransportFeedbackAndValidate(&tracker, base + 0x4321, {true}); | 343 AddTransportFeedbackAndValidate(&tracker, base + 0x4321, {true}); |
300 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | 344 ValidatePacketLossStatistics(tracker, 2.0f / 6.0f, 1.0f / 4.0f); |
301 EXPECT_EQ(plr, 2.0f / 6.0f); | |
302 EXPECT_EQ(cplr, 1.0f / 6.0f); | |
303 | 345 |
304 // Correct recognition of quadrant #2: up to, but not including, base + | 346 // Correct recognition of quadrant #2: up to, but not including, base + |
305 // 0x8000 | 347 // 0x8000 |
306 // Expected window contents: [10011-1] -> [10011-11]. | 348 // Expected window contents: [100111] -> [1001111]. |
307 AddTransportFeedbackAndValidate(&tracker, base + 0x7fff, {true}); | 349 AddTransportFeedbackAndValidate(&tracker, base + 0x7fff, {true}); |
308 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | 350 ValidatePacketLossStatistics(tracker, 2.0f / 7.0f, 1.0f / 4.0f); |
309 EXPECT_EQ(plr, 2.0f / 7.0f); | |
310 EXPECT_EQ(cplr, 1.0f / 7.0f); | |
311 } | 351 } |
312 } | 352 } |
313 | 353 |
314 // Insertion into the third quadrant moves the base of the window. | 354 // Insertion into the third quadrant moves the base of the window. |
315 TEST(TransportFeedbackPacketLossTrackerTest, ThirdQuadrantMovesBase) { | 355 TEST(TransportFeedbackPacketLossTrackerTest, ThirdQuadrantMovesBase) { |
316 for (uint16_t base : kBases) { | 356 for (uint16_t base : kBases) { |
317 float plr = 0.0f; // Packet-loss-rate | 357 TransportFeedbackPacketLossTracker tracker(20, 5, 1); |
318 float cplr = 0.0f; // Consecutive-packet-loss-rate | |
319 TransportFeedbackPacketLossTracker tracker(5, 20); | |
320 | 358 |
321 // Seed the test. | 359 // Seed the test. |
322 // Expected window contents: [] -> [10011-01]. | 360 // Expected window contents: [] -> [1001101]. |
323 AddTransportFeedbackAndValidate( | 361 AddTransportFeedbackAndValidate( |
324 &tracker, base, {true, false, false, true, true, false, true}); | 362 &tracker, base, {true, false, false, true, true, false, true}); |
| 363 ValidatePacketLossStatistics(tracker, 3.0f / 7.0f, 2.0f / 6.0f); |
325 | 364 |
326 // Quadrant #3 begins at base + 0x8000. It triggers moving the window so | 365 // Quadrant #3 begins at base + 0x8000. It triggers moving the window so |
327 // that | 366 // that |
328 // at least one (oldest) report shifts out of window. | 367 // at least one (oldest) report shifts out of window. |
329 // Expected window contents: [10011-01] -> [10110-01]. | 368 // Expected window contents: [1001101] -> [101-GAP-1001]. |
330 AddTransportFeedbackAndValidate(&tracker, base + 0x8000, | 369 AddTransportFeedbackAndValidate(&tracker, base + 0x8000, |
331 {true, false, false, true}); | 370 {true, false, false, true}); |
332 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | 371 ValidatePacketLossStatistics(tracker, 3.0f / 7.0f, 2.0f / 5.0f); |
333 EXPECT_EQ(plr, 3.0f / 7.0f); | |
334 EXPECT_EQ(cplr, 1.0f / 7.0f); | |
335 | 372 |
336 // The base can move more than once, because the minimum quadrant-1 packets | 373 // The base can move more than once, because the minimum quadrant-1 packets |
337 // were dropped out of the window, and some remain. | 374 // were dropped out of the window, and some remain. |
| 375 // Expected window contents: [101-GAP-1001] -> [1-GAP-100111]. |
338 AddTransportFeedbackAndValidate(&tracker, base + 0x8000 + 4, {true, true}); | 376 AddTransportFeedbackAndValidate(&tracker, base + 0x8000 + 4, {true, true}); |
339 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | 377 ValidatePacketLossStatistics(tracker, 2.0f / 7.0f, 1.0f / 5.0f); |
340 EXPECT_EQ(plr, 2.0f / 7.0f); | |
341 EXPECT_EQ(cplr, 1.0f / 7.0f); | |
342 } | 378 } |
343 } | 379 } |
344 | 380 |
345 // After the base has moved due to insertion into the third quadrant, it is | 381 // After the base has moved due to insertion into the third quadrant, it is |
346 // still possible to insert into the middle of the window and obtain the correct | 382 // still possible to insert into the middle of the window and obtain the correct |
347 // PLR and CPLR. Insertion into the middle before the max window size has been | 383 // PLR and RPLR. Insertion into the middle before the max window size has been |
348 // achieved does not cause older packets to be dropped. | 384 // achieved does not cause older packets to be dropped. |
349 TEST(TransportFeedbackPacketLossTrackerTest, InsertIntoMiddleAfterBaseMove) { | 385 TEST(TransportFeedbackPacketLossTrackerTest, InsertIntoMiddleAfterBaseMove) { |
350 for (uint16_t base : kBases) { | 386 for (uint16_t base : kBases) { |
351 float plr = 0.0f; // Packet-loss-rate | 387 TransportFeedbackPacketLossTracker tracker(20, 5, 1); |
352 float cplr = 0.0f; // Consecutive-packet-loss-rate | |
353 TransportFeedbackPacketLossTracker tracker(5, 20); | |
354 | 388 |
355 // Seed the test. | 389 // Seed the test. |
356 // Expected window contents: [] -> [10011-01]. | 390 // Expected window contents: [] -> [1001101]. |
357 AddTransportFeedbackAndValidate( | 391 AddTransportFeedbackAndValidate( |
358 &tracker, base, {true, false, false, true, true, false, true}); | 392 &tracker, base, {true, false, false, true, true, false, true}); |
359 | 393 ValidatePacketLossStatistics(tracker, 3.0f / 7.0f, 2.0f / 6.0f); |
360 // Expected window contents: [10011-01] -> [10110-01]. | 394 |
| 395 // Expected window contents: [1001101] -> [101-GAP-1001]. |
361 AddTransportFeedbackAndValidate(&tracker, base + 0x8000, | 396 AddTransportFeedbackAndValidate(&tracker, base + 0x8000, |
362 {true, false, false, true}); | 397 {true, false, false, true}); |
| 398 ValidatePacketLossStatistics(tracker, 3.0f / 7.0f, 2.0f / 5.0f); |
363 | 399 |
364 // Inserting into the middle still works after the base has shifted. | 400 // Inserting into the middle still works after the base has shifted. |
365 // Expected window contents: [10110-01] -> [10110-01011-001]. | 401 // Expected window contents: |
| 402 // [101-GAP-1001] -> [101-GAP-100101-GAP-1001] |
366 AddTransportFeedbackAndValidate(&tracker, base + 0x5000, | 403 AddTransportFeedbackAndValidate(&tracker, base + 0x5000, |
367 {true, false, false, true, false, true}); | 404 {true, false, false, true, false, true}); |
368 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | 405 ValidatePacketLossStatistics(tracker, 6.0f / 13.0f, 4.0f / 10.0f); |
369 EXPECT_EQ(plr, 6.0f / 13.0f); | |
370 EXPECT_EQ(cplr, 2.0f / 13.0f); | |
371 | 406 |
372 // The base can keep moving after inserting into the middle. | 407 // The base can keep moving after inserting into the middle. |
373 // Expected window contents: [10110-01011-001] -> [11001-01100-111]. | 408 // Expected window contents: |
| 409 // [101-GAP-100101-GAP-1001] -> [1-GAP-100101-GAP-100111]. |
374 AddTransportFeedbackAndValidate(&tracker, base + 0x8000 + 4, {true, true}); | 410 AddTransportFeedbackAndValidate(&tracker, base + 0x8000 + 4, {true, true}); |
375 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | 411 ValidatePacketLossStatistics(tracker, 5.0f / 13.0f, 3.0f / 10.0f); |
376 EXPECT_EQ(plr, 5.0f / 13.0f); | |
377 EXPECT_EQ(cplr, 2.0f / 13.0f); | |
378 } | 412 } |
379 } | 413 } |
380 | 414 |
381 // After moving the base of the window, the max window size is still observed. | 415 // After moving the base of the window, the max window size is still observed. |
382 TEST(TransportFeedbackPacketLossTrackerTest, ThirdQuadrantObservesMaxWindow) { | 416 TEST(TransportFeedbackPacketLossTrackerTest, ThirdQuadrantObservesMaxWindow) { |
383 for (uint16_t base : kBases) { | 417 for (uint16_t base : kBases) { |
384 float plr = 0.0f; // Packet-loss-rate | 418 TransportFeedbackPacketLossTracker tracker(15, 10, 1); |
385 float cplr = 0.0f; // Consecutive-packet-loss-rate | 419 |
386 TransportFeedbackPacketLossTracker tracker(10, 15); | 420 // Expected window contents: [] -> [1001110101]. |
387 | |
388 // Expected window contents: [] -> [10011-10101]. | |
389 AddTransportFeedbackAndValidate( | 421 AddTransportFeedbackAndValidate( |
390 &tracker, base, | 422 &tracker, base, |
391 {true, false, false, true, true, true, false, true, false, true}); | 423 {true, false, false, true, true, true, false, true, false, true}); |
392 | 424 ValidatePacketLossStatistics(tracker, 4.0f / 10.0f, 3.0f / 9.0f); |
393 // Expected window contents: [10011-10101] -> [11101-01101]. | 425 |
| 426 // Expected window contents: [1001110101] -> [1110101-GAP-101]. |
394 AddTransportFeedbackAndValidate(&tracker, base + 0x8000, | 427 AddTransportFeedbackAndValidate(&tracker, base + 0x8000, |
395 {true, false, true}); | 428 {true, false, true}); |
| 429 ValidatePacketLossStatistics(tracker, 3.0f / 10.0f, 3.0f / 8.0f); |
396 | 430 |
397 // Push into middle until max window is reached. | 431 // Push into middle until max window is reached. |
398 // Expected window contents: [11101-01101] -> [11101-01100-01101]. | 432 // Expected window contents: |
| 433 // [1110101-GAP-101] -> [1110101-GAP-10001-GAP-101] |
399 AddTransportFeedbackAndValidate(&tracker, base + 0x4000, | 434 AddTransportFeedbackAndValidate(&tracker, base + 0x4000, |
400 {true, false, false, false, true}); | 435 {true, false, false, false, true}); |
401 | 436 ValidatePacketLossStatistics(tracker, 6.0f / 15.0f, 4.0f / 12.0f); |
402 // Setup sanity | |
403 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
404 EXPECT_EQ(plr, 6.0f / 15.0f); | |
405 EXPECT_EQ(cplr, 2.0f / 15.0f); | |
406 | 437 |
407 // Pushing new packets into the middle would discard older packets. | 438 // Pushing new packets into the middle would discard older packets. |
408 // Expected window contents: [11101-01100-01101] -> [01011-00011-01101]. | 439 // Expected window contents: |
| 440 // [1110101-GAP-10001-GAP-101] -> [0101-GAP-10001101-GAP-101] |
409 AddTransportFeedbackAndValidate(&tracker, base + 0x4000 + 5, | 441 AddTransportFeedbackAndValidate(&tracker, base + 0x4000 + 5, |
410 {true, false, true}); | 442 {true, false, true}); |
411 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | 443 ValidatePacketLossStatistics(tracker, 7.0f / 15.0f, 5.0f / 12.0f); |
412 EXPECT_EQ(plr, 7.0f / 15.0f); | |
413 EXPECT_EQ(cplr, 2.0f / 15.0f); | |
414 } | 444 } |
415 } | 445 } |
416 | 446 |
417 // A new feedback in quadrant #3 might shift enough old feedbacks out of window, | 447 // A new feedback in quadrant #3 might shift enough old feedbacks out of window, |
418 // that we'd go back to an unknown PLR and CPLR. | 448 // that we'd go back to an unknown PLR and RPLR. |
419 TEST(TransportFeedbackPacketLossTrackerTest, QuadrantThreeMovedBaseMinWindow) { | 449 TEST(TransportFeedbackPacketLossTrackerTest, QuadrantThreeMovedBaseMinWindow) { |
420 for (uint16_t base : kBases) { | 450 for (uint16_t base : kBases) { |
421 float plr = 0.0f; // Packet-loss-rate | 451 TransportFeedbackPacketLossTracker tracker(20, 5, 1); |
422 float cplr = 0.0f; // Consecutive-packet-loss-rate | 452 |
423 TransportFeedbackPacketLossTracker tracker(5, 20); | 453 // Expected window contents: [] -> [1001110101]. |
424 | |
425 // Expected window contents: [] -> [10011-10101]. | |
426 AddTransportFeedbackAndValidate( | 454 AddTransportFeedbackAndValidate( |
427 &tracker, base, | 455 &tracker, base, |
428 {true, false, false, true, true, true, false, true, false, true}); | 456 {true, false, false, true, true, true, false, true, false, true}); |
429 EXPECT_TRUE( | 457 ValidatePacketLossStatistics(tracker, 4.0f / 10.0f, 3.0f / 9.0f); |
430 tracker.GetPacketLossRates(&plr, &cplr)); // Min window reached. | |
431 | 458 |
432 // A new feedback in quadrant #3 might shift enough old feedbacks out of | 459 // A new feedback in quadrant #3 might shift enough old feedbacks out of |
433 // window, that we'd go back to an unknown PLR and CPLR. This *doesn't* | 460 // window, that we'd go back to an unknown PLR and RPLR. This *doesn't* |
434 // necessarily mean all of the old ones were discarded, though. | 461 // necessarily mean all of the old ones were discarded, though. |
435 // Expected window contents: [10011-10101] -> [0111]. | 462 // Expected window contents: [1001110101] -> [01-GAP-11]. |
436 AddTransportFeedbackAndValidate(&tracker, base + 0x8006, {true, true}); | 463 AddTransportFeedbackAndValidate(&tracker, base + 0x8006, {true, true}); |
437 EXPECT_FALSE(tracker.GetPacketLossRates(&plr, &cplr)); | 464 ValidatePacketLossStatistics(tracker, |
| 465 rtc::Optional<float>(), // Still invalid. |
| 466 rtc::Optional<float>(1.0f / 2.0f)); |
438 | 467 |
439 // Inserting in the middle shows that though some of the elements were | 468 // Inserting in the middle shows that though some of the elements were |
440 // ejected, some were retained. | 469 // ejected, some were retained. |
441 // Expected window contents: [] -> [01101-11]. | 470 // Expected window contents: [01-GAP-11] -> [01-GAP-1001-GAP-11]. |
442 AddTransportFeedbackAndValidate(&tracker, base + 0x4000, | 471 AddTransportFeedbackAndValidate(&tracker, base + 0x4000, |
443 {true, false, true}); | 472 {true, false, false, true}); |
444 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | 473 ValidatePacketLossStatistics(tracker, 3.0f / 8.0f, 2.0f / 5.0f); |
445 EXPECT_EQ(plr, 2.0f / 7.0f); | |
446 EXPECT_EQ(cplr, 0.0f / 7.0f); | |
447 } | 474 } |
448 } | 475 } |
449 | 476 |
450 // Quadrant four reports ignored for up to kMaxConsecutiveOldReports times. | 477 // Quadrant four reports ignored for up to kMaxConsecutiveOldReports times. |
451 TEST(TransportFeedbackPacketLossTrackerTest, QuadrantFourInitiallyIgnored) { | 478 TEST(TransportFeedbackPacketLossTrackerTest, QuadrantFourInitiallyIgnored) { |
452 for (uint16_t base : kBases) { | 479 for (uint16_t base : kBases) { |
453 float plr = 0.0f; // Packet-loss-rate | 480 TransportFeedbackPacketLossTracker tracker(20, 5, 1); |
454 float cplr = 0.0f; // Consecutive-packet-loss-rate | |
455 TransportFeedbackPacketLossTracker tracker(5, 20); | |
456 | 481 |
457 // Expected window contents: [] -> [10011]. | 482 // Expected window contents: [] -> [10011]. |
458 AddTransportFeedbackAndValidate(&tracker, base, | 483 AddTransportFeedbackAndValidate(&tracker, base, |
459 {true, false, false, true, true}); | 484 {true, false, false, true, true}); |
460 | 485 |
461 // Feedbacks in quadrant #4 are discarded (up to kMaxConsecutiveOldReports | 486 // Feedbacks in quadrant #4 are discarded (up to kMaxConsecutiveOldReports |
462 // consecutive reports). | 487 // consecutive reports). |
463 // Expected window contents: [10011] -> [10011]. | 488 // Expected window contents: [10011] -> [10011]. |
464 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { | 489 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { |
465 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, {true, true}); | 490 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, {true, true}); |
466 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | 491 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); |
467 EXPECT_EQ(plr, 2.0f / 5.0f); | |
468 EXPECT_EQ(cplr, 1.0f / 5.0f); | |
469 } | 492 } |
470 } | 493 } |
471 } | 494 } |
472 | 495 |
473 // Receiving a packet from quadrant #1 resets the counter for quadrant #4. | 496 // Receiving a packet from quadrant #1 resets the counter for quadrant #4. |
474 TEST(TransportFeedbackPacketLossTrackerTest, QuadrantFourCounterResetByQ1) { | 497 TEST(TransportFeedbackPacketLossTrackerTest, QuadrantFourCounterResetByQ1) { |
475 for (uint16_t base : kBases) { | 498 for (uint16_t base : kBases) { |
476 float plr = 0.0f; // Packet-loss-rate | 499 TransportFeedbackPacketLossTracker tracker(20, 5, 1); |
477 float cplr = 0.0f; // Consecutive-packet-loss-rate | |
478 TransportFeedbackPacketLossTracker tracker(5, 20); | |
479 | 500 |
480 // Expected window contents: [] -> [10011]. | 501 // Expected window contents: [] -> [10011]. |
481 AddTransportFeedbackAndValidate(&tracker, base, | 502 AddTransportFeedbackAndValidate(&tracker, base, |
482 {true, false, false, true, true}); | 503 {true, false, false, true, true}); |
483 | 504 |
484 // Feedbacks in quadrant #4 are discarded (up to kMaxConsecutiveOldReports | 505 // Feedbacks in quadrant #4 are discarded (up to kMaxConsecutiveOldReports |
485 // consecutive reports). | 506 // consecutive reports). |
486 // Expected window contents: [10011] -> [10011]. | 507 // Expected window contents: [10011] -> [10011]. |
487 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { | 508 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { |
488 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, {true, true}); | 509 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, {true, true}); |
489 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | 510 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); |
490 EXPECT_EQ(plr, 2.0f / 5.0f); | |
491 EXPECT_EQ(cplr, 1.0f / 5.0f); | |
492 } | 511 } |
493 | 512 |
494 // If we receive a feedback in quadrant #1, the above counter is reset. | 513 // If we receive a feedback in quadrant #1, the above counter is reset. |
495 // Expected window contents: [10011] -> [10011-1]. | 514 // Expected window contents: [10011] -> [100111]. |
496 AddTransportFeedbackAndValidate(&tracker, base + 0x000f, {true}); | 515 AddTransportFeedbackAndValidate(&tracker, base + 5, {true}); |
497 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { | 516 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { |
498 // Note: though the feedback message reports three packets, it only gets | 517 // Note: though the feedback message reports three packets, it only gets |
499 // counted once. | 518 // counted once. |
500 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, | 519 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, |
501 {true, false, true}); | 520 {true, false, true}); |
502 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | 521 ValidatePacketLossStatistics(tracker, 2.0f / 6.0f, 1.0f / 5.0f); |
503 EXPECT_EQ(plr, 2.0f / 6.0f); | 522 } |
504 EXPECT_EQ(cplr, 1.0f / 6.0f); | 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); |
505 } | 533 } |
506 } | 534 } |
507 } | 535 } |
508 | 536 |
509 // Receiving a packet from quadrant #2 resets the counter for quadrant #4. | 537 // Receiving a packet from quadrant #2 resets the counter for quadrant #4. |
510 TEST(TransportFeedbackPacketLossTrackerTest, QuadrantFourCounterResetByQ2) { | 538 TEST(TransportFeedbackPacketLossTrackerTest, QuadrantFourCounterResetByQ2) { |
511 for (uint16_t base : kBases) { | 539 for (uint16_t base : kBases) { |
512 float plr = 0.0f; // Packet-loss-rate | 540 TransportFeedbackPacketLossTracker tracker(20, 5, 1); |
513 float cplr = 0.0f; // Consecutive-packet-loss-rate | |
514 TransportFeedbackPacketLossTracker tracker(5, 20); | |
515 | 541 |
516 // Expected window contents: [] -> [10011]. | 542 // Expected window contents: [] -> [10011]. |
517 AddTransportFeedbackAndValidate(&tracker, base, | 543 AddTransportFeedbackAndValidate(&tracker, base, |
518 {true, false, false, true, true}); | 544 {true, false, false, true, true}); |
519 | 545 |
520 // Feedbacks in quadrant #4 are discarded (up to kMaxConsecutiveOldReports | 546 // Feedbacks in quadrant #4 are discarded (up to kMaxConsecutiveOldReports |
521 // consecutive reports). | 547 // consecutive reports). |
522 // Expected window contents: [10011] -> [10011]. | 548 // Expected window contents: [10011] -> [10011]. |
523 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { | 549 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { |
524 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, {true, true}); | 550 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, {true, true}); |
525 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | 551 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); |
526 EXPECT_EQ(plr, 2.0f / 5.0f); | |
527 EXPECT_EQ(cplr, 1.0f / 5.0f); | |
528 } | 552 } |
529 | 553 |
530 // If we receive a feedback in quadrant #1, the above counter is reset. | 554 // If we receive a feedback in quadrant #2, the above counter is reset. |
531 // Expected window contents: [10011] -> [10011-1]. | 555 // Expected window contents: [10011] -> [10011-GAP-11]. |
532 AddTransportFeedbackAndValidate(&tracker, base + 0x400f, {true}); | 556 AddTransportFeedbackAndValidate(&tracker, base + 0x400f, {true, true}); |
533 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { | 557 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { |
534 // Note: though the feedback message reports three packets, it only gets | 558 // Note: though the feedback message reports three packets, it only gets |
535 // counted once. | 559 // counted once. |
536 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, | 560 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, |
537 {true, false, true}); | 561 {true, false, true}); |
538 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | 562 ValidatePacketLossStatistics(tracker, 2.0f / 7.0f, 1.0f / 5.0f); |
539 EXPECT_EQ(plr, 2.0f / 6.0f); | |
540 EXPECT_EQ(cplr, 1.0f / 6.0f); | |
541 } | 563 } |
542 } | 564 } |
543 } | 565 } |
544 | 566 |
545 // Receiving a packet from quadrant #3 resets the counter for quadrant #4. | 567 // Receiving a packet from quadrant #3 resets the counter for quadrant #4. |
546 TEST(TransportFeedbackPacketLossTrackerTest, QuadrantFourCounterResetByQ3) { | 568 TEST(TransportFeedbackPacketLossTrackerTest, QuadrantFourCounterResetByQ3) { |
547 for (uint16_t base : kBases) { | 569 for (uint16_t base : kBases) { |
548 float plr = 0.0f; // Packet-loss-rate | 570 TransportFeedbackPacketLossTracker tracker(20, 5, 1); |
549 float cplr = 0.0f; // Consecutive-packet-loss-rate | |
550 TransportFeedbackPacketLossTracker tracker(5, 20); | |
551 | 571 |
552 // Expected window contents: [] -> [10011-10001]. | 572 // Expected window contents: [] -> [1001110001]. |
553 AddTransportFeedbackAndValidate( | 573 AddTransportFeedbackAndValidate( |
554 &tracker, base, | 574 &tracker, base, |
555 {true, false, false, true, true, true, false, false, false, true}); | 575 {true, false, false, true, true, true, false, false, false, true}); |
556 | 576 |
557 // Feedbacks in quadrant #4 are discarded (up to kMaxConsecutiveOldReports | 577 // Feedbacks in quadrant #4 are discarded (up to kMaxConsecutiveOldReports |
558 // consecutive reports). | 578 // consecutive reports). |
559 // Expected window contents: [10011-10001] -> [10011-10001]. | 579 // Expected window contents: [1001110001] -> [1001110001]. |
560 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { | 580 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { |
561 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, {true, true}); | 581 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, {true, true}); |
562 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | 582 ValidatePacketLossStatistics(tracker, 5.0f / 10.0f, 2.0f / 9.0f); |
563 EXPECT_EQ(plr, 5.0f / 10.0f); | |
564 EXPECT_EQ(cplr, 3.0f / 10.0f); | |
565 } | 583 } |
566 | 584 |
567 // If we receive a feedback in quadrant #1, the above counter is reset. | 585 // If we receive a feedback in quadrant #1, the above counter is reset. |
568 // Expected window contents: [10011-10001] -> [11100-01111]. | 586 // Expected window contents: [1001110001] -> [1110001-GAP-111]. |
569 AddTransportFeedbackAndValidate(&tracker, base + 0x8000, | 587 AddTransportFeedbackAndValidate(&tracker, base + 0x8000, |
570 {true, true, true}); | 588 {true, true, true}); |
571 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { | 589 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { |
572 // Note: though the feedback message reports three packets, it only gets | 590 // Note: though the feedback message reports three packets, it only gets |
573 // counted once. | 591 // counted once. |
574 AddTransportFeedbackAndValidate(&tracker, base + 0xc000 + 10, | 592 AddTransportFeedbackAndValidate(&tracker, base + 0xc000 + 10, |
575 {true, false, true}); | 593 {true, false, true}); |
576 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | 594 ValidatePacketLossStatistics(tracker, 3.0f / 10.0f, 1.0f / 8.0f); |
577 EXPECT_EQ(plr, 3.0f / 10.0f); | |
578 EXPECT_EQ(cplr, 2.0f / 10.0f); | |
579 } | 595 } |
580 } | 596 } |
581 } | 597 } |
582 | 598 |
583 // Quadrant four reports ignored for up to kMaxConsecutiveOldReports times. | 599 // Quadrant four reports ignored for up to kMaxConsecutiveOldReports times. |
584 // After that, the window is reset. | 600 // After that, the window is reset. |
585 TEST(TransportFeedbackPacketLossTrackerTest, QuadrantFourReset) { | 601 TEST(TransportFeedbackPacketLossTrackerTest, QuadrantFourReset) { |
586 for (uint16_t base : kBases) { | 602 for (uint16_t base : kBases) { |
587 float plr = 0.0f; // Packet-loss-rate | 603 TransportFeedbackPacketLossTracker tracker(20, 5, 1); |
588 float cplr = 0.0f; // Consecutive-packet-loss-rate | |
589 TransportFeedbackPacketLossTracker tracker(5, 20); | |
590 | 604 |
591 // Expected window contents: [] -> [10011-10001]. | 605 // Expected window contents: [] -> [1001110001]. |
592 AddTransportFeedbackAndValidate( | 606 AddTransportFeedbackAndValidate( |
593 &tracker, base, | 607 &tracker, base, |
594 {true, false, false, true, true, true, false, false, false, true}); | 608 {true, false, false, true, true, true, false, false, false, true}); |
595 | 609 |
| 610 // Sanity |
| 611 ValidatePacketLossStatistics(tracker, 5.0f / 10.0f, 2.0f / 9.0f); |
| 612 |
596 // The first kMaxConsecutiveOldReports quadrant #4 reports are ignored. | 613 // The first kMaxConsecutiveOldReports quadrant #4 reports are ignored. |
597 // It doesn't matter that they consist of multiple packets - each report | 614 // It doesn't matter that they consist of multiple packets - each report |
598 // is only counted once. | 615 // is only counted once. |
599 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { | 616 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { |
600 // Expected window contents: [10011-10001] -> [10011-10001]. | 617 // Expected window contents: [1001110001] -> [1001110001]. |
601 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, | 618 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, |
602 {true, true, false, true}); | 619 {true, true, false, true}); |
603 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | 620 ValidatePacketLossStatistics(tracker, 5.0f / 10.0f, 2.0f / 9.0f); |
604 EXPECT_EQ(plr, 5.0f / 10.0f); | |
605 EXPECT_EQ(cplr, 3.0f / 10.0f); | |
606 } | 621 } |
607 | 622 |
608 // One additional feedback in quadrant #4 brings us over | 623 // One additional feedback in quadrant #4 brings us over |
609 // kMaxConsecutiveOldReports consecutive "old" reports, resetting the | 624 // kMaxConsecutiveOldReports consecutive "old" reports, resetting the |
610 // window. | 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. |
611 // Note: The report doesn't have to be the same as the previous ones. | 628 // Note: The report doesn't have to be the same as the previous ones. |
612 // Expected window contents: [10011-10001] -> [10011]. | 629 // Expected window contents: [1001110001] -> [10011]. |
613 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, | 630 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, |
614 {true, false, false, true, true}); | 631 {true, false, false, true, true}); |
615 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | 632 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); |
616 | |
617 // The new window is not completely empty - it's been seeded with the | |
618 // packets reported in the feedback that has triggered the reset. | |
619 EXPECT_EQ(plr, 2.0f / 5.0f); | |
620 EXPECT_EQ(cplr, 1.0f / 5.0f); | |
621 } | 633 } |
622 } | 634 } |
623 | 635 |
624 // Feedbacks spanning multiple quadrant are treated correctly (Q1-Q2). | 636 // Feedbacks spanning multiple quadrant are treated correctly (Q1-Q2). |
625 TEST(TransportFeedbackPacketLossTrackerTest, MultiQuadrantQ1Q2) { | 637 TEST(TransportFeedbackPacketLossTrackerTest, MultiQuadrantQ1Q2) { |
626 for (uint16_t base : kBases) { | 638 for (uint16_t base : kBases) { |
627 float plr = 0.0f; // Packet-loss-rate | 639 TransportFeedbackPacketLossTracker tracker(20, 5, 1); |
628 float cplr = 0.0f; // Consecutive-packet-loss-rate | |
629 TransportFeedbackPacketLossTracker tracker(5, 20); | |
630 | 640 |
631 // Expected window contents: [] -> [10011]. | 641 // Expected window contents: [] -> [10011]. |
632 AddTransportFeedbackAndValidate(&tracker, base, | 642 AddTransportFeedbackAndValidate(&tracker, base, |
633 {true, false, false, true, true}); | 643 {true, false, false, true, true}); |
634 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | 644 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); |
635 | 645 |
636 // A feedback with entries in both quadrant #1 and #2 gets both counted: | 646 // A feedback with entries in both quadrant #1 and #2 gets both counted: |
637 // Expected window contents: [10011] -> [10011-11]. | 647 // Expected window contents: [10011] -> [10011-GAP-1001]. |
638 AddTransportFeedbackAndValidate(&tracker, base + 0x3fff, {true, true}); | 648 AddTransportFeedbackAndValidate(&tracker, base + 0x3ffe, |
639 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | 649 {true, false, false, true}); |
640 EXPECT_EQ(plr, 2.0f / 7.0f); | 650 ValidatePacketLossStatistics(tracker, 4.0f / 9.0f, 2.0f / 7.0f); |
641 EXPECT_EQ(cplr, 1.0f / 7.0f); | |
642 } | 651 } |
643 } | 652 } |
644 | 653 |
645 // Feedbacks spanning multiple quadrant are treated correctly (Q2-Q3). | 654 // Feedbacks spanning multiple quadrant are treated correctly (Q2-Q3). |
646 TEST(TransportFeedbackPacketLossTrackerTest, MultiQuadrantQ2Q3) { | 655 TEST(TransportFeedbackPacketLossTrackerTest, MultiQuadrantQ2Q3) { |
647 for (uint16_t base : kBases) { | 656 for (uint16_t base : kBases) { |
648 float plr = 0.0f; // Packet-loss-rate | 657 TransportFeedbackPacketLossTracker tracker(20, 5, 1); |
649 float cplr = 0.0f; // Consecutive-packet-loss-rate | |
650 TransportFeedbackPacketLossTracker tracker(5, 20); | |
651 | 658 |
652 // Expected window contents: [] -> [10011-00001]. | 659 // Expected window contents: [] -> [1001100001]. |
653 AddTransportFeedbackAndValidate( | 660 AddTransportFeedbackAndValidate( |
654 &tracker, base, | 661 &tracker, base, |
655 {true, false, false, true, true, false, false, false, false, true}); | 662 {true, false, false, true, true, false, false, false, false, true}); |
656 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | 663 ValidatePacketLossStatistics(tracker, 6.0f / 10.0f, 2.0f / 9.0f); |
657 EXPECT_EQ(plr, 6.0f / 10.0f); | |
658 EXPECT_EQ(cplr, 4.0f / 10.0f); | |
659 | 664 |
660 // A feedback with entries in both quadrant #2 and #3 gets both counted, | 665 // A feedback with entries in both quadrant #2 and #3 gets both counted, |
661 // but only those from #3 trigger throwing out old entries from quadrant #1: | 666 // but only those from #3 trigger throwing out old entries from quadrant #1: |
662 // Expected window contents: [10011-00001] -> [01100-00110-01]. | 667 // Expected window contents: [1001100001] -> [01100001-GAP-1001]. |
663 AddTransportFeedbackAndValidate(&tracker, base + 0x7ffe, | 668 AddTransportFeedbackAndValidate(&tracker, base + 0x7ffe, |
664 {true, false, false, true}); | 669 {true, false, false, true}); |
665 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | 670 ValidatePacketLossStatistics(tracker, 7.0f / 12.0f, 3.0f / 10.0f); |
666 EXPECT_EQ(plr, 7.0f / 12.0f); | |
667 EXPECT_EQ(cplr, 4.0f / 12.0f); | |
668 } | 671 } |
669 } | 672 } |
670 | 673 |
671 // Feedbacks spanning multiple quadrant are treated correctly (Q2-Q3). | 674 // Feedbacks spanning multiple quadrant are treated correctly (Q3-Q4). |
672 TEST(TransportFeedbackPacketLossTrackerTest, MultiQuadrantQ3Q4) { | 675 TEST(TransportFeedbackPacketLossTrackerTest, MultiQuadrantQ3Q4) { |
673 for (uint16_t base : kBases) { | 676 for (uint16_t base : kBases) { |
674 float plr = 0.0f; // Packet-loss-rate | 677 TransportFeedbackPacketLossTracker tracker(20, 5, 1); |
675 float cplr = 0.0f; // Consecutive-packet-loss-rate | |
676 | 678 |
677 TransportFeedbackPacketLossTracker tracker(5, 20); | 679 // Expected window contents: [] -> [1001100001]. |
678 | |
679 // Expected window contents: [] -> [10011-00001]. | |
680 AddTransportFeedbackAndValidate( | 680 AddTransportFeedbackAndValidate( |
681 &tracker, base, | 681 &tracker, base, |
682 {true, false, false, true, true, false, false, false, false, true}); | 682 {true, false, false, true, true, false, false, false, false, true}); |
683 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | 683 ValidatePacketLossStatistics(tracker, 6.0f / 10.0f, 2.0f / 9.0f); |
684 EXPECT_EQ(plr, 6.0f / 10.0f); | |
685 EXPECT_EQ(cplr, 4.0f / 10.0f); | |
686 | 684 |
687 // A feedback with entries in both quadrant #3 and #4 would have the entries | 685 // A feedback with entries in both quadrant #3 and #4 would have the entries |
688 // from quadrant #3 shift enough quadrant #1 entries out of window, that | 686 // from quadrant #3 shift enough quadrant #1 entries out of window, that |
689 // by the time the #4 packets are examined, the moving baseline has made | 687 // by the time the #4 packets are examined, the moving baseline has made |
690 // them into quadrant #3 packets. | 688 // them into quadrant #3 packets. |
691 // Expected window contents: [10011-00001] -> [10011]. | 689 // Expected window contents: [1001100001] -> [10011]. |
692 AddTransportFeedbackAndValidate(&tracker, base + 0xbfff, | 690 AddTransportFeedbackAndValidate(&tracker, base + 0xbfff, |
693 {true, false, false, true, true}); | 691 {true, false, false, true, true}); |
694 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | 692 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); |
695 EXPECT_EQ(plr, 2.0f / 5.0f); | |
696 EXPECT_EQ(cplr, 1.0f / 5.0f); | |
697 } | 693 } |
698 } | 694 } |
699 | 695 |
700 } // namespace webrtc | 696 } // namespace webrtc |
OLD | NEW |