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

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

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

Powered by Google App Engine
This is Rietveld 408576698