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 const int kFlowId = 0; // Arbitrary value. |
| 435 AdaptiveVideoSource source(kFlowId, 30, 300, 0, 0); |
| 436 PacedVideoSender sender(&uplink_, &source, bwe_type); |
| 437 |
| 438 DefaultEvaluationFilter up_filter(&uplink_, kFlowId); |
| 439 LinkShare link_share(&(up_filter.choke)); |
| 440 MetricRecorder metric_recorder(bwe_names[bwe_type], kFlowId, &sender, |
| 441 &link_share); |
| 442 |
| 443 PacketReceiver receiver(&uplink_, kFlowId, bwe_type, true, true, |
| 444 &metric_recorder); |
| 445 |
| 446 metric_recorder.set_plot_available_capacity(plot_total_available_capacity_); |
| 447 |
| 448 DelayFilter down_filter(&downlink_, kFlowId); |
| 449 down_filter.SetOneWayDelayMs(kOneWayDelayMs); |
| 450 |
| 451 // Test also with one way propagation delay = 100ms. |
| 452 // up_filter.delay.SetOneWayDelayMs(100); |
| 453 // down_filter.SetOneWayDelayMs(100); |
| 454 |
| 455 up_filter.choke.set_capacity_kbps(1000); |
| 456 RunFor(40 * 1000); // 0-40s. |
| 457 up_filter.choke.set_capacity_kbps(2500); |
| 458 RunFor(20 * 1000); // 40-60s. |
| 459 up_filter.choke.set_capacity_kbps(600); |
| 460 RunFor(20 * 1000); // 60-80s. |
| 461 up_filter.choke.set_capacity_kbps(1000); |
| 462 RunFor(20 * 1000); // 80-100s. |
| 463 |
| 464 std::string title("5.1_Variable_capacity_single_flow"); |
| 465 metric_recorder.PlotThroughputHistogram(title, bwe_names[bwe_type], 1, 0); |
| 466 metric_recorder.PlotDelayHistogram(title, bwe_names[bwe_type], 1, |
| 467 kOneWayDelayMs); |
| 468 metric_recorder.PlotLossHistogram(title, bwe_names[bwe_type], 1, |
| 469 receiver.GlobalPacketLoss()); |
| 470 BWE_TEST_LOGGING_BASELINEBAR(5, bwe_names[bwe_type], kOneWayDelayMs, kFlowId); |
| 471 } |
| 472 |
| 473 // 5.2. Two forward direction competing flows, variable capacity. |
| 474 void BweTest::RunVariableCapacity2MultipleFlows(BandwidthEstimatorType bwe_type, |
| 475 size_t num_flows) { |
| 476 std::vector<VideoSource*> sources; |
| 477 std::vector<PacketSender*> senders; |
| 478 std::vector<MetricRecorder*> metric_recorders; |
| 479 std::vector<PacketReceiver*> receivers; |
| 480 |
| 481 const int64_t kStartingApartMs = 0; // Flows initialized simultaneously. |
| 482 |
| 483 for (size_t i = 0; i < num_flows; ++i) { |
| 484 sources.push_back(new AdaptiveVideoSource(static_cast<int>(i), 30, 300, 0, |
| 485 i * kStartingApartMs)); |
| 486 senders.push_back(new VideoSender(&uplink_, sources[i], bwe_type)); |
| 487 } |
| 488 |
| 489 FlowIds flow_ids = CreateFlowIdRange(0, static_cast<int>(num_flows - 1)); |
| 490 |
| 491 DefaultEvaluationFilter up_filter(&uplink_, flow_ids); |
| 492 LinkShare link_share(&(up_filter.choke)); |
| 493 |
| 494 RateCounterFilter total_utilization(&uplink_, flow_ids, "Total_utilization"); |
| 495 |
| 496 // Delays is being plotted only for the first flow. |
| 497 // To plot all of them, replace "i == 0" with "true" on new PacketReceiver(). |
| 498 for (size_t i = 0; i < num_flows; ++i) { |
| 499 metric_recorders.push_back(new MetricRecorder( |
| 500 bwe_names[bwe_type], static_cast<int>(i), senders[i], &link_share)); |
| 501 |
| 502 receivers.push_back(new PacketReceiver(&uplink_, static_cast<int>(i), |
| 503 bwe_type, i == 0, false, |
| 504 metric_recorders[i])); |
| 505 metric_recorders[i]->set_plot_available_capacity( |
| 506 i == 0 && plot_total_available_capacity_); |
| 507 } |
| 508 |
| 509 DelayFilter down_filter(&downlink_, flow_ids); |
| 510 down_filter.SetOneWayDelayMs(kOneWayDelayMs); |
| 511 // Test also with one way propagation delay = 100ms. |
| 512 // up_filter.delay.SetOneWayDelayMs(100); |
| 513 // down_filter.SetOneWayDelayMs(100); |
| 514 |
| 515 up_filter.choke.set_capacity_kbps(4000); |
| 516 RunFor(25 * 1000); // 0-25s. |
| 517 up_filter.choke.set_capacity_kbps(2000); |
| 518 RunFor(25 * 1000); // 25-50s. |
| 519 up_filter.choke.set_capacity_kbps(3500); |
| 520 RunFor(25 * 1000); // 50-75s. |
| 521 up_filter.choke.set_capacity_kbps(1000); |
| 522 RunFor(25 * 1000); // 75-100s. |
| 523 up_filter.choke.set_capacity_kbps(2000); |
| 524 RunFor(25 * 1000); // 100-125s. |
| 525 |
| 526 std::string title("5.2_Variable_capacity_two_flows"); |
| 527 for (size_t i = 0; i < num_flows; ++i) { |
| 528 metric_recorders[i]->PlotThroughputHistogram(title, bwe_names[bwe_type], |
| 529 num_flows, 0); |
| 530 metric_recorders[i]->PlotDelayHistogram(title, bwe_names[bwe_type], |
| 531 num_flows, kOneWayDelayMs); |
| 532 metric_recorders[i]->PlotLossHistogram(title, bwe_names[bwe_type], |
| 533 num_flows, |
| 534 receivers[i]->GlobalPacketLoss()); |
| 535 BWE_TEST_LOGGING_BASELINEBAR(5, bwe_names[bwe_type], kOneWayDelayMs, i); |
| 536 } |
| 537 |
| 538 for (VideoSource* source : sources) |
| 539 delete source; |
| 540 for (PacketSender* sender : senders) |
| 541 delete sender; |
| 542 for (MetricRecorder* recorder : metric_recorders) |
| 543 delete recorder; |
| 544 for (PacketReceiver* receiver : receivers) |
| 545 delete receiver; |
| 546 } |
| 547 |
| 548 // 5.3. Bi-directional RMCAT flows. |
| 549 void BweTest::RunBidirectionalFlow(BandwidthEstimatorType bwe_type) { |
| 550 enum direction { kForward = 0, kBackward }; |
| 551 const size_t kNumFlows = 2; |
| 552 rtc::scoped_ptr<AdaptiveVideoSource> sources[kNumFlows]; |
| 553 rtc::scoped_ptr<VideoSender> senders[kNumFlows]; |
| 554 rtc::scoped_ptr<MetricRecorder> metric_recorders[kNumFlows]; |
| 555 rtc::scoped_ptr<PacketReceiver> receivers[kNumFlows]; |
| 556 |
| 557 sources[kForward].reset(new AdaptiveVideoSource(kForward, 30, 300, 0, 0)); |
| 558 senders[kForward].reset( |
| 559 new VideoSender(&uplink_, sources[kForward].get(), bwe_type)); |
| 560 |
| 561 sources[kBackward].reset(new AdaptiveVideoSource(kBackward, 30, 300, 0, 0)); |
| 562 senders[kBackward].reset( |
| 563 new VideoSender(&downlink_, sources[kBackward].get(), bwe_type)); |
| 564 |
| 565 DefaultEvaluationFilter up_filter(&uplink_, kForward); |
| 566 LinkShare up_link_share(&(up_filter.choke)); |
| 567 |
| 568 metric_recorders[kForward].reset(new MetricRecorder( |
| 569 bwe_names[bwe_type], kForward, senders[kForward].get(), &up_link_share)); |
| 570 receivers[kForward].reset( |
| 571 new PacketReceiver(&uplink_, kForward, bwe_type, true, false, |
| 572 metric_recorders[kForward].get())); |
| 573 |
| 574 metric_recorders[kForward].get()->set_plot_available_capacity( |
| 575 plot_total_available_capacity_); |
| 576 |
| 577 DefaultEvaluationFilter down_filter(&downlink_, kBackward); |
| 578 LinkShare down_link_share(&(down_filter.choke)); |
| 579 |
| 580 metric_recorders[kBackward].reset( |
| 581 new MetricRecorder(bwe_names[bwe_type], kBackward, |
| 582 senders[kBackward].get(), &down_link_share)); |
| 583 receivers[kBackward].reset( |
| 584 new PacketReceiver(&downlink_, kBackward, bwe_type, true, false, |
| 585 metric_recorders[kBackward].get())); |
| 586 |
| 587 metric_recorders[kBackward].get()->set_plot_available_capacity( |
| 588 plot_total_available_capacity_); |
| 589 |
| 590 // Test also with one way propagation delay = 100ms. |
| 591 // up_filter.delay.SetOneWayDelayMs(100); |
| 592 // down_filter.delay.SetOneWayDelayMs(100); |
| 593 |
| 594 up_filter.choke.set_capacity_kbps(2000); |
| 595 down_filter.choke.set_capacity_kbps(2000); |
| 596 RunFor(20 * 1000); // 0-20s. |
| 597 |
| 598 up_filter.choke.set_capacity_kbps(1000); |
| 599 RunFor(15 * 1000); // 20-35s. |
| 600 |
| 601 down_filter.choke.set_capacity_kbps(800); |
| 602 RunFor(5 * 1000); // 35-40s. |
| 603 |
| 604 up_filter.choke.set_capacity_kbps(500); |
| 605 RunFor(20 * 1000); // 40-60s. |
| 606 |
| 607 up_filter.choke.set_capacity_kbps(2000); |
| 608 RunFor(10 * 1000); // 60-70s. |
| 609 |
| 610 down_filter.choke.set_capacity_kbps(2000); |
| 611 RunFor(30 * 1000); // 70-100s. |
| 612 |
| 613 std::string title("5.3_Bidirectional_flows"); |
| 614 for (size_t i = 0; i < kNumFlows; ++i) { |
| 615 metric_recorders[i].get()->PlotThroughputHistogram( |
| 616 title, bwe_names[bwe_type], kNumFlows, 0); |
| 617 metric_recorders[i].get()->PlotDelayHistogram(title, bwe_names[bwe_type], |
| 618 kNumFlows, kOneWayDelayMs); |
| 619 metric_recorders[i].get()->PlotLossHistogram( |
| 620 title, bwe_names[bwe_type], kNumFlows, |
| 621 receivers[i].get()->GlobalPacketLoss()); |
| 622 BWE_TEST_LOGGING_BASELINEBAR(5, bwe_names[bwe_type], kOneWayDelayMs, i); |
| 623 } |
| 624 } |
| 625 |
| 626 // 5.4. Three forward direction competing flows, constant capacity. |
| 627 void BweTest::RunSelfFairness(BandwidthEstimatorType bwe_type) { |
| 628 const int kNumRmcatFlows = 3; |
| 629 const int kNumTcpFlows = 0; |
| 630 const int64_t kRunTimeS = 120; |
| 631 const int kLinkCapacity = 3500; |
| 632 |
| 633 int64_t max_delay_ms = kMaxQueueingDelayMs; |
| 634 int64_t rtt_ms = 2 * kOneWayDelayMs; |
| 635 |
| 636 const int64_t kStartingApartMs = 20 * 1000; |
| 637 int64_t offsets_ms[kNumRmcatFlows]; |
| 638 for (int i = 0; i < kNumRmcatFlows; ++i) { |
| 639 offsets_ms[i] = kStartingApartMs * i; |
| 640 } |
| 641 |
| 642 // Test also with one way propagation delay = 100ms. |
| 643 // rtt_ms = 2 * 100; |
| 644 // Test also with bottleneck queue size = 20ms and 1000ms. |
| 645 // max_delay_ms = 20; |
| 646 // max_delay_ms = 1000; |
| 647 |
| 648 std::string title("5.4_Self_fairness_test"); |
| 649 |
| 650 // Test also with one way propagation delay = 100ms. |
| 651 RunFairnessTest(bwe_type, kNumRmcatFlows, kNumTcpFlows, kRunTimeS, |
| 652 kLinkCapacity, max_delay_ms, rtt_ms, kMaxJitterMs, offsets_ms, |
| 653 title, bwe_names[bwe_type]); |
| 654 } |
| 655 |
| 656 // 5.5. Five competing RMCAT flows under different RTTs. |
| 657 void BweTest::RunRoundTripTimeFairness(BandwidthEstimatorType bwe_type) { |
| 658 const int kAllFlowIds[] = {0, 1, 2, 3, 4}; // Five RMCAT flows. |
| 659 const int64_t kAllOneWayDelayMs[] = {10, 25, 50, 100, 150}; |
| 660 const size_t kNumFlows = ARRAY_SIZE(kAllFlowIds); |
| 661 rtc::scoped_ptr<AdaptiveVideoSource> sources[kNumFlows]; |
| 662 rtc::scoped_ptr<VideoSender> senders[kNumFlows]; |
| 663 rtc::scoped_ptr<MetricRecorder> metric_recorders[kNumFlows]; |
| 664 |
| 665 // Flows initialized 10 seconds apart. |
| 666 const int64_t kStartingApartMs = 10 * 1000; |
| 667 |
| 668 for (size_t i = 0; i < kNumFlows; ++i) { |
| 669 sources[i].reset(new AdaptiveVideoSource(kAllFlowIds[i], 30, 300, 0, |
| 670 i * kStartingApartMs)); |
| 671 senders[i].reset(new VideoSender(&uplink_, sources[i].get(), bwe_type)); |
| 672 } |
| 673 |
| 674 ChokeFilter choke_filter(&uplink_, CreateFlowIds(kAllFlowIds, kNumFlows)); |
| 675 LinkShare link_share(&choke_filter); |
| 676 |
| 677 JitterFilter jitter_filter(&uplink_, CreateFlowIds(kAllFlowIds, kNumFlows)); |
| 678 |
| 679 rtc::scoped_ptr<DelayFilter> up_delay_filters[kNumFlows]; |
| 680 for (size_t i = 0; i < kNumFlows; ++i) { |
| 681 up_delay_filters[i].reset(new DelayFilter(&uplink_, kAllFlowIds[i])); |
| 682 } |
| 683 |
| 684 RateCounterFilter total_utilization( |
| 685 &uplink_, CreateFlowIds(kAllFlowIds, kNumFlows), "Total_utilization"); |
| 686 |
| 687 // Delays is being plotted only for the first flow. |
| 688 // To plot all of them, replace "i == 0" with "true" on new PacketReceiver(). |
| 689 rtc::scoped_ptr<PacketReceiver> receivers[kNumFlows]; |
| 690 for (size_t i = 0; i < kNumFlows; ++i) { |
| 691 metric_recorders[i].reset( |
| 692 new MetricRecorder(bwe_names[bwe_type], static_cast<int>(i), |
| 693 senders[i].get(), &link_share)); |
| 694 |
| 695 receivers[i].reset(new PacketReceiver(&uplink_, kAllFlowIds[i], bwe_type, |
| 696 i == 0, false, |
| 697 metric_recorders[i].get())); |
| 698 metric_recorders[i].get()->set_start_computing_metrics_ms(kStartingApartMs * |
| 699 (kNumFlows - 1)); |
| 700 metric_recorders[i].get()->set_plot_available_capacity( |
| 701 i == 0 && plot_total_available_capacity_); |
| 702 } |
| 703 |
| 704 rtc::scoped_ptr<DelayFilter> down_delay_filters[kNumFlows]; |
| 705 for (size_t i = 0; i < kNumFlows; ++i) { |
| 706 down_delay_filters[i].reset(new DelayFilter(&downlink_, kAllFlowIds[i])); |
| 707 } |
| 708 |
| 709 jitter_filter.SetMaxJitter(kMaxJitterMs); |
| 710 choke_filter.set_max_delay_ms(kMaxQueueingDelayMs); |
| 711 |
| 712 for (size_t i = 0; i < kNumFlows; ++i) { |
| 713 up_delay_filters[i]->SetOneWayDelayMs(kAllOneWayDelayMs[i]); |
| 714 down_delay_filters[i]->SetOneWayDelayMs(kAllOneWayDelayMs[i]); |
| 715 } |
| 716 |
| 717 choke_filter.set_capacity_kbps(3500); |
| 718 |
| 719 RunFor(300 * 1000); // 0-300s. |
| 720 |
| 721 std::string title("5.5_Round_Trip_Time_Fairness"); |
| 722 for (size_t i = 0; i < kNumFlows; ++i) { |
| 723 metric_recorders[i].get()->PlotThroughputHistogram( |
| 724 title, bwe_names[bwe_type], kNumFlows, 0); |
| 725 metric_recorders[i].get()->PlotDelayHistogram(title, bwe_names[bwe_type], |
| 726 kNumFlows, kOneWayDelayMs); |
| 727 metric_recorders[i].get()->PlotLossHistogram( |
| 728 title, bwe_names[bwe_type], kNumFlows, |
| 729 receivers[i].get()->GlobalPacketLoss()); |
| 730 BWE_TEST_LOGGING_BASELINEBAR(5, bwe_names[bwe_type], kAllOneWayDelayMs[i], |
| 731 i); |
| 732 } |
| 733 } |
| 734 |
| 735 // 5.6. RMCAT Flow competing with a long TCP Flow. |
| 736 void BweTest::RunLongTcpFairness(BandwidthEstimatorType bwe_type) { |
| 737 const size_t kNumRmcatFlows = 1; |
| 738 const size_t kNumTcpFlows = 1; |
| 739 const int64_t kRunTimeS = 120; |
| 740 const int kCapacityKbps = 2000; |
| 741 // Tcp starts at t = 0, media flow at t = 5s. |
| 742 const int64_t kOffSetsMs[] = {5000, 0}; |
| 743 |
| 744 int64_t max_delay_ms = kMaxQueueingDelayMs; |
| 745 int64_t rtt_ms = 2 * kOneWayDelayMs; |
| 746 |
| 747 // Test also with one way propagation delay = 100ms. |
| 748 // rtt_ms = 2 * 100; |
| 749 // Test also with bottleneck queue size = 20ms and 1000ms. |
| 750 // max_delay_ms = 20; |
| 751 // max_delay_ms = 1000; |
| 752 |
| 753 std::string title("5.6_Long_TCP_Fairness"); |
| 754 std::string flow_name(bwe_names[bwe_type] + 'x' + bwe_names[kTcpEstimator]); |
| 755 |
| 756 RunFairnessTest(bwe_type, kNumRmcatFlows, kNumTcpFlows, kRunTimeS, |
| 757 kCapacityKbps, max_delay_ms, rtt_ms, kMaxJitterMs, kOffSetsMs, |
| 758 title, flow_name); |
| 759 } |
| 760 |
| 761 // 5.7. RMCAT Flows competing with multiple short TCP Flows. |
| 762 void BweTest::RunMultipleShortTcpFairness( |
| 763 BandwidthEstimatorType bwe_type, |
| 764 std::vector<int> tcp_file_sizes_bytes, |
| 765 std::vector<int64_t> tcp_starting_times_ms) { |
| 766 // Two RMCAT flows and ten TCP flows. |
| 767 const int kAllRmcatFlowIds[] = {0, 1}; |
| 768 const int kAllTcpFlowIds[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; |
| 769 |
| 770 assert(tcp_starting_times_ms.size() == tcp_file_sizes_bytes.size() && |
| 771 tcp_starting_times_ms.size() == ARRAY_SIZE(kAllTcpFlowIds)); |
| 772 |
| 773 const size_t kNumRmcatFlows = ARRAY_SIZE(kAllRmcatFlowIds); |
| 774 const size_t kNumTotalFlows = kNumRmcatFlows + ARRAY_SIZE(kAllTcpFlowIds); |
| 775 |
| 776 rtc::scoped_ptr<AdaptiveVideoSource> sources[kNumRmcatFlows]; |
| 777 rtc::scoped_ptr<PacketSender> senders[kNumTotalFlows]; |
| 778 rtc::scoped_ptr<MetricRecorder> metric_recorders[kNumTotalFlows]; |
| 779 rtc::scoped_ptr<PacketReceiver> receivers[kNumTotalFlows]; |
| 780 |
| 781 // RMCAT Flows are initialized simultaneosly at t=5 seconds. |
| 782 const int64_t kRmcatStartingTimeMs = 5 * 1000; |
| 783 for (size_t id : kAllRmcatFlowIds) { |
| 784 sources[id].reset(new AdaptiveVideoSource(static_cast<int>(id), 30, 300, 0, |
| 785 kRmcatStartingTimeMs)); |
| 786 senders[id].reset(new VideoSender(&uplink_, sources[id].get(), bwe_type)); |
| 787 } |
| 788 |
| 789 for (size_t id : kAllTcpFlowIds) { |
| 790 senders[id].reset(new TcpSender(&uplink_, static_cast<int>(id), |
| 791 tcp_starting_times_ms[id - kNumRmcatFlows], |
| 792 tcp_file_sizes_bytes[id - kNumRmcatFlows])); |
| 793 } |
| 794 |
| 795 FlowIds flow_ids = CreateFlowIdRange(0, static_cast<int>(kNumTotalFlows - 1)); |
| 796 DefaultEvaluationFilter up_filter(&uplink_, flow_ids); |
| 797 |
| 798 LinkShare link_share(&(up_filter.choke)); |
| 799 |
| 800 RateCounterFilter total_utilization(&uplink_, flow_ids, "Total_utilization"); |
| 801 |
| 802 // Delays is being plotted only for the first flow. |
| 803 // To plot all of them, replace "i == 0" with "true" on new PacketReceiver(). |
| 804 for (size_t id : kAllRmcatFlowIds) { |
| 805 metric_recorders[id].reset( |
| 806 new MetricRecorder(bwe_names[bwe_type], static_cast<int>(id), |
| 807 senders[id].get(), &link_share)); |
| 808 receivers[id].reset(new PacketReceiver(&uplink_, static_cast<int>(id), |
| 809 bwe_type, id == 0, false, |
| 810 metric_recorders[id].get())); |
| 811 metric_recorders[id].get()->set_start_computing_metrics_ms( |
| 812 kRmcatStartingTimeMs); |
| 813 metric_recorders[id].get()->set_plot_available_capacity( |
| 814 id == 0 && plot_total_available_capacity_); |
| 815 } |
| 816 |
| 817 // Delays is not being plotted only for TCP flows. To plot all of them, |
| 818 // replace first "false" occurence with "true" on new PacketReceiver(). |
| 819 for (size_t id : kAllTcpFlowIds) { |
| 820 metric_recorders[id].reset( |
| 821 new MetricRecorder(bwe_names[kTcpEstimator], static_cast<int>(id), |
| 822 senders[id].get(), &link_share)); |
| 823 receivers[id].reset(new PacketReceiver(&uplink_, static_cast<int>(id), |
| 824 kTcpEstimator, false, false, |
| 825 metric_recorders[id].get())); |
| 826 metric_recorders[id].get()->set_plot_available_capacity( |
| 827 id == 0 && plot_total_available_capacity_); |
| 828 } |
| 829 |
| 830 DelayFilter down_filter(&downlink_, flow_ids); |
| 831 down_filter.SetOneWayDelayMs(kOneWayDelayMs); |
| 832 |
| 833 // Test also with one way propagation delay = 100ms. |
| 834 // up_filter.delay.SetOneWayDelayMs(100); |
| 835 // down_filter.SetOneWayDelayms(100); |
| 836 |
| 837 // Test also with bottleneck queue size = 20ms and 1000ms. |
| 838 // up_filter.choke.set_max_delay_ms(20); |
| 839 // up_filter.choke.set_max_delay_ms(1000); |
| 840 |
| 841 // Test also with no Jitter: |
| 842 // up_filter.jitter.SetMaxJitter(0); |
| 843 |
| 844 up_filter.choke.set_capacity_kbps(2000); |
| 845 |
| 846 RunFor(300 * 1000); // 0-300s. |
| 847 |
| 848 std::string title("5.7_Multiple_short_TCP_flows"); |
| 849 for (size_t id : kAllRmcatFlowIds) { |
| 850 metric_recorders[id].get()->PlotThroughputHistogram( |
| 851 title, bwe_names[bwe_type], kNumRmcatFlows, 0); |
| 852 metric_recorders[id].get()->PlotDelayHistogram( |
| 853 title, bwe_names[bwe_type], kNumRmcatFlows, kOneWayDelayMs); |
| 854 metric_recorders[id].get()->PlotLossHistogram( |
| 855 title, bwe_names[bwe_type], kNumRmcatFlows, |
| 856 receivers[id].get()->GlobalPacketLoss()); |
| 857 BWE_TEST_LOGGING_BASELINEBAR(5, bwe_names[bwe_type], kOneWayDelayMs, id); |
| 858 } |
| 859 } |
| 860 |
| 861 // 5.8. Three forward direction competing flows, constant capacity. |
| 862 // During the test, one of the flows is paused and later resumed. |
| 863 void BweTest::RunPauseResumeFlows(BandwidthEstimatorType bwe_type) { |
| 864 const int kAllFlowIds[] = {0, 1, 2}; // Three RMCAT flows. |
| 865 const size_t kNumFlows = ARRAY_SIZE(kAllFlowIds); |
| 866 |
| 867 rtc::scoped_ptr<AdaptiveVideoSource> sources[kNumFlows]; |
| 868 rtc::scoped_ptr<VideoSender> senders[kNumFlows]; |
| 869 rtc::scoped_ptr<MetricRecorder> metric_recorders[kNumFlows]; |
| 870 rtc::scoped_ptr<PacketReceiver> receivers[kNumFlows]; |
| 871 |
| 872 // Flows initialized simultaneously. |
| 873 const int64_t kStartingApartMs = 0; |
| 874 |
| 875 for (size_t i = 0; i < kNumFlows; ++i) { |
| 876 sources[i].reset(new AdaptiveVideoSource(kAllFlowIds[i], 30, 300, 0, |
| 877 i * kStartingApartMs)); |
| 878 senders[i].reset(new VideoSender(&uplink_, sources[i].get(), bwe_type)); |
| 879 } |
| 880 |
| 881 DefaultEvaluationFilter filter(&uplink_, |
| 882 CreateFlowIds(kAllFlowIds, kNumFlows)); |
| 883 |
| 884 LinkShare link_share(&(filter.choke)); |
| 885 |
| 886 RateCounterFilter total_utilization( |
| 887 &uplink_, CreateFlowIds(kAllFlowIds, kNumFlows), "Total_utilization"); |
| 888 |
| 889 // Delays is being plotted only for the first flow. |
| 890 // To plot all of them, replace "i == 0" with "true" on new PacketReceiver(). |
| 891 for (size_t i = 0; i < kNumFlows; ++i) { |
| 892 metric_recorders[i].reset( |
| 893 new MetricRecorder(bwe_names[bwe_type], static_cast<int>(i), |
| 894 senders[i].get(), &link_share)); |
| 895 receivers[i].reset(new PacketReceiver(&uplink_, kAllFlowIds[i], bwe_type, |
| 896 i == 0, false, |
| 897 metric_recorders[i].get())); |
| 898 metric_recorders[i].get()->set_start_computing_metrics_ms(kStartingApartMs * |
| 899 (kNumFlows - 1)); |
| 900 metric_recorders[i].get()->set_plot_available_capacity( |
| 901 i == 0 && plot_total_available_capacity_); |
| 902 } |
| 903 |
| 904 // Test also with one way propagation delay = 100ms. |
| 905 // filter.delay.SetOneWayDelayMs(100); |
| 906 filter.choke.set_capacity_kbps(3500); |
| 907 |
| 908 RunFor(40 * 1000); // 0-40s. |
| 909 |
| 910 senders[0].get()->Pause(); |
| 911 metric_recorders[0].get()->PauseFlow(); |
| 912 RunFor(20 * 1000); // 40-60s. |
| 913 |
| 914 senders[0].get()->Resume(); |
| 915 metric_recorders[0].get()->ResumeFlow(20 * 1000); |
| 916 RunFor(60 * 1000); // 60-120s. |
| 917 |
| 918 int64_t paused[] = {20 * 1000, 0, 0}; |
| 919 |
| 920 // First flow is being paused, hence having a different optimum. |
| 921 const std::string optima_lines[] = {"1", "2", "2"}; |
| 922 |
| 923 std::string title("5.8_Pause_and_resume_media_flow"); |
| 924 for (size_t i = 0; i < kNumFlows; ++i) { |
| 925 metric_recorders[i].get()->PlotThroughputHistogram( |
| 926 title, bwe_names[bwe_type], kNumFlows, paused[i], optima_lines[i]); |
| 927 metric_recorders[i].get()->PlotDelayHistogram(title, bwe_names[bwe_type], |
| 928 kNumFlows, kOneWayDelayMs); |
| 929 metric_recorders[i].get()->PlotLossHistogram( |
| 930 title, bwe_names[bwe_type], kNumFlows, |
| 931 receivers[i].get()->GlobalPacketLoss()); |
| 932 BWE_TEST_LOGGING_BASELINEBAR(5, bwe_names[bwe_type], kOneWayDelayMs, i); |
| 933 } |
| 934 } |
| 935 |
| 936 // Following functions are used for randomizing TCP file size and |
| 937 // starting time, used on 5.7 RunMultipleShortTcpFairness. |
| 938 // They are pseudo-random generators, creating always the same |
| 939 // value sequence for a given Random seed. |
| 940 |
| 941 std::vector<int> BweTest::GetFileSizesBytes(int num_files) { |
| 942 // File size chosen from uniform distribution between [100,1000] kB. |
| 943 const int kMinKbytes = 100; |
| 944 const int kMaxKbytes = 1000; |
| 945 |
| 946 Random random(0x12345678); |
| 947 std::vector<int> tcp_file_sizes_bytes; |
| 948 |
| 949 while (num_files-- > 0) { |
| 950 tcp_file_sizes_bytes.push_back(random.Rand(kMinKbytes, kMaxKbytes) * 1000); |
| 951 } |
| 952 |
| 953 return tcp_file_sizes_bytes; |
| 954 } |
| 955 |
| 956 std::vector<int64_t> BweTest::GetStartingTimesMs(int num_files) { |
| 957 // OFF state behaves as an exp. distribution with mean = 10 seconds. |
| 958 const float kMeanMs = 10000.0f; |
| 959 Random random(0x12345678); |
| 960 |
| 961 std::vector<int64_t> tcp_starting_times_ms; |
| 962 |
| 963 // Two TCP Flows are initialized simultaneosly at t=0 seconds. |
| 964 for (int i = 0; i < 2; ++i, --num_files) { |
| 965 tcp_starting_times_ms.push_back(0); |
| 966 } |
| 967 |
| 968 // Other TCP Flows are initialized in an OFF state. |
| 969 while (num_files-- > 0) { |
| 970 tcp_starting_times_ms.push_back( |
| 971 static_cast<int64_t>(random.Exponential(1.0f / kMeanMs))); |
| 972 } |
| 973 |
| 974 return tcp_starting_times_ms; |
| 975 } |
| 976 |
327 } // namespace bwe | 977 } // namespace bwe |
328 } // namespace testing | 978 } // namespace testing |
329 } // namespace webrtc | 979 } // namespace webrtc |
OLD | NEW |