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

Side by Side Diff: webrtc/voice_engine/transport_feedback_packet_loss_tracker_unittest.cc

Issue 2629883003: First-order-FEC recoverability calculation (Closed)
Patch Set: nit Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698