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