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

Side by Side Diff: webrtc/modules/remote_bitrate_estimator/test/estimators/nada_unittest.cc

Issue 1202253003: More Simulation Framework features (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Using rtc::scoped_ptr on nada_unittest.cc Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/modules/remote_bitrate_estimator/test/estimators/nada.h" 11 #include "webrtc/modules/remote_bitrate_estimator/test/estimators/nada.h"
12 12
13 #include <algorithm> 13 #include <algorithm>
14 #include <numeric> 14 #include <numeric>
15 15
16 #include "webrtc/base/common.h" 16 #include "webrtc/base/common.h"
17 #include "webrtc/base/scoped_ptr.h"
17 #include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.h" 18 #include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.h"
18 #include "webrtc/modules/remote_bitrate_estimator/test/packet.h" 19 #include "webrtc/modules/remote_bitrate_estimator/test/packet.h"
19 #include "testing/gtest/include/gtest/gtest.h" 20 #include "testing/gtest/include/gtest/gtest.h"
20 #include "webrtc/base/constructormagic.h" 21 #include "webrtc/base/constructormagic.h"
21 #include "webrtc/modules/remote_bitrate_estimator/test/packet_sender.h" 22 #include "webrtc/modules/remote_bitrate_estimator/test/packet_sender.h"
22 #include "webrtc/test/testsupport/fileutils.h" 23 #include "webrtc/test/testsupport/fileutils.h"
23 24
24 namespace webrtc { 25 namespace webrtc {
25 namespace testing { 26 namespace testing {
26 namespace bwe { 27 namespace bwe {
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 106
106 private: 107 private:
107 TestBitrateObserver observer_; 108 TestBitrateObserver observer_;
108 SimulatedClock simulated_clock_; 109 SimulatedClock simulated_clock_;
109 110
110 protected: 111 protected:
111 NadaBweSender nada_sender_; 112 NadaBweSender nada_sender_;
112 }; 113 };
113 114
114 class NadaReceiverSideTest : public ::testing::Test { 115 class NadaReceiverSideTest : public ::testing::Test {
115 protected: 116 public:
116 NadaReceiverSideTest() : nada_receiver_(kFlowId) {} 117 NadaReceiverSideTest() : nada_receiver_(kFlowId) {}
117 ~NadaReceiverSideTest() {} 118 ~NadaReceiverSideTest() {}
118 119
119 const int kFlowId = 0; 120 protected:
121 const int kFlowId = 1; // Arbitrary.
120 NadaBweReceiver nada_receiver_; 122 NadaBweReceiver nada_receiver_;
121 }; 123 };
122 124
123 class NadaFbGenerator { 125 class NadaFbGenerator {
124 public: 126 public:
125 NadaFbGenerator(); 127 NadaFbGenerator();
126 128
127 static NadaFeedback NotCongestedFb(size_t receiving_rate, 129 static NadaFeedback NotCongestedFb(size_t receiving_rate,
128 int64_t ref_signal_ms, 130 int64_t ref_signal_ms,
129 int64_t send_time_ms) { 131 int64_t send_time_ms) {
(...skipping 28 matching lines...) Expand all
158 } 160 }
159 161
160 private: 162 private:
161 // Arbitrary values, won't change these test results. 163 // Arbitrary values, won't change these test results.
162 static const int kFlowId = 2; 164 static const int kFlowId = 2;
163 static const int64_t kNowMs = 1000; 165 static const int64_t kNowMs = 1000;
164 }; 166 };
165 167
166 // Verify if AcceleratedRampUp is called and that bitrate increases. 168 // Verify if AcceleratedRampUp is called and that bitrate increases.
167 TEST_F(NadaSenderSideTest, AcceleratedRampUp) { 169 TEST_F(NadaSenderSideTest, AcceleratedRampUp) {
168 const int64_t kRefSignalMs = 3; 170 const int64_t kRefSignalMs = 1;
169 const int64_t kOneWayDelayMs = 50; 171 const int64_t kOneWayDelayMs = 50;
170 int original_bitrate = 2 * NadaBweSender::kMinRefRateKbps; 172 int original_bitrate = 2 * kMinBitrateKbps;
171 size_t receiving_rate = static_cast<size_t>(original_bitrate); 173 size_t receiving_rate = static_cast<size_t>(original_bitrate);
172 int64_t send_time_ms = nada_sender_.NowMs() - kOneWayDelayMs; 174 int64_t send_time_ms = nada_sender_.NowMs() - kOneWayDelayMs;
173 175
174 NadaFeedback not_congested_fb = NadaFbGenerator::NotCongestedFb( 176 NadaFeedback not_congested_fb = NadaFbGenerator::NotCongestedFb(
175 receiving_rate, kRefSignalMs, send_time_ms); 177 receiving_rate, kRefSignalMs, send_time_ms);
176 178
177 nada_sender_.set_original_operating_mode(true); 179 nada_sender_.set_original_operating_mode(true);
178 nada_sender_.set_bitrate_kbps(original_bitrate); 180 nada_sender_.set_bitrate_kbps(original_bitrate);
179 181
180 // Trigger AcceleratedRampUp mode. 182 // Trigger AcceleratedRampUp mode.
(...skipping 11 matching lines...) Expand all
192 nada_sender_.GiveFeedback(not_congested_fb); 194 nada_sender_.GiveFeedback(not_congested_fb);
193 bitrate_1_kbps = nada_sender_.bitrate_kbps(); 195 bitrate_1_kbps = nada_sender_.bitrate_kbps();
194 EXPECT_GT(bitrate_1_kbps, original_bitrate); 196 EXPECT_GT(bitrate_1_kbps, original_bitrate);
195 nada_sender_.AcceleratedRampUp(not_congested_fb); 197 nada_sender_.AcceleratedRampUp(not_congested_fb);
196 EXPECT_EQ(nada_sender_.bitrate_kbps(), bitrate_1_kbps); 198 EXPECT_EQ(nada_sender_.bitrate_kbps(), bitrate_1_kbps);
197 } 199 }
198 200
199 // Verify if AcceleratedRampDown is called and if bitrate decreases. 201 // Verify if AcceleratedRampDown is called and if bitrate decreases.
200 TEST_F(NadaSenderSideTest, AcceleratedRampDown) { 202 TEST_F(NadaSenderSideTest, AcceleratedRampDown) {
201 const int64_t kOneWayDelayMs = 50; 203 const int64_t kOneWayDelayMs = 50;
202 int original_bitrate = 3 * NadaBweSender::kMinRefRateKbps; 204 int original_bitrate = 3 * kMinBitrateKbps;
203 size_t receiving_rate = static_cast<size_t>(original_bitrate); 205 size_t receiving_rate = static_cast<size_t>(original_bitrate);
204 int64_t send_time_ms = nada_sender_.NowMs() - kOneWayDelayMs; 206 int64_t send_time_ms = nada_sender_.NowMs() - kOneWayDelayMs;
205 207
206 NadaFeedback congested_fb = 208 NadaFeedback congested_fb =
207 NadaFbGenerator::CongestedFb(receiving_rate, send_time_ms); 209 NadaFbGenerator::CongestedFb(receiving_rate, send_time_ms);
208 210
209 nada_sender_.set_original_operating_mode(false); 211 nada_sender_.set_original_operating_mode(false);
210 nada_sender_.set_bitrate_kbps(original_bitrate); 212 nada_sender_.set_bitrate_kbps(original_bitrate);
211 nada_sender_.GiveFeedback(congested_fb); // Trigger AcceleratedRampDown mode. 213 nada_sender_.GiveFeedback(congested_fb); // Trigger AcceleratedRampDown mode.
212 int bitrate_1_kbps = nada_sender_.bitrate_kbps(); 214 int bitrate_1_kbps = nada_sender_.bitrate_kbps();
213 EXPECT_LE(bitrate_1_kbps, original_bitrate * 0.9f + 0.5f); 215 EXPECT_LE(bitrate_1_kbps, original_bitrate * 0.9f + 0.5f);
214 EXPECT_LT(bitrate_1_kbps, original_bitrate); 216 EXPECT_LT(bitrate_1_kbps, original_bitrate);
215 217
216 // Updates the bitrate according to the receiving rate and other constant 218 // Updates the bitrate according to the receiving rate and other constant
217 // parameters. 219 // parameters.
218 nada_sender_.AcceleratedRampDown(congested_fb); 220 nada_sender_.AcceleratedRampDown(congested_fb);
219 int bitrate_2_kbps = 221 int bitrate_2_kbps = std::max(nada_sender_.bitrate_kbps(), kMinBitrateKbps);
220 std::max(nada_sender_.bitrate_kbps(), NadaBweSender::kMinRefRateKbps);
221 EXPECT_EQ(bitrate_2_kbps, bitrate_1_kbps); 222 EXPECT_EQ(bitrate_2_kbps, bitrate_1_kbps);
222 } 223 }
223 224
224 TEST_F(NadaSenderSideTest, GradualRateUpdate) { 225 TEST_F(NadaSenderSideTest, GradualRateUpdate) {
225 const int64_t kDeltaSMs = 20; 226 const int64_t kDeltaSMs = 20;
226 const int64_t kRefSignalMs = 20; 227 const int64_t kRefSignalMs = 20;
227 const int64_t kOneWayDelayMs = 50; 228 const int64_t kOneWayDelayMs = 50;
228 int original_bitrate = 2 * NadaBweSender::kMinRefRateKbps; 229 int original_bitrate = 2 * kMinBitrateKbps;
229 size_t receiving_rate = static_cast<size_t>(original_bitrate); 230 size_t receiving_rate = static_cast<size_t>(original_bitrate);
230 int64_t send_time_ms = nada_sender_.NowMs() - kOneWayDelayMs; 231 int64_t send_time_ms = nada_sender_.NowMs() - kOneWayDelayMs;
231 232
232 NadaFeedback congested_fb = 233 NadaFeedback congested_fb =
233 NadaFbGenerator::CongestedFb(receiving_rate, send_time_ms); 234 NadaFbGenerator::CongestedFb(receiving_rate, send_time_ms);
234 NadaFeedback not_congested_fb = NadaFbGenerator::NotCongestedFb( 235 NadaFeedback not_congested_fb = NadaFbGenerator::NotCongestedFb(
235 original_bitrate, kRefSignalMs, send_time_ms); 236 original_bitrate, kRefSignalMs, send_time_ms);
236 237
237 nada_sender_.set_bitrate_kbps(original_bitrate); 238 nada_sender_.set_bitrate_kbps(original_bitrate);
238 double smoothing_factor = 0.0; 239 double smoothing_factor = 0.0;
239 nada_sender_.GradualRateUpdate(congested_fb, kDeltaSMs, smoothing_factor); 240 nada_sender_.GradualRateUpdate(congested_fb, kDeltaSMs, smoothing_factor);
240 EXPECT_EQ(nada_sender_.bitrate_kbps(), original_bitrate); 241 EXPECT_EQ(nada_sender_.bitrate_kbps(), original_bitrate);
241 242
242 smoothing_factor = 1.0; 243 smoothing_factor = 1.0;
243 nada_sender_.GradualRateUpdate(congested_fb, kDeltaSMs, smoothing_factor); 244 nada_sender_.GradualRateUpdate(congested_fb, kDeltaSMs, smoothing_factor);
244 EXPECT_LT(nada_sender_.bitrate_kbps(), original_bitrate); 245 EXPECT_LT(nada_sender_.bitrate_kbps(), original_bitrate);
245 246
246 nada_sender_.set_bitrate_kbps(original_bitrate); 247 nada_sender_.set_bitrate_kbps(original_bitrate);
247 nada_sender_.GradualRateUpdate(not_congested_fb, kDeltaSMs, smoothing_factor); 248 nada_sender_.GradualRateUpdate(not_congested_fb, kDeltaSMs, smoothing_factor);
248 EXPECT_GT(nada_sender_.bitrate_kbps(), original_bitrate); 249 EXPECT_GT(nada_sender_.bitrate_kbps(), original_bitrate);
249 } 250 }
250 251
251 // Sending bitrate should decrease and reach its Min bound. 252 // Sending bitrate should decrease and reach its Min bound.
252 TEST_F(NadaSenderSideTest, VeryLowBandwith) { 253 TEST_F(NadaSenderSideTest, VeryLowBandwith) {
253 const int64_t kOneWayDelayMs = 50; 254 const int64_t kOneWayDelayMs = 50;
254 const int kMin = NadaBweSender::kMinRefRateKbps; 255
255 size_t receiving_rate = static_cast<size_t>(kMin); 256 size_t receiving_rate = static_cast<size_t>(kMinBitrateKbps);
256 int64_t send_time_ms = nada_sender_.NowMs() - kOneWayDelayMs; 257 int64_t send_time_ms = nada_sender_.NowMs() - kOneWayDelayMs;
257 258
258 NadaFeedback extremely_congested_fb = 259 NadaFeedback extremely_congested_fb =
259 NadaFbGenerator::ExtremelyCongestedFb(receiving_rate, send_time_ms); 260 NadaFbGenerator::ExtremelyCongestedFb(receiving_rate, send_time_ms);
260 NadaFeedback congested_fb = 261 NadaFeedback congested_fb =
261 NadaFbGenerator::CongestedFb(receiving_rate, send_time_ms); 262 NadaFbGenerator::CongestedFb(receiving_rate, send_time_ms);
262 263
263 nada_sender_.set_bitrate_kbps(5 * kMin); 264 nada_sender_.set_bitrate_kbps(5 * kMinBitrateKbps);
264 nada_sender_.set_original_operating_mode(true); 265 nada_sender_.set_original_operating_mode(true);
265 for (int i = 0; i < 100; ++i) { 266 for (int i = 0; i < 100; ++i) {
266 // Trigger GradualRateUpdate mode. 267 // Trigger GradualRateUpdate mode.
267 nada_sender_.GiveFeedback(extremely_congested_fb); 268 nada_sender_.GiveFeedback(extremely_congested_fb);
268 } 269 }
269 // The original implementation doesn't allow the bitrate to stay at kMin, 270 // The original implementation doesn't allow the bitrate to stay at kMin,
270 // even if the congestion signal is very high. 271 // even if the congestion signal is very high.
271 EXPECT_GE(nada_sender_.bitrate_kbps(), kMin); 272 EXPECT_GE(nada_sender_.bitrate_kbps(), kMinBitrateKbps);
272 273
273 nada_sender_.set_original_operating_mode(false); 274 nada_sender_.set_original_operating_mode(false);
274 nada_sender_.set_bitrate_kbps(5 * kMin); 275 nada_sender_.set_bitrate_kbps(5 * kMinBitrateKbps);
275 276
276 for (int i = 0; i < 100; ++i) { 277 for (int i = 0; i < 1000; ++i) {
277 int previous_bitrate = nada_sender_.bitrate_kbps(); 278 int previous_bitrate = nada_sender_.bitrate_kbps();
278 // Trigger AcceleratedRampDown mode. 279 // Trigger AcceleratedRampDown mode.
279 nada_sender_.GiveFeedback(congested_fb); 280 nada_sender_.GiveFeedback(congested_fb);
280 EXPECT_LE(nada_sender_.bitrate_kbps(), previous_bitrate); 281 EXPECT_LE(nada_sender_.bitrate_kbps(), previous_bitrate);
281 } 282 }
282 EXPECT_EQ(nada_sender_.bitrate_kbps(), kMin); 283 EXPECT_EQ(nada_sender_.bitrate_kbps(), kMinBitrateKbps);
283 } 284 }
284 285
285 // Sending bitrate should increase and reach its Max bound. 286 // Sending bitrate should increase and reach its Max bound.
286 TEST_F(NadaSenderSideTest, VeryHighBandwith) { 287 TEST_F(NadaSenderSideTest, VeryHighBandwith) {
287 const int64_t kOneWayDelayMs = 50; 288 const int64_t kOneWayDelayMs = 50;
288 const int kMax = NadaBweSender::kMaxRefRateKbps; 289 const size_t kRecentReceivingRate = static_cast<size_t>(kMaxBitrateKbps);
289 const size_t kRecentReceivingRate = static_cast<size_t>(kMax); 290 const int64_t kRefSignalMs = 1;
290 const int64_t kRefSignalMs = 5;
291 int64_t send_time_ms = nada_sender_.NowMs() - kOneWayDelayMs; 291 int64_t send_time_ms = nada_sender_.NowMs() - kOneWayDelayMs;
292 292
293 NadaFeedback not_congested_fb = NadaFbGenerator::NotCongestedFb( 293 NadaFeedback not_congested_fb = NadaFbGenerator::NotCongestedFb(
294 kRecentReceivingRate, kRefSignalMs, send_time_ms); 294 kRecentReceivingRate, kRefSignalMs, send_time_ms);
295 295
296 nada_sender_.set_original_operating_mode(true); 296 nada_sender_.set_original_operating_mode(true);
297 for (int i = 0; i < 100; ++i) { 297 for (int i = 0; i < 100; ++i) {
298 int previous_bitrate = nada_sender_.bitrate_kbps(); 298 int previous_bitrate = nada_sender_.bitrate_kbps();
299 nada_sender_.GiveFeedback(not_congested_fb); 299 nada_sender_.GiveFeedback(not_congested_fb);
300 EXPECT_GE(nada_sender_.bitrate_kbps(), previous_bitrate); 300 EXPECT_GE(nada_sender_.bitrate_kbps(), previous_bitrate);
301 } 301 }
302 EXPECT_EQ(nada_sender_.bitrate_kbps(), kMax); 302 EXPECT_EQ(nada_sender_.bitrate_kbps(), kMaxBitrateKbps);
303 303
304 nada_sender_.set_original_operating_mode(false); 304 nada_sender_.set_original_operating_mode(false);
305 nada_sender_.set_bitrate_kbps(NadaBweSender::kMinRefRateKbps); 305 nada_sender_.set_bitrate_kbps(kMinBitrateKbps);
306 306
307 for (int i = 0; i < 100; ++i) { 307 for (int i = 0; i < 100; ++i) {
308 int previous_bitrate = nada_sender_.bitrate_kbps(); 308 int previous_bitrate = nada_sender_.bitrate_kbps();
309 nada_sender_.GiveFeedback(not_congested_fb); 309 nada_sender_.GiveFeedback(not_congested_fb);
310 EXPECT_GE(nada_sender_.bitrate_kbps(), previous_bitrate); 310 EXPECT_GE(nada_sender_.bitrate_kbps(), previous_bitrate);
311 } 311 }
312 EXPECT_EQ(nada_sender_.bitrate_kbps(), kMax); 312 EXPECT_EQ(nada_sender_.bitrate_kbps(), kMaxBitrateKbps);
313 } 313 }
314 314
315 TEST_F(NadaReceiverSideTest, ReceivingRateNoPackets) { 315 TEST_F(NadaReceiverSideTest, FeedbackInitialCases) {
316 EXPECT_EQ(nada_receiver_.RecentReceivingRate(), static_cast<size_t>(0)); 316 rtc::scoped_ptr<NadaFeedback> nada_feedback(
317 static_cast<NadaFeedback*>(nada_receiver_.GetFeedback(0)));
318 EXPECT_EQ(nada_feedback, nullptr);
319
320 nada_feedback.reset(
321 static_cast<NadaFeedback*>(nada_receiver_.GetFeedback(100)));
322 EXPECT_EQ(nada_feedback->exp_smoothed_delay_ms(), -1);
323 EXPECT_EQ(nada_feedback->est_queuing_delay_signal_ms(), 0L);
324 EXPECT_EQ(nada_feedback->congestion_signal(), 0L);
325 EXPECT_EQ(nada_feedback->derivative(), 0.0f);
326 EXPECT_EQ(nada_feedback->receiving_rate(), 0.0f);
317 } 327 }
318 328
319 TEST_F(NadaReceiverSideTest, ReceivingRateSinglePacket) { 329 TEST_F(NadaReceiverSideTest, FeedbackEmptyQueues) {
320 const size_t kPayloadSizeBytes = 500 * 1000; 330 const int64_t kTimeGapMs = 50; // Between each packet.
321 const int64_t kSendTimeUs = 300 * 1000; 331 const int64_t kOneWayDelayMs = 50;
322 const int64_t kArrivalTimeMs = kSendTimeUs / 1000 + 100;
323 const uint16_t kSequenceNumber = 1;
324 const int64_t kTimeWindowMs = NadaBweReceiver::kReceivingRateTimeWindowMs;
325 332
326 const MediaPacket media_packet(kFlowId, kSendTimeUs, kPayloadSizeBytes, 333 // No added latency, delay = kOneWayDelayMs.
327 kSequenceNumber); 334 for (int i = 1; i < 10; ++i) {
328 nada_receiver_.ReceivePacket(kArrivalTimeMs, media_packet);
329
330 const size_t kReceivingRateKbps = 8 * kPayloadSizeBytes / kTimeWindowMs;
331
332 EXPECT_EQ(nada_receiver_.RecentReceivingRate(), kReceivingRateKbps);
333 }
334
335 TEST_F(NadaReceiverSideTest, ReceivingRateLargePackets) {
336 const size_t kPayloadSizeBytes = 3000 * 1000;
337 const int64_t kTimeGapMs = 3000; // Between each packet.
338 const int64_t kOneWayDelayMs = 1000;
339
340 for (int i = 1; i < 5; ++i) {
341 int64_t send_time_us = i * kTimeGapMs * 1000; 335 int64_t send_time_us = i * kTimeGapMs * 1000;
342 int64_t arrival_time_ms = send_time_us / 1000 + kOneWayDelayMs; 336 int64_t arrival_time_ms = send_time_us / 1000 + kOneWayDelayMs;
343 uint16_t sequence_number = i; 337 uint16_t sequence_number = static_cast<uint16_t>(i);
344 const MediaPacket media_packet(kFlowId, send_time_us, kPayloadSizeBytes, 338 // Payload sizes are not important here.
345 sequence_number); 339 const MediaPacket media_packet(kFlowId, send_time_us, 0, sequence_number);
346 nada_receiver_.ReceivePacket(arrival_time_ms, media_packet); 340 nada_receiver_.ReceivePacket(arrival_time_ms, media_packet);
347 } 341 }
348 342
349 const size_t kReceivingRateKbps = 8 * kPayloadSizeBytes / kTimeGapMs; 343 // Baseline delay will be equal kOneWayDelayMs.
350 EXPECT_EQ(nada_receiver_.RecentReceivingRate(), kReceivingRateKbps); 344 rtc::scoped_ptr<NadaFeedback> nada_feedback(
345 static_cast<NadaFeedback*>(nada_receiver_.GetFeedback(500)));
346 EXPECT_EQ(nada_feedback->exp_smoothed_delay_ms(), 0L);
347 EXPECT_EQ(nada_feedback->est_queuing_delay_signal_ms(), 0L);
348 EXPECT_EQ(nada_feedback->congestion_signal(), 0L);
349 EXPECT_EQ(nada_feedback->derivative(), 0.0f);
351 } 350 }
352 351
353 TEST_F(NadaReceiverSideTest, ReceivingRateSmallPackets) { 352 TEST_F(NadaReceiverSideTest, FeedbackIncreasingDelay) {
354 const size_t kPayloadSizeBytes = 100 * 1000; 353 // Since packets are 100ms apart, each one corresponds to a feedback.
355 const int64_t kTimeGapMs = 50; // Between each packet. 354 const int64_t kTimeGapMs = 100; // Between each packet.
356 const int64_t kOneWayDelayMs = 50;
357 355
358 for (int i = 1; i < 50; ++i) { 356 // Raw delays are = [10 20 30 40 50 60 70 80] ms.
359 int64_t send_time_us = i * kTimeGapMs * 1000; 357 // Baseline delay will be 50 ms.
360 int64_t arrival_time_ms = send_time_us / 1000 + kOneWayDelayMs; 358 // Delay signals should be: [0 10 20 30 40 50 60 70] ms.
361 uint16_t sequence_number = i; 359 const int64_t kMedianFilteredDelaysMs[] = {0, 10, 10, 20, 20, 30, 40, 50};
362 const MediaPacket media_packet(kFlowId, send_time_us, kPayloadSizeBytes, 360 const int kNumPackets = ARRAY_SIZE(kMedianFilteredDelaysMs);
363 sequence_number); 361 const float kAlpha = 0.1f; // Used for exponential smoothing.
364 nada_receiver_.ReceivePacket(arrival_time_ms, media_packet); 362
363 int64_t exp_smoothed_delays_ms[kNumPackets];
364 exp_smoothed_delays_ms[0] = kMedianFilteredDelaysMs[0];
365
366 for (int i = 1; i < kNumPackets; ++i) {
367 exp_smoothed_delays_ms[i] = static_cast<int64_t>(
368 kAlpha * kMedianFilteredDelaysMs[i] +
369 (1.0f - kAlpha) * exp_smoothed_delays_ms[i - 1] + 0.5f);
365 } 370 }
366 371
367 const size_t kReceivingRateKbps = 8 * kPayloadSizeBytes / kTimeGapMs; 372 for (int i = 0; i < kNumPackets; ++i) {
368 EXPECT_EQ(nada_receiver_.RecentReceivingRate(), kReceivingRateKbps); 373 int64_t send_time_us = (i + 1) * kTimeGapMs * 1000;
374 int64_t arrival_time_ms = send_time_us / 1000 + 10 * (i + 1);
375 uint16_t sequence_number = static_cast<uint16_t>(i + 1);
376 // Payload sizes are not important here.
377 const MediaPacket media_packet(kFlowId, send_time_us, 0, sequence_number);
378 nada_receiver_.ReceivePacket(arrival_time_ms, media_packet);
379
380 rtc::scoped_ptr<NadaFeedback> nada_feedback(static_cast<NadaFeedback*>(
381 nada_receiver_.GetFeedback(arrival_time_ms)));
382 EXPECT_EQ(nada_feedback->exp_smoothed_delay_ms(),
383 exp_smoothed_delays_ms[i]);
384 // Since delay signals are lower than 50ms, they will not be non-linearly
385 // warped.
386 EXPECT_EQ(nada_feedback->est_queuing_delay_signal_ms(),
387 exp_smoothed_delays_ms[i]);
388 // Zero loss, congestion signal = queuing_delay
389 EXPECT_EQ(nada_feedback->congestion_signal(), exp_smoothed_delays_ms[i]);
390 if (i == 0) {
391 EXPECT_NEAR(nada_feedback->derivative(),
392 static_cast<float>(exp_smoothed_delays_ms[i]) / kTimeGapMs,
393 0.005f);
394 } else {
395 EXPECT_NEAR(nada_feedback->derivative(),
396 static_cast<float>(exp_smoothed_delays_ms[i] -
397 exp_smoothed_delays_ms[i - 1]) /
398 kTimeGapMs,
399 0.005f);
400 }
401 }
369 } 402 }
370 403
371 TEST_F(NadaReceiverSideTest, ReceivingRateIntermittentPackets) { 404 int64_t Warp(int64_t input) {
372 const size_t kPayloadSizeBytes = 100 * 1000; 405 const int64_t kMinThreshold = 50; // Referred as d_th.
373 const int64_t kTimeGapMs = 50; // Between each packet. 406 const int64_t kMaxThreshold = 400; // Referred as d_max.
374 const int64_t kFirstSendTimeMs = 0; 407 if (input < kMinThreshold) {
375 const int64_t kOneWayDelayMs = 50; 408 return input;
409 } else if (input < kMaxThreshold) {
410 return static_cast<int64_t>(
411 pow((static_cast<double>(kMaxThreshold - input)) /
412 (kMaxThreshold - kMinThreshold),
413 4.0) *
414 kMinThreshold);
415 } else {
416 return 0L;
417 }
418 }
376 419
377 // Gap between first and other packets 420 TEST_F(NadaReceiverSideTest, FeedbackWarpedDelay) {
378 const MediaPacket media_packet(kFlowId, kFirstSendTimeMs, kPayloadSizeBytes, 421 // Since packets are 100ms apart, each one corresponds to a feedback.
379 1); 422 const int64_t kTimeGapMs = 100; // Between each packet.
380 nada_receiver_.ReceivePacket(kFirstSendTimeMs + kOneWayDelayMs, media_packet);
381 423
382 const int64_t kDelayAfterFirstPacketMs = 1000; 424 // Raw delays are = [50 250 450 650 850 1050 1250 1450] ms.
383 const int kNumPackets = 5; // Small enough so that all packets are covered. 425 // Baseline delay will be 50 ms.
384 EXPECT_LT((kNumPackets - 2) * kTimeGapMs, 426 // Delay signals should be: [0 200 400 600 800 1000 1200 1400] ms.
385 NadaBweReceiver::kReceivingRateTimeWindowMs); 427 const int64_t kMedianFilteredDelaysMs[] = {
386 const int64_t kTimeWindowMs = 428 0, 200, 200, 400, 400, 600, 800, 1000};
387 kDelayAfterFirstPacketMs + (kNumPackets - 2) * kTimeGapMs; 429 const int kNumPackets = ARRAY_SIZE(kMedianFilteredDelaysMs);
430 const float kAlpha = 0.1f; // Used for exponential smoothing.
388 431
389 for (int i = 2; i <= kNumPackets; ++i) { 432 int64_t exp_smoothed_delays_ms[kNumPackets];
390 int64_t send_time_us = 433 exp_smoothed_delays_ms[0] = kMedianFilteredDelaysMs[0];
391 ((i - 2) * kTimeGapMs + kFirstSendTimeMs + kDelayAfterFirstPacketMs) * 434
392 1000; 435 for (int i = 1; i < kNumPackets; ++i) {
393 int64_t arrival_time_ms = send_time_us / 1000 + kOneWayDelayMs; 436 exp_smoothed_delays_ms[i] = static_cast<int64_t>(
394 uint16_t sequence_number = i; 437 kAlpha * kMedianFilteredDelaysMs[i] +
395 const MediaPacket media_packet(kFlowId, send_time_us, kPayloadSizeBytes, 438 (1.0f - kAlpha) * exp_smoothed_delays_ms[i - 1] + 0.5f);
396 sequence_number);
397 nada_receiver_.ReceivePacket(arrival_time_ms, media_packet);
398 } 439 }
399 440
400 const size_t kTotalReceivedKb = 8 * kNumPackets * kPayloadSizeBytes; 441 for (int i = 0; i < kNumPackets; ++i) {
401 const int64_t kCorrectedTimeWindowMs = 442 int64_t send_time_us = (i + 1) * kTimeGapMs * 1000;
402 (kTimeWindowMs * kNumPackets) / (kNumPackets - 1); 443 int64_t arrival_time_ms = send_time_us / 1000 + 50 + 200 * i;
403 EXPECT_EQ(nada_receiver_.RecentReceivingRate(), 444 uint16_t sequence_number = static_cast<uint16_t>(i + 1);
404 kTotalReceivedKb / kCorrectedTimeWindowMs); 445 // Payload sizes are not important here.
405 } 446 const MediaPacket media_packet(kFlowId, send_time_us, 0, sequence_number);
447 nada_receiver_.ReceivePacket(arrival_time_ms, media_packet);
406 448
407 TEST_F(NadaReceiverSideTest, ReceivingRateDuplicatedPackets) { 449 rtc::scoped_ptr<NadaFeedback> nada_feedback(static_cast<NadaFeedback*>(
408 const size_t kPayloadSizeBytes = 500 * 1000; 450 nada_receiver_.GetFeedback(arrival_time_ms)));
409 const int64_t kSendTimeUs = 300 * 1000; 451 EXPECT_EQ(nada_feedback->exp_smoothed_delay_ms(),
410 const int64_t kArrivalTimeMs = kSendTimeUs / 1000 + 100; 452 exp_smoothed_delays_ms[i]);
411 const uint16_t kSequenceNumber = 1; 453 // Delays can be non-linearly warped.
412 const int64_t kTimeWindowMs = NadaBweReceiver::kReceivingRateTimeWindowMs; 454 EXPECT_EQ(nada_feedback->est_queuing_delay_signal_ms(),
413 455 Warp(exp_smoothed_delays_ms[i]));
414 // Insert the same packet twice. 456 // Zero loss, congestion signal = queuing_delay
415 for (int i = 0; i < 2; ++i) { 457 EXPECT_EQ(nada_feedback->congestion_signal(),
416 const MediaPacket media_packet(kFlowId, kSendTimeUs + 50 * i, 458 Warp(exp_smoothed_delays_ms[i]));
417 kPayloadSizeBytes, kSequenceNumber);
418 nada_receiver_.ReceivePacket(kArrivalTimeMs + 50 * i, media_packet);
419 } 459 }
420 // Should be counted only once.
421 const size_t kReceivingRateKbps = 8 * kPayloadSizeBytes / kTimeWindowMs;
422
423 EXPECT_EQ(nada_receiver_.RecentReceivingRate(), kReceivingRateKbps);
424 }
425
426 TEST_F(NadaReceiverSideTest, PacketLossNoPackets) {
427 EXPECT_EQ(nada_receiver_.RecentPacketLossRatio(), 0.0f);
428 }
429
430 TEST_F(NadaReceiverSideTest, PacketLossSinglePacket) {
431 const MediaPacket media_packet(kFlowId, 0, 0, 0);
432 nada_receiver_.ReceivePacket(0, media_packet);
433 EXPECT_EQ(nada_receiver_.RecentPacketLossRatio(), 0.0f);
434 }
435
436 TEST_F(NadaReceiverSideTest, PacketLossContiguousPackets) {
437 const int64_t kTimeWindowMs = NadaBweReceiver::kPacketLossTimeWindowMs;
438 size_t set_capacity = nada_receiver_.GetSetCapacity();
439
440 for (int i = 0; i < 10; ++i) {
441 uint16_t sequence_number = static_cast<uint16_t>(i);
442 // Sequence_number and flow_id are the only members that matter here.
443 const MediaPacket media_packet(kFlowId, 0, 0, sequence_number);
444 // Arrival time = 0, all packets will be considered.
445 nada_receiver_.ReceivePacket(0, media_packet);
446 }
447 EXPECT_EQ(nada_receiver_.RecentPacketLossRatio(), 0.0f);
448
449 for (int i = 30; i > 20; i--) {
450 uint16_t sequence_number = static_cast<uint16_t>(i);
451 // Sequence_number and flow_id are the only members that matter here.
452 const MediaPacket media_packet(kFlowId, 0, 0, sequence_number);
453 // Only the packets sent in this for loop will be considered.
454 nada_receiver_.ReceivePacket(2 * kTimeWindowMs, media_packet);
455 }
456 EXPECT_EQ(nada_receiver_.RecentPacketLossRatio(), 0.0f);
457
458 // Should handle uint16_t overflow.
459 for (int i = 0xFFFF - 10; i < 0xFFFF + 10; ++i) {
460 uint16_t sequence_number = static_cast<uint16_t>(i);
461 const MediaPacket media_packet(kFlowId, 0, 0, sequence_number);
462 // Only the packets sent in this for loop will be considered.
463 nada_receiver_.ReceivePacket(4 * kTimeWindowMs, media_packet);
464 }
465 EXPECT_EQ(nada_receiver_.RecentPacketLossRatio(), 0.0f);
466
467 // Should handle set overflow.
468 for (int i = 0; i < set_capacity * 1.5; ++i) {
469 uint16_t sequence_number = static_cast<uint16_t>(i);
470 const MediaPacket media_packet(kFlowId, 0, 0, sequence_number);
471 // Only the packets sent in this for loop will be considered.
472 nada_receiver_.ReceivePacket(6 * kTimeWindowMs, media_packet);
473 }
474 EXPECT_EQ(nada_receiver_.RecentPacketLossRatio(), 0.0f);
475 }
476
477 // Should handle duplicates.
478 TEST_F(NadaReceiverSideTest, PacketLossDuplicatedPackets) {
479 const int64_t kTimeWindowMs = NadaBweReceiver::kPacketLossTimeWindowMs;
480
481 for (int i = 0; i < 10; ++i) {
482 const MediaPacket media_packet(kFlowId, 0, 0, 0);
483 // Arrival time = 0, all packets will be considered.
484 nada_receiver_.ReceivePacket(0, media_packet);
485 }
486 EXPECT_EQ(nada_receiver_.RecentPacketLossRatio(), 0.0f);
487
488 // Missing the element 5.
489 const uint16_t kSequenceNumbers[] = {1, 2, 3, 4, 6, 7, 8};
490 const int kNumPackets = ARRAY_SIZE(kSequenceNumbers);
491
492 // Insert each sequence number twice.
493 for (int i = 0; i < 2; ++i) {
494 for (int j = 0; j < kNumPackets; j++) {
495 const MediaPacket media_packet(kFlowId, 0, 0, kSequenceNumbers[j]);
496 // Only the packets sent in this for loop will be considered.
497 nada_receiver_.ReceivePacket(2 * kTimeWindowMs, media_packet);
498 }
499 }
500
501 EXPECT_NEAR(nada_receiver_.RecentPacketLossRatio(), 1.0f / (kNumPackets + 1),
502 0.1f / (kNumPackets + 1));
503 }
504
505 TEST_F(NadaReceiverSideTest, PacketLossLakingPackets) {
506 size_t set_capacity = nada_receiver_.GetSetCapacity();
507 EXPECT_LT(set_capacity, static_cast<size_t>(0xFFFF));
508
509 // Missing every other packet.
510 for (size_t i = 0; i < set_capacity; ++i) {
511 if ((i & 1) == 0) { // Only even sequence numbers.
512 uint16_t sequence_number = static_cast<uint16_t>(i);
513 const MediaPacket media_packet(kFlowId, 0, 0, sequence_number);
514 // Arrival time = 0, all packets will be considered.
515 nada_receiver_.ReceivePacket(0, media_packet);
516 }
517 }
518 EXPECT_NEAR(nada_receiver_.RecentPacketLossRatio(), 0.5f, 0.01f);
519 }
520
521 TEST_F(NadaReceiverSideTest, PacketLossLakingFewPackets) {
522 size_t set_capacity = nada_receiver_.GetSetCapacity();
523 EXPECT_LT(set_capacity, static_cast<size_t>(0xFFFF));
524
525 const int kPeriod = 100;
526 // Missing one for each kPeriod packets.
527 for (size_t i = 0; i < set_capacity; ++i) {
528 if ((i % kPeriod) != 0) {
529 uint16_t sequence_number = static_cast<uint16_t>(i);
530 const MediaPacket media_packet(kFlowId, 0, 0, sequence_number);
531 // Arrival time = 0, all packets will be considered.
532 nada_receiver_.ReceivePacket(0, media_packet);
533 }
534 }
535 EXPECT_NEAR(nada_receiver_.RecentPacketLossRatio(), 1.0f / kPeriod,
536 0.1f / kPeriod);
537 }
538
539 // Packet's sequence numbers greatly apart, expect high loss.
540 TEST_F(NadaReceiverSideTest, PacketLossWideGap) {
541 const int64_t kTimeWindowMs = NadaBweReceiver::kPacketLossTimeWindowMs;
542
543 const MediaPacket media_packet1(0, 0, 0, 1);
544 const MediaPacket media_packet2(0, 0, 0, 1000);
545 // Only these two packets will be considered.
546 nada_receiver_.ReceivePacket(0, media_packet1);
547 nada_receiver_.ReceivePacket(0, media_packet2);
548 EXPECT_NEAR(nada_receiver_.RecentPacketLossRatio(), 0.998f, 0.0001f);
549
550 const MediaPacket media_packet3(0, 0, 0, 0);
551 const MediaPacket media_packet4(0, 0, 0, 0x8000);
552 // Only these two packets will be considered.
553 nada_receiver_.ReceivePacket(2 * kTimeWindowMs, media_packet3);
554 nada_receiver_.ReceivePacket(2 * kTimeWindowMs, media_packet4);
555 EXPECT_NEAR(nada_receiver_.RecentPacketLossRatio(), 0.99994f, 0.00001f);
556 }
557
558 // Packets arriving unordered should not be counted as losted.
559 TEST_F(NadaReceiverSideTest, PacketLossUnorderedPackets) {
560 size_t num_packets = nada_receiver_.GetSetCapacity() / 2;
561 std::vector<uint16_t> sequence_numbers;
562
563 for (size_t i = 0; i < num_packets; ++i) {
564 sequence_numbers.push_back(static_cast<uint16_t>(i + 1));
565 }
566
567 random_shuffle(sequence_numbers.begin(), sequence_numbers.end());
568
569 for (size_t i = 0; i < num_packets; ++i) {
570 const MediaPacket media_packet(kFlowId, 0, 0, sequence_numbers[i]);
571 // Arrival time = 0, all packets will be considered.
572 nada_receiver_.ReceivePacket(0, media_packet);
573 }
574
575 EXPECT_EQ(nada_receiver_.RecentPacketLossRatio(), 0.0f);
576 } 460 }
577 461
578 TEST_F(FilterTest, MedianConstantArray) { 462 TEST_F(FilterTest, MedianConstantArray) {
579 MedianFilterConstantArray(); 463 MedianFilterConstantArray();
580 for (int i = 0; i < kNumElements; ++i) { 464 for (int i = 0; i < kNumElements; ++i) {
581 EXPECT_EQ(median_filtered_[i], raw_signal_[i]); 465 EXPECT_EQ(median_filtered_[i], raw_signal_[i]);
582 } 466 }
583 } 467 }
584 468
585 TEST_F(FilterTest, MedianIntermittentNoise) { 469 TEST_F(FilterTest, MedianIntermittentNoise) {
(...skipping 16 matching lines...) Expand all
602 for (int i = 1; i < kNumElements; ++i) { 486 for (int i = 1; i < kNumElements; ++i) {
603 EXPECT_EQ( 487 EXPECT_EQ(
604 exp_smoothed[i], 488 exp_smoothed[i],
605 static_cast<int64_t>(exp_smoothed[i - 1] * (1.0f - kAlpha) + 0.5f)); 489 static_cast<int64_t>(exp_smoothed[i - 1] * (1.0f - kAlpha) + 0.5f));
606 } 490 }
607 } 491 }
608 492
609 } // namespace bwe 493 } // namespace bwe
610 } // namespace testing 494 } // namespace testing
611 } // namespace webrtc 495 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698