| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 39 const std::vector<bool>& reception_status_vec) { | 39 const std::vector<bool>& reception_status_vec) { |
| 40 const int64_t kBaseTimeUs = 1234; // Irrelevant to this test. | 40 const int64_t kBaseTimeUs = 1234; // Irrelevant to this test. |
| 41 TransportFeedback test_feedback; | 41 TransportFeedback test_feedback; |
| 42 test_feedback.SetBase(base_sequence_num, kBaseTimeUs); | 42 test_feedback.SetBase(base_sequence_num, kBaseTimeUs); |
| 43 uint16_t sequence_num = base_sequence_num; | 43 uint16_t sequence_num = base_sequence_num; |
| 44 for (bool status : reception_status_vec) { | 44 for (bool status : reception_status_vec) { |
| 45 if (status) | 45 if (status) |
| 46 test_feedback.AddReceivedPacket(sequence_num, kBaseTimeUs); | 46 test_feedback.AddReceivedPacket(sequence_num, kBaseTimeUs); |
| 47 ++sequence_num; | 47 ++sequence_num; |
| 48 } | 48 } |
| 49 |
| 50 // TransportFeedback imposes some limitations on what constitutes a legal |
| 51 // status vector. For instance, the vector 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 |
| OLD | NEW |