OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2013 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/bwe_test.h" | 11 #include "webrtc/modules/remote_bitrate_estimator/test/bwe_test.h" |
12 | 12 |
13 #include <sstream> | |
14 | |
13 #include "webrtc/base/common.h" | 15 #include "webrtc/base/common.h" |
14 #include "webrtc/base/scoped_ptr.h" | 16 #include "webrtc/base/scoped_ptr.h" |
15 #include "webrtc/modules/interface/module_common_types.h" | 17 #include "webrtc/modules/interface/module_common_types.h" |
16 #include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.h" | 18 #include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.h" |
19 #include "webrtc/modules/remote_bitrate_estimator/test/metric_recorder.h" | |
17 #include "webrtc/modules/remote_bitrate_estimator/test/packet_receiver.h" | 20 #include "webrtc/modules/remote_bitrate_estimator/test/packet_receiver.h" |
18 #include "webrtc/modules/remote_bitrate_estimator/test/packet_sender.h" | 21 #include "webrtc/modules/remote_bitrate_estimator/test/packet_sender.h" |
19 #include "webrtc/system_wrappers/interface/clock.h" | 22 #include "webrtc/system_wrappers/interface/clock.h" |
20 #include "webrtc/test/testsupport/perf_test.h" | 23 #include "webrtc/test/testsupport/perf_test.h" |
21 | 24 |
22 using std::string; | 25 using std::string; |
23 using std::vector; | 26 using std::vector; |
24 | 27 |
25 namespace webrtc { | 28 namespace webrtc { |
26 namespace testing { | 29 namespace testing { |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
82 for (; it != queue_.end(); ++it) { | 85 for (; it != queue_.end(); ++it) { |
83 if ((*it)->send_time_us() > end_of_batch_time_us) { | 86 if ((*it)->send_time_us() > end_of_batch_time_us) { |
84 break; | 87 break; |
85 } | 88 } |
86 } | 89 } |
87 Packets to_transfer; | 90 Packets to_transfer; |
88 to_transfer.splice(to_transfer.begin(), queue_, queue_.begin(), it); | 91 to_transfer.splice(to_transfer.begin(), queue_, queue_.begin(), it); |
89 batch->merge(to_transfer, DereferencingComparator<Packet>); | 92 batch->merge(to_transfer, DereferencingComparator<Packet>); |
90 } | 93 } |
91 | 94 |
92 BweTest::BweTest() | 95 // Plot link capacity by default. |
93 : run_time_ms_(0), time_now_ms_(-1), simulation_interval_ms_(-1) { | 96 BweTest::BweTest() : BweTest(true) { |
97 } | |
98 | |
99 BweTest::BweTest(bool plot_capacity) | |
100 : run_time_ms_(0), | |
101 time_now_ms_(-1), | |
102 simulation_interval_ms_(-1), | |
103 plot_total_available_capacity_(plot_capacity) { | |
94 links_.push_back(&uplink_); | 104 links_.push_back(&uplink_); |
95 links_.push_back(&downlink_); | 105 links_.push_back(&downlink_); |
96 } | 106 } |
97 | 107 |
98 BweTest::~BweTest() { | 108 BweTest::~BweTest() { |
99 for (Packet* packet : packets_) | 109 for (Packet* packet : packets_) |
100 delete packet; | 110 delete packet; |
101 } | 111 } |
102 | 112 |
103 void BweTest::SetUp() { | 113 void BweTest::SetUp() { |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
227 fairness_index /= flow_throughput_kbps.size() * squared_bitrate_sum; | 237 fairness_index /= flow_throughput_kbps.size() * squared_bitrate_sum; |
228 } | 238 } |
229 webrtc::test::PrintResult("BwePerformance", GetTestName(), "Fairness", | 239 webrtc::test::PrintResult("BwePerformance", GetTestName(), "Fairness", |
230 fairness_index * 100, "%", false); | 240 fairness_index * 100, "%", false); |
231 } | 241 } |
232 | 242 |
233 void BweTest::RunFairnessTest(BandwidthEstimatorType bwe_type, | 243 void BweTest::RunFairnessTest(BandwidthEstimatorType bwe_type, |
234 size_t num_media_flows, | 244 size_t num_media_flows, |
235 size_t num_tcp_flows, | 245 size_t num_tcp_flows, |
236 int64_t run_time_seconds, | 246 int64_t run_time_seconds, |
237 int capacity_kbps, | 247 uint32_t capacity_kbps, |
238 int max_delay_ms) { | 248 int64_t max_delay_ms, |
249 int64_t rtt_ms, | |
250 int64_t max_jitter_ms, | |
251 const int64_t* offsets_ms) { | |
252 RunFairnessTest(bwe_type, num_media_flows, num_tcp_flows, run_time_seconds, | |
253 capacity_kbps, max_delay_ms, rtt_ms, max_jitter_ms, | |
254 offsets_ms, "Fairness_test", bwe_names[bwe_type]); | |
255 } | |
256 | |
257 void BweTest::RunFairnessTest(BandwidthEstimatorType bwe_type, | |
258 size_t num_media_flows, | |
259 size_t num_tcp_flows, | |
260 int64_t run_time_seconds, | |
261 uint32_t capacity_kbps, | |
262 int64_t max_delay_ms, | |
263 int64_t rtt_ms, | |
264 int64_t max_jitter_ms, | |
265 const int64_t* offsets_ms, | |
266 const std::string& title, | |
267 const std::string& flow_name) { | |
239 std::set<int> all_flow_ids; | 268 std::set<int> all_flow_ids; |
240 std::set<int> media_flow_ids; | 269 std::set<int> media_flow_ids; |
241 std::set<int> tcp_flow_ids; | 270 std::set<int> tcp_flow_ids; |
242 int next_flow_id = 0; | 271 int next_flow_id = 0; |
243 for (size_t i = 0; i < num_media_flows; ++i) { | 272 for (size_t i = 0; i < num_media_flows; ++i) { |
244 media_flow_ids.insert(next_flow_id); | 273 media_flow_ids.insert(next_flow_id); |
245 all_flow_ids.insert(next_flow_id); | 274 all_flow_ids.insert(next_flow_id); |
246 ++next_flow_id; | 275 ++next_flow_id; |
247 } | 276 } |
248 for (size_t i = 0; i < num_tcp_flows; ++i) { | 277 for (size_t i = 0; i < num_tcp_flows; ++i) { |
249 tcp_flow_ids.insert(next_flow_id); | 278 tcp_flow_ids.insert(next_flow_id); |
250 all_flow_ids.insert(next_flow_id); | 279 all_flow_ids.insert(next_flow_id); |
251 ++next_flow_id; | 280 ++next_flow_id; |
252 } | 281 } |
253 | 282 |
254 std::vector<VideoSource*> sources; | 283 std::vector<VideoSource*> sources; |
255 std::vector<PacketSender*> senders; | 284 std::vector<PacketSender*> senders; |
285 std::vector<MetricRecorder*> metric_recorders; | |
256 | 286 |
257 size_t i = 1; | 287 int64_t max_offset_ms = 0; |
288 | |
258 for (int media_flow : media_flow_ids) { | 289 for (int media_flow : media_flow_ids) { |
259 // Streams started 20 seconds apart to give them different advantage when | |
260 // competing for the bandwidth. | |
261 const int64_t kFlowStartOffsetMs = i++ * (rand() % 10000); | |
262 sources.push_back(new AdaptiveVideoSource(media_flow, 30, 300, 0, | 290 sources.push_back(new AdaptiveVideoSource(media_flow, 30, 300, 0, |
263 kFlowStartOffsetMs)); | 291 offsets_ms[media_flow])); |
264 senders.push_back(new PacedVideoSender(&uplink_, sources.back(), bwe_type)); | 292 senders.push_back(new PacedVideoSender(&uplink_, sources.back(), bwe_type)); |
293 max_offset_ms = std::max(max_offset_ms, offsets_ms[media_flow]); | |
265 } | 294 } |
266 | 295 |
267 const int64_t kTcpStartOffsetMs = 5000; | 296 for (int tcp_flow : tcp_flow_ids) { |
268 for (int tcp_flow : tcp_flow_ids) | 297 senders.push_back(new TcpSender(&uplink_, tcp_flow, offsets_ms[tcp_flow])); |
269 senders.push_back(new TcpSender(&uplink_, tcp_flow, kTcpStartOffsetMs)); | 298 max_offset_ms = std::max(max_offset_ms, offsets_ms[tcp_flow]); |
299 } | |
270 | 300 |
271 ChokeFilter choke(&uplink_, all_flow_ids); | 301 ChokeFilter choke(&uplink_, all_flow_ids); |
272 choke.set_capacity_kbps(capacity_kbps); | 302 choke.set_capacity_kbps(capacity_kbps); |
273 choke.set_max_delay_ms(max_delay_ms); | 303 choke.set_max_delay_ms(max_delay_ms); |
304 LinkShare link_share(&choke); | |
274 | 305 |
306 int64_t one_way_delay_ms = rtt_ms / 2; | |
275 DelayFilter delay_uplink(&uplink_, all_flow_ids); | 307 DelayFilter delay_uplink(&uplink_, all_flow_ids); |
276 delay_uplink.SetOneWayDelayMs(25); | 308 delay_uplink.SetOneWayDelayMs(one_way_delay_ms); |
309 | |
310 JitterFilter jitter(&uplink_, all_flow_ids); | |
311 jitter.SetMaxJitter(max_jitter_ms); | |
277 | 312 |
278 std::vector<RateCounterFilter*> rate_counters; | 313 std::vector<RateCounterFilter*> rate_counters; |
279 for (int flow : all_flow_ids) { | 314 for (int flow : all_flow_ids) { |
280 rate_counters.push_back( | 315 rate_counters.push_back( |
281 new RateCounterFilter(&uplink_, flow, "receiver_input")); | 316 new RateCounterFilter(&uplink_, flow, "receiver_input")); |
282 } | 317 } |
283 | 318 |
284 RateCounterFilter total_utilization(&uplink_, all_flow_ids, | 319 RateCounterFilter total_utilization(&uplink_, all_flow_ids, |
285 "total_utilization"); | 320 "total_utilization"); |
286 | 321 |
287 std::vector<PacketReceiver*> receivers; | 322 std::vector<PacketReceiver*> receivers; |
288 i = 0; | 323 // Delays is being plotted only for the first flow. |
324 // To plot all of them, replace "i == 0" with "true" on new PacketReceiver(). | |
289 for (int media_flow : media_flow_ids) { | 325 for (int media_flow : media_flow_ids) { |
290 receivers.push_back( | 326 metric_recorders.push_back( |
291 new PacketReceiver(&uplink_, media_flow, bwe_type, i++ == 0, false)); | 327 new MetricRecorder(bwe_names[bwe_type], static_cast<int>(media_flow), |
328 senders[media_flow], &link_share)); | |
329 receivers.push_back(new PacketReceiver(&uplink_, media_flow, bwe_type, | |
330 media_flow == 0, false, | |
331 metric_recorders[media_flow])); | |
332 metric_recorders[media_flow]->set_plot_available_capacity( | |
333 media_flow == 0 && plot_total_available_capacity_); | |
334 metric_recorders[media_flow]->set_start_computing_metrics_ms(max_offset_ms); | |
292 } | 335 } |
336 // Delays is not being plotted only for TCP flows. To plot all of them, | |
337 // replace first "false" occurence with "true" on new PacketReceiver(). | |
293 for (int tcp_flow : tcp_flow_ids) { | 338 for (int tcp_flow : tcp_flow_ids) { |
294 receivers.push_back( | 339 metric_recorders.push_back( |
295 new PacketReceiver(&uplink_, tcp_flow, kTcpEstimator, false, false)); | 340 new MetricRecorder(bwe_names[kTcpEstimator], static_cast<int>(tcp_flow), |
341 senders[tcp_flow], &link_share)); | |
342 receivers.push_back(new PacketReceiver(&uplink_, tcp_flow, kTcpEstimator, | |
343 false, false, | |
344 metric_recorders[tcp_flow])); | |
345 metric_recorders[tcp_flow]->set_plot_available_capacity( | |
346 tcp_flow == 0 && plot_total_available_capacity_); | |
296 } | 347 } |
297 | 348 |
298 DelayFilter delay_downlink(&downlink_, all_flow_ids); | 349 DelayFilter delay_downlink(&downlink_, all_flow_ids); |
299 delay_downlink.SetOneWayDelayMs(25); | 350 delay_downlink.SetOneWayDelayMs(one_way_delay_ms); |
300 | 351 |
301 RunFor(run_time_seconds * 1000); | 352 RunFor(run_time_seconds * 1000); |
302 | 353 |
303 std::map<int, Stats<double>> flow_throughput_kbps; | 354 std::map<int, Stats<double>> flow_throughput_kbps; |
304 for (RateCounterFilter* rate_counter : rate_counters) { | 355 for (RateCounterFilter* rate_counter : rate_counters) { |
305 int flow_id = *rate_counter->flow_ids().begin(); | 356 int flow_id = *rate_counter->flow_ids().begin(); |
306 flow_throughput_kbps[flow_id] = rate_counter->GetBitrateStats(); | 357 flow_throughput_kbps[flow_id] = rate_counter->GetBitrateStats(); |
307 } | 358 } |
308 | 359 |
309 std::map<int, Stats<double>> flow_delay_ms; | 360 std::map<int, Stats<double>> flow_delay_ms; |
310 for (PacketReceiver* receiver : receivers) { | 361 for (PacketReceiver* receiver : receivers) { |
311 int flow_id = *receiver->flow_ids().begin(); | 362 int flow_id = *receiver->flow_ids().begin(); |
312 flow_delay_ms[flow_id] = receiver->GetDelayStats(); | 363 flow_delay_ms[flow_id] = receiver->GetDelayStats(); |
313 } | 364 } |
314 | 365 |
315 PrintResults(capacity_kbps, total_utilization.GetBitrateStats(), | 366 PrintResults(capacity_kbps, total_utilization.GetBitrateStats(), |
316 flow_delay_ms, flow_throughput_kbps); | 367 flow_delay_ms, flow_throughput_kbps); |
317 | 368 |
369 for (int i : all_flow_ids) { | |
370 metric_recorders[i]->PlotThroughputHistogram( | |
371 title, flow_name, static_cast<int>(num_media_flows), 0); | |
372 | |
373 metric_recorders[i]->PlotLossHistogram(title, flow_name, | |
374 static_cast<int>(num_media_flows), | |
375 receivers[i]->GlobalPacketLoss()); | |
376 } | |
377 | |
378 // Pointless to show delay histogram for TCP flow. | |
379 for (int i : media_flow_ids) { | |
380 metric_recorders[i]->PlotDelayHistogram(title, bwe_names[bwe_type], | |
381 static_cast<int>(num_media_flows), | |
382 one_way_delay_ms); | |
383 BWE_TEST_LOGGING_BASELINEBAR(5, bwe_names[bwe_type], one_way_delay_ms, i); | |
384 } | |
385 | |
318 for (VideoSource* source : sources) | 386 for (VideoSource* source : sources) |
319 delete source; | 387 delete source; |
320 for (PacketSender* sender : senders) | 388 for (PacketSender* sender : senders) |
321 delete sender; | 389 delete sender; |
322 for (RateCounterFilter* rate_counter : rate_counters) | 390 for (RateCounterFilter* rate_counter : rate_counters) |
323 delete rate_counter; | 391 delete rate_counter; |
324 for (PacketReceiver* receiver : receivers) | 392 for (PacketReceiver* receiver : receivers) |
325 delete receiver; | 393 delete receiver; |
326 } | 394 for (MetricRecorder* recorder : metric_recorders) |
395 delete recorder; | |
396 } | |
397 | |
398 void BweTest::RunChoke(BandwidthEstimatorType bwe_type, | |
399 std::vector<int> capacities_kbps) { | |
400 int flow_id = bwe_type; | |
401 AdaptiveVideoSource source(flow_id, 30, 300, 0, 0); | |
402 VideoSender sender(&uplink_, &source, bwe_type); | |
403 ChokeFilter choke(&uplink_, flow_id); | |
404 LinkShare link_share(&choke); | |
405 MetricRecorder metric_recorder(bwe_names[bwe_type], flow_id, &sender, | |
406 &link_share); | |
407 PacketReceiver receiver(&uplink_, flow_id, bwe_type, true, false, | |
408 &metric_recorder); | |
409 metric_recorder.set_plot_available_capacity(plot_total_available_capacity_); | |
410 | |
411 choke.set_max_delay_ms(500); | |
412 const int64_t kRunTimeMs = 60 * 1000; | |
413 | |
414 std::stringstream title("Choke"); | |
415 char delimiter = '_'; | |
416 | |
417 for (auto it = capacities_kbps.begin(); it != capacities_kbps.end(); ++it) { | |
418 choke.set_capacity_kbps(*it); | |
419 RunFor(kRunTimeMs); | |
420 title << delimiter << (*it); | |
421 delimiter = '-'; | |
422 } | |
423 | |
424 title << "_kbps,_" << (kRunTimeMs / 1000) << "s_each"; | |
425 metric_recorder.PlotThroughputHistogram(title.str(), bwe_names[bwe_type], 1, | |
426 0); | |
427 metric_recorder.PlotDelayHistogram(title.str(), bwe_names[bwe_type], 1, 0); | |
428 // receiver.PlotLossHistogram(title, bwe_names[bwe_type], 1); | |
429 // receiver.PlotObjectiveHistogram(title, bwe_names[bwe_type], 1); | |
430 } | |
431 | |
432 // 5.1. Single Video and Audio media traffic, forward direction. | |
433 void BweTest::RunVariableCapacity1SingleFlow(BandwidthEstimatorType bwe_type) { | |
434 int flow_id = bwe_type; // Arbitrary value. | |
stefan-webrtc
2015/07/23 11:33:33
Hm, looks weird. Why not just 0?
magalhaesc
2015/07/23 12:11:53
Done.
| |
435 AdaptiveVideoSource source(flow_id, 30, 300, 0, 0); | |
436 PacedVideoSender sender(&uplink_, &source, bwe_type); | |
437 | |
438 DefaultEvaluationFilter up_filter(&uplink_, flow_id); | |
439 DelayFilter down_filter(&downlink_, flow_id); | |
440 | |
441 LinkShare link_share(&(up_filter.choke)); | |
442 MetricRecorder metric_recorder(bwe_names[bwe_type], flow_id, &sender, | |
443 &link_share); | |
444 | |
445 PacketReceiver receiver(&uplink_, flow_id, bwe_type, true, true, | |
446 &metric_recorder); | |
447 | |
448 metric_recorder.set_plot_available_capacity(plot_total_available_capacity_); | |
449 | |
450 down_filter.SetOneWayDelayMs(kOneWayDelayMs); | |
451 | |
452 // Test also with one way propagation delay = 100ms. | |
453 // up_filter.delay.SetOneWayDelayMs(100); | |
454 // down_filter.SetOneWayDelayMs(100); | |
455 | |
456 up_filter.choke.set_capacity_kbps(1000); | |
457 RunFor(40 * 1000); // 0-40s. | |
458 up_filter.choke.set_capacity_kbps(2500); | |
459 RunFor(20 * 1000); // 40-60s. | |
460 up_filter.choke.set_capacity_kbps(600); | |
461 RunFor(20 * 1000); // 60-80s. | |
462 up_filter.choke.set_capacity_kbps(1000); | |
463 RunFor(20 * 1000); // 80-100s. | |
464 | |
465 std::string title("5.1_Variable_capacity_single_flow"); | |
466 metric_recorder.PlotThroughputHistogram(title, bwe_names[bwe_type], 1, 0); | |
467 // metric_recorder.PlotDelayHistogram(title, bwe_names[bwe_type], 1, | |
468 // kOneWayDelayMs); | |
469 // metric_recorder.PlotLossHistogram(title, bwe_names[bwe_type], 1, | |
470 // receiver.GlobalPacketLoss()); | |
471 // BWE_TEST_LOGGING_BASELINEBAR(5, bwe_names[bwe_type], kOneWayDelayMs, | |
472 // flow_id); | |
stefan-webrtc
2015/07/23 11:33:33
Delete or uncomment.
magalhaesc
2015/07/23 12:11:53
Done.
| |
473 } | |
474 | |
475 // 5.2. Two forward direction competing flows, variable capacity. | |
476 void BweTest::RunVariableCapacity2MultipleFlows(BandwidthEstimatorType bwe_type, | |
477 size_t num_flows) { | |
478 std::vector<VideoSource*> sources; | |
479 std::vector<PacketSender*> senders; | |
480 std::vector<MetricRecorder*> metric_recorders; | |
481 std::vector<PacketReceiver*> receivers; | |
482 | |
483 const int64_t kStartingApartMs = 0; // Flows initialized simultaneously. | |
484 | |
485 for (size_t i = 0; i < num_flows; ++i) { | |
486 sources.push_back(new AdaptiveVideoSource(static_cast<int>(i), 30, 300, 0, | |
487 i * kStartingApartMs)); | |
488 senders.push_back(new VideoSender(&uplink_, sources[i], bwe_type)); | |
489 } | |
490 | |
491 FlowIds flow_ids = CreateFlowIdRange(0, static_cast<int>(num_flows - 1)); | |
492 | |
493 DefaultEvaluationFilter up_filter(&uplink_, flow_ids); | |
494 LinkShare link_share(&(up_filter.choke)); | |
495 DelayFilter down_filter(&downlink_, flow_ids); | |
stefan-webrtc
2015/07/23 11:33:33
I think it would make sense to move the down_filte
magalhaesc
2015/07/23 12:11:53
Right, done.
| |
496 | |
497 RateCounterFilter total_utilization(&uplink_, flow_ids, "Total_utilization"); | |
498 | |
499 // Delays is being plotted only for the first flow. | |
500 // To plot all of them, replace "i == 0" with "true" on new PacketReceiver(). | |
501 for (size_t i = 0; i < num_flows; ++i) { | |
502 metric_recorders.push_back(new MetricRecorder( | |
503 bwe_names[bwe_type], static_cast<int>(i), senders[i], &link_share)); | |
504 | |
505 receivers.push_back(new PacketReceiver(&uplink_, static_cast<int>(i), | |
506 bwe_type, i == 0, false, | |
507 metric_recorders[i])); | |
508 metric_recorders[i]->set_plot_available_capacity( | |
509 i == 0 && plot_total_available_capacity_); | |
510 } | |
511 | |
512 down_filter.SetOneWayDelayMs(kOneWayDelayMs); | |
513 // Test also with one way propagation delay = 100ms. | |
514 // up_filter.delay.SetOneWayDelayMs(100); | |
515 // down_filter.SetOneWayDelayMs(100); | |
516 | |
517 up_filter.choke.set_capacity_kbps(4000); | |
518 RunFor(25 * 1000); // 0-25s. | |
519 up_filter.choke.set_capacity_kbps(2000); | |
520 RunFor(25 * 1000); // 25-50s. | |
521 up_filter.choke.set_capacity_kbps(3500); | |
522 RunFor(25 * 1000); // 50-75s. | |
523 up_filter.choke.set_capacity_kbps(1000); | |
524 RunFor(25 * 1000); // 75-100s. | |
525 up_filter.choke.set_capacity_kbps(2000); | |
526 RunFor(25 * 1000); // 100-125s. | |
527 | |
528 std::string title("5.2_Variable_capacity_two_flows"); | |
529 for (size_t i = 0; i < num_flows; ++i) { | |
530 metric_recorders[i]->PlotThroughputHistogram(title, bwe_names[bwe_type], | |
531 num_flows, 0); | |
532 metric_recorders[i]->PlotDelayHistogram(title, bwe_names[bwe_type], | |
533 num_flows, kOneWayDelayMs); | |
534 metric_recorders[i]->PlotLossHistogram(title, bwe_names[bwe_type], | |
535 num_flows, | |
536 receivers[i]->GlobalPacketLoss()); | |
537 BWE_TEST_LOGGING_BASELINEBAR(5, bwe_names[bwe_type], kOneWayDelayMs, i); | |
538 } | |
539 | |
540 for (VideoSource* source : sources) | |
541 delete source; | |
542 for (PacketSender* sender : senders) | |
543 delete sender; | |
544 for (MetricRecorder* recorder : metric_recorders) | |
545 delete recorder; | |
546 for (PacketReceiver* receiver : receivers) | |
547 delete receiver; | |
548 } | |
549 | |
550 // 5.3. Bi-directional RMCAT flows. | |
551 void BweTest::RunBidirectionalFlow(BandwidthEstimatorType bwe_type) { | |
552 enum direction { kForward = 0, kBackward }; | |
553 const size_t kNumFlows = 2; | |
554 rtc::scoped_ptr<AdaptiveVideoSource> sources[kNumFlows]; | |
555 rtc::scoped_ptr<VideoSender> senders[kNumFlows]; | |
556 rtc::scoped_ptr<MetricRecorder> metric_recorders[kNumFlows]; | |
557 rtc::scoped_ptr<PacketReceiver> receivers[kNumFlows]; | |
558 | |
559 sources[kForward].reset(new AdaptiveVideoSource(kForward, 30, 300, 0, 0)); | |
560 senders[kForward].reset( | |
561 new VideoSender(&uplink_, sources[kForward].get(), bwe_type)); | |
562 | |
563 sources[kBackward].reset(new AdaptiveVideoSource(kBackward, 30, 300, 0, 0)); | |
564 senders[kBackward].reset( | |
565 new VideoSender(&downlink_, sources[kBackward].get(), bwe_type)); | |
566 | |
567 DefaultEvaluationFilter up_filter(&uplink_, kForward); | |
568 DefaultEvaluationFilter down_filter(&downlink_, kBackward); | |
569 LinkShare up_link_share(&(up_filter.choke)); | |
570 LinkShare down_link_share(&(down_filter.choke)); | |
571 | |
572 metric_recorders[kForward].reset(new MetricRecorder( | |
573 bwe_names[bwe_type], kForward, senders[kForward].get(), &up_link_share)); | |
574 receivers[kForward].reset( | |
575 new PacketReceiver(&uplink_, kForward, bwe_type, true, false, | |
576 metric_recorders[kForward].get())); | |
577 | |
578 metric_recorders[kForward].get()->set_plot_available_capacity( | |
579 plot_total_available_capacity_); | |
580 | |
581 metric_recorders[kBackward].reset( | |
582 new MetricRecorder(bwe_names[bwe_type], kBackward, | |
583 senders[kBackward].get(), &down_link_share)); | |
584 receivers[kBackward].reset( | |
585 new PacketReceiver(&downlink_, kBackward, bwe_type, true, false, | |
586 metric_recorders[kBackward].get())); | |
587 | |
588 metric_recorders[kBackward].get()->set_plot_available_capacity( | |
589 plot_total_available_capacity_); | |
590 | |
591 // Test also with one way propagation delay = 100ms. | |
592 // up_filter.delay.SetOneWayDelayMs(100); | |
593 // down_filter.delay.SetOneWayDelayMs(100); | |
594 | |
595 up_filter.choke.set_capacity_kbps(2000); | |
596 down_filter.choke.set_capacity_kbps(2000); | |
597 RunFor(20 * 1000); // 0-20s. | |
598 | |
599 up_filter.choke.set_capacity_kbps(1000); | |
600 RunFor(15 * 1000); // 20-35s. | |
601 | |
602 down_filter.choke.set_capacity_kbps(800); | |
603 RunFor(5 * 1000); // 35-40s. | |
604 | |
605 up_filter.choke.set_capacity_kbps(500); | |
606 RunFor(20 * 1000); // 40-60s. | |
607 | |
608 up_filter.choke.set_capacity_kbps(2000); | |
609 RunFor(10 * 1000); // 60-70s. | |
610 | |
611 down_filter.choke.set_capacity_kbps(2000); | |
612 RunFor(30 * 1000); // 70-100s. | |
613 | |
614 std::string title("5.3_Bidirectional_flows"); | |
615 for (size_t i = 0; i < kNumFlows; ++i) { | |
616 metric_recorders[i].get()->PlotThroughputHistogram( | |
617 title, bwe_names[bwe_type], kNumFlows, 0); | |
618 metric_recorders[i].get()->PlotDelayHistogram(title, bwe_names[bwe_type], | |
619 kNumFlows, kOneWayDelayMs); | |
620 metric_recorders[i].get()->PlotLossHistogram( | |
621 title, bwe_names[bwe_type], kNumFlows, | |
622 receivers[i].get()->GlobalPacketLoss()); | |
623 BWE_TEST_LOGGING_BASELINEBAR(5, bwe_names[bwe_type], kOneWayDelayMs, i); | |
624 } | |
625 } | |
626 | |
627 // 5.4. Three forward direction competing flows, constant capacity. | |
628 void BweTest::RunSelfFairness(BandwidthEstimatorType bwe_type) { | |
629 const int kNumRmcatFlows = 3; | |
630 const int kNumTcpFlows = 0; | |
631 const int64_t kRunTimeS = 120; | |
632 const int kLinkCapacity = 3500; | |
633 | |
634 int64_t max_delay_ms = kMaxQueueingDelayMs; | |
635 int64_t rtt_ms = 2 * kOneWayDelayMs; | |
636 | |
637 const int64_t kStartingApartMs = 20 * 1000; | |
638 int64_t offsets_ms[kNumRmcatFlows]; | |
639 for (int i = 0; i < kNumRmcatFlows; ++i) { | |
640 offsets_ms[i] = kStartingApartMs * i; | |
641 } | |
642 | |
643 // Test also with one way propagation delay = 100ms. | |
644 // rtt_ms = 2 * 100; | |
645 // Test also with bottleneck queue size = 20ms and 1000ms. | |
646 // max_delay_ms = 20; | |
647 // max_delay_ms = 1000; | |
648 | |
649 std::string title("5.4_Self_fairness_test"); | |
650 | |
651 // Test also with one way propagation delay = 100ms. | |
652 RunFairnessTest(bwe_type, kNumRmcatFlows, kNumTcpFlows, kRunTimeS, | |
653 kLinkCapacity, max_delay_ms, rtt_ms, kMaxJitterMs, offsets_ms, | |
654 title, bwe_names[bwe_type]); | |
655 } | |
656 | |
657 // 5.5. Five competing RMCAT flows under different RTTs. | |
658 void BweTest::RunRoundTripTimeFairness(BandwidthEstimatorType bwe_type) { | |
659 const int kAllFlowIds[] = {0, 1, 2, 3, 4}; // Five RMCAT flows. | |
660 const int64_t kAllOneWayDelayMs[] = {10, 25, 50, 100, 150}; | |
661 const size_t kNumFlows = ARRAY_SIZE(kAllFlowIds); | |
662 rtc::scoped_ptr<AdaptiveVideoSource> sources[kNumFlows]; | |
663 rtc::scoped_ptr<VideoSender> senders[kNumFlows]; | |
664 rtc::scoped_ptr<MetricRecorder> metric_recorders[kNumFlows]; | |
665 | |
666 // Flows initialized 10 seconds apart. | |
667 const int64_t kStartingApartMs = 10 * 1000; | |
668 | |
669 for (size_t i = 0; i < kNumFlows; ++i) { | |
670 sources[i].reset(new AdaptiveVideoSource(kAllFlowIds[i], 30, 300, 0, | |
671 i * kStartingApartMs)); | |
672 senders[i].reset(new VideoSender(&uplink_, sources[i].get(), bwe_type)); | |
673 } | |
674 | |
675 ChokeFilter choke_filter(&uplink_, CreateFlowIds(kAllFlowIds, kNumFlows)); | |
676 JitterFilter jitter_filter(&uplink_, CreateFlowIds(kAllFlowIds, kNumFlows)); | |
677 rtc::scoped_ptr<DelayFilter> up_delay_filters[kNumFlows]; | |
678 rtc::scoped_ptr<DelayFilter> down_delay_filters[kNumFlows]; | |
679 | |
680 LinkShare link_share(&choke_filter); | |
681 | |
682 for (size_t i = 0; i < kNumFlows; ++i) { | |
683 up_delay_filters[i].reset(new DelayFilter(&uplink_, kAllFlowIds[i])); | |
684 down_delay_filters[i].reset(new DelayFilter(&downlink_, kAllFlowIds[i])); | |
685 } | |
686 | |
687 RateCounterFilter total_utilization( | |
688 &uplink_, CreateFlowIds(kAllFlowIds, kNumFlows), "Total_utilization"); | |
689 | |
690 // Delays is being plotted only for the first flow. | |
691 // To plot all of them, replace "i == 0" with "true" on new PacketReceiver(). | |
692 rtc::scoped_ptr<PacketReceiver> receivers[kNumFlows]; | |
693 for (size_t i = 0; i < kNumFlows; ++i) { | |
694 metric_recorders[i].reset( | |
695 new MetricRecorder(bwe_names[bwe_type], static_cast<int>(i), | |
696 senders[i].get(), &link_share)); | |
697 | |
698 receivers[i].reset(new PacketReceiver(&uplink_, kAllFlowIds[i], bwe_type, | |
699 i == 0, false, | |
700 metric_recorders[i].get())); | |
701 metric_recorders[i].get()->set_start_computing_metrics_ms(kStartingApartMs * | |
702 (kNumFlows - 1)); | |
703 metric_recorders[i].get()->set_plot_available_capacity( | |
704 i == 0 && plot_total_available_capacity_); | |
705 } | |
706 | |
707 jitter_filter.SetMaxJitter(kMaxJitterMs); | |
708 choke_filter.set_max_delay_ms(kMaxQueueingDelayMs); | |
709 | |
710 for (size_t i = 0; i < kNumFlows; ++i) { | |
711 up_delay_filters[i]->SetOneWayDelayMs(kAllOneWayDelayMs[i]); | |
712 down_delay_filters[i]->SetOneWayDelayMs(kAllOneWayDelayMs[i]); | |
713 } | |
714 | |
715 choke_filter.set_capacity_kbps(3500); | |
716 | |
717 RunFor(300 * 1000); // 0-300s. | |
718 | |
719 std::string title("5.5_Round_Trip_Time_Fairness"); | |
720 for (size_t i = 0; i < kNumFlows; ++i) { | |
721 metric_recorders[i].get()->PlotThroughputHistogram( | |
722 title, bwe_names[bwe_type], kNumFlows, 0); | |
723 metric_recorders[i].get()->PlotDelayHistogram(title, bwe_names[bwe_type], | |
724 kNumFlows, kOneWayDelayMs); | |
725 metric_recorders[i].get()->PlotLossHistogram( | |
726 title, bwe_names[bwe_type], kNumFlows, | |
727 receivers[i].get()->GlobalPacketLoss()); | |
728 BWE_TEST_LOGGING_BASELINEBAR(5, bwe_names[bwe_type], kAllOneWayDelayMs[i], | |
729 i); | |
730 } | |
731 } | |
732 | |
733 // 5.6. RMCAT Flow competing with a long TCP Flow. | |
734 void BweTest::RunLongTcpFairness(BandwidthEstimatorType bwe_type) { | |
735 const size_t kNumRmcatFlows = 1; | |
736 const size_t kNumTcpFlows = 1; | |
737 const int64_t kRunTimeS = 120; | |
738 const int kCapacityKbps = 2000; | |
739 // Tcp starts at t = 0, media flow at t = 5s. | |
740 const int64_t kOffSetsMs[] = {5000, 0}; | |
741 | |
742 int64_t max_delay_ms = kMaxQueueingDelayMs; | |
743 int64_t rtt_ms = 2 * kOneWayDelayMs; | |
744 | |
745 // Test also with one way propagation delay = 100ms. | |
746 // rtt_ms = 2 * 100; | |
747 // Test also with bottleneck queue size = 20ms and 1000ms. | |
748 // max_delay_ms = 20; | |
749 // max_delay_ms = 1000; | |
750 | |
751 std::string title("5.6_Long_TCP_Fairness"); | |
752 std::string flow_name(bwe_names[bwe_type] + 'x' + bwe_names[kTcpEstimator]); | |
753 | |
754 RunFairnessTest(bwe_type, kNumRmcatFlows, kNumTcpFlows, kRunTimeS, | |
755 kCapacityKbps, max_delay_ms, rtt_ms, kMaxJitterMs, kOffSetsMs, | |
756 title, flow_name); | |
757 } | |
758 | |
759 // 5.7. RMCAT Flows competing with multiple short TCP Flows. | |
760 void BweTest::RunMultipleShortTcpFairness( | |
761 BandwidthEstimatorType bwe_type, | |
762 std::vector<int> tcp_file_sizes_bytes, | |
763 std::vector<int64_t> tcp_starting_times_ms) { | |
764 // Two RMCAT flows and ten TCP flows. | |
765 const int kAllRmcatFlowIds[] = {0, 1}; | |
766 const int kAllTcpFlowIds[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; | |
767 | |
768 assert(tcp_starting_times_ms.size() == tcp_file_sizes_bytes.size() && | |
769 tcp_starting_times_ms.size() == ARRAY_SIZE(kAllTcpFlowIds)); | |
770 | |
771 const size_t kNumRmcatFlows = ARRAY_SIZE(kAllRmcatFlowIds); | |
772 const size_t kNumTotalFlows = kNumRmcatFlows + ARRAY_SIZE(kAllTcpFlowIds); | |
773 | |
774 rtc::scoped_ptr<AdaptiveVideoSource> sources[kNumRmcatFlows]; | |
775 rtc::scoped_ptr<PacketSender> senders[kNumTotalFlows]; | |
776 rtc::scoped_ptr<MetricRecorder> metric_recorders[kNumTotalFlows]; | |
777 rtc::scoped_ptr<PacketReceiver> receivers[kNumTotalFlows]; | |
778 | |
779 // RMCAT Flows are initialized simultaneosly at t=5 seconds. | |
780 const int64_t kRmcatStartingTimeMs = 5 * 1000; | |
781 for (size_t id : kAllRmcatFlowIds) { | |
782 sources[id].reset(new AdaptiveVideoSource(static_cast<int>(id), 30, 300, 0, | |
783 kRmcatStartingTimeMs)); | |
784 senders[id].reset(new VideoSender(&uplink_, sources[id].get(), bwe_type)); | |
785 } | |
786 | |
787 for (size_t id : kAllTcpFlowIds) { | |
788 senders[id].reset(new TcpSender(&uplink_, static_cast<int>(id), | |
789 tcp_starting_times_ms[id - kNumRmcatFlows], | |
790 tcp_file_sizes_bytes[id - kNumRmcatFlows])); | |
791 } | |
792 | |
793 FlowIds flow_ids = CreateFlowIdRange(0, static_cast<int>(kNumTotalFlows - 1)); | |
794 DefaultEvaluationFilter up_filter(&uplink_, flow_ids); | |
795 DelayFilter down_filter(&downlink_, flow_ids); | |
796 | |
797 LinkShare link_share(&(up_filter.choke)); | |
798 | |
799 RateCounterFilter total_utilization(&uplink_, flow_ids, "Total_utilization"); | |
800 | |
801 // Delays is being plotted only for the first flow. | |
802 // To plot all of them, replace "i == 0" with "true" on new PacketReceiver(). | |
803 for (size_t id : kAllRmcatFlowIds) { | |
804 metric_recorders[id].reset( | |
805 new MetricRecorder(bwe_names[bwe_type], static_cast<int>(id), | |
806 senders[id].get(), &link_share)); | |
807 receivers[id].reset(new PacketReceiver(&uplink_, static_cast<int>(id), | |
808 bwe_type, id == 0, false, | |
809 metric_recorders[id].get())); | |
810 metric_recorders[id].get()->set_start_computing_metrics_ms( | |
811 kRmcatStartingTimeMs); | |
812 metric_recorders[id].get()->set_plot_available_capacity( | |
813 id == 0 && plot_total_available_capacity_); | |
814 } | |
815 | |
816 // Delays is not being plotted only for TCP flows. To plot all of them, | |
817 // replace first "false" occurence with "true" on new PacketReceiver(). | |
818 for (size_t id : kAllTcpFlowIds) { | |
819 metric_recorders[id].reset( | |
820 new MetricRecorder(bwe_names[kTcpEstimator], static_cast<int>(id), | |
821 senders[id].get(), &link_share)); | |
822 receivers[id].reset(new PacketReceiver(&uplink_, static_cast<int>(id), | |
823 kTcpEstimator, false, false, | |
824 metric_recorders[id].get())); | |
825 metric_recorders[id].get()->set_plot_available_capacity( | |
826 id == 0 && plot_total_available_capacity_); | |
827 } | |
828 | |
829 down_filter.SetOneWayDelayMs(kOneWayDelayMs); | |
830 | |
831 // Test also with one way propagation delay = 100ms. | |
832 // up_filter.delay.SetOneWayDelayMs(100); | |
833 // down_filter.SetOneWayDelayms(100); | |
834 | |
835 // Test also with bottleneck queue size = 20ms and 1000ms. | |
836 // up_filter.choke.set_max_delay_ms(20); | |
837 // up_filter.choke.set_max_delay_ms(1000); | |
838 | |
839 // Test also with no Jitter: | |
840 // up_filter.jitter.SetMaxJitter(0); | |
841 | |
842 up_filter.choke.set_capacity_kbps(2000); | |
843 | |
844 RunFor(300 * 1000); // 0-300s. | |
845 | |
846 std::string title("5.7_Multiple_short_TCP_flows"); | |
847 for (size_t id : kAllRmcatFlowIds) { | |
848 metric_recorders[id].get()->PlotThroughputHistogram( | |
849 title, bwe_names[bwe_type], kNumRmcatFlows, 0); | |
850 metric_recorders[id].get()->PlotDelayHistogram( | |
851 title, bwe_names[bwe_type], kNumRmcatFlows, kOneWayDelayMs); | |
852 metric_recorders[id].get()->PlotLossHistogram( | |
853 title, bwe_names[bwe_type], kNumRmcatFlows, | |
854 receivers[id].get()->GlobalPacketLoss()); | |
855 BWE_TEST_LOGGING_BASELINEBAR(5, bwe_names[bwe_type], kOneWayDelayMs, id); | |
856 } | |
857 } | |
858 | |
859 // 5.8. Three forward direction competing flows, constant capacity. | |
860 // During the test, one of the flows is paused and later resumed. | |
861 void BweTest::RunPauseResumeFlows(BandwidthEstimatorType bwe_type) { | |
862 const int kAllFlowIds[] = {0, 1, 2}; // Three RMCAT flows. | |
863 const size_t kNumFlows = ARRAY_SIZE(kAllFlowIds); | |
864 | |
865 rtc::scoped_ptr<AdaptiveVideoSource> sources[kNumFlows]; | |
866 rtc::scoped_ptr<VideoSender> senders[kNumFlows]; | |
867 rtc::scoped_ptr<MetricRecorder> metric_recorders[kNumFlows]; | |
868 rtc::scoped_ptr<PacketReceiver> receivers[kNumFlows]; | |
869 | |
870 // Flows initialized simultaneously. | |
871 const int64_t kStartingApartMs = 0; | |
872 | |
873 for (size_t i = 0; i < kNumFlows; ++i) { | |
874 sources[i].reset(new AdaptiveVideoSource(kAllFlowIds[i], 30, 300, 0, | |
875 i * kStartingApartMs)); | |
876 senders[i].reset(new VideoSender(&uplink_, sources[i].get(), bwe_type)); | |
877 } | |
878 | |
879 DefaultEvaluationFilter filter(&uplink_, | |
880 CreateFlowIds(kAllFlowIds, kNumFlows)); | |
881 | |
882 LinkShare link_share(&(filter.choke)); | |
883 | |
884 RateCounterFilter total_utilization( | |
885 &uplink_, CreateFlowIds(kAllFlowIds, kNumFlows), "Total_utilization"); | |
886 | |
887 // Delays is being plotted only for the first flow. | |
888 // To plot all of them, replace "i == 0" with "true" on new PacketReceiver(). | |
889 for (size_t i = 0; i < kNumFlows; ++i) { | |
890 metric_recorders[i].reset( | |
891 new MetricRecorder(bwe_names[bwe_type], static_cast<int>(i), | |
892 senders[i].get(), &link_share)); | |
893 receivers[i].reset(new PacketReceiver(&uplink_, kAllFlowIds[i], bwe_type, | |
894 i == 0, false, | |
895 metric_recorders[i].get())); | |
896 metric_recorders[i].get()->set_start_computing_metrics_ms(kStartingApartMs * | |
897 (kNumFlows - 1)); | |
898 metric_recorders[i].get()->set_plot_available_capacity( | |
899 i == 0 && plot_total_available_capacity_); | |
900 } | |
901 | |
902 // Test also with one way propagation delay = 100ms. | |
903 // filter.delay.SetOneWayDelayMs(100); | |
904 filter.choke.set_capacity_kbps(3500); | |
905 | |
906 RunFor(40 * 1000); // 0-40s. | |
907 | |
908 senders[0].get()->Pause(); | |
909 metric_recorders[0].get()->PauseFlow(); | |
910 RunFor(20 * 1000); // 40-60s. | |
911 | |
912 senders[0].get()->Resume(); | |
913 metric_recorders[0].get()->ResumeFlow(20 * 1000); | |
914 RunFor(60 * 1000); // 60-120s. | |
915 | |
916 int64_t paused[] = {20 * 1000, 0, 0}; | |
917 | |
918 // First flow is being paused, hence having a different optimum. | |
919 const std::string optima_lines[] = {"1", "2", "2"}; | |
920 | |
921 std::string title("5.8_Pause_and_resume_media_flow"); | |
922 for (size_t i = 0; i < kNumFlows; ++i) { | |
923 metric_recorders[i].get()->PlotThroughputHistogram( | |
924 title, bwe_names[bwe_type], kNumFlows, paused[i], optima_lines[i]); | |
925 metric_recorders[i].get()->PlotDelayHistogram(title, bwe_names[bwe_type], | |
926 kNumFlows, kOneWayDelayMs); | |
927 metric_recorders[i].get()->PlotLossHistogram( | |
928 title, bwe_names[bwe_type], kNumFlows, | |
929 receivers[i].get()->GlobalPacketLoss()); | |
930 BWE_TEST_LOGGING_BASELINEBAR(5, bwe_names[bwe_type], kOneWayDelayMs, i); | |
931 } | |
932 } | |
933 | |
934 // Following functions are used for randomizing TCP file size and | |
935 // starting time, used on 5.7 RunMultipleShortTcpFairness. | |
936 // They are pseudo-random generators, creating always the same | |
937 // value sequence for a given Random seed. | |
938 | |
939 std::vector<int> BweTest::GetFileSizesBytes(int num_files) { | |
940 // File size chosen from uniform distribution between [100,1000] kB. | |
941 const int kMinKbytes = 100; | |
942 const int kMaxKbytes = 1000; | |
943 | |
944 Random random(0x12345678); | |
945 std::vector<int> tcp_file_sizes_bytes; | |
946 | |
947 while (num_files-- > 0) { | |
948 tcp_file_sizes_bytes.push_back(random.Rand(kMinKbytes, kMaxKbytes) * 1000); | |
949 } | |
950 | |
951 return tcp_file_sizes_bytes; | |
952 } | |
953 | |
954 std::vector<int64_t> BweTest::GetStartingTimesMs(int num_files) { | |
955 // OFF state behaves as an exp. distribution with mean = 10 seconds. | |
956 const float kMeanMs = 10000.0f; | |
957 Random random(0x12345678); | |
958 | |
959 std::vector<int64_t> tcp_starting_times_ms; | |
960 | |
961 // Two TCP Flows are initialized simultaneosly at t=0 seconds. | |
962 for (int i = 0; i < 2; ++i, --num_files) { | |
963 tcp_starting_times_ms.push_back(0); | |
964 } | |
965 | |
966 // Other TCP Flows are initialized in an OFF state. | |
967 while (num_files-- > 0) { | |
968 tcp_starting_times_ms.push_back( | |
969 static_cast<int64_t>(random.Exponential(1.0f / kMeanMs))); | |
970 } | |
971 | |
972 return tcp_starting_times_ms; | |
973 } | |
974 | |
327 } // namespace bwe | 975 } // namespace bwe |
328 } // namespace testing | 976 } // namespace testing |
329 } // namespace webrtc | 977 } // namespace webrtc |
OLD | NEW |